summaryrefslogtreecommitdiff
path: root/drivers/mxc
diff options
context:
space:
mode:
authorIan Wisbon <ian.wisbon@timesys.com>2011-02-10 17:15:15 -0500
committerIan Wisbon <ian.wisbon@timesys.com>2011-02-10 17:19:54 -0500
commit0eb553bf96e2c990d3bfccaa07da0863624c89ab (patch)
tree79b396bf70ae3795e6ee9a3b645e64f7e29474e7 /drivers/mxc
parenteffff5718c380983788fe6c380671c18e15ac7c2 (diff)
Linux 2.6.31 Release for Digi ConnectCore Wi-i.MX boards
Digi 01262011 Release
Diffstat (limited to 'drivers/mxc')
-rw-r--r--drivers/mxc/Kconfig1
-rw-r--r--drivers/mxc/Makefile1
-rw-r--r--drivers/mxc/ipu/ipu_common.c32
-rw-r--r--drivers/mxc/ipu/ipu_csi.c9
-rw-r--r--drivers/mxc/ipu/ipu_device.c1
-rw-r--r--drivers/mxc/ipu/ipu_ic.c6
-rw-r--r--drivers/mxc/ipu/pf/mxc_pf.c1
-rw-r--r--drivers/mxc/ipu3/ipu_calc_stripes_sizes.c2
-rw-r--r--drivers/mxc/ipu3/ipu_capture.c130
-rw-r--r--drivers/mxc/ipu3/ipu_common.c184
-rw-r--r--drivers/mxc/ipu3/ipu_device.c25
-rw-r--r--drivers/mxc/ipu3/ipu_disp.c364
-rw-r--r--drivers/mxc/ipu3/ipu_ic.c39
-rw-r--r--drivers/mxc/ipu3/ipu_param_mem.h55
-rw-r--r--drivers/mxc/ipu3/ipu_prv.h4
-rw-r--r--drivers/mxc/ipu3/ipu_regs.h11
-rw-r--r--drivers/mxc/mlb/Kconfig2
-rw-r--r--drivers/mxc/pmic/core/mc13892.c3
-rw-r--r--drivers/mxc/pmic/core/pmic.h5
-rw-r--r--drivers/mxc/pmic/mc13892/pmic_adc.c321
-rw-r--r--drivers/mxc/pmic/mc13892/pmic_battery.c59
-rw-r--r--drivers/mxc/security/Kconfig1
-rw-r--r--drivers/mxc/security/sahara2/fsl_shw_auth.c4
-rw-r--r--drivers/mxc/security/scc2_driver.c2
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c47
25 files changed, 1040 insertions, 269 deletions
diff --git a/drivers/mxc/Kconfig b/drivers/mxc/Kconfig
index 6e67087d2efa..b26c1dc11ad6 100644
--- a/drivers/mxc/Kconfig
+++ b/drivers/mxc/Kconfig
@@ -33,6 +33,7 @@ source "drivers/mxc/bt/Kconfig"
source "drivers/mxc/gps_ioctrl/Kconfig"
source "drivers/mxc/mlb/Kconfig"
source "drivers/mxc/adc/Kconfig"
+source "drivers/mxc/amd-gpu/Kconfig"
endmenu
diff --git a/drivers/mxc/Makefile b/drivers/mxc/Makefile
index 6416bc429888..5193fa50eb9f 100644
--- a/drivers/mxc/Makefile
+++ b/drivers/mxc/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_MXC_BLUETOOTH) += bt/
obj-$(CONFIG_GPS_IOCTRL) += gps_ioctrl/
obj-$(CONFIG_MXC_MLB) += mlb/
obj-$(CONFIG_IMX_ADC) += adc/
+obj-$(CONFIG_MXC_AMD_GPU) += amd-gpu/
diff --git a/drivers/mxc/ipu/ipu_common.c b/drivers/mxc/ipu/ipu_common.c
index 43ba100b5c5d..a1dc566e7f8f 100644
--- a/drivers/mxc/ipu/ipu_common.c
+++ b/drivers/mxc/ipu/ipu_common.c
@@ -707,6 +707,38 @@ int32_t ipu_select_buffer(ipu_channel_t channel, ipu_buffer_t type,
}
/*!
+ * This function check buffer ready for a logical channel.
+ *
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to clear.
+ *
+ * @param bufNum Input parameter for which buffer number clear
+ * ready state.
+ *
+ */
+int32_t ipu_check_buffer_busy(ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum)
+{
+ uint32_t dma_chan = channel_2_dma(channel, type);
+ uint32_t reg;
+
+ if (dma_chan == IDMA_CHAN_INVALID)
+ return -EINVAL;
+
+ if (bufNum == 0)
+ reg = __raw_readl(IPU_CHA_BUF0_RDY);
+ else
+ reg = __raw_readl(IPU_CHA_BUF1_RDY);
+
+ if (reg & (1UL << dma_chan))
+ return 1;
+ else
+ return 0;
+}
+EXPORT_SYMBOL(ipu_check_buffer_busy);
+
+/*!
* This function links 2 channels together for automatic frame
* synchronization. The output of the source channel is linked to the input of
* the destination channel.
diff --git a/drivers/mxc/ipu/ipu_csi.c b/drivers/mxc/ipu/ipu_csi.c
index 10708cf3ba54..58d58c10af51 100644
--- a/drivers/mxc/ipu/ipu_csi.c
+++ b/drivers/mxc/ipu/ipu_csi.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -90,10 +90,13 @@ ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt,
__raw_writel(height << 16 | 0x22, CSI_FLASH_STROBE_2);
/* Set CCIR registers */
- if ((sig.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) ||
- (sig.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED)) {
+ if (sig.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) {
__raw_writel(0x40030, CSI_CCIR_CODE_1);
__raw_writel(0xFF0000, CSI_CCIR_CODE_3);
+ } else if (sig.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED) {
+ __raw_writel(0xD07DF, CSI_CCIR_CODE_1);
+ __raw_writel(0x40596, CSI_CCIR_CODE_2);
+ __raw_writel(0xFF0000, CSI_CCIR_CODE_3);
}
dev_dbg(g_ipu_dev, "CSI_SENS_CONF = 0x%08X\n",
diff --git a/drivers/mxc/ipu/ipu_device.c b/drivers/mxc/ipu/ipu_device.c
index 5fd1c51ec9b1..713ba2005ae9 100644
--- a/drivers/mxc/ipu/ipu_device.c
+++ b/drivers/mxc/ipu/ipu_device.c
@@ -169,6 +169,7 @@ static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
sizeof(ipu_channel_buf_parm))) {
return -EFAULT;
}
+
ret =
ipu_init_channel_buffer(parm.channel, parm.type,
parm.pixel_fmt,
diff --git a/drivers/mxc/ipu/ipu_ic.c b/drivers/mxc/ipu/ipu_ic.c
index cdf823a2760b..9fe087590368 100644
--- a/drivers/mxc/ipu/ipu_ic.c
+++ b/drivers/mxc/ipu/ipu_ic.c
@@ -71,8 +71,7 @@ void _ipu_ic_enable_task(ipu_channel_t channel)
case MEM_ROT_PP_MEM:
ic_conf |= IC_CONF_PP_ROT_EN;
break;
- case CSI_MEM:
- // ???
+ case CSI_MEM1:
ic_conf |= IC_CONF_RWS_EN | IC_CONF_PRPENC_EN;
break;
default:
@@ -110,8 +109,7 @@ void _ipu_ic_disable_task(ipu_channel_t channel)
case MEM_ROT_PP_MEM:
ic_conf &= ~IC_CONF_PP_ROT_EN;
break;
- case CSI_MEM:
- // ???
+ case CSI_MEM1:
ic_conf &= ~(IC_CONF_RWS_EN | IC_CONF_PRPENC_EN);
break;
default:
diff --git a/drivers/mxc/ipu/pf/mxc_pf.c b/drivers/mxc/ipu/pf/mxc_pf.c
index 744152415e3a..8abffb4d8d44 100644
--- a/drivers/mxc/ipu/pf/mxc_pf.c
+++ b/drivers/mxc/ipu/pf/mxc_pf.c
@@ -108,6 +108,7 @@ static int mxc_pf_init(pf_init_params * pf_init)
memset(&params, 0, sizeof(params));
params.mem_pf_mem.operation = pf_data.mode;
+
err = ipu_init_channel(MEM_PF_Y_MEM, &params);
if (err < 0) {
printk(KERN_ERR "mxc_pf: error initializing channel\n");
diff --git a/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c b/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
index 6a29c90fe095..5d5e0b9155a0 100644
--- a/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
+++ b/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
@@ -260,7 +260,7 @@ int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
input_frame_width >> 1;
left->output_width = right->output_width = right->output_column =
output_frame_width >> 1;
- left->input_column = right->input_column = 0;
+ left->input_column = 0;
div = _do_div(((((u64)irr_steps) << 32) *
(right->input_width - 1)), (right->output_width - 1));
left->irr = right->irr = truncate(0, div, 1);
diff --git a/drivers/mxc/ipu3/ipu_capture.c b/drivers/mxc/ipu3/ipu_capture.c
index 5d084ab37b0b..b9967135eac1 100644
--- a/drivers/mxc/ipu3/ipu_capture.c
+++ b/drivers/mxc/ipu3/ipu_capture.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/ipu.h>
#include <linux/clk.h>
+#include <mach/mxc_dvfs.h>
#include "ipu_prv.h"
#include "ipu_regs.h"
@@ -93,6 +94,12 @@ ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt,
cfg_param.force_eof << CSI_SENS_CONF_FORCE_EOF_SHIFT |
cfg_param.data_en_pol << CSI_SENS_CONF_DATA_EN_POL_SHIFT;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
__raw_writel(data, CSI_SENS_CONF(csi));
@@ -101,11 +108,18 @@ ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt,
__raw_writel((width - 1) | (height - 1) << 16, CSI_SENS_FRM_SIZE(csi));
/* Set CCIR registers */
- if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) ||
- (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED)) {
- _ipu_csi_ccir_err_detection_enable(csi);
+ if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) {
__raw_writel(0x40030, CSI_CCIR_CODE_1(csi));
__raw_writel(0xFF0000, CSI_CCIR_CODE_3(csi));
+ } else if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED) {
+ _ipu_csi_ccir_err_detection_enable(csi);
+ /* Field0BlankEnd = 0x7, Field0BlankStart = 0x3,
+ Field0ActiveEnd = 0x5, Field0ActiveStart = 0x1 */
+ __raw_writel(0xD07DF, CSI_CCIR_CODE_1(csi));
+ /* Field1BlankEnd = 0x6, Field1BlankStart = 0x2,
+ Field1ActiveEnd = 0x4, Field1ActiveStart = 0 */
+ __raw_writel(0x40596, CSI_CCIR_CODE_2(csi));
+ __raw_writel(0xFF0000, CSI_CCIR_CODE_3(csi));
} else if ((cfg_param.clk_mode ==
IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR) ||
(cfg_param.clk_mode ==
@@ -171,34 +185,13 @@ int _ipu_csi_mclk_set(uint32_t pixel_clk, uint32_t csi)
*/
int ipu_csi_enable_mclk(int csi, bool flag, bool wait)
{
- struct clk *clk;
if (flag) {
- if (cpu_is_mx53()) {
- if (csi == 0) {
- clk = clk_get(NULL, "ssi_ext1_clk");
- clk_enable(clk);
- clk_put(clk);
- } else {
- pr_err("invalid csi num %d\n", csi);
- return -EINVAL;
- }
- } else
- clk_enable(g_csi_clk[csi]);
+ clk_enable(g_csi_clk[csi]);
if (wait == true)
msleep(10);
} else {
- if (cpu_is_mx53()) {
- if (csi == 0) {
- clk = clk_get(NULL, "ssi_ext1_clk");
- clk_disable(clk);
- clk_put(clk);
- } else {
- pr_err("invalid csi num %d\n", csi);
- return -EINVAL;
- }
- } else
- clk_disable(g_csi_clk[csi]);
+ clk_disable(g_csi_clk[csi]);
}
return 0;
@@ -217,6 +210,12 @@ void ipu_csi_get_window_size(uint32_t *width, uint32_t *height, uint32_t csi)
uint32_t reg;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
reg = __raw_readl(CSI_ACT_FRM_SIZE(csi));
@@ -238,6 +237,12 @@ void ipu_csi_set_window_size(uint32_t width, uint32_t height, uint32_t csi)
{
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
__raw_writel((width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE(csi));
@@ -258,6 +263,12 @@ void ipu_csi_set_window_pos(uint32_t left, uint32_t top, uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -280,6 +291,12 @@ void _ipu_csi_horizontal_downsize_enable(uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -300,6 +317,12 @@ void _ipu_csi_horizontal_downsize_disable(uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -320,6 +343,12 @@ void _ipu_csi_vertical_downsize_enable(uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -340,6 +369,12 @@ void _ipu_csi_vertical_downsize_disable(uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -366,6 +401,12 @@ void ipu_csi_set_test_generator(bool active, uint32_t r_value,
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_TST_CTRL(csi));
@@ -401,6 +442,12 @@ void _ipu_csi_ccir_err_detection_enable(uint32_t csi)
{
uint32_t temp;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
temp = __raw_readl(CSI_CCIR_CODE_1(csi));
temp |= CSI_CCIR_ERR_DET_EN;
__raw_writel(temp, CSI_CCIR_CODE_1(csi));
@@ -417,6 +464,12 @@ void _ipu_csi_ccir_err_detection_disable(uint32_t csi)
{
uint32_t temp;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
temp = __raw_readl(CSI_CCIR_CODE_1(csi));
temp &= ~CSI_CCIR_ERR_DET_EN;
__raw_writel(temp, CSI_CCIR_CODE_1(csi));
@@ -442,6 +495,12 @@ int _ipu_csi_set_mipi_di(uint32_t num, uint32_t di_val, uint32_t csi)
goto err;
}
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_MIPI_DI(csi));
@@ -499,6 +558,12 @@ int _ipu_csi_set_skip_isp(uint32_t skip, uint32_t max_ratio, uint32_t csi)
goto err;
}
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_SKIP(csi));
@@ -536,6 +601,12 @@ int _ipu_csi_set_skip_smfc(uint32_t skip, uint32_t max_ratio,
goto err;
}
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_SKIP(csi));
@@ -585,7 +656,6 @@ void _ipu_smfc_init(ipu_channel_t channel, uint32_t mipi_id, uint32_t csi)
default:
return;
}
-
__raw_writel(temp, SMFC_MAP);
}
@@ -604,6 +674,12 @@ void _ipu_smfc_set_wmc(ipu_channel_t channel, bool set, uint32_t level)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(SMFC_WMC);
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index 68be542e8370..b1b8a8b39ae1 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -52,8 +52,8 @@ unsigned char g_dc_di_assignment[10];
ipu_channel_t g_ipu_csi_channel[2];
int g_ipu_irq[2];
int g_ipu_hw_rev;
-bool g_sec_chan_en[22];
-bool g_thrd_chan_en[21];
+bool g_sec_chan_en[24];
+bool g_thrd_chan_en[24];
uint32_t g_channel_init_mask;
uint32_t g_channel_enable_mask;
DEFINE_SPINLOCK(ipu_lock);
@@ -354,8 +354,8 @@ static int ipu_probe(struct platform_device *pdev)
g_di_clk[0] = plat_data->di_clk[0];
g_di_clk[1] = plat_data->di_clk[1];
- g_csi_clk[0] = clk_get(&pdev->dev, "csi_mclk1");
- g_csi_clk[1] = clk_get(&pdev->dev, "csi_mclk2");
+ g_csi_clk[0] = plat_data->csi_clk[0];
+ g_csi_clk[1] = plat_data->csi_clk[1];
__raw_writel(0x807FFFFF, IPU_MEM_RST);
while (__raw_readl(IPU_MEM_RST) & 0x80000000) ;
@@ -372,7 +372,7 @@ static int ipu_probe(struct platform_device *pdev)
_ipu_dmfc_init(DMFC_NORMAL, 1);
/* Set sync refresh channels and CSI->mem channel as high priority */
- __raw_writel(0x18800001L, IDMAC_CHA_PRI(0));
+ __raw_writel(0x18800003L, IDMAC_CHA_PRI(0));
/* Set MCU_T to divide MCU access window into 2 */
__raw_writel(0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN);
@@ -415,7 +415,10 @@ int ipu_remove(struct platform_device *pdev)
void ipu_dump_registers(void)
{
+ printk(KERN_DEBUG "--------------------------------------------\n");
printk(KERN_DEBUG "IPU_CONF = \t0x%08X\n", __raw_readl(IPU_CONF));
+ printk(KERN_DEBUG "SMFC_MAP = \t0x%08X\n", __raw_readl(SMFC_MAP));
+ printk(KERN_DEBUG "SMFC_WMC = \t0x%08X\n", __raw_readl(SMFC_WMC));
printk(KERN_DEBUG "IDMAC_CONF = \t0x%08X\n", __raw_readl(IDMAC_CONF));
printk(KERN_DEBUG "IDMAC_CHA_EN1 = \t0x%08X\n",
__raw_readl(IDMAC_CHA_EN(0)));
@@ -451,6 +454,25 @@ void ipu_dump_registers(void)
__raw_readl(IPU_FS_PROC_FLOW3));
printk(KERN_DEBUG "IPU_FS_DISP_FLOW1 = \t0x%08X\n",
__raw_readl(IPU_FS_DISP_FLOW1));
+
+ printk(KERN_DEBUG "IPU_INT_CTRL_1 = \t0x%08X\n", __raw_readl(IPU_INT_CTRL (1)));
+ printk(KERN_DEBUG "IPU_INT_STAT_1 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (1)));
+ printk(KERN_DEBUG "IPU_INT_STAT_2 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (2)));
+ printk(KERN_DEBUG "IPU_INT_STAT_3 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (3)));
+ printk(KERN_DEBUG "IPU_INT_STAT_4 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (4)));
+ printk(KERN_DEBUG "IPU_INT_STAT_5 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (5)));
+ printk(KERN_DEBUG "IPU_INT_STAT_6 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (6)));
+
+ printk(KERN_DEBUG "CSI0_SENS_CONF = \t0x%08X\n", __raw_readl(CSI_SENS_CONF (0)));
+ printk(KERN_DEBUG "CSI0_SENS_FRM_SIZE = \t0x%08X\n", __raw_readl(CSI_SENS_FRM_SIZE(0)));
+ printk(KERN_DEBUG "CSI0_ACT_FRM_SIZE = \t0x%08X\n", __raw_readl(CSI_ACT_FRM_SIZE(0)));
+ printk(KERN_DEBUG "CSI0_SKIP = \t0x%08X\n", __raw_readl(CSI_SKIP(0)));
+
+ printk(KERN_DEBUG "CSI1_SENS_CONF = \t0x%08X\n", __raw_readl(CSI_SENS_CONF (1)));
+ printk(KERN_DEBUG "CSI1_SENS_FRM_SIZE = \t0x%08X\n", __raw_readl(CSI_SENS_FRM_SIZE(1)));
+ printk(KERN_DEBUG "CSI1_ACT_FRM_SIZE = \t0x%08X\n", __raw_readl(CSI_ACT_FRM_SIZE(1)));
+ printk(KERN_DEBUG "CSI1_SKIP = \t0x%08X\n", __raw_readl(CSI_SKIP(1)));
+ printk(KERN_DEBUG "--------------------------------------------\n");
}
/*!
@@ -660,7 +682,8 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
g_dc_di_assignment[1] = params->mem_dc_sync.di;
_ipu_dc_init(1, params->mem_dc_sync.di,
- params->mem_dc_sync.interlaced);
+ params->mem_dc_sync.interlaced,
+ params->mem_dc_sync.out_pixel_fmt);
ipu_di_use_count[params->mem_dc_sync.di]++;
ipu_dc_use_count++;
ipu_dmfc_use_count++;
@@ -678,7 +701,8 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
_ipu_dp_init(channel, params->mem_dp_bg_sync.in_pixel_fmt,
params->mem_dp_bg_sync.out_pixel_fmt);
_ipu_dc_init(5, params->mem_dp_bg_sync.di,
- params->mem_dp_bg_sync.interlaced);
+ params->mem_dp_bg_sync.interlaced,
+ params->mem_dp_bg_sync.out_pixel_fmt);
ipu_di_use_count[params->mem_dp_bg_sync.di]++;
ipu_dc_use_count++;
ipu_dp_use_count++;
@@ -702,7 +726,7 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
}
g_dc_di_assignment[8] = params->direct_async.di;
- _ipu_dc_init(8, params->direct_async.di, false);
+ _ipu_dc_init(8, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
ipu_di_use_count[params->direct_async.di]++;
ipu_dc_use_count++;
break;
@@ -713,7 +737,7 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
}
g_dc_di_assignment[9] = params->direct_async.di;
- _ipu_dc_init(9, params->direct_async.di, false);
+ _ipu_dc_init(9, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
ipu_di_use_count[params->direct_async.di]++;
ipu_dc_use_count++;
break;
@@ -724,31 +748,8 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
/* Enable IPU sub module */
g_channel_init_mask |= 1L << IPU_CHAN_ID(channel);
- if (ipu_ic_use_count == 1)
- ipu_conf |= IPU_CONF_IC_EN;
- if (ipu_vdi_use_count == 1) {
- ipu_conf |= IPU_CONF_VDI_EN;
- ipu_conf |= IPU_CONF_IC_INPUT;
- }
- if (ipu_rot_use_count == 1)
- ipu_conf |= IPU_CONF_ROT_EN;
- if (ipu_dc_use_count == 1)
- ipu_conf |= IPU_CONF_DC_EN;
- if (ipu_dp_use_count == 1)
- ipu_conf |= IPU_CONF_DP_EN;
- if (ipu_dmfc_use_count == 1)
- ipu_conf |= IPU_CONF_DMFC_EN;
- if (ipu_di_use_count[0] == 1) {
- ipu_conf |= IPU_CONF_DI0_EN;
- }
- if (ipu_di_use_count[1] == 1) {
- ipu_conf |= IPU_CONF_DI1_EN;
- }
- if (ipu_smfc_use_count == 1)
- ipu_conf |= IPU_CONF_SMFC_EN;
__raw_writel(ipu_conf, IPU_CONF);
-
err:
spin_unlock_irqrestore(&ipu_lock, lock_flags);
return ret;
@@ -775,8 +776,8 @@ void ipu_uninit_channel(ipu_channel_t channel)
/* Make sure channel is disabled */
/* Get input and output dma channels */
- in_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
- out_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
+ in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
+ out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
if (idma_is_set(IDMAC_CHA_EN, in_dma) ||
idma_is_set(IDMAC_CHA_EN, out_dma)) {
@@ -796,8 +797,10 @@ void ipu_uninit_channel(ipu_channel_t channel)
reg = __raw_readl(IPU_CHA_DB_MODE_SEL(out_dma));
__raw_writel(reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma));
- g_sec_chan_en[IPU_CHAN_ID(channel)] = false;
- g_thrd_chan_en[IPU_CHAN_ID(channel)] = false;
+ if (_ipu_is_ic_chan(in_dma) || _ipu_is_dp_graphic_chan(in_dma)) {
+ g_sec_chan_en[IPU_CHAN_ID(channel)] = false;
+ g_thrd_chan_en[IPU_CHAN_ID(channel)] = false;
+ }
switch (channel) {
case CSI_MEM0:
@@ -849,6 +852,9 @@ void ipu_uninit_channel(ipu_channel_t channel)
reg = __raw_readl(IPU_FS_PROC_FLOW1);
__raw_writel(reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
break;
+ case MEM_VDI_PRP_VF_MEM_P:
+ case MEM_VDI_PRP_VF_MEM_N:
+ break;
case MEM_ROT_VF_MEM:
ipu_rot_use_count--;
ipu_ic_use_count--;
@@ -913,6 +919,7 @@ void ipu_uninit_channel(ipu_channel_t channel)
if (ipu_ic_use_count == 0)
ipu_conf &= ~IPU_CONF_IC_EN;
if (ipu_vdi_use_count == 0) {
+ ipu_conf &= ~IPU_CONF_ISP_EN;
ipu_conf &= ~IPU_CONF_VDI_EN;
ipu_conf &= ~IPU_CONF_IC_INPUT;
}
@@ -1239,8 +1246,6 @@ int32_t ipu_select_buffer(ipu_channel_t channel, ipu_buffer_t type,
__raw_writel(idma_mask(dma_chan) | reg,
IPU_CHA_BUF1_RDY(dma_chan));
}
- if (channel == MEM_VDI_PRP_VF_MEM)
- _ipu_vdi_toggle_top_field_man();
return 0;
}
EXPORT_SYMBOL(ipu_select_buffer);
@@ -1269,10 +1274,9 @@ int32_t ipu_select_multi_vdi_buffer(uint32_t bufNum)
__raw_writel(mask_bit | reg, IPU_CHA_BUF0_RDY(dma_chan));
} else {
/*Mark buffer 1 as ready. */
- reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan));
+ reg = __raw_readl(IPU_CHA_BUF1_RDY(dma_chan));
__raw_writel(mask_bit | reg, IPU_CHA_BUF1_RDY(dma_chan));
}
- _ipu_vdi_toggle_top_field_man();
return 0;
}
EXPORT_SYMBOL(ipu_select_multi_vdi_buffer);
@@ -1282,7 +1286,7 @@ static int proc_dest_sel[] =
{ 0, 1, 1, 3, 5, 5, 4, 7, 8, 9, 10, 11, 12, 14, 15, 16,
0, 1, 1, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 14, 31 };
static int proc_src_sel[] = { 0, 6, 7, 6, 7, 8, 5, NA, NA, NA,
- NA, NA, NA, NA, NA, 1, 2, 3, 4, 7, 8, NA, NA, NA };
+ NA, NA, NA, NA, NA, 1, 2, 3, 4, 7, 8, NA, 8, NA };
static int disp_src_sel[] = { 0, 6, 7, 8, 3, 4, 5, NA, NA, NA,
NA, NA, NA, NA, NA, 1, NA, 2, NA, 3, 4, 4, 4, 4 };
@@ -1659,6 +1663,7 @@ int32_t ipu_enable_channel(ipu_channel_t channel)
{
uint32_t reg;
unsigned long lock_flags;
+ uint32_t ipu_conf;
uint32_t in_dma;
uint32_t out_dma;
uint32_t sec_dma;
@@ -1675,6 +1680,32 @@ int32_t ipu_enable_channel(ipu_channel_t channel)
spin_lock_irqsave(&ipu_lock, lock_flags);
+ ipu_conf = __raw_readl(IPU_CONF);
+ if (ipu_di_use_count[0] > 0) {
+ ipu_conf |= IPU_CONF_DI0_EN;
+ }
+ if (ipu_di_use_count[1] > 0) {
+ ipu_conf |= IPU_CONF_DI1_EN;
+ }
+ if (ipu_dp_use_count > 0)
+ ipu_conf |= IPU_CONF_DP_EN;
+ if (ipu_dc_use_count > 0)
+ ipu_conf |= IPU_CONF_DC_EN;
+ if (ipu_dmfc_use_count > 0)
+ ipu_conf |= IPU_CONF_DMFC_EN;
+ if (ipu_ic_use_count > 0)
+ ipu_conf |= IPU_CONF_IC_EN;
+ if (ipu_vdi_use_count > 0) {
+ ipu_conf |= IPU_CONF_ISP_EN;
+ ipu_conf |= IPU_CONF_VDI_EN;
+ ipu_conf |= IPU_CONF_IC_INPUT;
+ }
+ if (ipu_rot_use_count > 0)
+ ipu_conf |= IPU_CONF_ROT_EN;
+ if (ipu_smfc_use_count > 0)
+ ipu_conf |= IPU_CONF_SMFC_EN;
+ __raw_writel(ipu_conf, IPU_CONF);
+
if (idma_is_valid(in_dma)) {
reg = __raw_readl(IDMAC_CHA_EN(in_dma));
__raw_writel(reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
@@ -1710,8 +1741,11 @@ int32_t ipu_enable_channel(ipu_channel_t channel)
}
if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) ||
- (channel == MEM_FG_SYNC))
+ (channel == MEM_FG_SYNC)) {
+ reg = __raw_readl(IDMAC_WM_EN(in_dma));
+ __raw_writel(reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma));
_ipu_dp_dc_enable(channel);
+ }
if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
_ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma))
@@ -1726,6 +1760,38 @@ int32_t ipu_enable_channel(ipu_channel_t channel)
EXPORT_SYMBOL(ipu_enable_channel);
/*!
+ * This function check buffer ready for a logical channel.
+ *
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to clear.
+ *
+ * @param bufNum Input parameter for which buffer number clear
+ * ready state.
+ *
+ */
+int32_t ipu_check_buffer_busy(ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum)
+{
+ uint32_t dma_chan = channel_2_dma(channel, type);
+ uint32_t reg;
+
+ if (dma_chan == IDMA_CHAN_INVALID)
+ return -EINVAL;
+
+ if (bufNum == 0)
+ reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan));
+ else
+ reg = __raw_readl(IPU_CHA_BUF1_RDY(dma_chan));
+
+ if (reg & idma_mask(dma_chan))
+ return 1;
+ else
+ return 0;
+}
+EXPORT_SYMBOL(ipu_check_buffer_busy);
+
+/*!
* This function clear buffer ready for a logical channel.
*
* @param channel Input parameter for the logical channel ID.
@@ -1817,7 +1883,30 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop)
if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
(channel == MEM_DC_SYNC)) {
+ if (channel == MEM_FG_SYNC)
+ ipu_disp_set_window_pos(channel, 0, 0);
+
_ipu_dp_dc_disable(channel, false);
+
+ /*
+ * wait for BG channel EOF then disable FG-IDMAC,
+ * it avoid FG NFB4EOF error.
+ */
+ if (channel == MEM_FG_SYNC) {
+ int timeout = 50;
+
+ __raw_writel(IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF),
+ IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF));
+ while ((__raw_readl(IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF)) &
+ IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF)) == 0) {
+ msleep(10);
+ timeout -= 10;
+ if (timeout <= 0) {
+ dev_err(g_ipu_dev, "warning: wait for bg sync eof timeout\n");
+ break;
+ }
+ }
+ }
} else if (wait_for_stop) {
while (idma_is_set(IDMAC_CHA_BUSY, in_dma) ||
idma_is_set(IDMAC_CHA_BUSY, out_dma) ||
@@ -1861,6 +1950,12 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop)
spin_lock_irqsave(&ipu_lock, lock_flags);
+ if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
+ (channel == MEM_DC_SYNC)) {
+ reg = __raw_readl(IDMAC_WM_EN(in_dma));
+ __raw_writel(reg & ~idma_mask(in_dma), IDMAC_WM_EN(in_dma));
+ }
+
/* Disable IC task */
if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
_ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma))
@@ -1897,8 +1992,6 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop)
g_channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel));
- spin_unlock_irqrestore(&ipu_lock, lock_flags);
-
/* Set channel buffers NOT to be ready */
if (idma_is_valid(in_dma)) {
ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 0);
@@ -1917,6 +2010,8 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop)
ipu_clear_buffer_ready(channel, IPU_ALPHA_IN_BUFFER, 1);
}
+ spin_unlock_irqrestore(&ipu_lock, lock_flags);
+
return 0;
}
EXPORT_SYMBOL(ipu_disable_channel);
@@ -2029,7 +2124,6 @@ static irqreturn_t ipu_irq_handler(int irq, void *desc)
dev_id);
}
}
-
return result;
}
diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c
index 27455fe26ab6..bf71ea833f58 100644
--- a/drivers/mxc/ipu3/ipu_device.c
+++ b/drivers/mxc/ipu3/ipu_device.c
@@ -124,7 +124,6 @@ static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
(&parm, (ipu_channel_buf_parm *) arg,
sizeof(ipu_channel_buf_parm)))
return -EFAULT;
-
ret =
ipu_init_channel_buffer(
parm.channel, parm.type,
@@ -183,6 +182,17 @@ static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
}
break;
+ case IPU_SELECT_MULTI_VDI_BUFFER:
+ {
+ uint32_t parm;
+ if (copy_from_user
+ (&parm, (uint32_t *) arg,
+ sizeof(uint32_t)))
+ return -EFAULT;
+
+ ret = ipu_select_multi_vdi_buffer(parm);
+ }
+ break;
case IPU_LINK_CHANNELS:
{
ipu_channel_link link;
@@ -225,7 +235,6 @@ static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
(&info, (ipu_channel_info *) arg,
sizeof(ipu_channel_info)))
return -EFAULT;
-
ret = ipu_disable_channel(info.channel,
info.stop);
}
@@ -435,7 +444,7 @@ static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
static int mxc_ipu_mmap(struct file *file, struct vm_area_struct *vma)
{
-// vma->vm_page_prot = pgprot_writethru(vma->vm_page_prot);
+ vma->vm_page_prot = pgprot_writethru(vma->vm_page_prot);
if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
@@ -452,12 +461,20 @@ static int mxc_ipu_release(struct inode *inode, struct file *file)
return 0;
}
+int mxc_ipu_fsync(struct file *filp, struct dentry *dentry, int datasync)
+{
+ flush_cache_all();
+ outer_flush_all();
+ return 0;
+}
+
static struct file_operations mxc_ipu_fops = {
.owner = THIS_MODULE,
.open = mxc_ipu_open,
.mmap = mxc_ipu_mmap,
.release = mxc_ipu_release,
- .ioctl = mxc_ipu_ioctl
+ .ioctl = mxc_ipu_ioctl,
+ .fsync = mxc_ipu_fsync
};
int register_ipu_device()
diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c
index 00c5008d149f..14dde404990b 100644
--- a/drivers/mxc/ipu3/ipu_disp.c
+++ b/drivers/mxc/ipu3/ipu_disp.c
@@ -147,6 +147,37 @@ static int __init dmfc_setup(char *options)
}
__setup("dmfc=", dmfc_setup);
+static bool _ipu_update_dmfc_used_size(int dma_chan, int width, int dmfc_size)
+{
+ u32 fifo_size_5f = 1;
+ u32 dmfc_dp_chan = __raw_readl(DMFC_DP_CHAN);
+
+ if ((width > 352) && (dmfc_size == (256 * 4)))
+ fifo_size_5f = 1;
+ else if (width > 176)
+ fifo_size_5f = 2;
+ else if (width > 88)
+ fifo_size_5f = 3;
+ else if (width > 44)
+ fifo_size_5f = 4;
+ else if (width > 22)
+ fifo_size_5f = 5;
+ else if (width > 11)
+ fifo_size_5f = 6;
+ else if (width > 6)
+ fifo_size_5f = 7;
+ else
+ return false;
+
+ if (dma_chan == 27) {
+ dmfc_dp_chan &= ~DMFC_FIFO_SIZE_5F;
+ dmfc_dp_chan |= fifo_size_5f << 11;
+ __raw_writel(dmfc_dp_chan, DMFC_DP_CHAN);
+ }
+
+ return true;
+}
+
void _ipu_dmfc_set_wait4eot(int dma_chan, int width)
{
u32 dmfc_gen1 = __raw_readl(DMFC_GENERAL1);
@@ -169,7 +200,7 @@ void _ipu_dmfc_set_wait4eot(int dma_chan, int width)
else
dmfc_gen1 &= ~(1UL << 22);
} else if (dma_chan == 27) { /*5F*/
- if (dmfc_size_27/width > 2)
+ if (!_ipu_update_dmfc_used_size(dma_chan, width, dmfc_size_27))
dmfc_gen1 |= 1UL << 21;
else
dmfc_gen1 &= ~(1UL << 21);
@@ -245,6 +276,24 @@ static void _ipu_di_sync_config(int di, int wave_gen,
__raw_writel(reg, DI_STP_REP(di, wave_gen));
}
+static void _ipu_dc_map_link(int current_map,
+ int base_map_0, int buf_num_0,
+ int base_map_1, int buf_num_1,
+ int base_map_2, int buf_num_2)
+{
+ int ptr_0 = base_map_0 * 3 + buf_num_0;
+ int ptr_1 = base_map_1 * 3 + buf_num_1;
+ int ptr_2 = base_map_2 * 3 + buf_num_2;
+ int ptr;
+ u32 reg;
+ ptr = (ptr_2 << 10) + (ptr_1 << 5) + ptr_0;
+
+ reg = __raw_readl(DC_MAP_CONF_PTR(current_map));
+ reg &= ~(0x1F << ((16 * (current_map & 0x1))));
+ reg |= ptr << ((16 * (current_map & 0x1)));
+ __raw_writel(reg, DC_MAP_CONF_PTR(current_map));
+}
+
static void _ipu_dc_map_config(int map, int byte_num, int offset, int mask)
{
int ptr = map * 3 + byte_num;
@@ -269,32 +318,63 @@ static void _ipu_dc_map_clear(int map)
}
static void _ipu_dc_write_tmpl(int word, u32 opcode, u32 operand, int map,
- int wave, int glue, int sync)
+ int wave, int glue, int sync, int stop)
{
u32 reg;
- int stop = 1;
-
- reg = sync;
- reg |= (glue << 4);
- reg |= (++wave << 11);
- reg |= (++map << 15);
- reg |= (operand << 20) & 0xFFF00000;
- __raw_writel(reg, ipu_dc_tmpl_reg + word * 2);
-
- reg = (operand >> 12);
- reg |= opcode << 4;
- reg |= (stop << 9);
- __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1);
+
+ if (opcode == WRG) {
+ reg = sync;
+ reg |= (glue << 4);
+ reg |= (++wave << 11);
+ reg |= ((operand & 0x1FFFF) << 15);
+ __raw_writel(reg, ipu_dc_tmpl_reg + word * 2);
+
+ reg = (operand >> 17);
+ reg |= opcode << 7;
+ reg |= (stop << 9);
+ __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1);
+ } else {
+ reg = sync;
+ reg |= (glue << 4);
+ reg |= (++wave << 11);
+ reg |= (++map << 15);
+ reg |= (operand << 20) & 0xFFF00000;
+ __raw_writel(reg, ipu_dc_tmpl_reg + word * 2);
+
+ reg = (operand >> 12);
+ reg |= opcode << 4;
+ reg |= (stop << 9);
+ __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1);
+ }
}
static void _ipu_dc_link_event(int chan, int event, int addr, int priority)
{
u32 reg;
-
- reg = __raw_readl(DC_RL_CH(chan, event));
- reg &= ~(0xFFFF << (16 * (event & 0x1)));
- reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
- __raw_writel(reg, DC_RL_CH(chan, event));
+ u32 address_shift;
+ if (event < DC_EVEN_UGDE0) {
+ reg = __raw_readl(DC_RL_CH(chan, event));
+ reg &= ~(0xFFFF << (16 * (event & 0x1)));
+ reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
+ __raw_writel(reg, DC_RL_CH(chan, event));
+ } else {
+ reg = __raw_readl(DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
+ if ((event - DC_EVEN_UGDE0) & 0x1) {
+ reg &= ~(0x2FF << 16);
+ reg |= (addr << 16);
+ reg |= priority ? (2 << 24) : 0x0;
+ } else {
+ reg &= ~0xFC00FFFF;
+ if (priority)
+ chan = (chan >> 1) +
+ ((((chan & 0x1) + ((chan & 0x2) >> 1))) | (chan >> 3));
+ else
+ chan = 0x7;
+ address_shift = ((event - DC_EVEN_UGDE0) >> 1) ? 7 : 8;
+ reg |= (addr << address_shift) | (priority << 3) | chan;
+ }
+ __raw_writel(reg, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
+ }
}
/* Y = R * 1.200 + G * 2.343 + B * .453 + 0.250;
@@ -503,7 +583,7 @@ void _ipu_dp_uninit(ipu_channel_t channel)
__ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], false);
}
-void _ipu_dc_init(int dc_chan, int di, bool interlaced)
+void _ipu_dc_init(int dc_chan, int di, bool interlaced, uint32_t pixel_fmt)
{
u32 reg = 0;
@@ -517,10 +597,24 @@ void _ipu_dc_init(int dc_chan, int di, bool interlaced)
_ipu_dc_link_event(dc_chan, DC_EVT_NL, 2, 3);
_ipu_dc_link_event(dc_chan, DC_EVT_EOL, 3, 2);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 4, 1);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_link_event(dc_chan, DC_ODD_UGDE1, 9, 5);
+ _ipu_dc_link_event(dc_chan, DC_EVEN_UGDE1, 8, 5);
+ }
} else {
_ipu_dc_link_event(dc_chan, DC_EVT_NL, 5, 3);
_ipu_dc_link_event(dc_chan, DC_EVT_EOL, 6, 2);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 7, 1);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_link_event(dc_chan, DC_ODD_UGDE0, 10, 5);
+ _ipu_dc_link_event(dc_chan, DC_EVEN_UGDE0, 11, 5);
+ }
}
}
_ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0);
@@ -562,6 +656,10 @@ void _ipu_dc_uninit(int dc_chan)
_ipu_dc_link_event(dc_chan, DC_EVT_EOFIELD, 0, 0);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN, 0, 0);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR, 0, 0);
+ _ipu_dc_link_event(dc_chan, DC_ODD_UGDE0, 0, 0);
+ _ipu_dc_link_event(dc_chan, DC_EVEN_UGDE0, 0, 0);
+ _ipu_dc_link_event(dc_chan, DC_ODD_UGDE1, 0, 0);
+ _ipu_dc_link_event(dc_chan, DC_EVEN_UGDE1, 0, 0);
} else if ((dc_chan == 8) || (dc_chan == 9)) {
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0);
@@ -637,6 +735,26 @@ static bool dc_swap;
static irqreturn_t dc_irq_handler(int irq, void *dev_id)
{
struct completion *comp = dev_id;
+ uint32_t reg;
+ uint32_t dc_chan;
+
+ if (irq == IPU_IRQ_DC_FC_1)
+ dc_chan = 1;
+ else
+ dc_chan = 5;
+
+ if (!dc_swap) {
+ reg = __raw_readl(DC_WR_CH_CONF(dc_chan));
+ reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
+ __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
+
+ reg = __raw_readl(IPU_DISP_GEN);
+ if (g_dc_di_assignment[dc_chan])
+ reg &= ~DI1_COUNTER_RELEASE;
+ else
+ reg &= ~DI0_COUNTER_RELEASE;
+ __raw_writel(reg, IPU_DISP_GEN);
+ }
complete(comp);
return IRQ_HANDLED;
@@ -689,29 +807,6 @@ void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap)
if (timeout <= 0)
break;
}
-
- timeout = 50;
-
- /*
- * Wait for DC triple buffer to empty,
- * this check is useful for tv overlay.
- */
- if (g_dc_di_assignment[dc_chan] == 0)
- while ((__raw_readl(DC_STAT) & 0x00000002)
- != 0x00000002) {
- msleep(2);
- timeout -= 2;
- if (timeout <= 0)
- break;
- }
- else if (g_dc_di_assignment[dc_chan] == 1)
- while ((__raw_readl(DC_STAT) & 0x00000020)
- != 0x00000020) {
- msleep(2);
- timeout -= 2;
- if (timeout <= 0)
- break;
- }
return;
} else {
return;
@@ -743,39 +838,6 @@ void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap)
__raw_writel(reg, DC_WR_CH_CONF(dc_chan));
spin_unlock_irqrestore(&ipu_lock, lock_flags);
} else {
- timeout = 50;
-
- /* Wait for DC triple buffer to empty */
- if (g_dc_di_assignment[dc_chan] == 0)
- while ((__raw_readl(DC_STAT) & 0x00000002)
- != 0x00000002) {
- msleep(2);
- timeout -= 2;
- if (timeout <= 0)
- break;
- }
- else if (g_dc_di_assignment[dc_chan] == 1)
- while ((__raw_readl(DC_STAT) & 0x00000020)
- != 0x00000020) {
- msleep(2);
- timeout -= 2;
- if (timeout <= 0)
- break;
- }
-
- spin_lock_irqsave(&ipu_lock, lock_flags);
- reg = __raw_readl(DC_WR_CH_CONF(dc_chan));
- reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
- __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
-
- reg = __raw_readl(IPU_DISP_GEN);
- if (g_dc_di_assignment[dc_chan])
- reg &= ~DI1_COUNTER_RELEASE;
- else
- reg &= ~DI0_COUNTER_RELEASE;
- __raw_writel(reg, IPU_DISP_GEN);
-
- spin_unlock_irqrestore(&ipu_lock, lock_flags);
/* Clock is already off because it must be done quickly, but
we need to fix the ref count */
clk_disable(g_pixel_clk[g_dc_di_assignment[dc_chan]]);
@@ -821,6 +883,34 @@ void _ipu_init_dc_mappings(void)
_ipu_dc_map_config(4, 0, 5, 0xFC);
_ipu_dc_map_config(4, 1, 13, 0xFC);
_ipu_dc_map_config(4, 2, 21, 0xFC);
+
+ /* IPU_PIX_FMT_VYUY 16bit width */
+ _ipu_dc_map_clear(5);
+ _ipu_dc_map_config(5, 0, 7, 0xFF);
+ _ipu_dc_map_config(5, 1, 0, 0x0);
+ _ipu_dc_map_config(5, 2, 15, 0xFF);
+ _ipu_dc_map_clear(6);
+ _ipu_dc_map_config(6, 0, 0, 0x0);
+ _ipu_dc_map_config(6, 1, 7, 0xFF);
+ _ipu_dc_map_config(6, 2, 15, 0xFF);
+
+ /* IPU_PIX_FMT_UYUV 16bit width */
+ _ipu_dc_map_clear(7);
+ _ipu_dc_map_link(7, 6, 0, 6, 1, 6, 2);
+ _ipu_dc_map_clear(8);
+ _ipu_dc_map_link(8, 5, 0, 5, 1, 5, 2);
+
+ /* IPU_PIX_FMT_YUYV 16bit width */
+ _ipu_dc_map_clear(9);
+ _ipu_dc_map_link(9, 5, 2, 5, 1, 5, 0);
+ _ipu_dc_map_clear(10);
+ _ipu_dc_map_link(10, 5, 1, 5, 2, 5, 0);
+
+ /* IPU_PIX_FMT_YVYU 16bit width */
+ _ipu_dc_map_clear(11);
+ _ipu_dc_map_link(11, 5, 1, 5, 2, 5, 0);
+ _ipu_dc_map_clear(12);
+ _ipu_dc_map_link(12, 5, 2, 5, 1, 5, 0);
}
int _ipu_pixfmt_to_map(uint32_t fmt)
@@ -837,6 +927,14 @@ int _ipu_pixfmt_to_map(uint32_t fmt)
return 3;
case IPU_PIX_FMT_LVDS666:
return 4;
+ case IPU_PIX_FMT_VYUY:
+ return 6;
+ case IPU_PIX_FMT_UYVY:
+ return 8;
+ case IPU_PIX_FMT_YUYV:
+ return 10;
+ case IPU_PIX_FMT_YVYU:
+ return 12;
}
return -1;
@@ -964,22 +1062,22 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
dev_dbg(g_ipu_dev, "pixel clk = %d\n", pixel_clk);
if (sig.ext_clk) {
- /* Set the PLL to be an even multiple of the pixel clock. not round div for tvout*/
- if ((clk_get_usecount(g_pixel_clk[0]) == 0) &&
- (clk_get_usecount(g_pixel_clk[1]) == 0)) {
+ /*
+ * Set the PLL to be an even multiple of the pixel clock.
+ * Not round div for tvout and ldb.
+ * Did not consider both DI come from the same ext clk, if
+ * meet such case, ext clk rate should be set specially.
+ */
+ if (clk_get_usecount(g_pixel_clk[disp]) == 0) {
di_parent = clk_get_parent(g_di_clk[disp]);
- if (strcmp(di_parent->name, "tve_clk") != 0) {
- rounded_pixel_clk =
- clk_round_rate(g_pixel_clk[disp], pixel_clk);
- div = clk_get_rate(di_parent) / rounded_pixel_clk;
- if (div % 2)
- div++;
-
- if (clk_get_rate(di_parent) != div * rounded_pixel_clk)
- clk_set_rate(di_parent, div * rounded_pixel_clk);
- msleep(10);
- clk_set_rate(g_di_clk[disp], 2 * rounded_pixel_clk);
- msleep(10);
+ if (strcmp(di_parent->name, "tve_clk") != 0 &&
+ strcmp(di_parent->name, "ldb_di0_clk") != 0 &&
+ strcmp(di_parent->name, "ldb_di1_clk") != 0) {
+ rounded_pixel_clk = pixel_clk * 2;
+ while (rounded_pixel_clk < 150000000)
+ rounded_pixel_clk += pixel_clk * 2;
+ clk_set_rate(di_parent, rounded_pixel_clk);
+ clk_set_rate(g_di_clk[disp], pixel_clk);
}
}
clk_set_parent(g_pixel_clk[disp], g_di_clk[disp]);
@@ -1019,7 +1117,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
di_gen = __raw_readl(DI_GENERAL(disp));
if (sig.interlaced) {
- if (cpu_is_mx51_rev(CHIP_REV_2_0)) {
+ if (g_ipu_hw_rev >= 2) {
/* Setup internal HSYNC waveform */
_ipu_di_sync_config(
disp, /* display */
@@ -1259,7 +1357,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
}
/* Init template microcode */
- _ipu_dc_write_tmpl(0, WROD(0), 0, map, SYNC_WAVE, 0, 8);
+ _ipu_dc_write_tmpl(0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
if (sig.Hsync_pol)
di_gen |= DI_GEN_POLARITY_3;
@@ -1322,13 +1420,31 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
/* Init template microcode */
if (disp) {
- _ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5);
- _ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5);
- _ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_write_tmpl(8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
+ _ipu_dc_write_tmpl(9, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
+ /* configure user events according to DISP NUM */
+ __raw_writel((width - 1), DC_UGDE_3(disp));
+ }
+ _ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
+ _ipu_dc_write_tmpl(3, WRG, 0, map, SYNC_WAVE, 4, 5, 1);
+ _ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
} else {
- _ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5);
- _ipu_dc_write_tmpl(6, WROD(0), 0, map, SYNC_WAVE, 4, 5);
- _ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_write_tmpl(10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
+ _ipu_dc_write_tmpl(11, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
+ /* configure user events according to DISP NUM */
+ __raw_writel(width - 1, DC_UGDE_3(disp));
+ }
+ _ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
+ _ipu_dc_write_tmpl(6, WRG, 0, map, SYNC_WAVE, 4, 5, 1);
+ _ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
}
if (sig.Hsync_pol)
@@ -1340,6 +1456,19 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
/* Set the clock to stop at counter 6. */
di_gen |= 0x6000000;
}
+ /* changinc DISP_CLK polarity: it can be wrong for some applications */
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY))
+ di_gen |= 0x00020000;
+ else {
+ /* Configure accordingly to the received configuration */
+ if (sig.clk_pol)
+ di_gen |= 0x00020000;
+ else
+ di_gen &= ~0x00020000;
+ }
__raw_writel(di_gen, DI_GENERAL(disp));
@@ -1402,7 +1531,7 @@ int ipu_init_async_panel(int disp, int type, uint32_t cycle_time,
_ipu_di_data_pin_config(disp, ASYNC_SER_WAVE, DI_PIN_SER_RS,
2, 0, 0);
- _ipu_dc_write_tmpl(0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0);
+ _ipu_dc_write_tmpl(0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0, 1);
/* Configure DC for serial panel */
__raw_writel(0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL));
@@ -1679,6 +1808,39 @@ int32_t ipu_disp_set_window_pos(ipu_channel_t channel, int16_t x_pos,
}
EXPORT_SYMBOL(ipu_disp_set_window_pos);
+int32_t ipu_disp_get_window_pos(ipu_channel_t channel, int16_t *x_pos,
+ int16_t *y_pos)
+{
+ u32 reg;
+ unsigned long lock_flags;
+ uint32_t flow = 0;
+
+ if (channel == MEM_FG_SYNC)
+ flow = DP_SYNC;
+ else if (channel == MEM_FG_ASYNC0)
+ flow = DP_ASYNC0;
+ else if (channel == MEM_FG_ASYNC1)
+ flow = DP_ASYNC1;
+ else
+ return -EINVAL;
+
+ if (!g_ipu_clk_enabled)
+ clk_enable(g_ipu_clk);
+ spin_lock_irqsave(&ipu_lock, lock_flags);
+
+ reg = __raw_readl(DP_FG_POS(flow));
+
+ *x_pos = (reg >> 16) & 0x7FF;
+ *y_pos = reg & 0x7FF;
+
+ spin_unlock_irqrestore(&ipu_lock, lock_flags);
+ if (!g_ipu_clk_enabled)
+ clk_disable(g_ipu_clk);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_disp_get_window_pos);
+
void ipu_disp_direct_write(ipu_channel_t channel, u32 value, u32 offset)
{
if (channel == DIRECT_ASYNC0)
diff --git a/drivers/mxc/ipu3/ipu_ic.c b/drivers/mxc/ipu3/ipu_ic.c
index 564fab0b699a..78c3a9228941 100644
--- a/drivers/mxc/ipu3/ipu_ic.c
+++ b/drivers/mxc/ipu3/ipu_ic.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -157,7 +157,6 @@ void _ipu_vdi_init(ipu_channel_t channel, ipu_channel_params_t *params)
{
uint32_t reg;
uint32_t pixel_fmt;
- bool top_field_0;
reg = ((params->mem_prp_vf_mem.in_height-1) << 16) |
(params->mem_prp_vf_mem.in_width-1);
@@ -186,19 +185,7 @@ void _ipu_vdi_init(ipu_channel_t channel, ipu_channel_params_t *params)
}
__raw_writel(reg, VDI_C);
- /* MED_MOTION and LOW_MOTION algorithm that are using 3 fields
- * should start presenting using the 2nd field.
- */
- if (((params->mem_prp_vf_mem.field_fmt == V4L2_FIELD_INTERLACED_TB) &&
- (params->mem_prp_vf_mem.motion_sel != HIGH_MOTION)) ||
- ((params->mem_prp_vf_mem.field_fmt == V4L2_FIELD_INTERLACED_BT) &&
- (params->mem_prp_vf_mem.motion_sel == HIGH_MOTION)))
- top_field_0 = false;
- else
- top_field_0 = true;
-
- /* Buffer selection toggle the value therefore init val is inverted. */
- _ipu_vdi_set_top_field_man(!top_field_0);
+ _ipu_vdi_set_top_field_man(false);
_ipu_vdi_set_motion(params->mem_prp_vf_mem.motion_sel);
@@ -227,13 +214,13 @@ void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi)
/* Setup horizontal resizing */
/* Upadeted for IC split case */
- if (!(params->mem_prp_vf_mem.out_resize_ratio)) {
+ if (!(params->mem_prp_vf_mem.outh_resize_ratio)) {
_calc_resize_coeffs(params->mem_prp_vf_mem.in_width,
params->mem_prp_vf_mem.out_width,
&resizeCoeff, &downsizeCoeff);
reg |= (downsizeCoeff << 14) | resizeCoeff;
} else
- reg |= params->mem_prp_vf_mem.out_resize_ratio;
+ reg |= params->mem_prp_vf_mem.outh_resize_ratio;
__raw_writel(reg, IC_PRP_VF_RSC);
@@ -349,13 +336,13 @@ void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi)
/* Setup horizontal resizing */
/* Upadeted for IC split case */
- if (!(params->mem_prp_enc_mem.out_resize_ratio)) {
+ if (!(params->mem_prp_enc_mem.outh_resize_ratio)) {
_calc_resize_coeffs(params->mem_prp_enc_mem.in_width,
params->mem_prp_enc_mem.out_width,
&resizeCoeff, &downsizeCoeff);
reg |= (downsizeCoeff << 14) | resizeCoeff;
} else
- reg |= params->mem_prp_enc_mem.out_resize_ratio;
+ reg |= params->mem_prp_enc_mem.outh_resize_ratio;
__raw_writel(reg, IC_PRP_ENC_RSC);
@@ -387,6 +374,8 @@ void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi)
ic_conf |= IC_CONF_RWS_EN;
__raw_writel(ic_conf, IC_CONF);
+
+// ic_dump_register();
}
void _ipu_ic_uninit_prpenc(void)
@@ -418,20 +407,24 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params)
ipu_color_space_t in_fmt, out_fmt;
/* Setup vertical resizing */
- _calc_resize_coeffs(params->mem_pp_mem.in_height,
+ if (!(params->mem_pp_mem.outv_resize_ratio)) {
+ _calc_resize_coeffs(params->mem_pp_mem.in_height,
params->mem_pp_mem.out_height,
&resizeCoeff, &downsizeCoeff);
- reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
+ reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
+ } else {
+ reg = (params->mem_pp_mem.outv_resize_ratio) << 16;
+ }
/* Setup horizontal resizing */
/* Upadeted for IC split case */
- if (!(params->mem_pp_mem.out_resize_ratio)) {
+ if (!(params->mem_pp_mem.outh_resize_ratio)) {
_calc_resize_coeffs(params->mem_pp_mem.in_width,
params->mem_pp_mem.out_width,
&resizeCoeff, &downsizeCoeff);
reg |= (downsizeCoeff << 14) | resizeCoeff;
} else {
- reg |= params->mem_pp_mem.out_resize_ratio;
+ reg |= params->mem_pp_mem.outh_resize_ratio;
}
__raw_writel(reg, IC_PP_RSC);
diff --git a/drivers/mxc/ipu3/ipu_param_mem.h b/drivers/mxc/ipu3/ipu_param_mem.h
index dab3b617db1c..30e6dc1005ba 100644
--- a/drivers/mxc/ipu3/ipu_param_mem.h
+++ b/drivers/mxc/ipu3/ipu_param_mem.h
@@ -155,8 +155,15 @@ static inline void _ipu_ch_param_init(int ch,
ipu_ch_param_set_field(&params, 1, 102, 14, stride - 1);
}
+ /* EBA is 8-byte aligned */
ipu_ch_param_set_field(&params, 1, 0, 29, addr0 >> 3);
ipu_ch_param_set_field(&params, 1, 29, 29, addr1 >> 3);
+ if (addr0%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's EBA0 is not 8-byte aligned\n", ch);
+ if (addr1%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's EBA1 is not 8-byte aligned\n", ch);
switch (pixel_fmt) {
case IPU_PIX_FMT_GENERIC:
@@ -210,13 +217,14 @@ static inline void _ipu_ch_param_init(int ch,
case IPU_PIX_FMT_ABGR32:
ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
_ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
break;
case IPU_PIX_FMT_UYVY:
ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
ipu_ch_param_set_field(&params, 1, 85, 4, 0xA); /* pix format */
- ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
break;
case IPU_PIX_FMT_YUYV:
ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
@@ -289,13 +297,19 @@ static inline void _ipu_ch_param_init(int ch,
v_offset = v;
}
- /* UBO and VBO are 22-bit */
+ /* UBO and VBO are 22-bit and 8-byte aligned */
if (u_offset/8 > 0x3fffff)
- dev_err(g_ipu_dev,
- "The value of U offset exceeds IPU limitation\n");
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's U offset exceeds IPU limitation\n", ch);
if (v_offset/8 > 0x3fffff)
- dev_err(g_ipu_dev,
- "The value of V offset exceeds IPU limitation\n");
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's V offset exceeds IPU limitation\n", ch);
+ if (u_offset%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's U offset is not 8-byte aligned\n", ch);
+ if (v_offset%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's V offset is not 8-byte aligned\n", ch);
ipu_ch_param_set_field(&params, 0, 46, 22, u_offset / 8);
ipu_ch_param_set_field(&params, 0, 68, 22, v_offset / 8);
@@ -386,6 +400,13 @@ static inline void _ipu_ch_param_set_interlaced_scan(uint32_t ch)
u32 stride;
ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 113, 1, 1);
stride = ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14) + 1;
+ /* ILO is 20-bit and 8-byte aligned */
+ if (stride/8 > 0xfffff)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's ILO exceeds IPU limitation\n", ch);
+ if (stride%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's ILO is not 8-byte aligned\n", ch);
ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 58, 20, stride / 8);
stride *= 2;
ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 102, 14, stride - 1);
@@ -442,7 +463,7 @@ static inline void _ipu_ch_offset_update(int ch,
(uv_stride * vertical_offset / 2) +
horizontal_offset / 2;
v_offset = u_offset + (uv_stride * height / 2);
- u_fix = u ? (u + (uv_stride * vertical_offset) +
+ u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
(horizontal_offset / 2) -
(stride * vertical_offset) - (horizontal_offset)) :
u_offset;
@@ -493,9 +514,9 @@ static inline void _ipu_ch_offset_update(int ch,
uv_stride = stride;
u_offset = stride * (height - vertical_offset - 1) +
(stride - horizontal_offset) +
- (uv_stride * vertical_offset) +
+ (uv_stride * vertical_offset / 2) +
horizontal_offset;
- u_fix = u ? (u + (uv_stride * vertical_offset) +
+ u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
horizontal_offset -
(stride * vertical_offset) - (horizontal_offset)) :
u_offset;
@@ -514,13 +535,19 @@ static inline void _ipu_ch_offset_update(int ch,
if (v_fix > v_offset)
v_offset = v_fix;
- /* UBO and VBO are 22-bit */
+ /* UBO and VBO are 22-bit and 8-byte aligned */
if (u_offset/8 > 0x3fffff)
- dev_err(g_ipu_dev,
- "The value of U offset exceeds IPU limitation\n");
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's U offset exceeds IPU limitation\n", ch);
if (v_offset/8 > 0x3fffff)
- dev_err(g_ipu_dev,
- "The value of V offset exceeds IPU limitation\n");
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's V offset exceeds IPU limitation\n", ch);
+ if (u_offset%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's U offset is not 8-byte aligned\n", ch);
+ if (v_offset%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's V offset is not 8-byte aligned\n", ch);
ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 46, 22, u_offset / 8);
ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 68, 22, v_offset / 8);
diff --git a/drivers/mxc/ipu3/ipu_prv.h b/drivers/mxc/ipu3/ipu_prv.h
index 213ded04c87d..4e62b256889f 100644
--- a/drivers/mxc/ipu3/ipu_prv.h
+++ b/drivers/mxc/ipu3/ipu_prv.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -60,7 +60,7 @@ void _ipu_init_dc_mappings(void);
int _ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt,
uint32_t out_pixel_fmt);
void _ipu_dp_uninit(ipu_channel_t channel);
-void _ipu_dc_init(int dc_chan, int di, bool interlaced);
+void _ipu_dc_init(int dc_chan, int di, bool interlaced, uint32_t pixel_fmt);
void _ipu_dc_uninit(int dc_chan);
void _ipu_dp_dc_enable(ipu_channel_t channel);
void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap);
diff --git a/drivers/mxc/ipu3/ipu_regs.h b/drivers/mxc/ipu3/ipu_regs.h
index 2438df60a0ce..4a78e14df560 100644
--- a/drivers/mxc/ipu3/ipu_regs.h
+++ b/drivers/mxc/ipu3/ipu_regs.h
@@ -261,6 +261,14 @@ extern u32 *ipu_vdi_reg;
#define DC_EVT_NEW_CHAN_R_1 9
#define DC_EVT_NEW_DATA_R_0 10
#define DC_EVT_NEW_DATA_R_1 11
+#define DC_EVEN_UGDE0 12
+#define DC_ODD_UGDE0 13
+#define DC_EVEN_UGDE1 14
+#define DC_ODD_UGDE1 15
+#define DC_EVEN_UGDE2 16
+#define DC_ODD_UGDE2 17
+#define DC_EVEN_UGDE3 18
+#define DC_ODD_UGDE3 19
#define dc_ch_offset(ch) \
({ \
@@ -627,6 +635,8 @@ enum {
VDI_C_VWM3_CLR_2 = 0x02000000,
VDI_C_TOP_FIELD_MAN_1 = 0x40000000,
VDI_C_TOP_FIELD_AUTO_1 = 0x80000000,
+
+ DMFC_FIFO_SIZE_5F = 0x00003800,
};
enum di_pins {
@@ -654,5 +664,6 @@ enum di_sync_wave {
/* DC template opcodes */
#define WROD(lf) (0x18 | (lf << 1))
+#define WRG (0x01)
#endif
diff --git a/drivers/mxc/mlb/Kconfig b/drivers/mxc/mlb/Kconfig
index 294c9776fb4d..7e3b16c2ddae 100644
--- a/drivers/mxc/mlb/Kconfig
+++ b/drivers/mxc/mlb/Kconfig
@@ -6,7 +6,7 @@ menu "MXC Media Local Bus Driver"
config MXC_MLB
tristate "MLB support"
- depends on ARCH_MX35
+ depends on ARCH_MX35 || ARCH_MX53
---help---
Say Y to get the MLB support.
diff --git a/drivers/mxc/pmic/core/mc13892.c b/drivers/mxc/pmic/core/mc13892.c
index 9f232a4f5718..1175ab633fc6 100644
--- a/drivers/mxc/pmic/core/mc13892.c
+++ b/drivers/mxc/pmic/core/mc13892.c
@@ -262,6 +262,7 @@ int pmic_event_unmask(type_event event)
return ret;
}
+EXPORT_SYMBOL(pmic_event_unmask);
int pmic_event_mask(type_event event)
{
@@ -294,7 +295,7 @@ int pmic_event_mask(type_event event)
return ret;
}
-
+EXPORT_SYMBOL(pmic_event_mask);
/*!
* This function returns the PMIC version in system.
*
diff --git a/drivers/mxc/pmic/core/pmic.h b/drivers/mxc/pmic/core/pmic.h
index 964c44a06bc1..da61b19a3f31 100644
--- a/drivers/mxc/pmic/core/pmic.h
+++ b/drivers/mxc/pmic/core/pmic.h
@@ -58,8 +58,6 @@ static inline int spi_rw(struct spi_device *spi, u8 * buf, size_t len)
.cs_change = 0,
.delay_usecs = 0,
};
- mxc_spi_poll_transfer(spi, &t);
- return 0;
#if 0
struct spi_message m;
@@ -68,6 +66,9 @@ static inline int spi_rw(struct spi_device *spi, u8 * buf, size_t len)
if (spi_sync(spi, &m) != 0 || m.status != 0)
return PMIC_ERROR;
return (len - m.actual_length);
+#else
+ mxc_spi_poll_transfer(spi, &t);
+ return 0;
#endif
}
diff --git a/drivers/mxc/pmic/mc13892/pmic_adc.c b/drivers/mxc/pmic/mc13892/pmic_adc.c
index 68588a40d7e4..60ce35e86a06 100644
--- a/drivers/mxc/pmic/mc13892/pmic_adc.c
+++ b/drivers/mxc/pmic/mc13892/pmic_adc.c
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/device.h>
+#include <linux/cdev.h>
#include <linux/pmic_adc.h>
#include <linux/pmic_status.h>
@@ -33,6 +34,9 @@
#define MC13892_ADC0_TS_M_LSH 14
#define MC13892_ADC0_TS_M_WID 3
+static int pmic_adc_major;
+static struct class *pmic_adc_class;
+
/*
* Maximun allowed variation in the three X/Y co-ordinates acquired from
* touch-screen
@@ -924,17 +928,322 @@ static ssize_t adc_ctl(struct device *dev, struct device_attribute *attr,
#endif
+/*!
+ * This function triggers a conversion and returns sampling results of each
+ * specified channel.
+ *
+ * @param channels This input parameter is bitmap to specify channels
+ * to be sampled.
+ * @param result The pointer to array to store sampling results.
+ * The memory should be allocated by the caller of this
+ * function.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_adc_convert_multichnnel(t_channel channels,
+ unsigned short *result)
+{
+ t_adc_param adc_param;
+ int i;
+ PMIC_STATUS ret;
+ if (suspend_flag == 1) {
+ return -EBUSY;
+ }
+ mc13892_adc_init_param(&adc_param);
+ pr_debug("pmic_adc_convert_multichnnel\n");
+
+ channels = channel_num[channels];
+
+ if (channels == -1) {
+ pr_debug("Wrong channel ID\n");
+ return PMIC_PARAMETER_ERROR;
+ }
+
+ adc_param.read_ts = false;
+ adc_param.single_channel = false;
+ if ((channels >= 0) && (channels <= 7)) {
+ adc_param.channel_0 = channels;
+ adc_param.channel_1 = ((channels + 4) % 4) + 4;
+ } else {
+ return PMIC_PARAMETER_ERROR;
+ }
+ adc_param.read_mode = 0x00003f;
+ adc_param.read_ts = false;
+ ret = mc13892_adc_convert(&adc_param);
+
+ for (i = 0; i <= 7; i++) {
+ result[i] = adc_param.value[i];
+ }
+ return ret;
+}
+
+/*!
+ * This function starts a Battery Current mode conversion.
+ *
+ * @param mode Conversion mode.
+ * @param result Battery Current measurement result.
+ * if \a mode = ADC_8CHAN_1X, the result is \n
+ * result[0] = (BATTP - BATT_I) \n
+ * if \a mode = ADC_1CHAN_8X, the result is \n
+ * result[0] = BATTP \n
+ * result[1] = BATT_I \n
+ * result[2] = BATTP \n
+ * result[3] = BATT_I \n
+ * result[4] = BATTP \n
+ * result[5] = BATT_I \n
+ * result[6] = BATTP \n
+ * result[7] = BATT_I
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_adc_get_battery_current(t_conversion_mode mode,
+ unsigned short *result)
+{
+ PMIC_STATUS ret;
+ t_channel channel;
+ if (suspend_flag == 1) {
+ return -EBUSY;
+ }
+ channel = BATTERY_CURRENT;
+ if (mode == ADC_8CHAN_1X) {
+ ret = pmic_adc_convert(channel, result);
+ } else {
+ ret = pmic_adc_convert_8x(channel, result);
+ }
+ return ret;
+}
+
+/*!
+ * This function implements the open method on a MC13892 ADC device.
+ *
+ * @param inode pointer on the node
+ * @param file pointer on the file
+ * @return This function returns 0.
+ */
+static int pmic_adc_open(struct inode *inode, struct file *file)
+{
+ while (suspend_flag == 1) {
+ swait++;
+ /* Block if the device is suspended */
+ if (wait_event_interruptible(suspendq, (suspend_flag == 0))) {
+ return -ERESTARTSYS;
+ }
+ }
+ pr_debug("mc13892_adc : mc13892_adc_open()\n");
+ return 0;
+}
+
+/*!
+ * This function implements the release method on a MC13892 ADC device.
+ *
+ * @param inode pointer on the node
+ * @param file pointer on the file
+ * @return This function returns 0.
+ */
+static int pmic_adc_free(struct inode *inode, struct file *file)
+{
+ pr_debug("mc13892_adc : mc13892_adc_free()\n");
+ return 0;
+}
+
+/*!
+ * This function implements IOCTL controls on a MC13892 ADC device.
+ *
+ * @param inode pointer on the node
+ * @param file pointer on the file
+ * @param cmd the command
+ * @param arg the parameter
+ * @return This function returns 0 if successful.
+ */
+static int pmic_adc_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ t_adc_convert_param *convert_param;
+ t_touch_mode touch_mode;
+ t_touch_screen touch_sample;
+ unsigned short b_current;
+
+ if ((_IOC_TYPE(cmd) != 'p') && (_IOC_TYPE(cmd) != 'D'))
+ return -ENOTTY;
+
+ while (suspend_flag == 1) {
+ swait++;
+ /* Block if the device is suspended */
+ if (wait_event_interruptible(suspendq, (suspend_flag == 0))) {
+ return -ERESTARTSYS;
+ }
+ }
+
+ switch (cmd) {
+ case PMIC_ADC_INIT:
+ CHECK_ERROR(pmic_adc_init());
+ break;
+
+ case PMIC_ADC_DEINIT:
+ CHECK_ERROR(pmic_adc_deinit());
+ break;
+
+ case PMIC_ADC_CONVERT:
+ if ((convert_param = kmalloc(sizeof(t_adc_convert_param),
+ GFP_KERNEL)) == NULL) {
+ return -ENOMEM;
+ }
+ if (copy_from_user(convert_param, (t_adc_convert_param *) arg,
+ sizeof(t_adc_convert_param))) {
+ kfree(convert_param);
+ return -EFAULT;
+ }
+ CHECK_ERROR_KFREE(pmic_adc_convert(convert_param->channel,
+ convert_param->result),
+ (kfree(convert_param)));
+
+ if (copy_to_user((t_adc_convert_param *) arg, convert_param,
+ sizeof(t_adc_convert_param))) {
+ kfree(convert_param);
+ return -EFAULT;
+ }
+ kfree(convert_param);
+ break;
+
+ case PMIC_ADC_CONVERT_8X:
+ if ((convert_param = kmalloc(sizeof(t_adc_convert_param),
+ GFP_KERNEL)) == NULL) {
+ return -ENOMEM;
+ }
+ if (copy_from_user(convert_param, (t_adc_convert_param *) arg,
+ sizeof(t_adc_convert_param))) {
+ kfree(convert_param);
+ return -EFAULT;
+ }
+ CHECK_ERROR_KFREE(pmic_adc_convert_8x(convert_param->channel,
+ convert_param->result),
+ (kfree(convert_param)));
+
+ if (copy_to_user((t_adc_convert_param *) arg, convert_param,
+ sizeof(t_adc_convert_param))) {
+ kfree(convert_param);
+ return -EFAULT;
+ }
+ kfree(convert_param);
+ break;
+
+ case PMIC_ADC_CONVERT_MULTICHANNEL:
+ if ((convert_param = kmalloc(sizeof(t_adc_convert_param),
+ GFP_KERNEL)) == NULL) {
+ return -ENOMEM;
+ }
+ if (copy_from_user(convert_param, (t_adc_convert_param *) arg,
+ sizeof(t_adc_convert_param))) {
+ kfree(convert_param);
+ return -EFAULT;
+ }
+
+ CHECK_ERROR_KFREE(pmic_adc_convert_multichnnel
+ (convert_param->channel,
+ convert_param->result),
+ (kfree(convert_param)));
+
+ if (copy_to_user((t_adc_convert_param *) arg, convert_param,
+ sizeof(t_adc_convert_param))) {
+ kfree(convert_param);
+ return -EFAULT;
+ }
+ kfree(convert_param);
+ break;
+
+ case PMIC_ADC_SET_TOUCH_MODE:
+ CHECK_ERROR(pmic_adc_set_touch_mode((t_touch_mode) arg));
+ break;
+
+ case PMIC_ADC_GET_TOUCH_MODE:
+ CHECK_ERROR(pmic_adc_get_touch_mode(&touch_mode));
+ if (copy_to_user((t_touch_mode *) arg, &touch_mode,
+ sizeof(t_touch_mode))) {
+ return -EFAULT;
+ }
+ break;
+
+ case PMIC_ADC_GET_TOUCH_SAMPLE:
+ CHECK_ERROR(pmic_adc_get_touch_sample(&touch_sample, 1));
+ if (copy_to_user((t_touch_screen *) arg, &touch_sample,
+ sizeof(t_touch_screen))) {
+ return -EFAULT;
+ }
+ break;
+
+ case PMIC_ADC_GET_BATTERY_CURRENT:
+ CHECK_ERROR(pmic_adc_get_battery_current(ADC_8CHAN_1X,
+ &b_current));
+ if (copy_to_user((unsigned short *)arg, &b_current,
+ sizeof(unsigned short))) {
+
+ return -EFAULT;
+ }
+ break;
+
+ default:
+ pr_debug("pmic_adc_ioctl: unsupported ioctl command 0x%x\n",
+ cmd);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct file_operations mc13892_adc_fops = {
+ .owner = THIS_MODULE,
+ .ioctl = pmic_adc_ioctl,
+ .open = pmic_adc_open,
+ .release = pmic_adc_free,
+};
+
+static struct cdev pmic_adc_cdev;
static DEVICE_ATTR(adc, 0644, adc_info, adc_ctl);
static int pmic_adc_module_probe(struct platform_device *pdev)
{
int ret = 0;
+ struct device * sdev;
+ dev_t devid;
pr_debug("PMIC ADC start probe\n");
+
+ if( (ret = alloc_chrdev_region(&devid, 0, 8, "pmic_adc")) < 0 ) {
+ pr_debug(KERN_ERR "Unable to allocate device range for pmic_adc\n");
+ return ret;
+ }
+ pmic_adc_major = MAJOR(devid);
+ if (pmic_adc_major < 0) {
+ pr_debug(KERN_ERR "Unable to get a major for pmic_adc\n");
+ ret = pmic_adc_major;
+ goto unreg_char;
+ }
+
+ cdev_init(&pmic_adc_cdev, &mc13892_adc_fops);
+ ret =cdev_add(&pmic_adc_cdev, devid, 8);
+ if (ret < 0) {
+ pr_err("pmic_adc: cannot add character device\n");
+ goto unreg_char;
+ }
+
+ pmic_adc_class = class_create(THIS_MODULE, "pmic_adc");
+ if (IS_ERR(pmic_adc_class)) {
+ pr_debug(KERN_ERR "Error creating pmic_adc class.\n");
+ ret = PTR_ERR(pmic_adc_class);
+ goto unreg_char;
+ }
+
+ sdev = device_create(pmic_adc_class, NULL, devid, NULL, "pmic_adc");
+ if (IS_ERR(sdev) ) {
+ pr_debug(KERN_ERR "Error creating pmic_adc class device.\n");
+ ret = PTR_ERR(sdev);
+ goto cl_destroy;
+ }
+
ret = device_create_file(&(pdev->dev), &dev_attr_adc);
if (ret) {
pr_debug("Can't create device file!\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto dev_destroy;
}
init_waitqueue_head(&suspendq);
@@ -946,11 +1255,17 @@ static int pmic_adc_module_probe(struct platform_device *pdev)
}
pmic_adc_ready = 1;
- pr_debug("PMIC ADC successfully probed\n");
+ printk(KERN_DEBUG"PMIC ADC successfully probed\n");
return 0;
- rm_dev_file:
+rm_dev_file:
device_remove_file(&(pdev->dev), &dev_attr_adc);
+dev_destroy:
+ device_destroy(pmic_adc_class, MKDEV(pmic_adc_major, 0));
+cl_destroy:
+ class_destroy(pmic_adc_class);
+unreg_char:
+ unregister_chrdev(pmic_adc_major, "pmic_adc");
return ret;
}
diff --git a/drivers/mxc/pmic/mc13892/pmic_battery.c b/drivers/mxc/pmic/mc13892/pmic_battery.c
index 8535eb0a34e4..c355e0c4338f 100644
--- a/drivers/mxc/pmic/mc13892/pmic_battery.c
+++ b/drivers/mxc/pmic/mc13892/pmic_battery.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -104,6 +104,19 @@ enum chg_setting {
VI_PROGRAM_EN
};
+
+static unsigned int max_voltage_design = 3800000;
+module_param(max_voltage_design, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(max_voltage_design, "Maximum battery voltage by design.");
+
+static unsigned int min_voltage_design = 3300000;
+module_param(min_voltage_design, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(min_voltage_design, "Minimum battery voltage by design.");
+
+static unsigned int main_charger_current = 0x8; /* 720 mA */
+module_param(main_charger_current, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(main_charger_current, "Main charge path regulator current limit.");
+
static int pmic_set_chg_current(unsigned short curr)
{
unsigned int mask;
@@ -180,15 +193,35 @@ static int pmic_set_chg_misc(enum chg_setting type, unsigned short flag)
return 0;
}
+static void pmic_stop_charging(void)
+{
+ pmic_set_chg_misc(AUTO_CHG_DIS, 0);
+ pmic_set_chg_current(0);
+}
+
+static int pmic_restart_charging(void)
+{
+ pmic_set_chg_misc(BAT_TH_CHECK_DIS, 1);
+ pmic_set_chg_misc(AUTO_CHG_DIS, 0);
+ pmic_set_chg_misc(VI_PROGRAM_EN, 1);
+ pmic_set_chg_current(main_charger_current);
+ pmic_set_chg_misc(RESTART_CHG_STAT, 1);
+ return 0;
+}
+
static int pmic_get_batt_voltage(unsigned short *voltage)
{
t_channel channel;
unsigned short result[8];
+ pmic_stop_charging();
+
channel = BATTERY_VOLTAGE;
CHECK_ERROR(pmic_adc_convert(channel, result));
*voltage = result[0];
+ pmic_restart_charging();
+
return 0;
}
@@ -197,10 +230,14 @@ static int pmic_get_batt_current(unsigned short *curr)
t_channel channel;
unsigned short result[8];
+ pmic_stop_charging();
+
channel = BATTERY_CURRENT;
CHECK_ERROR(pmic_adc_convert(channel, result));
*curr = result[0];
+ pmic_restart_charging();
+
return 0;
}
@@ -284,16 +321,6 @@ static int pmic_get_charger_coulomb(int *coulomb)
return 0;
}
-static int pmic_restart_charging(void)
-{
- pmic_set_chg_misc(BAT_TH_CHECK_DIS, 1);
- pmic_set_chg_misc(AUTO_CHG_DIS, 0);
- pmic_set_chg_misc(VI_PROGRAM_EN, 1);
- pmic_set_chg_current(0x8);
- pmic_set_chg_misc(RESTART_CHG_STAT, 1);
- return 0;
-}
-
struct mc13892_dev_info {
struct device *dev;
@@ -353,8 +380,8 @@ static int mc13892_charger_update_status(struct mc13892_dev_info *di)
pmic_restart_charging();
} else
pmic_stop_coulomb_counter();
+ }
}
- }
return ret;
}
@@ -422,7 +449,7 @@ static void mc13892_battery_update_status(struct mc13892_dev_info *di)
else
di->battery_status =
POWER_SUPPLY_STATUS_NOT_CHARGING;
- }
+ }
if (di->battery_status == POWER_SUPPLY_STATUS_NOT_CHARGING)
di->full_counter++;
@@ -491,10 +518,10 @@ static int mc13892_battery_get_property(struct power_supply *psy,
val->intval = di->accum_current_uAh;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
- val->intval = 3800000;
+ val->intval = max_voltage_design;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
- val->intval = 3300000;
+ val->intval = min_voltage_design;
break;
default:
return -EINVAL;
@@ -536,7 +563,7 @@ static int pmic_battery_probe(struct platform_device *pdev)
pr_debug("Battery driver is only applied for MC13892 V2.0\n");
return -1;
}
- if (machine_is_mx51_babbage()) {
+ if (machine_is_mx51_babbage() || machine_is_mx50_arm2()) {
pr_debug("mc13892 charger is not used for this platform\n");
return -1;
}
diff --git a/drivers/mxc/security/Kconfig b/drivers/mxc/security/Kconfig
index 875848b2c69c..3e36a29ace64 100644
--- a/drivers/mxc/security/Kconfig
+++ b/drivers/mxc/security/Kconfig
@@ -27,6 +27,7 @@ config MXC_SECURITY_RNG
depends on ARCH_MXC
depends on !ARCH_MXC91321
depends on !ARCH_MX27
+ depends on !ARCH_MX51
default n
select MXC_SECURITY_CORE
---help---
diff --git a/drivers/mxc/security/sahara2/fsl_shw_auth.c b/drivers/mxc/security/sahara2/fsl_shw_auth.c
index d3100f01380a..b3f8788b553a 100644
--- a/drivers/mxc/security/sahara2/fsl_shw_auth.c
+++ b/drivers/mxc/security/sahara2/fsl_shw_auth.c
@@ -326,7 +326,7 @@ static inline fsl_shw_return_t add_assoc_preamble(sah_Head_Desc ** desc_chain,
return status;
} /* add_assoc_preamble() */
-#if SUPPORT_SSL
+#ifdef SUPPORT_SSL
/*!
* Generate an SSL value
*
@@ -473,7 +473,7 @@ fsl_shw_return_t fsl_shw_gen_encrypt(fsl_shw_uco_t * user_ctx,
SAH_SF_USER_CHECK();
if (auth_ctx->mode == FSL_ACC_MODE_SSL) {
-#if SUPPORT_SSL
+#ifdef SUPPORT_SSL
ret = do_ssl_gen(user_ctx, auth_ctx, cipher_key_info,
auth_key_info, auth_data_length, auth_data,
payload_length, payload, ct, auth_value);
diff --git a/drivers/mxc/security/scc2_driver.c b/drivers/mxc/security/scc2_driver.c
index 3249405c86a1..5c0d8b4dc26d 100644
--- a/drivers/mxc/security/scc2_driver.c
+++ b/drivers/mxc/security/scc2_driver.c
@@ -415,6 +415,7 @@ extern scc_partition_status_t scc_partition_status(void *part_base)
break;
}
}
+EXPORT_SYMBOL(scc_partition_status);
/**
* Calculate the physical address from the kernel virtual address.
@@ -427,6 +428,7 @@ uint32_t scc_virt_to_phys(void *address)
return (uint32_t) address - (uint32_t) scm_ram_base
+ (uint32_t) scm_ram_phys_base;
}
+EXPORT_SYMBOL(scc_virt_to_phys);
/**
* Engage partition of secure memory
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index b9ae23928c5d..9fc25edc33fa 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -73,6 +73,7 @@ static struct vpu_mem_desc user_data_mem = { 0 };
static struct vpu_mem_desc share_mem = { 0 };
static void __iomem *vpu_base;
+static int vpu_irq;
static u32 phy_vpu_base_addr;
static struct mxc_vpu_platform_data *vpu_plat;
@@ -539,7 +540,7 @@ static int vpu_map_mem(struct file *fp, struct vm_area_struct *vm)
request_size);
vm->vm_flags |= VM_IO | VM_RESERVED;
- vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+ vm->vm_page_prot = pgprot_writecombine(vm->vm_page_prot);
return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff,
request_size, vm->vm_page_prot) ? -EAGAIN : 0;
@@ -635,8 +636,9 @@ static int vpu_dev_probe(struct platform_device *pdev)
err = -ENXIO;
goto err_out_class;
}
+ vpu_irq = res->start;
- err = request_irq(res->start, vpu_irq_handler, 0, "VPU_CODEC_IRQ",
+ err = request_irq(vpu_irq, vpu_irq_handler, 0, "VPU_CODEC_IRQ",
(void *)(&vpu_data));
if (err)
goto err_out_class;
@@ -660,6 +662,7 @@ static int vpu_dev_probe(struct platform_device *pdev)
static int vpu_dev_remove(struct platform_device *pdev)
{
+ free_irq(vpu_irq, &vpu_data);
iounmap(vpu_base);
iram_free(iram.start, VPU_IRAM_SIZE);
@@ -690,22 +693,25 @@ static int vpu_suspend(struct platform_device *pdev, pm_message_t state)
for (i = 0; i < vpu_clk_usercount; i++)
clk_disable(vpu_clk);
- clk_enable(vpu_clk);
- if (bitwork_mem.cpu_addr != 0) {
- SAVE_WORK_REGS;
- SAVE_CTRL_REGS;
- SAVE_RDWR_PTR_REGS;
- SAVE_DIS_FLAG_REGS;
-
- WRITE_REG(0x1, BIT_BUSY_FLAG);
- WRITE_REG(VPU_SLEEP_REG_VALUE, BIT_RUN_COMMAND);
- while (READ_REG(BIT_BUSY_FLAG)) ;
+ if (!cpu_is_mx37())
+ return 0;
+ else {
+ clk_enable(vpu_clk);
+ if (bitwork_mem.cpu_addr != 0) {
+ SAVE_WORK_REGS;
+ SAVE_CTRL_REGS;
+ SAVE_RDWR_PTR_REGS;
+ SAVE_DIS_FLAG_REGS;
+
+ WRITE_REG(0x1, BIT_BUSY_FLAG);
+ WRITE_REG(VPU_SLEEP_REG_VALUE, BIT_RUN_COMMAND);
+ while (READ_REG(BIT_BUSY_FLAG))
+ ;
+ }
+ clk_disable(vpu_clk);
}
- clk_disable(vpu_clk);
-
- if (cpu_is_mx37() || cpu_is_mx51())
- mxc_pg_enable(pdev);
+ mxc_pg_enable(pdev);
return 0;
@@ -719,11 +725,12 @@ static int vpu_resume(struct platform_device *pdev)
{
int i;
- if (cpu_is_mx37() || cpu_is_mx51())
+ if (cpu_is_mx37())
mxc_pg_disable(pdev);
+ else
+ goto recover_clk;
clk_enable(vpu_clk);
-
if (bitwork_mem.cpu_addr != 0) {
u32 *p = (u32 *) bitwork_mem.cpu_addr;
u32 data;
@@ -786,12 +793,13 @@ static int vpu_resume(struct platform_device *pdev)
WRITE_REG(VPU_WAKE_REG_VALUE, BIT_RUN_COMMAND);
while (READ_REG(BIT_BUSY_FLAG)) ;
}
-
clk_disable(vpu_clk);
+recover_clk:
/* Recover vpu clock */
for (i = 0; i < vpu_clk_usercount; i++)
clk_enable(vpu_clk);
+ printk("vpu_resume end\n");
return 0;
}
@@ -824,7 +832,6 @@ static int __init vpu_init(void)
static void __exit vpu_exit(void)
{
- free_irq(MXC_INT_VPU, (void *)(&vpu_data));
if (vpu_major > 0) {
device_destroy(vpu_class, MKDEV(vpu_major, 0));
class_destroy(vpu_class);