diff options
author | Liu Ying <b17645@freescale.com> | 2010-02-10 09:07:24 -0500 |
---|---|---|
committer | Alejandro Gonzalez <alex.gonzalez@digi.com> | 2010-05-24 12:16:01 +0200 |
commit | 965df65cd32fd43efe48c9bc8b362a5d6c778281 (patch) | |
tree | 2d94b276f6dfd041a26ae6b5b12b71325904b5d0 /drivers/mxc/ipu3 | |
parent | 726cee7d9425750df86caaa85920d5a6bdee9794 (diff) |
ENGR00119169 V4L2 capture:enable CSI after PRP channels are setup
To preview with V4L2 overlay and capture at the same time may fail.
This patch implements workaround for this issue by enabling CSI after
PRP channels are setup.
Signed-off-by: Liu Ying <b17645@freescale.com>
Signed-off-by: Alejandro Gonzalez <alex.gonzalez@digi.com>
Diffstat (limited to 'drivers/mxc/ipu3')
-rw-r--r-- | drivers/mxc/ipu3/ipu_common.c | 83 |
1 files changed, 66 insertions, 17 deletions
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c index f53a047a186a..0cb367bf38c6 100644 --- a/drivers/mxc/ipu3/ipu_common.c +++ b/drivers/mxc/ipu3/ipu_common.c @@ -513,7 +513,6 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) } ipu_smfc_use_count++; - ipu_csi_use_count[params->csi_mem.csi]++; g_ipu_csi_channel[params->csi_mem.csi] = channel; /*SMFC setting*/ @@ -543,7 +542,6 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) using_ic_dirct_ch = CSI_PRP_ENC_MEM; ipu_ic_use_count++; - ipu_csi_use_count[params->csi_prp_enc_mem.csi]++; g_ipu_csi_channel[params->csi_prp_enc_mem.csi] = channel; /*Without SMFC, CSI only support parallel data source*/ @@ -577,7 +575,6 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) using_ic_dirct_ch = CSI_PRP_VF_MEM; ipu_ic_use_count++; - ipu_csi_use_count[params->csi_prp_vf_mem.csi]++; g_ipu_csi_channel[params->csi_prp_vf_mem.csi] = channel; /*Without SMFC, CSI only support parallel data source*/ @@ -758,10 +755,6 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) } if (ipu_smfc_use_count == 1) ipu_conf |= IPU_CONF_SMFC_EN; - if (ipu_csi_use_count[0] == 1) - ipu_conf |= IPU_CONF_CSI0_EN; - if (ipu_csi_use_count[1] == 1) - ipu_conf |= IPU_CONF_CSI1_EN; __raw_writel(ipu_conf, IPU_CONF); @@ -823,10 +816,8 @@ void ipu_uninit_channel(ipu_channel_t channel) ipu_smfc_use_count--; if (g_ipu_csi_channel[0] == channel) { g_ipu_csi_channel[0] = CHAN_NONE; - ipu_csi_use_count[0]--; } else if (g_ipu_csi_channel[1] == channel) { g_ipu_csi_channel[1] = CHAN_NONE; - ipu_csi_use_count[1]--; } break; case CSI_PRP_ENC_MEM: @@ -836,10 +827,8 @@ void ipu_uninit_channel(ipu_channel_t channel) _ipu_ic_uninit_prpenc(); if (g_ipu_csi_channel[0] == channel) { g_ipu_csi_channel[0] = CHAN_NONE; - ipu_csi_use_count[0]--; } else if (g_ipu_csi_channel[1] == channel) { g_ipu_csi_channel[1] = CHAN_NONE; - ipu_csi_use_count[1]--; } break; case CSI_PRP_VF_MEM: @@ -849,10 +838,8 @@ void ipu_uninit_channel(ipu_channel_t channel) _ipu_ic_uninit_prpvf(); if (g_ipu_csi_channel[0] == channel) { g_ipu_csi_channel[0] = CHAN_NONE; - ipu_csi_use_count[0]--; } else if (g_ipu_csi_channel[1] == channel) { g_ipu_csi_channel[1] = CHAN_NONE; - ipu_csi_use_count[1]--; } break; case MEM_PRP_VF_MEM: @@ -954,10 +941,6 @@ void ipu_uninit_channel(ipu_channel_t channel) } if (ipu_smfc_use_count == 0) ipu_conf &= ~IPU_CONF_SMFC_EN; - if (ipu_csi_use_count[0] == 0) - ipu_conf &= ~IPU_CONF_CSI0_EN; - if (ipu_csi_use_count[1] == 0) - ipu_conf &= ~IPU_CONF_CSI1_EN; __raw_writel(ipu_conf, IPU_CONF); @@ -1947,6 +1930,72 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop) } EXPORT_SYMBOL(ipu_disable_channel); +/*! + * This function enables CSI. + * + * @param csi csi num 0 or 1 + * + * @return This function returns 0 on success or negative error code on + * fail. + */ +int32_t ipu_enable_csi(uint32_t csi) +{ + uint32_t reg; + unsigned long lock_flags; + + if (csi > 1) { + dev_err(g_ipu_dev, "Wrong csi num_%d\n", csi); + return -EINVAL; + } + + spin_lock_irqsave(&ipu_lock, lock_flags); + ipu_csi_use_count[csi]++; + + if (ipu_csi_use_count[csi] == 1) { + reg = __raw_readl(IPU_CONF); + if (csi == 0) + __raw_writel(reg | IPU_CONF_CSI0_EN, IPU_CONF); + else + __raw_writel(reg | IPU_CONF_CSI1_EN, IPU_CONF); + } + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return 0; +} +EXPORT_SYMBOL(ipu_enable_csi); + +/*! + * This function disables CSI. + * + * @param csi csi num 0 or 1 + * + * @return This function returns 0 on success or negative error code on + * fail. + */ +int32_t ipu_disable_csi(uint32_t csi) +{ + uint32_t reg; + unsigned long lock_flags; + + if (csi > 1) { + dev_err(g_ipu_dev, "Wrong csi num_%d\n", csi); + return -EINVAL; + } + + spin_lock_irqsave(&ipu_lock, lock_flags); + ipu_csi_use_count[csi]--; + + if (ipu_csi_use_count[csi] == 0) { + reg = __raw_readl(IPU_CONF); + if (csi == 0) + __raw_writel(reg & ~IPU_CONF_CSI0_EN, IPU_CONF); + else + __raw_writel(reg & ~IPU_CONF_CSI1_EN, IPU_CONF); + } + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return 0; +} +EXPORT_SYMBOL(ipu_disable_csi); + static irqreturn_t ipu_irq_handler(int irq, void *desc) { int i; |