diff options
author | Jimmy Rubin <jimmy.rubin@stericsson.com> | 2011-05-09 07:29:50 +0200 |
---|---|---|
committer | Henrik Aberg <henrik.aberg@stericsson.com> | 2011-05-18 09:40:17 +0200 |
commit | 394adf8c524b5dbf9774bfdc5f4ebd7cf7f02fda (patch) | |
tree | aaab5e05d0019352e7a77bf7bfe182300c2efc40 | |
parent | 2a765fda1bfa97cee2c00f3ec2df1563181c3f7e (diff) |
video: mcde: Fix chnl_disable for U5500
Channel disable is handled different for V1 and V2
hardware. If the channel is not properly disabled
problems with suspend/resume can occur
ST-Ericsson ID: 338578
ST-Ericsson Linux next: Not tested, ER 282779
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: Ib760b7bf2246ad017605ea24d14bcb5574834e23
Signed-off-by: Jimmy Rubin <jimmy.rubin@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/22661
Reviewed-by: QATOOLS
Reviewed-by: QATEST
Reviewed-by: Per PERSSON <per.xb.persson@stericsson.com>
Reviewed-by: Marcel TUNNISSEN <marcel.tuennissen@stericsson.com>
-rw-r--r-- | drivers/video/mcde/mcde_hw.c | 128 |
1 files changed, 81 insertions, 47 deletions
diff --git a/drivers/video/mcde/mcde_hw.c b/drivers/video/mcde/mcde_hw.c index 2bfd0c1f6ef..05759bffd94 100644 --- a/drivers/video/mcde/mcde_hw.c +++ b/drivers/video/mcde/mcde_hw.c @@ -1504,59 +1504,93 @@ static void disable_channel(struct mcde_chnl_state *chnl) chnl->continous_running = false; } - switch (chnl->id) { - case MCDE_CHNL_A: - mcde_wfld(MCDE_CRA0, FLOEN, false); - wait_for_channel(chnl); - for (i = 0; i < MCDE_FLOWEN_MAX_TRIAL; i++) { - msleep(1); - if (!mcde_rfld(MCDE_CRA0, FLOEN)) { - dev_vdbg(&mcde_dev->dev, - "Flow (A) disable after >= %d ms\n", i); - goto break_switch; + if (hardware_version == MCDE_CHIP_VERSION_1_0_4) { + if (is_channel_enabled(chnl)) { + wait_for_channel(chnl); + /* + * Just to make sure that a frame is triggered when + * we try to disable the channel + */ + chnl->transactionid++; + mcde_wreg(MCDE_CHNL0SYNCHSW + + chnl->id * MCDE_CHNL0SYNCHSW_GROUPOFFSET, + MCDE_CHNL0SYNCHSW_SW_TRIG(true)); + disable_flow(chnl); + wait_for_channel(chnl); + for (i = 0; i < MCDE_FLOWEN_MAX_TRIAL; i++) { + if (!is_channel_enabled(chnl)) { + dev_vdbg(&mcde_dev->dev, + "Flow %d off after >= %d ms\n", + chnl->id, i); + goto break_switch; + } + msleep(1); } + } else { + dev_vdbg(&mcde_dev->dev, + "Flow %d disable after >= %d ms\n", + chnl->id, i); + goto break_switch; } - dev_warn(&mcde_dev->dev, "%s: channel A timeout\n", __func__); - break; - case MCDE_CHNL_B: - mcde_wfld(MCDE_CRB0, FLOEN, false); - wait_for_channel(chnl); - for (i = 0; i < MCDE_FLOWEN_MAX_TRIAL; i++) { - msleep(1); - if (!mcde_rfld(MCDE_CRB0, FLOEN)) { - dev_vdbg(&mcde_dev->dev, - "Flow (B) disable after >= %d ms\n", i); - goto break_switch; + } else { + switch (chnl->id) { + case MCDE_CHNL_A: + mcde_wfld(MCDE_CRA0, FLOEN, false); + wait_for_channel(chnl); + for (i = 0; i < MCDE_FLOWEN_MAX_TRIAL; i++) { + msleep(1); + if (!mcde_rfld(MCDE_CRA0, FLOEN)) { + dev_vdbg(&mcde_dev->dev, + "Flow (A) off after >= %d ms\n", i); + goto break_switch; + } } - } - dev_warn(&mcde_dev->dev, "%s: channel B timeout\n", __func__); - break; - case MCDE_CHNL_C0: - mcde_wfld(MCDE_CRC, C1EN, false); - wait_for_channel(chnl); - for (i = 0; i < MCDE_FLOWEN_MAX_TRIAL; i++) { - msleep(1); - if (!mcde_rfld(MCDE_CRC, C1EN)) { - dev_vdbg(&mcde_dev->dev, - "Flow (C1) disable after >= %d ms\n", i); - goto break_switch; + dev_warn(&mcde_dev->dev, + "%s: channel A timeout\n", __func__); + break; + case MCDE_CHNL_B: + mcde_wfld(MCDE_CRB0, FLOEN, false); + wait_for_channel(chnl); + for (i = 0; i < MCDE_FLOWEN_MAX_TRIAL; i++) { + msleep(1); + if (!mcde_rfld(MCDE_CRB0, FLOEN)) { + dev_vdbg(&mcde_dev->dev, + "Flow (B) off after >= %d ms\n", i); + goto break_switch; + } } - } - dev_warn(&mcde_dev->dev, "%s: channel C0 timeout\n", __func__); - break; - case MCDE_CHNL_C1: - mcde_wfld(MCDE_CRC, C2EN, false); - wait_for_channel(chnl); - for (i = 0; i < MCDE_FLOWEN_MAX_TRIAL; i++) { - msleep(1); - if (!mcde_rfld(MCDE_CRC, C2EN)) { - dev_vdbg(&mcde_dev->dev, - "Flow (C2) disable after >= %d ms\n", i); - goto break_switch; + dev_warn(&mcde_dev->dev, "%s: channel B timeout\n", + __func__); + break; + case MCDE_CHNL_C0: + mcde_wfld(MCDE_CRC, C1EN, false); + wait_for_channel(chnl); + for (i = 0; i < MCDE_FLOWEN_MAX_TRIAL; i++) { + msleep(1); + if (!mcde_rfld(MCDE_CRC, C1EN)) { + dev_vdbg(&mcde_dev->dev, + "Flow (C1) off after >= %d ms\n", i); + goto break_switch; + } + } + dev_warn(&mcde_dev->dev, "%s: channel C0 timeout\n", + __func__); + break; + case MCDE_CHNL_C1: + mcde_wfld(MCDE_CRC, C2EN, false); + wait_for_channel(chnl); + for (i = 0; i < MCDE_FLOWEN_MAX_TRIAL; i++) { + msleep(1); + if (!mcde_rfld(MCDE_CRC, C2EN)) { + dev_vdbg(&mcde_dev->dev, + "Flow (C2) off after >= %d ms\n", i); + goto break_switch; + } } + dev_warn(&mcde_dev->dev, "%s: channel C1 timeout\n", + __func__); + break; } - dev_warn(&mcde_dev->dev, "%s: channel C1 timeout\n", __func__); - break; } break_switch: chnl->continous_running = false; |