diff options
author | Archit Taneja <archit@ti.com> | 2013-08-06 09:26:55 (GMT) |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2013-10-09 09:42:03 (GMT) |
commit | f382d9eb82cac42b5d162cb498cd41245dfafb42 (patch) | |
tree | 466af4988df7a57e70de0b1316ebe91e18add757 /drivers/video/omap2 | |
parent | 9f192a92286c41c32b0929e60ac7136baa5bd2a8 (diff) | |
download | linux-f382d9eb82cac42b5d162cb498cd41245dfafb42.tar.xz |
omapdss: HDMI: create a Wrapper library
HDMI wrapper is a block common to DSS in OMAP4, OMAP5 and DRA7x. Move the
existing functions from ti_hdmi_4xxx_ip.c to a separate file. These funcs are
called directly from the hdmi driver rather than hdmi_ip_ops funtion pointer
calls.
Add new wrapper funcs which can be used by other hdmi libraries like core, pll
and phy. Move some of the enums, structs and funcs related to the wrapper from
ti_hdmi_4xxx_ip.h to ti_hdmi.h. These will be shared amongst the omap4/5 hdmi
platform drivers and other libraries.
The old hdmi_wp_init() is removed since it didn't do anything. Timing parameters
like interlace, hsync_level and vsync_level weren't copied correctly before.
Those are copied correctly now.
The DT/hwmod information for hdmi doesn't split the address space according to
the required sub blocks. Keep the address offset and size information in the
driver for now. This will be removed when the driver gets the information
correctly from DT/hwmod.
Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r-- | drivers/video/omap2/dss/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 5 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 26 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi_wp.c | 302 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi.h | 131 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 308 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h | 85 |
7 files changed, 479 insertions, 380 deletions
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile index 94832eb..56ce6bd 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/omap2/dss/Makefile @@ -10,5 +10,5 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o -omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o ti_hdmi_4xxx_ip.o +omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o hdmi_wp.o ti_hdmi_4xxx_ip.o ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index b9cfebb..db359e8 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -799,15 +799,10 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { .read_edid = ti_hdmi_4xxx_read_edid, .pll_enable = ti_hdmi_4xxx_pll_enable, .pll_disable = ti_hdmi_4xxx_pll_disable, - .video_enable = ti_hdmi_4xxx_wp_video_start, - .video_disable = ti_hdmi_4xxx_wp_video_stop, - .dump_wrapper = ti_hdmi_4xxx_wp_dump, .dump_core = ti_hdmi_4xxx_core_dump, .dump_pll = ti_hdmi_4xxx_pll_dump, .dump_phy = ti_hdmi_4xxx_phy_dump, #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) - .audio_enable = ti_hdmi_4xxx_wp_audio_enable, - .audio_disable = ti_hdmi_4xxx_wp_audio_disable, .audio_start = ti_hdmi_4xxx_audio_start, .audio_stop = ti_hdmi_4xxx_audio_stop, .audio_config = ti_hdmi_4xxx_audio_config, diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 82a9640..f2475fc 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -40,7 +40,6 @@ #include "dss.h" #include "dss_features.h" -#define HDMI_WP 0x0 #define HDMI_CORE_SYS 0x400 #define HDMI_CORE_AV 0x900 #define HDMI_PLLCTRL 0x200 @@ -529,7 +528,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); - hdmi.ip_data.ops->video_disable(&hdmi.ip_data); + hdmi_wp_video_stop(&hdmi.ip_data.wp); /* config the PLL and PHY hdmi_set_pll_pwrfirst */ r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); @@ -552,7 +551,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) /* tv size */ dss_mgr_set_timings(mgr, p); - r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); + r = hdmi_wp_video_start(&hdmi.ip_data.wp); if (r) goto err_vid_enable; @@ -563,7 +562,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) return 0; err_mgr_enable: - hdmi.ip_data.ops->video_disable(&hdmi.ip_data); + hdmi_wp_video_stop(&hdmi.ip_data.wp); err_vid_enable: hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); err_phy_enable: @@ -579,7 +578,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev) dss_mgr_disable(mgr); - hdmi.ip_data.ops->video_disable(&hdmi.ip_data); + hdmi_wp_video_stop(&hdmi.ip_data.wp); hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); @@ -642,7 +641,7 @@ static void hdmi_dump_regs(struct seq_file *s) return; } - hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); + hdmi_wp_dump(&hdmi.ip_data.wp, s); hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s); hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s); @@ -946,8 +945,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev) goto err; } - - r = hdmi.ip_data.ops->audio_enable(&hdmi.ip_data); + r = hdmi_wp_audio_enable(&hdmi.ip_data.wp, true); if (r) goto err; @@ -961,7 +959,7 @@ err: static void hdmi_audio_disable(struct omap_dss_device *dssdev) { - hdmi.ip_data.ops->audio_disable(&hdmi.ip_data); + hdmi_wp_audio_enable(&hdmi.ip_data.wp, false); } static int hdmi_audio_start(struct omap_dss_device *dssdev) @@ -1086,7 +1084,6 @@ static void __exit hdmi_uninit_output(struct platform_device *pdev) /* HDMI HW IP initialisation */ static int omapdss_hdmihw_probe(struct platform_device *pdev) { - struct resource *res; int r; hdmi.pdev = pdev; @@ -1094,12 +1091,9 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) mutex_init(&hdmi.lock); mutex_init(&hdmi.ip_data.lock); - res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); - - /* Base address taken from platform */ - hdmi.ip_data.base_wp = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(hdmi.ip_data.base_wp)) - return PTR_ERR(hdmi.ip_data.base_wp); + r = hdmi_wp_init(pdev, &hdmi.ip_data.wp); + if (r) + return r; hdmi.ip_data.irq = platform_get_irq(pdev, 0); if (hdmi.ip_data.irq < 0) { diff --git a/drivers/video/omap2/dss/hdmi_wp.c b/drivers/video/omap2/dss/hdmi_wp.c new file mode 100644 index 0000000..1b6dbe10 --- /dev/null +++ b/drivers/video/omap2/dss/hdmi_wp.c @@ -0,0 +1,302 @@ +/* + * HDMI wrapper + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <video/omapdss.h> + +#include "dss.h" +#include "ti_hdmi.h" +#include "ti_hdmi_4xxx_ip.h" + +static inline void hdmi_write_reg(void __iomem *base_addr, const u16 idx, + u32 val) +{ + __raw_writel(val, base_addr + idx); +} + +static inline u32 hdmi_read_reg(void __iomem *base_addr, const u16 idx) +{ + return __raw_readl(base_addr + idx); +} + +#define REG_FLD_MOD(base, idx, val, start, end) \ + hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\ + val, start, end)) +#define REG_GET(base, idx, start, end) \ + FLD_GET(hdmi_read_reg(base, idx), start, end) + +static inline int hdmi_wait_for_bit_change(void __iomem *base_addr, + const u16 idx, int b2, int b1, u32 val) +{ + u32 t = 0; + while (val != REG_GET(base_addr, idx, b2, b1)) { + udelay(1); + if (t++ > 10000) + return !val; + } + return val; +} + +void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s) +{ +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, hdmi_read_reg(wp->base, r)) + + DUMPREG(HDMI_WP_REVISION); + DUMPREG(HDMI_WP_SYSCONFIG); + DUMPREG(HDMI_WP_IRQSTATUS_RAW); + DUMPREG(HDMI_WP_IRQSTATUS); + DUMPREG(HDMI_WP_IRQENABLE_SET); + DUMPREG(HDMI_WP_IRQENABLE_CLR); + DUMPREG(HDMI_WP_IRQWAKEEN); + DUMPREG(HDMI_WP_PWR_CTRL); + DUMPREG(HDMI_WP_DEBOUNCE); + DUMPREG(HDMI_WP_VIDEO_CFG); + DUMPREG(HDMI_WP_VIDEO_SIZE); + DUMPREG(HDMI_WP_VIDEO_TIMING_H); + DUMPREG(HDMI_WP_VIDEO_TIMING_V); + DUMPREG(HDMI_WP_WP_CLK); + DUMPREG(HDMI_WP_AUDIO_CFG); + DUMPREG(HDMI_WP_AUDIO_CFG2); + DUMPREG(HDMI_WP_AUDIO_CTRL); + DUMPREG(HDMI_WP_AUDIO_DATA); +} + +u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp) +{ + return hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS); +} + +void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus) +{ + hdmi_write_reg(wp->base, HDMI_WP_IRQSTATUS, irqstatus); + /* flush posted write */ + hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS); +} + +void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask) +{ + hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_SET, mask); +} + +void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask) +{ + hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_CLR, mask); +} + +/* PHY_PWR_CMD */ +int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val) +{ + /* Return if already the state */ + if (REG_GET(wp->base, HDMI_WP_PWR_CTRL, 5, 4) == val) + return 0; + + /* Command for power control of HDMI PHY */ + REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 7, 6); + + /* Status of the power control of HDMI PHY */ + if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val) + != val) { + pr_err("Failed to set PHY power mode to %d\n", val); + return -ETIMEDOUT; + } + + return 0; +} + +/* PLL_PWR_CMD */ +int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val) +{ + /* Command for power control of HDMI PLL */ + REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 3, 2); + + /* wait till PHY_PWR_STATUS is set */ + if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val) + != val) { + pr_err("Failed to set PLL_PWR_STATUS\n"); + return -ETIMEDOUT; + } + + return 0; +} + +int hdmi_wp_video_start(struct hdmi_wp_data *wp) +{ + REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, true, 31, 31); + + return 0; +} + +void hdmi_wp_video_stop(struct hdmi_wp_data *wp) +{ + REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, false, 31, 31); +} + +void hdmi_wp_video_config_format(struct hdmi_wp_data *wp, + struct hdmi_video_format *video_fmt) +{ + u32 l = 0; + + REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, + 10, 8); + + l |= FLD_VAL(video_fmt->y_res, 31, 16); + l |= FLD_VAL(video_fmt->x_res, 15, 0); + hdmi_write_reg(wp->base, HDMI_WP_VIDEO_SIZE, l); +} + +void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp, + struct omap_video_timings *timings) +{ + u32 r; + bool vsync_pol, hsync_pol; + pr_debug("Enter hdmi_wp_video_config_interface\n"); + + vsync_pol = timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; + hsync_pol = timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; + + r = hdmi_read_reg(wp->base, HDMI_WP_VIDEO_CFG); + r = FLD_MOD(r, vsync_pol, 7, 7); + r = FLD_MOD(r, hsync_pol, 6, 6); + r = FLD_MOD(r, timings->interlace, 3, 3); + r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ + hdmi_write_reg(wp->base, HDMI_WP_VIDEO_CFG, r); +} + +void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp, + struct omap_video_timings *timings) +{ + u32 timing_h = 0; + u32 timing_v = 0; + + pr_debug("Enter hdmi_wp_video_config_timing\n"); + + timing_h |= FLD_VAL(timings->hbp, 31, 20); + timing_h |= FLD_VAL(timings->hfp, 19, 8); + timing_h |= FLD_VAL(timings->hsw, 7, 0); + hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_H, timing_h); + + timing_v |= FLD_VAL(timings->vbp, 31, 20); + timing_v |= FLD_VAL(timings->vfp, 19, 8); + timing_v |= FLD_VAL(timings->vsw, 7, 0); + hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_V, timing_v); +} + +void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, + struct omap_video_timings *timings, struct hdmi_config *param) +{ + pr_debug("Enter hdmi_wp_video_init_format\n"); + + video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444; + video_fmt->y_res = param->timings.y_res; + video_fmt->x_res = param->timings.x_res; + + timings->hbp = param->timings.hbp; + timings->hfp = param->timings.hfp; + timings->hsw = param->timings.hsw; + timings->vbp = param->timings.vbp; + timings->vfp = param->timings.vfp; + timings->vsw = param->timings.vsw; + timings->vsync_level = param->timings.vsync_level; + timings->hsync_level = param->timings.hsync_level; + timings->interlace = param->timings.interlace; +} + +#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) +void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, + struct hdmi_audio_format *aud_fmt) +{ + u32 r; + + DSSDBG("Enter hdmi_wp_audio_config_format\n"); + + r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG); + r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); + r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); + r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); + r = FLD_MOD(r, aud_fmt->type, 4, 4); + r = FLD_MOD(r, aud_fmt->justification, 3, 3); + r = FLD_MOD(r, aud_fmt->sample_order, 2, 2); + r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1); + r = FLD_MOD(r, aud_fmt->sample_size, 0, 0); + hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG, r); +} + +void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp, + struct hdmi_audio_dma *aud_dma) +{ + u32 r; + + DSSDBG("Enter hdmi_wp_audio_config_dma\n"); + + r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG2); + r = FLD_MOD(r, aud_dma->transfer_size, 15, 8); + r = FLD_MOD(r, aud_dma->block_size, 7, 0); + hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG2, r); + + r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CTRL); + r = FLD_MOD(r, aud_dma->mode, 9, 9); + r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0); + hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CTRL, r); +} + +int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable) +{ + REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 31, 31); + + return 0; +} + +int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable) +{ + REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 30, 30); + + return 0; +} +#endif + +#define WP_SIZE 0x200 + +int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp) +{ + struct resource *res; + struct resource temp_res; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_wp"); + if (!res) { + DSSDBG("can't get WP mem resource by name\n"); + /* + * if hwmod/DT doesn't have the memory resource information + * split into HDMI sub blocks by name, we try again by getting + * the platform's first resource. this code will be removed when + * the driver can get the mem resources by name + */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + DSSERR("can't get WP mem resource\n"); + return -EINVAL; + } + + temp_res.start = res->start; + temp_res.end = temp_res.start + WP_SIZE - 1; + res = &temp_res; + } + + wp->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!wp->base) { + DSSERR("can't ioremap HDMI WP\n"); + return -ENOMEM; + } + + return 0; +} diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h index 45215f4..d16f28d 100644 --- a/drivers/video/omap2/dss/ti_hdmi.h +++ b/drivers/video/omap2/dss/ti_hdmi.h @@ -21,6 +21,8 @@ #ifndef _TI_HDMI_H #define _TI_HDMI_H +#include <linux/platform_device.h> + struct hdmi_ip_data; enum hdmi_pll_pwr { @@ -30,6 +32,12 @@ enum hdmi_pll_pwr { HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3 }; +enum hdmi_phy_pwr { + HDMI_PHYPWRCMD_OFF = 0, + HDMI_PHYPWRCMD_LDOON = 1, + HDMI_PHYPWRCMD_TXON = 2 +}; + enum hdmi_core_hdmi_dvi { HDMI_DVI = 0, HDMI_HDMI = 1 @@ -42,11 +50,67 @@ enum hdmi_clk_refsel { HDMI_REFSEL_SYSCLK = 3 }; +enum hdmi_packing_mode { + HDMI_PACK_10b_RGB_YUV444 = 0, + HDMI_PACK_24b_RGB_YUV444_YUV422 = 1, + HDMI_PACK_20b_YUV422 = 2, + HDMI_PACK_ALREADYPACKED = 7 +}; + +enum hdmi_stereo_channels { + HDMI_AUDIO_STEREO_NOCHANNELS = 0, + HDMI_AUDIO_STEREO_ONECHANNEL = 1, + HDMI_AUDIO_STEREO_TWOCHANNELS = 2, + HDMI_AUDIO_STEREO_THREECHANNELS = 3, + HDMI_AUDIO_STEREO_FOURCHANNELS = 4 +}; + +enum hdmi_audio_type { + HDMI_AUDIO_TYPE_LPCM = 0, + HDMI_AUDIO_TYPE_IEC = 1 +}; + +enum hdmi_audio_justify { + HDMI_AUDIO_JUSTIFY_LEFT = 0, + HDMI_AUDIO_JUSTIFY_RIGHT = 1 +}; + +enum hdmi_audio_sample_order { + HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0, + HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1 +}; + +enum hdmi_audio_samples_perword { + HDMI_AUDIO_ONEWORD_ONESAMPLE = 0, + HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1 +}; + +enum hdmi_audio_sample_size { + HDMI_AUDIO_SAMPLE_16BITS = 0, + HDMI_AUDIO_SAMPLE_24BITS = 1 +}; + +enum hdmi_audio_transf_mode { + HDMI_AUDIO_TRANSF_DMA = 0, + HDMI_AUDIO_TRANSF_IRQ = 1 +}; + +enum hdmi_audio_blk_strt_end_sig { + HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0, + HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1 +}; + struct hdmi_cm { int code; int mode; }; +struct hdmi_video_format { + enum hdmi_packing_mode packing_mode; + u32 y_res; /* Line per panel */ + u32 x_res; /* pixel per line */ +}; + struct hdmi_config { struct omap_video_timings timings; struct hdmi_cm cm; @@ -63,6 +127,24 @@ struct hdmi_pll_info { enum hdmi_clk_refsel refsel; }; +struct hdmi_audio_format { + enum hdmi_stereo_channels stereo_channels; + u8 active_chnnls_msk; + enum hdmi_audio_type type; + enum hdmi_audio_justify justification; + enum hdmi_audio_sample_order sample_order; + enum hdmi_audio_samples_perword samples_per_word; + enum hdmi_audio_sample_size sample_size; + enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end; +}; + +struct hdmi_audio_dma { + u8 transfer_size; + u8 block_size; + enum hdmi_audio_transf_mode mode; + u16 fifo_threshold; +}; + struct ti_hdmi_ip_ops { void (*video_configure)(struct hdmi_ip_data *ip_data); @@ -77,12 +159,6 @@ struct ti_hdmi_ip_ops { void (*pll_disable)(struct hdmi_ip_data *ip_data); - int (*video_enable)(struct hdmi_ip_data *ip_data); - - void (*video_disable)(struct hdmi_ip_data *ip_data); - - void (*dump_wrapper)(struct hdmi_ip_data *ip_data, struct seq_file *s); - void (*dump_core)(struct hdmi_ip_data *ip_data, struct seq_file *s); void (*dump_pll)(struct hdmi_ip_data *ip_data, struct seq_file *s); @@ -90,10 +166,6 @@ struct ti_hdmi_ip_ops { void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s); #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) - int (*audio_enable)(struct hdmi_ip_data *ip_data); - - void (*audio_disable)(struct hdmi_ip_data *ip_data); - int (*audio_start)(struct hdmi_ip_data *ip_data); void (*audio_stop)(struct hdmi_ip_data *ip_data); @@ -147,8 +219,13 @@ struct hdmi_core_infoframe_avi { u16 db12_13_pixel_sofright; }; +struct hdmi_wp_data { + void __iomem *base; +}; + struct hdmi_ip_data { - void __iomem *base_wp; /* HDMI wrapper */ + struct hdmi_wp_data wp; + unsigned long core_sys_offset; unsigned long core_av_offset; unsigned long pll_offset; @@ -162,22 +239,44 @@ struct hdmi_ip_data { /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ struct mutex lock; }; + +/* HDMI wrapper funcs */ +int hdmi_wp_video_start(struct hdmi_wp_data *wp); +void hdmi_wp_video_stop(struct hdmi_wp_data *wp); +void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s); +u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp); +void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus); +void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask); +void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask); +int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val); +int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val); +void hdmi_wp_video_config_format(struct hdmi_wp_data *wp, + struct hdmi_video_format *video_fmt); +void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp, + struct omap_video_timings *timings); +void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp, + struct omap_video_timings *timings); +void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, + struct omap_video_timings *timings, struct hdmi_config *param); +int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp); + int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); -int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data); int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data); void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts); -int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data); +int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); +int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable); +void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, + struct hdmi_audio_format *aud_fmt); +void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp, + struct hdmi_audio_dma *aud_dma); int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data); void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data); int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index fd4172b..d4b8883 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c @@ -52,43 +52,44 @@ static inline u32 hdmi_read_reg(void __iomem *base_addr, return __raw_readl(base_addr + idx); } -static inline void __iomem *hdmi_wp_base(struct hdmi_ip_data *ip_data) +#define REG_FLD_MOD(base, idx, val, start, end) \ + hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\ + val, start, end)) +#define REG_GET(base, idx, start, end) \ + FLD_GET(hdmi_read_reg(base, idx), start, end) + +static inline int hdmi_wait_for_bit_change(void __iomem *base_addr, + const u16 idx, int b2, int b1, u32 val) { - return ip_data->base_wp; + u32 t = 0; + while (val != REG_GET(base_addr, idx, b2, b1)) { + udelay(1); + if (t++ > 10000) + return !val; + } + return val; } static inline void __iomem *hdmi_phy_base(struct hdmi_ip_data *ip_data) { - return ip_data->base_wp + ip_data->phy_offset; + return ip_data->wp.base + ip_data->phy_offset; } static inline void __iomem *hdmi_pll_base(struct hdmi_ip_data *ip_data) { - return ip_data->base_wp + ip_data->pll_offset; + return ip_data->wp.base + ip_data->pll_offset; } static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data) { - return ip_data->base_wp + ip_data->core_av_offset; + return ip_data->wp.base + ip_data->core_av_offset; } static inline void __iomem *hdmi_core_sys_base(struct hdmi_ip_data *ip_data) { - return ip_data->base_wp + ip_data->core_sys_offset; + return ip_data->wp.base + ip_data->core_sys_offset; } -static inline int hdmi_wait_for_bit_change(void __iomem *base_addr, - const u16 idx, - int b2, int b1, u32 val) -{ - u32 t = 0; - while (val != REG_GET(base_addr, idx, b2, b1)) { - udelay(1); - if (t++ > 10000) - return !val; - } - return val; -} static int hdmi_pll_init(struct hdmi_ip_data *ip_data) { @@ -156,41 +157,6 @@ static int hdmi_pll_init(struct hdmi_ip_data *ip_data) return 0; } -/* PHY_PWR_CMD */ -static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val) -{ - /* Return if already the state */ - if (REG_GET(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, 5, 4) == val) - return 0; - - /* Command for power control of HDMI PHY */ - REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6); - - /* Status of the power control of HDMI PHY */ - if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), - HDMI_WP_PWR_CTRL, 5, 4, val) != val) { - pr_err("Failed to set PHY power mode to %d\n", val); - return -ETIMEDOUT; - } - - return 0; -} - -/* PLL_PWR_CMD */ -static int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val) -{ - /* Command for power control of HDMI PLL */ - REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 3, 2); - - /* wait till PHY_PWR_STATUS is set */ - if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, - 1, 0, val) != val) { - pr_err("Failed to set PLL_PWR_STATUS\n"); - return -ETIMEDOUT; - } - - return 0; -} static int hdmi_pll_reset(struct hdmi_ip_data *ip_data) { @@ -211,11 +177,11 @@ int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data) { u16 r = 0; - r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); + r = hdmi_wp_set_pll_pwr(&ip_data->wp, HDMI_PLLPWRCMD_ALLOFF); if (r) return r; - r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); + r = hdmi_wp_set_pll_pwr(&ip_data->wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); if (r) return r; @@ -232,19 +198,16 @@ int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data) void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data) { - hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); + hdmi_wp_set_pll_pwr(&ip_data->wp, HDMI_PLLPWRCMD_ALLOFF); } static irqreturn_t hdmi_irq_handler(int irq, void *data) { struct hdmi_ip_data *ip_data = data; - void __iomem *wp_base = hdmi_wp_base(ip_data); u32 irqstatus; - irqstatus = hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS); - hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS, irqstatus); - /* flush posted write */ - hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS); + irqstatus = hdmi_wp_get_irqstatus(&ip_data->wp); + hdmi_wp_set_irqstatus(&ip_data->wp, irqstatus); if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && irqstatus & HDMI_IRQ_LINK_DISCONNECT) { @@ -254,18 +217,16 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) * raises connect interrupt if a cable is connected, or nothing * if cable is not connected. */ - hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); + hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_OFF); - hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS, - HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); - /* flush posted write */ - hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS); + hdmi_wp_set_irqstatus(&ip_data->wp, HDMI_IRQ_LINK_CONNECT | + HDMI_IRQ_LINK_DISCONNECT); - hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); + hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_LDOON); } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { - hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON); + hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_TXON); } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { - hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); + hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_LDOON); } return IRQ_HANDLED; @@ -274,15 +235,15 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data) { u16 r = 0; + u32 irqstatus; void __iomem *phy_base = hdmi_phy_base(ip_data); - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_CLR, - 0xffffffff); + hdmi_wp_clear_irqenable(&ip_data->wp, 0xffffffff); - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQSTATUS, - HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); + irqstatus = hdmi_wp_get_irqstatus(&ip_data->wp); + hdmi_wp_set_irqstatus(&ip_data->wp, irqstatus); - r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); + r = hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_LDOON); if (r) return r; @@ -311,12 +272,12 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data) IRQF_ONESHOT, "OMAP HDMI", ip_data); if (r) { DSSERR("HDMI IRQ request failed\n"); - hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); + hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_OFF); return r; } - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_SET, - HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); + hdmi_wp_set_irqenable(&ip_data->wp, + HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); return 0; } @@ -325,7 +286,7 @@ void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data) { free_irq(ip_data->irq, ip_data); - hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); + hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_OFF); } static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) @@ -679,99 +640,7 @@ static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data, (repeat_cfg.generic_pkt_repeat)); } -static void hdmi_wp_init(struct omap_video_timings *timings, - struct hdmi_video_format *video_fmt) -{ - pr_debug("Enter hdmi_wp_init\n"); - - timings->hbp = 0; - timings->hfp = 0; - timings->hsw = 0; - timings->vbp = 0; - timings->vfp = 0; - timings->vsw = 0; - - video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444; - video_fmt->y_res = 0; - video_fmt->x_res = 0; - -} - -int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data) -{ - REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, true, 31, 31); - return 0; -} - -void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data) -{ - REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, false, 31, 31); -} - -static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, - struct omap_video_timings *timings, struct hdmi_config *param) -{ - pr_debug("Enter hdmi_wp_video_init_format\n"); - - video_fmt->y_res = param->timings.y_res; - video_fmt->x_res = param->timings.x_res; - - timings->hbp = param->timings.hbp; - timings->hfp = param->timings.hfp; - timings->hsw = param->timings.hsw; - timings->vbp = param->timings.vbp; - timings->vfp = param->timings.vfp; - timings->vsw = param->timings.vsw; -} - -static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, - struct hdmi_video_format *video_fmt) -{ - u32 l = 0; - - REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, - video_fmt->packing_mode, 10, 8); - - l |= FLD_VAL(video_fmt->y_res, 31, 16); - l |= FLD_VAL(video_fmt->x_res, 15, 0); - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l); -} - -static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) -{ - u32 r; - bool vsync_pol, hsync_pol; - pr_debug("Enter hdmi_wp_video_config_interface\n"); - - vsync_pol = ip_data->cfg.timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; - hsync_pol = ip_data->cfg.timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; - - r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); - r = FLD_MOD(r, vsync_pol, 7, 7); - r = FLD_MOD(r, hsync_pol, 6, 6); - r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3); - r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); -} - -static void hdmi_wp_video_config_timing(struct hdmi_ip_data *ip_data, - struct omap_video_timings *timings) -{ - u32 timing_h = 0; - u32 timing_v = 0; - - pr_debug("Enter hdmi_wp_video_config_timing\n"); - timing_h |= FLD_VAL(timings->hbp, 31, 20); - timing_h |= FLD_VAL(timings->hfp, 19, 8); - timing_h |= FLD_VAL(timings->hsw, 7, 0); - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_H, timing_h); - - timing_v |= FLD_VAL(timings->vbp, 31, 20); - timing_v |= FLD_VAL(timings->vfp, 19, 8); - timing_v |= FLD_VAL(timings->vsw, 7, 0); - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v); -} void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) { @@ -784,20 +653,18 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) struct hdmi_core_packet_enable_repeat repeat_cfg; struct hdmi_config *cfg = &ip_data->cfg; - hdmi_wp_init(&video_timing, &video_format); - hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg); - hdmi_wp_video_init_format(&video_format, &video_timing, cfg); + hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); - hdmi_wp_video_config_timing(ip_data, &video_timing); + hdmi_wp_video_config_timing(&ip_data->wp, &video_timing); /* video config */ video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; - hdmi_wp_video_config_format(ip_data, &video_format); + hdmi_wp_video_config_format(&ip_data->wp, &video_format); - hdmi_wp_video_config_interface(ip_data); + hdmi_wp_video_config_interface(&ip_data->wp, &video_timing); /* * configure core video part @@ -850,31 +717,6 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) hdmi_core_av_packet_config(ip_data, repeat_cfg); } -void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) -{ -#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r,\ - hdmi_read_reg(hdmi_wp_base(ip_data), r)) - - DUMPREG(HDMI_WP_REVISION); - DUMPREG(HDMI_WP_SYSCONFIG); - DUMPREG(HDMI_WP_IRQSTATUS_RAW); - DUMPREG(HDMI_WP_IRQSTATUS); - DUMPREG(HDMI_WP_IRQENABLE_SET); - DUMPREG(HDMI_WP_IRQENABLE_CLR); - DUMPREG(HDMI_WP_IRQWAKEEN); - DUMPREG(HDMI_WP_PWR_CTRL); - DUMPREG(HDMI_WP_DEBOUNCE); - DUMPREG(HDMI_WP_VIDEO_CFG); - DUMPREG(HDMI_WP_VIDEO_SIZE); - DUMPREG(HDMI_WP_VIDEO_TIMING_H); - DUMPREG(HDMI_WP_VIDEO_TIMING_V); - DUMPREG(HDMI_WP_WP_CLK); - DUMPREG(HDMI_WP_AUDIO_CFG); - DUMPREG(HDMI_WP_AUDIO_CFG2); - DUMPREG(HDMI_WP_AUDIO_CTRL); - DUMPREG(HDMI_WP_AUDIO_DATA); -} - void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) { #define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ @@ -1071,43 +913,6 @@ void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) } #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -static void ti_hdmi_4xxx_wp_audio_config_format(struct hdmi_ip_data *ip_data, - struct hdmi_audio_format *aud_fmt) -{ - u32 r; - - DSSDBG("Enter hdmi_wp_audio_config_format\n"); - - r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG); - r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); - r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); - r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); - r = FLD_MOD(r, aud_fmt->type, 4, 4); - r = FLD_MOD(r, aud_fmt->justification, 3, 3); - r = FLD_MOD(r, aud_fmt->sample_order, 2, 2); - r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1); - r = FLD_MOD(r, aud_fmt->sample_size, 0, 0); - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r); -} - -static void ti_hdmi_4xxx_wp_audio_config_dma(struct hdmi_ip_data *ip_data, - struct hdmi_audio_dma *aud_dma) -{ - u32 r; - - DSSDBG("Enter hdmi_wp_audio_config_dma\n"); - - r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2); - r = FLD_MOD(r, aud_dma->transfer_size, 15, 8); - r = FLD_MOD(r, aud_dma->block_size, 7, 0); - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2, r); - - r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL); - r = FLD_MOD(r, aud_dma->mode, 9, 9); - r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0); - hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r); -} - static void ti_hdmi_4xxx_core_audio_config(struct hdmi_ip_data *ip_data, struct hdmi_core_audio_config *cfg) { @@ -1424,8 +1229,8 @@ int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; /* configure DMA and audio FIFO format*/ - ti_hdmi_4xxx_wp_audio_config_dma(ip_data, &audio_dma); - ti_hdmi_4xxx_wp_audio_config_format(ip_data, &audio_format); + hdmi_wp_audio_config_dma(&ip_data->wp, &audio_dma); + hdmi_wp_audio_config_format(&ip_data->wp, &audio_format); /* configure the core*/ ti_hdmi_4xxx_core_audio_config(ip_data, &core); @@ -1436,25 +1241,13 @@ int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, return 0; } -int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data) -{ - REG_FLD_MOD(hdmi_wp_base(ip_data), - HDMI_WP_AUDIO_CTRL, true, 31, 31); - return 0; -} - -void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data) -{ - REG_FLD_MOD(hdmi_wp_base(ip_data), - HDMI_WP_AUDIO_CTRL, false, 31, 31); -} - int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data) { REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_MODE, true, 0, 0); - REG_FLD_MOD(hdmi_wp_base(ip_data), - HDMI_WP_AUDIO_CTRL, true, 30, 30); + + hdmi_wp_audio_core_req_enable(&ip_data->wp, true); + return 0; } @@ -1462,8 +1255,8 @@ void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data) { REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_AUD_MODE, false, 0, 0); - REG_FLD_MOD(hdmi_wp_base(ip_data), - HDMI_WP_AUDIO_CTRL, false, 30, 30); + + hdmi_wp_audio_core_req_enable(&ip_data->wp, false); } int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size) @@ -1474,4 +1267,5 @@ int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size) *size = 4; return 0; } + #endif diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h index b25269c..dc49713 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h @@ -226,18 +226,6 @@ #define HDMI_TXPHY_POWER_CTRL 0x8 #define HDMI_TXPHY_PAD_CFG_CTRL 0xC -#define REG_FLD_MOD(base, idx, val, start, end) \ - hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\ - val, start, end)) -#define REG_GET(base, idx, start, end) \ - FLD_GET(hdmi_read_reg(base, idx), start, end) - -enum hdmi_phy_pwr { - HDMI_PHYPWRCMD_OFF = 0, - HDMI_PHYPWRCMD_LDOON = 1, - HDMI_PHYPWRCMD_TXON = 2 -}; - enum hdmi_core_inputbus_width { HDMI_INPUT_8BIT = 0, HDMI_INPUT_10BIT = 1, @@ -328,13 +316,6 @@ enum hdmi_core_infoframe { HDMI_INFOFRAME_AVI_DB5PR_10 = 9, }; -enum hdmi_packing_mode { - HDMI_PACK_10b_RGB_YUV444 = 0, - HDMI_PACK_24b_RGB_YUV444_YUV422 = 1, - HDMI_PACK_20b_YUV422 = 2, - HDMI_PACK_ALREADYPACKED = 7 -}; - enum hdmi_core_audio_layout { HDMI_AUDIO_LAYOUT_2CH = 0, HDMI_AUDIO_LAYOUT_8CH = 1 @@ -345,49 +326,6 @@ enum hdmi_core_cts_mode { HDMI_AUDIO_CTS_MODE_SW = 1 }; -enum hdmi_stereo_channels { - HDMI_AUDIO_STEREO_NOCHANNELS = 0, - HDMI_AUDIO_STEREO_ONECHANNEL = 1, - HDMI_AUDIO_STEREO_TWOCHANNELS = 2, - HDMI_AUDIO_STEREO_THREECHANNELS = 3, - HDMI_AUDIO_STEREO_FOURCHANNELS = 4 -}; - -enum hdmi_audio_type { - HDMI_AUDIO_TYPE_LPCM = 0, - HDMI_AUDIO_TYPE_IEC = 1 -}; - -enum hdmi_audio_justify { - HDMI_AUDIO_JUSTIFY_LEFT = 0, - HDMI_AUDIO_JUSTIFY_RIGHT = 1 -}; - -enum hdmi_audio_sample_order { - HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0, - HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1 -}; - -enum hdmi_audio_samples_perword { - HDMI_AUDIO_ONEWORD_ONESAMPLE = 0, - HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1 -}; - -enum hdmi_audio_sample_size { - HDMI_AUDIO_SAMPLE_16BITS = 0, - HDMI_AUDIO_SAMPLE_24BITS = 1 -}; - -enum hdmi_audio_transf_mode { - HDMI_AUDIO_TRANSF_DMA = 0, - HDMI_AUDIO_TRANSF_IRQ = 1 -}; - -enum hdmi_audio_blk_strt_end_sig { - HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0, - HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1 -}; - enum hdmi_audio_i2s_config { HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0, HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1, @@ -434,29 +372,6 @@ struct hdmi_core_packet_enable_repeat { u32 generic_pkt_repeat; }; -struct hdmi_video_format { - enum hdmi_packing_mode packing_mode; - u32 y_res; /* Line per panel */ - u32 x_res; /* pixel per line */ -}; - -struct hdmi_audio_format { - enum hdmi_stereo_channels stereo_channels; - u8 active_chnnls_msk; - enum hdmi_audio_type type; - enum hdmi_audio_justify justification; - enum hdmi_audio_sample_order sample_order; - enum hdmi_audio_samples_perword samples_per_word; - enum hdmi_audio_sample_size sample_size; - enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end; -}; - -struct hdmi_audio_dma { - u8 transfer_size; - u8 block_size; - enum hdmi_audio_transf_mode mode; - u16 fifo_threshold; -}; struct hdmi_core_audio_i2s_config { u8 in_length_bits; |