aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarcel Tunnissen <Marcel.Tuennissen@stericsson.com>2011-04-19 09:15:46 +0200
committerJonas ABERG <jonas.aberg@stericsson.com>2011-04-21 15:00:11 +0200
commit8fd63b94c44be823a9d9b1df41e4463046b3aba8 (patch)
treed1218fdf82d65c4c4350c711361ebf0d6093704e /drivers
parent360791e8963a0e7357da48edc195600d67ab53c4 (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.c128
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__);