summaryrefslogtreecommitdiff
path: root/drivers/mxc/ipu3/ipu_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/ipu3/ipu_common.c')
-rw-r--r--drivers/mxc/ipu3/ipu_common.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index e7713199abcb..b29402539582 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -490,6 +490,10 @@ static int __devinit ipu_probe(struct platform_device *pdev)
/* Set sync refresh channels and CSI->mem channel as high priority */
ipu_idmac_write(ipu, 0x18800001L, IDMAC_CHA_PRI(0));
+ /* AXI burst setting for sync refresh channels */
+ if (g_ipu_hw_rev == 3)
+ ipu_idmac_write(ipu, 0x003F0000, IDMAC_CH_LOCK_EN_1);
+
/* Set MCU_T to divide MCU access window into 2 */
ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN);
@@ -1095,6 +1099,13 @@ void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel)
ipu->channel_init_mask &= ~(1L << IPU_CHAN_ID(channel));
+ /* Restore IDMAC_LOCK_EN when we don't use dual display */
+ /* and the video mode for single display is not tough */
+ if (!(ipu->di_use_count[0] && ipu->di_use_count[1]) &&
+ dmfc_type_setup != DMFC_HIGH_RESOLUTION_ONLY_DP &&
+ _ipu_is_dmfc_chan(in_dma) && g_ipu_hw_rev == 3)
+ ipu_idmac_write(ipu, 0x003F0000, IDMAC_CH_LOCK_EN_1);
+
_ipu_unlock(ipu);
_ipu_put(ipu);
@@ -1259,7 +1270,7 @@ int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
if (idma_is_set(ipu, IDMAC_CHA_PRI, dma_chan)) {
unsigned reg = IDMAC_CH_LOCK_EN_1;
uint32_t value = 0;
- if (cpu_is_mx53() || cpu_is_mx6q()) {
+ if (cpu_is_mx6q()) {
_ipu_ch_param_set_axi_id(ipu, dma_chan, 0);
switch (dma_chan) {
case 5:
@@ -1985,6 +1996,16 @@ int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel)
ipu_conf |= IPU_CONF_SMFC_EN;
ipu_cm_write(ipu, ipu_conf, IPU_CONF);
+ /* Clear IDMAC_LOCK_EN to workaround black flash for dual display */
+ /* and for tough video mode of single display */
+ if (g_ipu_hw_rev == 3 && _ipu_is_dmfc_chan(in_dma)) {
+ if ((ipu->di_use_count[1] && ipu->di_use_count[0]) ||
+ (dmfc_type_setup == DMFC_HIGH_RESOLUTION_ONLY_DP))
+ ipu_idmac_write(ipu, 0x0, IDMAC_CH_LOCK_EN_1);
+ else
+ ipu_idmac_write(ipu, 0x003F0000, IDMAC_CH_LOCK_EN_1);
+ }
+
if (idma_is_valid(in_dma)) {
reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma));
ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
@@ -2095,15 +2116,22 @@ void _ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buf
return;
ipu_cm_write(ipu, 0xF0300000, IPU_GPR); /* write one to clear */
- if (bufNum == 0)
- ipu_cm_write(ipu, idma_mask(dma_ch),
+ if (bufNum == 0) {
+ if (idma_is_set(ipu, IPU_CHA_BUF0_RDY, dma_ch)) {
+ ipu_cm_write(ipu, idma_mask(dma_ch),
IPU_CHA_BUF0_RDY(dma_ch));
- else if (bufNum == 1)
- ipu_cm_write(ipu, idma_mask(dma_ch),
+ }
+ } else if (bufNum == 1) {
+ if (idma_is_set(ipu, IPU_CHA_BUF1_RDY, dma_ch)) {
+ ipu_cm_write(ipu, idma_mask(dma_ch),
IPU_CHA_BUF1_RDY(dma_ch));
- else
- ipu_cm_write(ipu, idma_mask(dma_ch),
+ }
+ } else {
+ if (idma_is_set(ipu, IPU_CHA_BUF2_RDY, dma_ch)) {
+ ipu_cm_write(ipu, idma_mask(dma_ch),
IPU_CHA_BUF2_RDY(dma_ch));
+ }
+ }
ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
}
@@ -2935,6 +2963,11 @@ static int ipu_resume_noirq(struct device *dev)
_ipu_init_dc_mappings(ipu);
/* Set sync refresh channels as high priority */
ipu_idmac_write(ipu, 0x18800001L, IDMAC_CHA_PRI(0));
+
+ /* AXI burst setting for sync refresh channels */
+ if (g_ipu_hw_rev == 3)
+ ipu_idmac_write(ipu, 0x003F0000, IDMAC_CH_LOCK_EN_1);
+
_ipu_put(ipu);
}