diff options
author | Marcel Tunnissen <Marcel.Tuennissen@stericsson.com> | 2011-04-19 09:15:46 +0200 |
---|---|---|
committer | Jonas ABERG <jonas.aberg@stericsson.com> | 2011-04-21 15:00:11 +0200 |
commit | 8fd63b94c44be823a9d9b1df41e4463046b3aba8 (patch) | |
tree | d1218fdf82d65c4c4350c711361ebf0d6093704e /drivers | |
parent | 360791e8963a0e7357da48edc195600d67ab53c4 (diff) |
video: mcde: fix SDTV through AB8500 flashes
The patch fixes flashes that are seen when running SDTV through AB8500.
The flashes are symptons of writing to the same buffer as MCDE. This is
because MCDE generates a VCMP interrupt for each field, instead of each
frame.
ST-Ericsson ID: 336212
ST-Ericsson Linux next: Not tested, ER 282779
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I84b13bf94e11a7742a0369b237594c565d0a64ea
Signed-off-by: Marcel Tunnissen <Marcel.Tuennissen@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/21217
Tested-by: Marcel TUNNISSEN <marcel.tuennissen@stericsson.com>
Reviewed-by: QATOOLS
Reviewed-by: QATEST
Reviewed-by: Jimmy RUBIN <jimmy.rubin@stericsson.com>
Reviewed-by: Per PERSSON <per.xb.persson@stericsson.com>
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Reviewed-by: Dan JOHANSSON <dan.johansson@stericsson.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/mcde/mcde_hw.c | 128 |
1 files changed, 39 insertions, 89 deletions
diff --git a/drivers/video/mcde/mcde_hw.c b/drivers/video/mcde/mcde_hw.c index c245009cbc1..e795e38d256 100644 --- a/drivers/video/mcde/mcde_hw.c +++ b/drivers/video/mcde/mcde_hw.c @@ -276,6 +276,10 @@ struct mcde_chnl_state { struct col_regs col_regs; struct tv_regs tv_regs; + /* an interlaced digital TV signal generates a VCMP per field */ + bool vcmp_per_field; + bool even_vcmp; + bool continous_running; bool disable_software_trig; bool formatter_updated; @@ -857,47 +861,12 @@ static struct mcde_chnl_state *find_channel_by_dsilink(int link) return NULL; } -static irqreturn_t mcde_irq_handler(int irq, void *dev) +static inline void mcde_handle_vcmp(struct mcde_chnl_state *chnl, u32 int_fld) { - int i; - u32 irq_status; - struct mcde_chnl_state *chnl; - - /* Handle overlay irqs */ - irq_status = mcde_rfld(MCDE_RISOVL, OVLFDRIS); - mcde_wfld(MCDE_RISOVL, OVLFDRIS, irq_status); - - /* Handle channel irqs */ - irq_status = mcde_rreg(MCDE_RISPP); - if (irq_status & MCDE_RISPP_VCMPARIS_MASK) { - chnl = &channels[MCDE_CHNL_A]; - chnl->transactionid_hw = chnl->transactionid_regs; - wake_up(&chnl->waitq_hw); - mcde_wfld(MCDE_RISPP, VCMPARIS, 1); - if (chnl->port.update_auto_trig && - chnl->port.sync_src == MCDE_SYNCSRC_OFF && - chnl->port.type == MCDE_PORTTYPE_DSI && - chnl->continous_running) { - if (hardware_version == MCDE_CHIP_VERSION_3_0_8) - enable_channel(chnl); - - mcde_wreg(MCDE_CHNL0SYNCHSW + - chnl->id * MCDE_CHNL0SYNCHSW_GROUPOFFSET, - MCDE_CHNL0SYNCHSW_SW_TRIG(true)); - - if (hardware_version == MCDE_CHIP_VERSION_3_0_8) - disable_flow(chnl); - mod_timer(&chnl->auto_sync_timer, - jiffies + - msecs_to_jiffies(MCDE_AUTO_SYNC_WATCHDOG - * 1000)); - } - } - if (irq_status & MCDE_RISPP_VCMPBRIS_MASK) { - chnl = &channels[MCDE_CHNL_B]; + if (!chnl->vcmp_per_field || + (chnl->vcmp_per_field && chnl->even_vcmp)) { chnl->transactionid_hw = chnl->transactionid_regs; wake_up(&chnl->waitq_hw); - mcde_wfld(MCDE_RISPP, VCMPBRIS, 1); if (chnl->port.update_auto_trig && chnl->port.sync_src == MCDE_SYNCSRC_OFF && chnl->port.type == MCDE_PORTTYPE_DSI && @@ -917,55 +886,33 @@ static irqreturn_t mcde_irq_handler(int irq, void *dev) * 1000)); } } - if (irq_status & MCDE_RISPP_VCMPC0RIS_MASK) { - chnl = &channels[MCDE_CHNL_C0]; - chnl->transactionid_hw = chnl->transactionid_regs; - wake_up(&chnl->waitq_hw); - mcde_wfld(MCDE_RISPP, VCMPC0RIS, 1); - if (chnl->port.update_auto_trig && - chnl->port.sync_src == MCDE_SYNCSRC_OFF && - chnl->port.type == MCDE_PORTTYPE_DSI && - chnl->continous_running) { - if (hardware_version == MCDE_CHIP_VERSION_3_0_8) - enable_channel(chnl); - - mcde_wreg(MCDE_CHNL0SYNCHSW + - chnl->id * MCDE_CHNL0SYNCHSW_GROUPOFFSET, - MCDE_CHNL0SYNCHSW_SW_TRIG(true)); - - if (hardware_version == MCDE_CHIP_VERSION_3_0_8) - disable_flow(chnl); - mod_timer(&chnl->auto_sync_timer, - jiffies + - msecs_to_jiffies(MCDE_AUTO_SYNC_WATCHDOG - * 1000)); + chnl->even_vcmp = !chnl->even_vcmp; + mcde_wreg_fld(MCDE_RISPP, 0x1 << int_fld, int_fld, 1); +} - } - } - if (irq_status & MCDE_RISPP_VCMPC1RIS_MASK) { - chnl = &channels[MCDE_CHNL_C1]; - chnl->transactionid_hw = chnl->transactionid_regs; - wake_up(&chnl->waitq_hw); - mcde_wfld(MCDE_RISPP, VCMPC1RIS, 1); - if (chnl->port.update_auto_trig && - chnl->port.sync_src == MCDE_SYNCSRC_OFF && - chnl->port.type == MCDE_PORTTYPE_DSI && - chnl->continous_running) { - if (hardware_version == MCDE_CHIP_VERSION_3_0_8) - enable_channel(chnl); +static irqreturn_t mcde_irq_handler(int irq, void *dev) +{ + int i; + u32 irq_status; - mcde_wreg(MCDE_CHNL0SYNCHSW + - chnl->id * MCDE_CHNL0SYNCHSW_GROUPOFFSET, - MCDE_CHNL0SYNCHSW_SW_TRIG(true)); + /* Handle overlay irqs */ + irq_status = mcde_rfld(MCDE_RISOVL, OVLFDRIS); + mcde_wfld(MCDE_RISOVL, OVLFDRIS, irq_status); - if (hardware_version == MCDE_CHIP_VERSION_3_0_8) - disable_flow(chnl); - mod_timer(&chnl->auto_sync_timer, - jiffies + - msecs_to_jiffies(MCDE_AUTO_SYNC_WATCHDOG - * 1000)); - } - } + /* Handle channel irqs */ + irq_status = mcde_rreg(MCDE_RISPP); + if (irq_status & MCDE_RISPP_VCMPARIS_MASK) + mcde_handle_vcmp(&channels[MCDE_CHNL_A], + MCDE_RISPP_VCMPARIS_SHIFT); + if (irq_status & MCDE_RISPP_VCMPBRIS_MASK) + mcde_handle_vcmp(&channels[MCDE_CHNL_B], + MCDE_RISPP_VCMPBRIS_SHIFT); + if (irq_status & MCDE_RISPP_VCMPC0RIS_MASK) + mcde_handle_vcmp(&channels[MCDE_CHNL_C0], + MCDE_RISPP_VCMPC0RIS_SHIFT); + if (irq_status & MCDE_RISPP_VCMPC1RIS_MASK) + mcde_handle_vcmp(&channels[MCDE_CHNL_C1], + MCDE_RISPP_VCMPC1RIS_SHIFT); for (i = 0; i < num_dsilinks; i++) { struct mcde_chnl_state *chnl_from_dsi; @@ -1423,11 +1370,8 @@ static void update_overlay_registers(u8 idx, struct ovly_regs *regs, sel_mod = MCDE_EXTSRC0CR_SEL_MOD_AUTO_TOGGLE; break; } - } else if (port->type == MCDE_PORTTYPE_DPI) { - sel_mod = port->update_auto_trig ? - MCDE_EXTSRC0CR_SEL_MOD_AUTO_TOGGLE : - MCDE_EXTSRC0CR_SEL_MOD_SOFTWARE_SEL; - } + } else if (port->type == MCDE_PORTTYPE_DPI) + sel_mod = MCDE_EXTSRC0CR_SEL_MOD_SOFTWARE_SEL; regs->update = false; mcde_wreg(MCDE_EXTSRC0CONF + idx * MCDE_EXTSRC0CONF_GROUPOFFSET, @@ -2258,6 +2202,8 @@ static struct mcde_chnl_state *_mcde_chnl_get(enum mcde_chnl chnl_id, } } else if (chnl->port.type == MCDE_PORTTYPE_DPI) { chnl->port.phy.dpi.clk_dpi = clock_dpi; + if (chnl->port.phy.dpi.tv_mode) + chnl->vcmp_per_field = true; } #ifdef CONFIG_REGULATOR @@ -2680,6 +2626,10 @@ void mcde_chnl_put(struct mcde_chnl_state *chnl) } } else if (chnl->port.type == MCDE_PORTTYPE_DPI) { chnl->port.phy.dpi.clk_dpi = NULL; + if (chnl->port.phy.dpi.tv_mode) { + chnl->vcmp_per_field = false; + chnl->even_vcmp = false; + } } dev_vdbg(&mcde_dev->dev, "%s exit\n", __func__); |