diff options
author | Jason Chen <b02280@freescale.com> | 2011-07-13 12:17:01 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-01-09 20:18:40 +0800 |
commit | 34fd7c4af3ddfa229388bc3bf4d86ead529346ed (patch) | |
tree | aa2d45380c04ffe33b327808b95420685f3028d8 /drivers/mxc/ipu3 | |
parent | 620171671b07df60df0d8efc55f4dc4fb726da47 (diff) |
ENGR00152845-4 ipuv3: add multiple instance support
add multiple instance support.
Signed-off-by: Jason Chen <jason.chen@freescale.com>
Diffstat (limited to 'drivers/mxc/ipu3')
-rw-r--r-- | drivers/mxc/ipu3/Kconfig | 6 | ||||
-rw-r--r-- | drivers/mxc/ipu3/Makefile | 3 | ||||
-rw-r--r-- | drivers/mxc/ipu3/ipu_capture.c | 392 | ||||
-rw-r--r-- | drivers/mxc/ipu3/ipu_common.c | 1907 | ||||
-rw-r--r-- | drivers/mxc/ipu3/ipu_disp.c | 1161 | ||||
-rw-r--r-- | drivers/mxc/ipu3/ipu_ic.c | 266 | ||||
-rw-r--r-- | drivers/mxc/ipu3/ipu_param_mem.h | 207 | ||||
-rw-r--r-- | drivers/mxc/ipu3/ipu_prv.h | 296 | ||||
-rw-r--r-- | drivers/mxc/ipu3/ipu_regs.h | 383 |
9 files changed, 2527 insertions, 2094 deletions
diff --git a/drivers/mxc/ipu3/Kconfig b/drivers/mxc/ipu3/Kconfig index 0ae0ffa9e19d..b1461ce46244 100644 --- a/drivers/mxc/ipu3/Kconfig +++ b/drivers/mxc/ipu3/Kconfig @@ -3,3 +3,9 @@ config MXC_IPU_V3 config MXC_IPU_V3D bool + +config MXC_IPU_V3EX + bool + +config MXC_IPU_V3H + bool diff --git a/drivers/mxc/ipu3/Makefile b/drivers/mxc/ipu3/Makefile index aa3e7b1bb501..022541115dd8 100644 --- a/drivers/mxc/ipu3/Makefile +++ b/drivers/mxc/ipu3/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_MXC_IPU_V3) = mxc_ipu.o -mxc_ipu-objs := ipu_common.o ipu_ic.o ipu_disp.o ipu_capture.o ipu_device.o ipu_calc_stripes_sizes.o +#mxc_ipu-objs := ipu_common.o ipu_ic.o ipu_disp.o ipu_capture.o ipu_device.o ipu_calc_stripes_sizes.o +mxc_ipu-objs := ipu_common.o ipu_ic.o ipu_disp.o ipu_capture.o ipu_calc_stripes_sizes.o diff --git a/drivers/mxc/ipu3/ipu_capture.c b/drivers/mxc/ipu3/ipu_capture.c index 32d3522cb859..88b1a3954ae5 100644 --- a/drivers/mxc/ipu3/ipu_capture.c +++ b/drivers/mxc/ipu3/ipu_capture.c @@ -35,6 +35,7 @@ * Sets initial values for the CSI registers. * The width and height of the sensor and the actual frame size will be * set to the same values. + * @param ipu ipu handler * @param width Sensor width * @param height Sensor height * @param pixel_fmt pixel format @@ -44,8 +45,8 @@ * @return 0 for success, -EINVAL for error */ int32_t -ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt, - ipu_csi_signal_cfg_t cfg_param) +ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height, + uint32_t pixel_fmt, ipu_csi_signal_cfg_t cfg_param) { uint32_t data = 0; uint32_t csi = cfg_param.csi; @@ -93,22 +94,20 @@ 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) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - __raw_writel(data, CSI_SENS_CONF(csi)); + ipu_csi_write(ipu, csi, data, CSI_SENS_CONF); /* Setup sensor frame size */ - __raw_writel((width - 1) | (height - 1) << 16, CSI_SENS_FRM_SIZE(csi)); + ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_SENS_FRM_SIZE); /* Set CCIR registers */ 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)); + ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1); + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3); } else if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED) { if (width == 720 && height == 625) { /* PAL case */ @@ -116,33 +115,35 @@ ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt, * Field0BlankEnd = 0x6, Field0BlankStart = 0x2, * Field0ActiveEnd = 0x4, Field0ActiveStart = 0 */ - __raw_writel(0x40596, CSI_CCIR_CODE_1(csi)); + ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_1); /* * Field1BlankEnd = 0x7, Field1BlankStart = 0x3, * Field1ActiveEnd = 0x5, Field1ActiveStart = 0x1 */ - __raw_writel(0xD07DF, CSI_CCIR_CODE_2(csi)); - __raw_writel(0xFF0000, CSI_CCIR_CODE_3(csi)); + ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_2); + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3); } else if (width == 720 && height == 525) { /* NTSC case */ /* * Field0BlankEnd = 0x7, Field0BlankStart = 0x3, * Field0ActiveEnd = 0x5, Field0ActiveStart = 0x1 */ - __raw_writel(0xD07DF, CSI_CCIR_CODE_1(csi)); + ipu_csi_write(ipu, csi, 0xD07DF, CSI_CCIR_CODE_1); /* * Field1BlankEnd = 0x6, Field1BlankStart = 0x2, * Field1ActiveEnd = 0x4, Field1ActiveStart = 0 */ - __raw_writel(0x40596, CSI_CCIR_CODE_2(csi)); - __raw_writel(0xFF0000, CSI_CCIR_CODE_3(csi)); + ipu_csi_write(ipu, csi, 0x40596, CSI_CCIR_CODE_2); + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3); } else { - spin_unlock_irqrestore(&ipu_lock, lock_flags); - dev_err(g_ipu_dev, "Unsupported CCIR656 interlaced " + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + dev_err(ipu->dev, "Unsupported CCIR656 interlaced " "video mode\n"); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); return -EINVAL; } - _ipu_csi_ccir_err_detection_enable(csi); + _ipu_csi_ccir_err_detection_enable(ipu, csi); } else if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR) || (cfg_param.clk_mode == @@ -151,20 +152,23 @@ ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt, IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR) || (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR)) { - __raw_writel(0x40030, CSI_CCIR_CODE_1(csi)); - __raw_writel(0xFF0000, CSI_CCIR_CODE_3(csi)); - _ipu_csi_ccir_err_detection_enable(csi); + ipu_csi_write(ipu, csi, 0x40030, CSI_CCIR_CODE_1); + ipu_csi_write(ipu, csi, 0xFF0000, CSI_CCIR_CODE_3); + _ipu_csi_ccir_err_detection_enable(ipu, csi); } else if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_GATED_CLK) || (cfg_param.clk_mode == IPU_CSI_CLK_MODE_NONGATED_CLK)) { - _ipu_csi_ccir_err_detection_disable(csi); + _ipu_csi_ccir_err_detection_disable(ipu, csi); } - dev_dbg(g_ipu_dev, "CSI_SENS_CONF = 0x%08X\n", - __raw_readl(CSI_SENS_CONF(csi))); - dev_dbg(g_ipu_dev, "CSI_ACT_FRM_SIZE = 0x%08X\n", - __raw_readl(CSI_ACT_FRM_SIZE(csi))); + dev_dbg(ipu->dev, "CSI_SENS_CONF = 0x%08X\n", + ipu_csi_read(ipu, csi, CSI_SENS_CONF)); + dev_dbg(ipu->dev, "CSI_ACT_FRM_SIZE = 0x%08X\n", + ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE)); + + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); return 0; } @@ -173,13 +177,14 @@ EXPORT_SYMBOL(ipu_csi_init_interface); /*! * ipu_csi_get_sensor_protocol * + * @param ipu ipu handler * @param csi csi 0 or csi 1 * * @return Returns sensor protocol */ -int32_t ipu_csi_get_sensor_protocol(uint32_t csi) +int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi) { - return (__raw_readl(CSI_SENS_CONF(csi)) & + return (ipu_csi_read(ipu, csi, CSI_SENS_CONF) & CSI_SENS_CONF_SENS_PRTCL_MASK) >> CSI_SENS_CONF_SENS_PRTCL_SHIFT; } @@ -188,27 +193,28 @@ EXPORT_SYMBOL(ipu_csi_get_sensor_protocol); /*! * _ipu_csi_mclk_set * + * @param ipu ipu handler * @param pixel_clk desired pixel clock frequency in Hz * @param csi csi 0 or csi 1 * * @return Returns 0 on success or negative error code on fail */ -int _ipu_csi_mclk_set(uint32_t pixel_clk, uint32_t csi) +int _ipu_csi_mclk_set(struct ipu_soc *ipu, uint32_t pixel_clk, uint32_t csi) { uint32_t temp; uint32_t div_ratio; - div_ratio = (clk_get_rate(g_ipu_clk) / pixel_clk) - 1; + div_ratio = (clk_get_rate(ipu->ipu_clk) / pixel_clk) - 1; if (div_ratio > 0xFF || div_ratio < 0) { - dev_dbg(g_ipu_dev, "The value of pixel_clk extends normal range\n"); + dev_dbg(ipu->dev, "The value of pixel_clk extends normal range\n"); return -EINVAL; } - temp = __raw_readl(CSI_SENS_CONF(csi)); + temp = ipu_csi_read(ipu, csi, CSI_SENS_CONF); temp &= ~CSI_SENS_CONF_DIVRATIO_MASK; - __raw_writel(temp | (div_ratio << CSI_SENS_CONF_DIVRATIO_SHIFT), - CSI_SENS_CONF(csi)); + ipu_csi_write(ipu, csi, temp | (div_ratio << CSI_SENS_CONF_DIVRATIO_SHIFT), + CSI_SENS_CONF); return 0; } @@ -216,20 +222,21 @@ int _ipu_csi_mclk_set(uint32_t pixel_clk, uint32_t csi) /*! * ipu_csi_enable_mclk * + * @param ipu ipu handler * @param csi csi 0 or csi 1 * @param flag true to enable mclk, false to disable mclk * @param wait true to wait 100ms make clock stable, false not wait * * @return Returns 0 on success */ -int ipu_csi_enable_mclk(int csi, bool flag, bool wait) +int ipu_csi_enable_mclk(struct ipu_soc *ipu, int csi, bool flag, bool wait) { if (flag) { - clk_enable(g_csi_clk[csi]); + clk_enable(ipu->csi_clk[csi]); if (wait == true) msleep(10); } else { - clk_disable(g_csi_clk[csi]); + clk_disable(ipu->csi_clk[csi]); } return 0; @@ -239,79 +246,85 @@ EXPORT_SYMBOL(ipu_csi_enable_mclk); /*! * ipu_csi_get_window_size * + * @param ipu ipu handler * @param width pointer to window width * @param height pointer to window height * @param csi csi 0 or csi 1 */ -void ipu_csi_get_window_size(uint32_t *width, uint32_t *height, uint32_t csi) +void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi) { uint32_t reg; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - reg = __raw_readl(CSI_ACT_FRM_SIZE(csi)); + reg = ipu_csi_read(ipu, csi, CSI_ACT_FRM_SIZE); *width = (reg & 0xFFFF) + 1; *height = (reg >> 16 & 0xFFFF) + 1; - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } EXPORT_SYMBOL(ipu_csi_get_window_size); /*! * ipu_csi_set_window_size * + * @param ipu ipu handler * @param width window width * @param height window height * @param csi csi 0 or csi 1 */ -void ipu_csi_set_window_size(uint32_t width, uint32_t height, uint32_t csi) +void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi) { unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); + + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - spin_lock_irqsave(&ipu_lock, lock_flags); + ipu_csi_write(ipu, csi, (width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE); - __raw_writel((width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE(csi)); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } EXPORT_SYMBOL(ipu_csi_set_window_size); /*! * ipu_csi_set_window_pos * + * @param ipu ipu handler * @param left uint32 window x start * @param top uint32 window y start * @param csi csi 0 or csi 1 */ -void ipu_csi_set_window_pos(uint32_t left, uint32_t top, uint32_t csi) +void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi) { uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL); temp &= ~(CSI_HSC_MASK | CSI_VSC_MASK); temp |= ((top << CSI_VSC_SHIFT) | (left << CSI_HSC_SHIFT)); - __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } EXPORT_SYMBOL(ipu_csi_set_window_pos); @@ -319,105 +332,114 @@ EXPORT_SYMBOL(ipu_csi_set_window_pos); * _ipu_csi_horizontal_downsize_enable * Enable horizontal downsizing(decimation) by 2. * + * @param ipu ipu handler * @param csi csi 0 or csi 1 */ -void _ipu_csi_horizontal_downsize_enable(uint32_t csi) +void _ipu_csi_horizontal_downsize_enable(struct ipu_soc *ipu, uint32_t csi) { uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL); temp |= CSI_HORI_DOWNSIZE_EN; - __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } /*! * _ipu_csi_horizontal_downsize_disable * Disable horizontal downsizing(decimation) by 2. * + * @param ipu ipu handler * @param csi csi 0 or csi 1 */ -void _ipu_csi_horizontal_downsize_disable(uint32_t csi) +void _ipu_csi_horizontal_downsize_disable(struct ipu_soc *ipu, uint32_t csi) { uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL); temp &= ~CSI_HORI_DOWNSIZE_EN; - __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } /*! * _ipu_csi_vertical_downsize_enable * Enable vertical downsizing(decimation) by 2. * + * @param ipu ipu handler * @param csi csi 0 or csi 1 */ -void _ipu_csi_vertical_downsize_enable(uint32_t csi) +void _ipu_csi_vertical_downsize_enable(struct ipu_soc *ipu, uint32_t csi) { uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL); temp |= CSI_VERT_DOWNSIZE_EN; - __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL); + + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } /*! * _ipu_csi_vertical_downsize_disable * Disable vertical downsizing(decimation) by 2. * + * @param ipu ipu handler * @param csi csi 0 or csi 1 */ -void _ipu_csi_vertical_downsize_disable(uint32_t csi) +void _ipu_csi_vertical_downsize_disable(struct ipu_soc *ipu, uint32_t csi) { uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp = ipu_csi_read(ipu, csi, CSI_OUT_FRM_CTRL); temp &= ~CSI_VERT_DOWNSIZE_EN; - __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + ipu_csi_write(ipu, csi, temp, CSI_OUT_FRM_CTRL); + + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } /*! * ipu_csi_set_test_generator * + * @param ipu ipu handler * @param active 1 for active and 0 for inactive * @param r_value red value for the generated pattern of even pixel * @param g_value green value for the generated pattern of even @@ -426,27 +448,25 @@ void _ipu_csi_vertical_downsize_disable(uint32_t csi) * @param pixel_clk desired pixel clock frequency in Hz * @param csi csi 0 or csi 1 */ -void ipu_csi_set_test_generator(bool active, uint32_t r_value, +void ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value, uint32_t g_value, uint32_t b_value, uint32_t pix_clk, uint32_t csi) { uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(CSI_TST_CTRL(csi)); + temp = ipu_csi_read(ipu, csi, CSI_TST_CTRL); if (active == false) { temp &= ~CSI_TEST_GEN_MODE_EN; - __raw_writel(temp, CSI_TST_CTRL(csi)); + ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL); } else { /* Set sensb_mclk div_ratio*/ - _ipu_csi_mclk_set(pix_clk, csi); + _ipu_csi_mclk_set(ipu, pix_clk, csi); temp &= ~(CSI_TEST_GEN_R_MASK | CSI_TEST_GEN_G_MASK | CSI_TEST_GEN_B_MASK); @@ -454,10 +474,13 @@ void ipu_csi_set_test_generator(bool active, uint32_t r_value, temp |= (r_value << CSI_TEST_GEN_R_SHIFT) | (g_value << CSI_TEST_GEN_G_SHIFT) | (b_value << CSI_TEST_GEN_B_SHIFT); - __raw_writel(temp, CSI_TST_CTRL(csi)); + ipu_csi_write(ipu, csi, temp, CSI_TST_CTRL); } - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } EXPORT_SYMBOL(ipu_csi_set_test_generator); @@ -466,20 +489,22 @@ EXPORT_SYMBOL(ipu_csi_set_test_generator); * Enable error detection and correction for * CCIR interlaced mode with protection bit. * + * @param ipu ipu handler * @param csi csi 0 or csi 1 */ -void _ipu_csi_ccir_err_detection_enable(uint32_t csi) +void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi) { uint32_t temp; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - temp = __raw_readl(CSI_CCIR_CODE_1(csi)); + temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1); temp |= CSI_CCIR_ERR_DET_EN; - __raw_writel(temp, CSI_CCIR_CODE_1(csi)); + ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1); + + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } /*! @@ -487,32 +512,35 @@ void _ipu_csi_ccir_err_detection_enable(uint32_t csi) * Disable error detection and correction for * CCIR interlaced mode with protection bit. * + * @param ipu ipu handler * @param csi csi 0 or csi 1 */ -void _ipu_csi_ccir_err_detection_disable(uint32_t csi) +void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi) { uint32_t temp; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - temp = __raw_readl(CSI_CCIR_CODE_1(csi)); + temp = ipu_csi_read(ipu, csi, CSI_CCIR_CODE_1); temp &= ~CSI_CCIR_ERR_DET_EN; - __raw_writel(temp, CSI_CCIR_CODE_1(csi)); + ipu_csi_write(ipu, csi, temp, CSI_CCIR_CODE_1); + + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } /*! * _ipu_csi_set_mipi_di * + * @param ipu ipu handler * @param num MIPI data identifier 0-3 handled by CSI * @param di_val data identifier value * @param csi csi 0 or csi 1 * * @return Returns 0 on success or negative error code on fail */ -int _ipu_csi_set_mipi_di(uint32_t num, uint32_t di_val, uint32_t csi) +int _ipu_csi_set_mipi_di(struct ipu_soc *ipu, uint32_t num, uint32_t di_val, uint32_t csi) { uint32_t temp; int retval = 0; @@ -523,42 +551,41 @@ int _ipu_csi_set_mipi_di(uint32_t num, uint32_t di_val, uint32_t csi) goto err; } - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(CSI_MIPI_DI(csi)); + temp = ipu_csi_read(ipu, csi, CSI_MIPI_DI); switch (num) { case IPU_CSI_MIPI_DI0: temp &= ~CSI_MIPI_DI0_MASK; temp |= (di_val << CSI_MIPI_DI0_SHIFT); - __raw_writel(temp, CSI_MIPI_DI(csi)); + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI); break; case IPU_CSI_MIPI_DI1: temp &= ~CSI_MIPI_DI1_MASK; temp |= (di_val << CSI_MIPI_DI1_SHIFT); - __raw_writel(temp, CSI_MIPI_DI(csi)); + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI); break; case IPU_CSI_MIPI_DI2: temp &= ~CSI_MIPI_DI2_MASK; temp |= (di_val << CSI_MIPI_DI2_SHIFT); - __raw_writel(temp, CSI_MIPI_DI(csi)); + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI); break; case IPU_CSI_MIPI_DI3: temp &= ~CSI_MIPI_DI3_MASK; temp |= (di_val << CSI_MIPI_DI3_SHIFT); - __raw_writel(temp, CSI_MIPI_DI(csi)); + ipu_csi_write(ipu, csi, temp, CSI_MIPI_DI); break; default: retval = -EINVAL; - goto err; } - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); err: return retval; } @@ -566,6 +593,7 @@ err: /*! * _ipu_csi_set_skip_isp * + * @param ipu ipu handler * @param skip select frames to be skipped and set the * correspond bits to 1 * @param max_ratio number of frames in a skipping set and the @@ -574,7 +602,7 @@ err: * * @return Returns 0 on success or negative error code on fail */ -int _ipu_csi_set_skip_isp(uint32_t skip, uint32_t max_ratio, uint32_t csi) +int _ipu_csi_set_skip_isp(struct ipu_soc *ipu, uint32_t skip, uint32_t max_ratio, uint32_t csi) { uint32_t temp; int retval = 0; @@ -585,20 +613,20 @@ int _ipu_csi_set_skip_isp(uint32_t skip, uint32_t max_ratio, uint32_t csi) goto err; } - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(CSI_SKIP(csi)); + temp = ipu_csi_read(ipu, csi, CSI_SKIP); temp &= ~(CSI_MAX_RATIO_SKIP_ISP_MASK | CSI_SKIP_ISP_MASK); temp |= (max_ratio << CSI_MAX_RATIO_SKIP_ISP_SHIFT) | (skip << CSI_SKIP_ISP_SHIFT); - __raw_writel(temp, CSI_SKIP(csi)); + ipu_csi_write(ipu, csi, temp, CSI_SKIP); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); err: return retval; } @@ -606,6 +634,7 @@ err: /*! * _ipu_csi_set_skip_smfc * + * @param ipu ipu handler * @param skip select frames to be skipped and set the * correspond bits to 1 * @param max_ratio number of frames in a skipping set and the @@ -615,8 +644,8 @@ err: * * @return Returns 0 on success or negative error code on fail */ -int _ipu_csi_set_skip_smfc(uint32_t skip, uint32_t max_ratio, - uint32_t id, uint32_t csi) +int _ipu_csi_set_skip_smfc(struct ipu_soc *ipu, uint32_t skip, + uint32_t max_ratio, uint32_t id, uint32_t csi) { uint32_t temp; int retval = 0; @@ -627,22 +656,23 @@ int _ipu_csi_set_skip_smfc(uint32_t skip, uint32_t max_ratio, goto err; } - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(CSI_SKIP(csi)); + temp = ipu_csi_read(ipu, csi, CSI_SKIP); temp &= ~(CSI_MAX_RATIO_SKIP_SMFC_MASK | CSI_ID_2_SKIP_MASK | CSI_SKIP_SMFC_MASK); temp |= (max_ratio << CSI_MAX_RATIO_SKIP_SMFC_SHIFT) | (id << CSI_ID_2_SKIP_SHIFT) | (skip << CSI_SKIP_SMFC_SHIFT); - __raw_writel(temp, CSI_SKIP(csi)); + ipu_csi_write(ipu, csi, temp, CSI_SKIP); + + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); err: return retval; } @@ -651,15 +681,16 @@ err: * _ipu_smfc_init * Map CSI frames to IDMAC channels. * + * @param ipu ipu handler * @param channel IDMAC channel 0-3 * @param mipi_id mipi id number 0-3 * @param csi csi0 or csi1 */ -void _ipu_smfc_init(ipu_channel_t channel, uint32_t mipi_id, uint32_t csi) +void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi) { uint32_t temp; - temp = __raw_readl(SMFC_MAP); + temp = ipu_smfc_read(ipu, SMFC_MAP); switch (channel) { case CSI_MEM0: @@ -682,7 +713,7 @@ void _ipu_smfc_init(ipu_channel_t channel, uint32_t mipi_id, uint32_t csi) return; } - __raw_writel(temp, SMFC_MAP); + ipu_smfc_write(ipu, temp, SMFC_MAP); } /*! @@ -690,24 +721,23 @@ void _ipu_smfc_init(ipu_channel_t channel, uint32_t mipi_id, uint32_t csi) * Caution: The number of required channels, the enabled channels * and the FIFO size per channel are configured restrictedly. * + * @param ipu ipu handler * @param channel IDMAC channel 0-3 * @param set set 1 or clear 0 * @param level water mark level when FIFO is on the * relative size */ -void _ipu_smfc_set_wmc(ipu_channel_t channel, bool set, uint32_t level) +void _ipu_smfc_set_wmc(struct ipu_soc *ipu, ipu_channel_t channel, bool set, uint32_t level) { uint32_t temp; unsigned long lock_flags; - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); - } + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(SMFC_WMC); + temp = ipu_smfc_read(ipu, SMFC_WMC); switch (channel) { case CSI_MEM0: @@ -750,26 +780,29 @@ void _ipu_smfc_set_wmc(ipu_channel_t channel, bool set, uint32_t level) return; } - __raw_writel(temp, SMFC_WMC); + ipu_smfc_write(ipu, temp, SMFC_WMC); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } /*! * _ipu_smfc_set_burst_size * + * @param ipu ipu handler * @param channel IDMAC channel 0-3 * @param bs burst size of IDMAC channel, * the value programmed here shoud be BURST_SIZE-1 */ -void _ipu_smfc_set_burst_size(ipu_channel_t channel, uint32_t bs) +void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs) { uint32_t temp; unsigned long lock_flags; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - temp = __raw_readl(SMFC_BS); + temp = ipu_smfc_read(ipu, SMFC_BS); switch (channel) { case CSI_MEM0: @@ -792,20 +825,21 @@ void _ipu_smfc_set_burst_size(ipu_channel_t channel, uint32_t bs) return; } - __raw_writel(temp, SMFC_BS); + ipu_smfc_write(ipu, temp, SMFC_BS); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); } /*! * _ipu_csi_init * + * @param ipu ipu handler * @param channel IDMAC channel * @param csi csi 0 or csi 1 * * @return Returns 0 on success or negative error code on fail */ -int _ipu_csi_init(ipu_channel_t channel, uint32_t csi) +int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi) { uint32_t csi_sens_conf, csi_dest; int retval = 0; @@ -826,10 +860,10 @@ int _ipu_csi_init(ipu_channel_t channel, uint32_t csi) goto err; } - csi_sens_conf = __raw_readl(CSI_SENS_CONF(csi)); + csi_sens_conf = ipu_csi_read(ipu, csi, CSI_SENS_CONF); csi_sens_conf &= ~CSI_SENS_CONF_DATA_DEST_MASK; - __raw_writel(csi_sens_conf | (csi_dest << - CSI_SENS_CONF_DATA_DEST_SHIFT), CSI_SENS_CONF(csi)); + ipu_csi_write(ipu, csi, csi_sens_conf | (csi_dest << + CSI_SENS_CONF_DATA_DEST_SHIFT), CSI_SENS_CONF); err: return retval; } diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c index 185352250ac3..7927665c92a6 100644 --- a/drivers/mxc/ipu3/ipu_common.c +++ b/drivers/mxc/ipu3/ipu_common.c @@ -26,6 +26,8 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/irq.h> +#include <linux/irqdesc.h> #include <linux/ipu.h> #include <linux/clk.h> #include <linux/clkdev.h> @@ -38,44 +40,13 @@ #include "ipu_regs.h" #include "ipu_param_mem.h" -struct ipu_irq_node { - irqreturn_t(*handler) (int, void *); /*!< the ISR */ - const char *name; /*!< device associated with the interrupt */ - void *dev_id; /*!< some unique information for the ISR */ - __u32 flags; /*!< not used */ -}; - -/* Globals */ -struct clk *g_ipu_clk; -bool g_ipu_clk_enabled; -struct clk *g_di_clk[2]; -struct clk *g_pixel_clk[2]; -struct clk *g_csi_clk[2]; -unsigned char g_dc_di_assignment[10]; -ipu_channel_t g_ipu_csi_channel[2]; -int g_ipu_irq[2]; +#ifdef CONFIG_MXC_IPU_V3H +#define MXC_IPU_MAX_NUM 2 +#else +#define MXC_IPU_MAX_NUM 1 +#endif +static struct ipu_soc ipu_array[MXC_IPU_MAX_NUM]; int g_ipu_hw_rev; -bool g_sec_chan_en[24]; -bool g_thrd_chan_en[24]; -bool g_chan_is_interlaced[52]; -uint32_t g_channel_init_mask; -uint32_t g_channel_enable_mask; -DEFINE_SPINLOCK(ipu_lock); -struct device *g_ipu_dev; - -static struct ipu_irq_node ipu_irq_list[IPU_IRQ_COUNT]; - -static int ipu_dc_use_count; -static int ipu_dp_use_count; -static int ipu_dmfc_use_count; -static int ipu_smfc_use_count; -static int ipu_ic_use_count; -static int ipu_rot_use_count; -static int ipu_vdi_use_count; -static int ipu_di_use_count[2]; -static int ipu_csi_use_count[2]; -/* Set to the follow using IC direct channel, default non */ -static ipu_channel_t using_ic_dirct_ch; /* for power gating */ static uint32_t ipu_conf_reg; @@ -88,21 +59,6 @@ static uint32_t idma_sub_addr_reg[5]; static uint32_t idma_enable_reg[2]; static uint32_t buf_ready_reg[10]; -u32 *ipu_cm_reg; -u32 *ipu_idmac_reg; -u32 *ipu_dp_reg; -u32 *ipu_ic_reg; -u32 *ipu_dc_reg; -u32 *ipu_dc_tmpl_reg; -u32 *ipu_dmfc_reg; -u32 *ipu_di_reg[2]; -u32 *ipu_smfc_reg; -u32 *ipu_csi_reg[2]; -u32 *ipu_cpmem_base; -u32 *ipu_tpmem_base; -u32 *ipu_disp_base[2]; -u32 *ipu_vdi_reg; - /* Static functions */ static irqreturn_t ipu_irq_handler(int irq, void *desc); @@ -153,13 +109,39 @@ static inline int _ipu_is_trb_chan(uint32_t dma_chan) #define idma_is_valid(ch) (ch != NO_DMA) #define idma_mask(ch) (idma_is_valid(ch) ? (1UL << (ch & 0x1F)) : 0) -#define idma_is_set(reg, dma) (__raw_readl(reg(dma)) & idma_mask(dma)) +#define idma_is_set(ipu, reg, dma) (ipu_idmac_read(ipu, reg(dma)) & idma_mask(dma)) #define tri_cur_buf_mask(ch) (idma_mask(ch*2) * 3) #define tri_cur_buf_shift(ch) (ffs(idma_mask(ch*2)) - 1) +static int ipu_reset(struct ipu_soc *ipu) +{ + int timeout = 1000; + + ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST); + + while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) { + if (!timeout--) + return -ETIME; + msleep(1); + } + + return 0; +} + +static inline struct ipu_soc *pixelclk2ipu(struct clk *clk) +{ + struct ipu_soc *ipu; + struct clk *base = clk - clk->id; + + ipu = container_of(base, struct ipu_soc, pixel_clk[0]); + + return ipu; +} + static unsigned long _ipu_pixel_clk_get_rate(struct clk *clk) { - u32 div = __raw_readl(DI_BS_CLKGEN0(clk->id)); + struct ipu_soc *ipu = pixelclk2ipu(clk); + u32 div = ipu_di_read(ipu, clk->id, DI_BS_CLKGEN0); if (div == 0) return 0; return (clk_get_rate(clk->parent) * 16) / div; @@ -192,46 +174,60 @@ static unsigned long _ipu_pixel_clk_round_rate(struct clk *clk, unsigned long ra static int _ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate) { + struct ipu_soc *ipu = pixelclk2ipu(clk); u32 div = (clk_get_rate(clk->parent) * 16) / rate; + unsigned long lock_flags; - __raw_writel(div, DI_BS_CLKGEN0(clk->id)); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); + ipu_di_write(ipu, clk->id, div, DI_BS_CLKGEN0); /* Setup pixel clock timing */ /* FIXME: needs to be more flexible */ /* Down time is half of period */ - __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id)); + ipu_di_write(ipu, clk->id, (div / 16) << 16, DI_BS_CLKGEN1); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } static int _ipu_pixel_clk_enable(struct clk *clk) { - u32 disp_gen = __raw_readl(IPU_DISP_GEN); + struct ipu_soc *ipu = pixelclk2ipu(clk); + u32 disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN); disp_gen |= clk->id ? DI1_COUNTER_RELEASE : DI0_COUNTER_RELEASE; - __raw_writel(disp_gen, IPU_DISP_GEN); + ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN); return 0; } static void _ipu_pixel_clk_disable(struct clk *clk) { - u32 disp_gen = __raw_readl(IPU_DISP_GEN); + struct ipu_soc *ipu = pixelclk2ipu(clk); + + u32 disp_gen = ipu_cm_read(ipu, IPU_DISP_GEN); disp_gen &= clk->id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE; - __raw_writel(disp_gen, IPU_DISP_GEN); + ipu_cm_write(ipu, disp_gen, IPU_DISP_GEN); } static int _ipu_pixel_clk_set_parent(struct clk *clk, struct clk *parent) { - u32 di_gen = __raw_readl(DI_GENERAL(clk->id)); + struct ipu_soc *ipu = pixelclk2ipu(clk); + unsigned long lock_flags; + u32 di_gen; - if (parent == g_ipu_clk) + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); + di_gen = ipu_di_read(ipu, clk->id, DI_GENERAL); + if (parent == ipu->ipu_clk) di_gen &= ~DI_GEN_DI_CLK_EXT; - else if (!IS_ERR(g_di_clk[clk->id]) && parent == g_di_clk[clk->id]) + else if (!IS_ERR(ipu->di_clk[clk->id]) && parent == ipu->di_clk[clk->id]) di_gen |= DI_GEN_DI_CLK_EXT; - else + else { + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return -EINVAL; + } - __raw_writel(di_gen, DI_GENERAL(clk->id)); + ipu_di_write(ipu, clk->id, di_gen, DI_GENERAL); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } @@ -240,113 +236,254 @@ static int _ipu_pixel_clk_set_parent(struct clk *clk, struct clk *parent) #else #define __INIT_CLK_DEBUG(n) #endif -static struct clk pixel_clk[] = { - { - __INIT_CLK_DEBUG(pixel_clk_0) - .id = 0, - .get_rate = _ipu_pixel_clk_get_rate, - .set_rate = _ipu_pixel_clk_set_rate, - .round_rate = _ipu_pixel_clk_round_rate, - .set_parent = _ipu_pixel_clk_set_parent, - .enable = _ipu_pixel_clk_enable, - .disable = _ipu_pixel_clk_disable, - }, - { - __INIT_CLK_DEBUG(pixel_clk_1) - .id = 1, - .get_rate = _ipu_pixel_clk_get_rate, - .set_rate = _ipu_pixel_clk_set_rate, - .round_rate = _ipu_pixel_clk_round_rate, - .set_parent = _ipu_pixel_clk_set_parent, - .enable = _ipu_pixel_clk_enable, - .disable = _ipu_pixel_clk_disable, - }, -}; +static int __devinit ipu_clk_setup(struct ipu_soc *ipu, + struct platform_device *pdev) +{ + struct imx_ipuv3_platform_data *plat_data = pdev->dev.platform_data; + static struct clk ipu_pixel_clk[] = { + { + __INIT_CLK_DEBUG(pixel_clk_0) + .id = 0, + .get_rate = _ipu_pixel_clk_get_rate, + .set_rate = _ipu_pixel_clk_set_rate, + .round_rate = _ipu_pixel_clk_round_rate, + .set_parent = _ipu_pixel_clk_set_parent, + .enable = _ipu_pixel_clk_enable, + .disable = _ipu_pixel_clk_disable, + }, + { + __INIT_CLK_DEBUG(pixel_clk_1) + .id = 1, + .get_rate = _ipu_pixel_clk_get_rate, + .set_rate = _ipu_pixel_clk_set_rate, + .round_rate = _ipu_pixel_clk_round_rate, + .set_parent = _ipu_pixel_clk_set_parent, + .enable = _ipu_pixel_clk_enable, + .disable = _ipu_pixel_clk_disable, + }, + }; + static struct clk_lookup ipu_lookups[] = { + { + .dev_id = NULL, + .con_id = "pixel_clk_0", + }, + { + .dev_id = NULL, + .con_id = "pixel_clk_1", + }, + }; + char ipu_clk[] = "ipu1_clk"; + char di0_clk[] = "ipu1_di0_clk"; + char di1_clk[] = "ipu1_di1_clk"; + + ipu_clk[3] += pdev->id; + di0_clk[3] += pdev->id; + di1_clk[3] += pdev->id; + + ipu->ipu_clk = clk_get(ipu->dev, ipu_clk); + if (IS_ERR(ipu->ipu_clk)) { + dev_err(ipu->dev, "clk_get failed"); + return PTR_ERR(ipu->ipu_clk); + } + dev_dbg(ipu->dev, "ipu_clk = %lu\n", clk_get_rate(ipu->ipu_clk)); + + ipu->pixel_clk[0] = ipu_pixel_clk[0]; + ipu->pixel_clk[1] = ipu_pixel_clk[1]; + + ipu_lookups[0].clk = &ipu->pixel_clk[0]; + ipu_lookups[1].clk = &ipu->pixel_clk[1]; + clkdev_add(&ipu_lookups[0]); + clkdev_add(&ipu_lookups[1]); + + clk_debug_register(&ipu->pixel_clk[0]); + clk_debug_register(&ipu->pixel_clk[1]); + + clk_set_parent(&ipu->pixel_clk[0], ipu->ipu_clk); + clk_set_parent(&ipu->pixel_clk[1], ipu->ipu_clk); + + ipu->di_clk[0] = clk_get(ipu->dev, di0_clk); + ipu->di_clk[1] = clk_get(ipu->dev, di1_clk); + + ipu->csi_clk[0] = clk_get(ipu->dev, plat_data->csi_clk[0]); + ipu->csi_clk[1] = clk_get(ipu->dev, plat_data->csi_clk[1]); + + return 0; +} + +#if 0 +static void ipu_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct ipu_soc *ipu = irq_desc_get_handler_data(desc); + const int int_reg[] = { 1, 2, 3, 4, 11, 12, 13, 14, 15, 0 }; + u32 status; + int i, line; + + for (i = 0;; i++) { + if (int_reg[i] == 0) + break; + + status = ipu_cm_read(ipu, IPU_INT_STAT(int_reg[i])); + status &= ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i])); + + while ((line = ffs(status))) { + line--; + status &= ~(1UL << line); + line += ipu->irq_start + (int_reg[i] - 1) * 32; + generic_handle_irq(line); + } -#define _REGISTER_CLOCK(d, n, c) \ - { \ - .dev_id = d, \ - .con_id = n, \ - .clk = &c, \ } +} -static struct clk_lookup ipu_lookups[] = { - _REGISTER_CLOCK(NULL, "pixel_clk_0", pixel_clk[0]), - _REGISTER_CLOCK(NULL, "pixel_clk_1", pixel_clk[1]), +static void ipu_err_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + struct ipu_soc *ipu = irq_desc_get_handler_data(desc); + const int int_reg[] = { 5, 6, 9, 10, 0 }; + u32 status; + int i, line; + for (i = 0;; i++) { + if (int_reg[i] == 0) + break; + + status = ipu_cm_read(ipu, IPU_INT_STAT(int_reg[i])); + status &= ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i])); + + while ((line = ffs(status))) { + line--; + status &= ~(1UL << line); + line += ipu->irq_start + (int_reg[i] - 1) * 32; + generic_handle_irq(line); + } + + } +} + +static void ipu_ack_irq(struct irq_data *d) +{ + struct ipu_soc *ipu = irq_data_get_irq_chip_data(d); + unsigned int irq = d->irq - ipu->irq_start; + unsigned long flags; + + spin_lock_irqsave(&ipu->ipu_lock, flags); + ipu_cm_write(ipu, 1 << (irq % 32), IPU_INT_STAT(irq / 32 + 1)); + spin_unlock_irqrestore(&ipu->ipu_lock, flags); +} + +static void ipu_unmask_irq(struct irq_data *d) +{ + struct ipu_soc *ipu = irq_data_get_irq_chip_data(d); + unsigned int irq = d->irq - ipu->irq_start; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&ipu->ipu_lock, flags); + reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32 + 1)); + reg |= 1 << (irq % 32); + ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32 + 1)); + spin_unlock_irqrestore(&ipu->ipu_lock, flags); +} + +static void ipu_mask_irq(struct irq_data *d) +{ + struct ipu_soc *ipu = irq_data_get_irq_chip_data(d); + unsigned int irq = d->irq - ipu->irq_start; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&ipu->ipu_lock, flags); + reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32 + 1)); + reg &= ~(1 << (irq % 32)); + ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32 + 1)); + spin_unlock_irqrestore(&ipu->ipu_lock, flags); +} + +static struct irq_chip ipu_irq_chip = { + .name = "IPU", + .irq_ack = ipu_ack_irq, + .irq_mask = ipu_mask_irq, + .irq_unmask = ipu_unmask_irq, }; -int __initdata primary_di = { 0 }; -static int __init di1_setup(char *__unused) +static void __devinit ipu_irq_setup(struct ipu_soc *ipu) { - primary_di = MXC_PRI_DI1; - return 1; + int i; + + for (i = ipu->irq_start; i < ipu->irq_start + MX5_IPU_IRQS; i++) { + irq_set_chip_and_handler(i, &ipu_irq_chip, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + irq_set_chip_data(i, ipu); + } + + irq_set_chained_handler(ipu->irq_sync, ipu_irq_handler); + irq_set_handler_data(ipu->irq_sync, ipu); + irq_set_chained_handler(ipu->irq_err, ipu_err_irq_handler); + irq_set_handler_data(ipu->irq_err, ipu); } -__setup("di1_primary", di1_setup); -static int __init di0_setup(char *__unused) +int ipu_request_irq(struct ipu_soc *ipu, unsigned int irq, + irq_handler_t handler, unsigned long flags, + const char *name, void *dev) { - primary_di = MXC_PRI_DI0; - return 1; + return request_irq(ipu->irq_start + irq, handler, flags, name, dev); } -__setup("di0_primary", di0_setup); +EXPORT_SYMBOL_GPL(ipu_request_irq); -struct platform_device *__init imx_add_ipuv3_fb( - const struct ipuv3_fb_platform_data *pdata, int id) +void ipu_enable_irq(struct ipu_soc *ipu, unsigned int irq) { - if (pdata) { - if (pdata->res_size > 0) { - struct resource res[] = { - { - .start = pdata->res_base, - .end = pdata->res_base + pdata->res_size - 1, - .flags = IORESOURCE_MEM, - }, - }; + return enable_irq(ipu->irq_start + irq); +} +EXPORT_SYMBOL_GPL(ipu_disable_irq); - return imx_add_platform_device_dmamask("mxc_sdc_fb", - id, res, ARRAY_SIZE(res), pdata, - sizeof(*pdata), DMA_BIT_MASK(32)); - } else - return imx_add_platform_device_dmamask("mxc_sdc_fb", id, - NULL, 0, pdata, sizeof(*pdata), - DMA_BIT_MASK(32)); - } else - return imx_add_platform_device_dmamask("mxc_sdc_fb", id, - NULL, 0, NULL, 0, DMA_BIT_MASK(32)); +void ipu_disable_irq(struct ipu_soc *ipu, unsigned int irq) +{ + return disable_irq(ipu->irq_start + irq); } +EXPORT_SYMBOL_GPL(ipu_disable_irq); -static int __init register_fb_device(struct platform_device *pdev) +void ipu_free_irq(struct ipu_soc *ipu, unsigned int irq, void *dev_id) { - struct imx_ipuv3_platform_data *plat_data = pdev->dev.platform_data; + free_irq(ipu->irq_start + irq, dev_id); +} +EXPORT_SYMBOL_GPL(ipu_free_irq); - if (!primary_di) - primary_di = plat_data->primary_di; - - if (primary_di == MXC_PRI_DI1) { - dev_info(g_ipu_dev, "DI1 is primary\n"); - /* DI1 -> DP-BG channel: */ - imx_add_ipuv3_fb(plat_data->fb_head1_platform_data, 1); - /* DI0 -> DC channel: */ - plat_data->fb_head0_platform_data->res_base = 0; - plat_data->fb_head0_platform_data->res_size = 0; - imx_add_ipuv3_fb(plat_data->fb_head0_platform_data, 0); - } else { - dev_info(g_ipu_dev, "DI0 is primary\n"); - /* DI0 -> DP-BG channel: */ - imx_add_ipuv3_fb(plat_data->fb_head0_platform_data, 0); - /* DI1 -> DC channel: */ - plat_data->fb_head1_platform_data->res_base = 0; - plat_data->fb_head1_platform_data->res_size = 0; - imx_add_ipuv3_fb(plat_data->fb_head1_platform_data, 1); +static irqreturn_t ipu_completion_handler(int irq, void *dev) +{ + struct completion *completion = dev; + + complete(completion); + return IRQ_HANDLED; +} + +int ipu_wait_for_interrupt(struct ipu_soc *ipu, int interrupt, int timeout_ms) +{ + DECLARE_COMPLETION_ONSTACK(completion); + int ret; + + ret = ipu_request_irq(ipu, interrupt, ipu_completion_handler, + 0, NULL, &completion); + if (ret) { + dev_err(ipu->dev, + "ipu request irq %d fail\n", interrupt); + return ret; } - /* - * DI0/1 DP-FG channel: - */ - imx_add_ipuv3_fb(NULL, 2); + ret = wait_for_completion_timeout(&completion, + msecs_to_jiffies(timeout_ms)); - return 0; + ipu_free_irq(ipu, interrupt, &completion); + + return ret > 0 ? 0 : -ETIMEDOUT; +} +EXPORT_SYMBOL_GPL(ipu_wait_for_interrupt); +#endif + +struct ipu_soc *ipu_get_soc(int id) +{ + if (id >= MXC_IPU_MAX_NUM) + return ERR_PTR(-ENODEV); + else + return &(ipu_array[id]); } /*! @@ -358,216 +495,241 @@ static int __init register_fb_device(struct platform_device *pdev) * * @return Returns 0 on success or negative error code on error */ -static int ipu_probe(struct platform_device *pdev) +static int __devinit ipu_probe(struct platform_device *pdev) { - struct resource *res; struct imx_ipuv3_platform_data *plat_data = pdev->dev.platform_data; + struct ipu_soc *ipu; + struct resource *res; unsigned long ipu_base; + int ret = 0; - spin_lock_init(&ipu_lock); + if (pdev->id >= MXC_IPU_MAX_NUM) + return -ENODEV; + + ipu = &ipu_array[pdev->id]; + memset(ipu, 0, sizeof(struct ipu_soc)); + + spin_lock_init(&ipu->ipu_lock); g_ipu_hw_rev = plat_data->rev; - g_ipu_dev = &pdev->dev; + ipu->dev = &pdev->dev; - /* Register IPU interrupts */ - g_ipu_irq[0] = platform_get_irq(pdev, 0); - if (g_ipu_irq[0] < 0) - return -EINVAL; + if (plat_data->init) + plat_data->init(pdev->id); + + ipu->irq_sync = platform_get_irq(pdev, 0); + ipu->irq_err = platform_get_irq(pdev, 1); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (!res || ipu->irq_sync < 0 || ipu->irq_err < 0) { + ret = -ENODEV; + goto failed_get_res; + } - if (request_irq(g_ipu_irq[0], ipu_irq_handler, 0, pdev->name, 0) != 0) { - dev_err(g_ipu_dev, "request SYNC interrupt failed\n"); - return -EBUSY; + if (request_irq(ipu->irq_sync, ipu_irq_handler, 0, pdev->name, ipu) != 0) { + dev_err(ipu->dev, "request SYNC interrupt failed\n"); + ret = -EBUSY; + goto failed_req_irq_sync; } /* Some platforms have 2 IPU interrupts */ - g_ipu_irq[1] = platform_get_irq(pdev, 1); - if (g_ipu_irq[1] >= 0) { + if (ipu->irq_err >= 0) { if (request_irq - (g_ipu_irq[1], ipu_irq_handler, 0, pdev->name, 0) != 0) { - dev_err(g_ipu_dev, "request ERR interrupt failed\n"); - return -EBUSY; + (ipu->irq_err, ipu_irq_handler, 0, pdev->name, ipu) != 0) { + dev_err(ipu->dev, "request ERR interrupt failed\n"); + ret = -EBUSY; + goto failed_req_irq_err; } } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (IS_ERR(res)) - return -ENODEV; - ipu_base = res->start; - if (g_ipu_hw_rev == 3) /* IPUv3M */ + /* base fixup */ + if (g_ipu_hw_rev == 4) /* IPUv3H */ + ipu_base += IPUV3H_REG_BASE; + else if (g_ipu_hw_rev == 3) /* IPUv3M */ ipu_base += IPUV3M_REG_BASE; else /* IPUv3D, v3E, v3EX */ - ipu_base += IPU_REG_BASE; + ipu_base += IPUV3DEX_REG_BASE; - ipu_cm_reg = ioremap(ipu_base + IPU_CM_REG_BASE, PAGE_SIZE); - ipu_ic_reg = ioremap(ipu_base + IPU_IC_REG_BASE, PAGE_SIZE); - ipu_idmac_reg = ioremap(ipu_base + IPU_IDMAC_REG_BASE, PAGE_SIZE); + ipu->cm_reg = ioremap(ipu_base + IPU_CM_REG_BASE, PAGE_SIZE); + ipu->ic_reg = ioremap(ipu_base + IPU_IC_REG_BASE, PAGE_SIZE); + ipu->idmac_reg = ioremap(ipu_base + IPU_IDMAC_REG_BASE, PAGE_SIZE); /* DP Registers are accessed thru the SRM */ - ipu_dp_reg = ioremap(ipu_base + IPU_SRM_REG_BASE, PAGE_SIZE); - ipu_dc_reg = ioremap(ipu_base + IPU_DC_REG_BASE, PAGE_SIZE); - ipu_dmfc_reg = ioremap(ipu_base + IPU_DMFC_REG_BASE, PAGE_SIZE); - ipu_di_reg[0] = ioremap(ipu_base + IPU_DI0_REG_BASE, PAGE_SIZE); - ipu_di_reg[1] = ioremap(ipu_base + IPU_DI1_REG_BASE, PAGE_SIZE); - ipu_smfc_reg = ioremap(ipu_base + IPU_SMFC_REG_BASE, PAGE_SIZE); - ipu_csi_reg[0] = ioremap(ipu_base + IPU_CSI0_REG_BASE, PAGE_SIZE); - ipu_csi_reg[1] = ioremap(ipu_base + IPU_CSI1_REG_BASE, PAGE_SIZE); - ipu_cpmem_base = ioremap(ipu_base + IPU_CPMEM_REG_BASE, SZ_128K); - ipu_tpmem_base = ioremap(ipu_base + IPU_TPM_REG_BASE, SZ_64K); - ipu_dc_tmpl_reg = ioremap(ipu_base + IPU_DC_TMPL_REG_BASE, SZ_128K); - ipu_disp_base[1] = ioremap(ipu_base + IPU_DISP1_BASE, SZ_4K); - ipu_vdi_reg = ioremap(ipu_base + IPU_VDI_REG_BASE, PAGE_SIZE); - - dev_dbg(g_ipu_dev, "IPU VDI Regs = %p\n", ipu_vdi_reg); - dev_dbg(g_ipu_dev, "IPU CM Regs = %p\n", ipu_cm_reg); - dev_dbg(g_ipu_dev, "IPU IC Regs = %p\n", ipu_ic_reg); - dev_dbg(g_ipu_dev, "IPU IDMAC Regs = %p\n", ipu_idmac_reg); - dev_dbg(g_ipu_dev, "IPU DP Regs = %p\n", ipu_dp_reg); - dev_dbg(g_ipu_dev, "IPU DC Regs = %p\n", ipu_dc_reg); - dev_dbg(g_ipu_dev, "IPU DMFC Regs = %p\n", ipu_dmfc_reg); - dev_dbg(g_ipu_dev, "IPU DI0 Regs = %p\n", ipu_di_reg[0]); - dev_dbg(g_ipu_dev, "IPU DI1 Regs = %p\n", ipu_di_reg[1]); - dev_dbg(g_ipu_dev, "IPU SMFC Regs = %p\n", ipu_smfc_reg); - dev_dbg(g_ipu_dev, "IPU CSI0 Regs = %p\n", ipu_csi_reg[0]); - dev_dbg(g_ipu_dev, "IPU CSI1 Regs = %p\n", ipu_csi_reg[1]); - dev_dbg(g_ipu_dev, "IPU CPMem = %p\n", ipu_cpmem_base); - dev_dbg(g_ipu_dev, "IPU TPMem = %p\n", ipu_tpmem_base); - dev_dbg(g_ipu_dev, "IPU DC Template Mem = %p\n", ipu_dc_tmpl_reg); - dev_dbg(g_ipu_dev, "IPU Display Region 1 Mem = %p\n", ipu_disp_base[1]); - - clkdev_add(&ipu_lookups[0]); - clkdev_add(&ipu_lookups[1]); - clk_debug_register(&pixel_clk[0]); - clk_debug_register(&pixel_clk[1]); - - g_pixel_clk[0] = &pixel_clk[0]; - g_pixel_clk[1] = &pixel_clk[1]; - - /* Enable IPU and CSI clocks */ - /* Get IPU clock freq */ - g_ipu_clk = clk_get(&pdev->dev, "ipu_clk"); - dev_dbg(g_ipu_dev, "ipu_clk = %lu\n", clk_get_rate(g_ipu_clk)); - - if (plat_data->init) - plat_data->init(); - - clk_set_parent(g_pixel_clk[0], g_ipu_clk); - clk_set_parent(g_pixel_clk[1], g_ipu_clk); - clk_enable(g_ipu_clk); - - g_di_clk[0] = clk_get(&pdev->dev, "ipu_di0_clk"); - g_di_clk[1] = clk_get(&pdev->dev, "ipu_di1_clk"); - - 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) - ; - - _ipu_init_dc_mappings(); - - /* Enable error interrupts by default */ - __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(5)); - __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(6)); - __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(9)); - __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(10)); - - /* DMFC Init */ - _ipu_dmfc_init(DMFC_NORMAL, 1); + ipu->dp_reg = ioremap(ipu_base + IPU_SRM_REG_BASE, PAGE_SIZE); + ipu->dc_reg = ioremap(ipu_base + IPU_DC_REG_BASE, PAGE_SIZE); + ipu->dmfc_reg = ioremap(ipu_base + IPU_DMFC_REG_BASE, PAGE_SIZE); + ipu->di_reg[0] = ioremap(ipu_base + IPU_DI0_REG_BASE, PAGE_SIZE); + ipu->di_reg[1] = ioremap(ipu_base + IPU_DI1_REG_BASE, PAGE_SIZE); + ipu->smfc_reg = ioremap(ipu_base + IPU_SMFC_REG_BASE, PAGE_SIZE); + ipu->csi_reg[0] = ioremap(ipu_base + IPU_CSI0_REG_BASE, PAGE_SIZE); + ipu->csi_reg[1] = ioremap(ipu_base + IPU_CSI1_REG_BASE, PAGE_SIZE); + ipu->cpmem_base = ioremap(ipu_base + IPU_CPMEM_REG_BASE, SZ_128K); + ipu->tpmem_base = ioremap(ipu_base + IPU_TPM_REG_BASE, SZ_64K); + ipu->dc_tmpl_reg = ioremap(ipu_base + IPU_DC_TMPL_REG_BASE, SZ_128K); + ipu->vdi_reg = ioremap(ipu_base + IPU_VDI_REG_BASE, PAGE_SIZE); + ipu->disp_base[1] = ioremap(ipu_base + IPU_DISP1_BASE, SZ_4K); + + if (!ipu->cm_reg || !ipu->ic_reg || !ipu->idmac_reg || + !ipu->dp_reg || !ipu->dc_reg || !ipu->dmfc_reg || + !ipu->di_reg[0] || !ipu->di_reg[1] || !ipu->smfc_reg || + !ipu->csi_reg[0] || !ipu->csi_reg[1] || !ipu->cpmem_base || + !ipu->tpmem_base || !ipu->dc_tmpl_reg || !ipu->disp_base[1] + || !ipu->vdi_reg) { + ret = -ENOMEM; + goto failed_ioremap; + } + + dev_dbg(ipu->dev, "IPU CM Regs = %p\n", ipu->cm_reg); + dev_dbg(ipu->dev, "IPU IC Regs = %p\n", ipu->ic_reg); + dev_dbg(ipu->dev, "IPU IDMAC Regs = %p\n", ipu->idmac_reg); + dev_dbg(ipu->dev, "IPU DP Regs = %p\n", ipu->dp_reg); + dev_dbg(ipu->dev, "IPU DC Regs = %p\n", ipu->dc_reg); + dev_dbg(ipu->dev, "IPU DMFC Regs = %p\n", ipu->dmfc_reg); + dev_dbg(ipu->dev, "IPU DI0 Regs = %p\n", ipu->di_reg[0]); + dev_dbg(ipu->dev, "IPU DI1 Regs = %p\n", ipu->di_reg[1]); + dev_dbg(ipu->dev, "IPU SMFC Regs = %p\n", ipu->smfc_reg); + dev_dbg(ipu->dev, "IPU CSI0 Regs = %p\n", ipu->csi_reg[0]); + dev_dbg(ipu->dev, "IPU CSI1 Regs = %p\n", ipu->csi_reg[1]); + dev_dbg(ipu->dev, "IPU CPMem = %p\n", ipu->cpmem_base); + dev_dbg(ipu->dev, "IPU TPMem = %p\n", ipu->tpmem_base); + dev_dbg(ipu->dev, "IPU DC Template Mem = %p\n", ipu->dc_tmpl_reg); + dev_dbg(ipu->dev, "IPU Display Region 1 Mem = %p\n", ipu->disp_base[1]); + dev_dbg(ipu->dev, "IPU VDI Regs = %p\n", ipu->vdi_reg); + + ret = ipu_clk_setup(ipu, pdev); + if (ret < 0) { + dev_err(ipu->dev, "ipu clk setup failed\n"); + goto failed_clk_setup; + } + + clk_enable(ipu->ipu_clk); + + platform_set_drvdata(pdev, ipu); + + ipu_reset(ipu); + + ipu_disp_init(ipu); /* Set sync refresh channels and CSI->mem channel as high priority */ - __raw_writel(0x18800001L, IDMAC_CHA_PRI(0)); + ipu_idmac_write(ipu, 0x18800001L, 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); + ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN); - clk_disable(g_ipu_clk); + clk_disable(ipu->ipu_clk); - register_fb_device(pdev); + /*register_ipu_device();*/ - register_ipu_device(); + return ret; - return 0; +failed_clk_setup: + iounmap(ipu->cm_reg); + iounmap(ipu->ic_reg); + iounmap(ipu->idmac_reg); + iounmap(ipu->dc_reg); + iounmap(ipu->dp_reg); + iounmap(ipu->dmfc_reg); + iounmap(ipu->di_reg[0]); + iounmap(ipu->di_reg[1]); + iounmap(ipu->smfc_reg); + iounmap(ipu->csi_reg[0]); + iounmap(ipu->csi_reg[1]); + iounmap(ipu->cpmem_base); + iounmap(ipu->tpmem_base); + iounmap(ipu->dc_tmpl_reg); + iounmap(ipu->disp_base[1]); + iounmap(ipu->vdi_reg); +failed_ioremap: + if (ipu->irq_sync) + free_irq(ipu->irq_err, ipu); +failed_req_irq_err: + free_irq(ipu->irq_sync, ipu); +failed_req_irq_sync: +failed_get_res: + return ret; } -int ipu_remove(struct platform_device *pdev) -{ - if (g_ipu_irq[0]) - free_irq(g_ipu_irq[0], 0); - if (g_ipu_irq[1]) - free_irq(g_ipu_irq[1], 0); - - clk_put(g_ipu_clk); - - iounmap(ipu_cm_reg); - iounmap(ipu_ic_reg); - iounmap(ipu_idmac_reg); - iounmap(ipu_dc_reg); - iounmap(ipu_dp_reg); - iounmap(ipu_dmfc_reg); - iounmap(ipu_di_reg[0]); - iounmap(ipu_di_reg[1]); - iounmap(ipu_smfc_reg); - iounmap(ipu_csi_reg[0]); - iounmap(ipu_csi_reg[1]); - iounmap(ipu_cpmem_base); - iounmap(ipu_tpmem_base); - iounmap(ipu_dc_tmpl_reg); - iounmap(ipu_disp_base[1]); - iounmap(ipu_vdi_reg); +int __devexit ipu_remove(struct platform_device *pdev) +{ + struct ipu_soc *ipu = platform_get_drvdata(pdev); + + if (ipu->irq_sync) + free_irq(ipu->irq_sync, ipu); + if (ipu->irq_err) + free_irq(ipu->irq_err, ipu); + + clk_put(ipu->ipu_clk); + + iounmap(ipu->cm_reg); + iounmap(ipu->ic_reg); + iounmap(ipu->idmac_reg); + iounmap(ipu->dc_reg); + iounmap(ipu->dp_reg); + iounmap(ipu->dmfc_reg); + iounmap(ipu->di_reg[0]); + iounmap(ipu->di_reg[1]); + iounmap(ipu->smfc_reg); + iounmap(ipu->csi_reg[0]); + iounmap(ipu->csi_reg[1]); + iounmap(ipu->cpmem_base); + iounmap(ipu->tpmem_base); + iounmap(ipu->dc_tmpl_reg); + iounmap(ipu->disp_base[1]); + iounmap(ipu->vdi_reg); return 0; } -void ipu_dump_registers(void) -{ - printk(KERN_DEBUG "IPU_CONF = \t0x%08X\n", __raw_readl(IPU_CONF)); - 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))); - printk(KERN_DEBUG "IDMAC_CHA_EN2 = \t0x%08X\n", - __raw_readl(IDMAC_CHA_EN(32))); - printk(KERN_DEBUG "IDMAC_CHA_PRI1 = \t0x%08X\n", - __raw_readl(IDMAC_CHA_PRI(0))); - printk(KERN_DEBUG "IDMAC_CHA_PRI2 = \t0x%08X\n", - __raw_readl(IDMAC_CHA_PRI(32))); - printk(KERN_DEBUG "IDMAC_BAND_EN1 = \t0x%08X\n", - __raw_readl(IDMAC_BAND_EN(0))); - printk(KERN_DEBUG "IDMAC_BAND_EN2 = \t0x%08X\n", - __raw_readl(IDMAC_BAND_EN(32))); - printk(KERN_DEBUG "IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n", - __raw_readl(IPU_CHA_DB_MODE_SEL(0))); - printk(KERN_DEBUG "IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n", - __raw_readl(IPU_CHA_DB_MODE_SEL(32))); +void ipu_dump_registers(struct ipu_soc *ipu) +{ + dev_dbg(ipu->dev, "IPU_CONF = \t0x%08X\n", ipu_cm_read(ipu, IPU_CONF)); + dev_dbg(ipu->dev, "IDMAC_CONF = \t0x%08X\n", ipu_idmac_read(ipu, IDMAC_CONF)); + dev_dbg(ipu->dev, "IDMAC_CHA_EN1 = \t0x%08X\n", + ipu_idmac_read(ipu, IDMAC_CHA_EN(0))); + dev_dbg(ipu->dev, "IDMAC_CHA_EN2 = \t0x%08X\n", + ipu_idmac_read(ipu, IDMAC_CHA_EN(32))); + dev_dbg(ipu->dev, "IDMAC_CHA_PRI1 = \t0x%08X\n", + ipu_idmac_read(ipu, IDMAC_CHA_PRI(0))); + dev_dbg(ipu->dev, "IDMAC_CHA_PRI2 = \t0x%08X\n", + ipu_idmac_read(ipu, IDMAC_CHA_PRI(32))); + dev_dbg(ipu->dev, "IDMAC_BAND_EN1 = \t0x%08X\n", + ipu_idmac_read(ipu, IDMAC_BAND_EN(0))); + dev_dbg(ipu->dev, "IDMAC_BAND_EN2 = \t0x%08X\n", + ipu_idmac_read(ipu, IDMAC_BAND_EN(32))); + dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n", + ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(0))); + dev_dbg(ipu->dev, "IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n", + ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(32))); if (g_ipu_hw_rev >= 2) { - printk(KERN_DEBUG "IPU_CHA_TRB_MODE_SEL0 = \t0x%08X\n", - __raw_readl(IPU_CHA_TRB_MODE_SEL(0))); - printk(KERN_DEBUG "IPU_CHA_TRB_MODE_SEL1 = \t0x%08X\n", - __raw_readl(IPU_CHA_TRB_MODE_SEL(32))); - } - printk(KERN_DEBUG "DMFC_WR_CHAN = \t0x%08X\n", - __raw_readl(DMFC_WR_CHAN)); - printk(KERN_DEBUG "DMFC_WR_CHAN_DEF = \t0x%08X\n", - __raw_readl(DMFC_WR_CHAN_DEF)); - printk(KERN_DEBUG "DMFC_DP_CHAN = \t0x%08X\n", - __raw_readl(DMFC_DP_CHAN)); - printk(KERN_DEBUG "DMFC_DP_CHAN_DEF = \t0x%08X\n", - __raw_readl(DMFC_DP_CHAN_DEF)); - printk(KERN_DEBUG "DMFC_IC_CTRL = \t0x%08X\n", - __raw_readl(DMFC_IC_CTRL)); - printk(KERN_DEBUG "IPU_FS_PROC_FLOW1 = \t0x%08X\n", - __raw_readl(IPU_FS_PROC_FLOW1)); - printk(KERN_DEBUG "IPU_FS_PROC_FLOW2 = \t0x%08X\n", - __raw_readl(IPU_FS_PROC_FLOW2)); - printk(KERN_DEBUG "IPU_FS_PROC_FLOW3 = \t0x%08X\n", - __raw_readl(IPU_FS_PROC_FLOW3)); - printk(KERN_DEBUG "IPU_FS_DISP_FLOW1 = \t0x%08X\n", - __raw_readl(IPU_FS_DISP_FLOW1)); + dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL0 = \t0x%08X\n", + ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(0))); + dev_dbg(ipu->dev, "IPU_CHA_TRB_MODE_SEL1 = \t0x%08X\n", + ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(32))); + } + dev_dbg(ipu->dev, "DMFC_WR_CHAN = \t0x%08X\n", + ipu_dmfc_read(ipu, DMFC_WR_CHAN)); + dev_dbg(ipu->dev, "DMFC_WR_CHAN_DEF = \t0x%08X\n", + ipu_dmfc_read(ipu, DMFC_WR_CHAN_DEF)); + dev_dbg(ipu->dev, "DMFC_DP_CHAN = \t0x%08X\n", + ipu_dmfc_read(ipu, DMFC_DP_CHAN)); + dev_dbg(ipu->dev, "DMFC_DP_CHAN_DEF = \t0x%08X\n", + ipu_dmfc_read(ipu, DMFC_DP_CHAN_DEF)); + dev_dbg(ipu->dev, "DMFC_IC_CTRL = \t0x%08X\n", + ipu_dmfc_read(ipu, DMFC_IC_CTRL)); + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW1 = \t0x%08X\n", + ipu_cm_read(ipu, IPU_FS_PROC_FLOW1)); + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW2 = \t0x%08X\n", + ipu_cm_read(ipu, IPU_FS_PROC_FLOW2)); + dev_dbg(ipu->dev, "IPU_FS_PROC_FLOW3 = \t0x%08X\n", + ipu_cm_read(ipu, IPU_FS_PROC_FLOW3)); + dev_dbg(ipu->dev, "IPU_FS_DISP_FLOW1 = \t0x%08X\n", + ipu_cm_read(ipu, IPU_FS_DISP_FLOW1)); } /*! * This function is called to initialize a logical IPU channel. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID to init. * * @param params Input parameter containing union of channel @@ -575,34 +737,28 @@ void ipu_dump_registers(void) * * @return Returns 0 on success or negative error code on fail */ -int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) +int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params) { int ret = 0; uint32_t ipu_conf; uint32_t reg; unsigned long lock_flags; - dev_dbg(g_ipu_dev, "init channel = %d\n", IPU_CHAN_ID(channel)); + dev_dbg(ipu->dev, "init channel = %d\n", IPU_CHAN_ID(channel)); - /* re-enable error interrupts every time a channel is initialized */ - __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(5)); - __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(6)); - __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(9)); - __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(10)); - - if (g_ipu_clk_enabled == false) { - g_ipu_clk_enabled = true; - clk_enable(g_ipu_clk); + if (ipu->clk_enabled == false) { + ipu->clk_enabled = true; + clk_enable(ipu->ipu_clk); } - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - if (g_channel_init_mask & (1L << IPU_CHAN_ID(channel))) { - dev_err(g_ipu_dev, "Warning: channel already initialized %d\n", + if (ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) { + dev_err(ipu->dev, "Warning: channel already initialized %d\n", IPU_CHAN_ID(channel)); } - ipu_conf = __raw_readl(IPU_CONF); + ipu_conf = ipu_cm_read(ipu, IPU_CONF); switch (channel) { case CSI_MEM0: @@ -615,43 +771,43 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) } if (params->csi_mem.interlaced) - g_chan_is_interlaced[channel_2_dma(channel, + ipu->chan_is_interlaced[channel_2_dma(channel, IPU_OUTPUT_BUFFER)] = true; else - g_chan_is_interlaced[channel_2_dma(channel, + ipu->chan_is_interlaced[channel_2_dma(channel, IPU_OUTPUT_BUFFER)] = false; - ipu_smfc_use_count++; - g_ipu_csi_channel[params->csi_mem.csi] = channel; + ipu->smfc_use_count++; + ipu->csi_channel[params->csi_mem.csi] = channel; /*SMFC setting*/ if (params->csi_mem.mipi_en) { ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET + params->csi_mem.csi)); - _ipu_smfc_init(channel, params->csi_mem.mipi_id, + _ipu_smfc_init(ipu, channel, params->csi_mem.mipi_id, params->csi_mem.csi); } else { ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET + params->csi_mem.csi)); - _ipu_smfc_init(channel, 0, params->csi_mem.csi); + _ipu_smfc_init(ipu, channel, 0, params->csi_mem.csi); } /*CSI data (include compander) dest*/ - _ipu_csi_init(channel, params->csi_mem.csi); + _ipu_csi_init(ipu, channel, params->csi_mem.csi); break; case CSI_PRP_ENC_MEM: if (params->csi_prp_enc_mem.csi > 1) { ret = -EINVAL; goto err; } - if (using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) { + if (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) { ret = -EINVAL; goto err; } - using_ic_dirct_ch = CSI_PRP_ENC_MEM; + ipu->using_ic_dirct_ch = CSI_PRP_ENC_MEM; - ipu_ic_use_count++; - g_ipu_csi_channel[params->csi_prp_enc_mem.csi] = channel; + ipu->ic_use_count++; + ipu->csi_channel[params->csi_prp_enc_mem.csi] = channel; /*Without SMFC, CSI only support parallel data source*/ ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET + @@ -665,26 +821,26 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) ipu_conf &= ~IPU_CONF_CSI_SEL; /*PRP skip buffer in memory, only valid when RWS_EN is true*/ - reg = __raw_readl(IPU_FS_PROC_FLOW1); - __raw_writel(reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1); + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1); /*CSI data (include compander) dest*/ - _ipu_csi_init(channel, params->csi_prp_enc_mem.csi); - _ipu_ic_init_prpenc(params, true); + _ipu_csi_init(ipu, channel, params->csi_prp_enc_mem.csi); + _ipu_ic_init_prpenc(ipu, params, true); break; case CSI_PRP_VF_MEM: if (params->csi_prp_vf_mem.csi > 1) { ret = -EINVAL; goto err; } - if (using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) { + if (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) { ret = -EINVAL; goto err; } - using_ic_dirct_ch = CSI_PRP_VF_MEM; + ipu->using_ic_dirct_ch = CSI_PRP_VF_MEM; - ipu_ic_use_count++; - g_ipu_csi_channel[params->csi_prp_vf_mem.csi] = channel; + ipu->ic_use_count++; + ipu->csi_channel[params->csi_prp_vf_mem.csi] = channel; /*Without SMFC, CSI only support parallel data source*/ ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET + @@ -698,77 +854,77 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) ipu_conf &= ~IPU_CONF_CSI_SEL; /*PRP skip buffer in memory, only valid when RWS_EN is true*/ - reg = __raw_readl(IPU_FS_PROC_FLOW1); - __raw_writel(reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); /*CSI data (include compander) dest*/ - _ipu_csi_init(channel, params->csi_prp_vf_mem.csi); - _ipu_ic_init_prpvf(params, true); + _ipu_csi_init(ipu, channel, params->csi_prp_vf_mem.csi); + _ipu_ic_init_prpvf(ipu, params, true); break; case MEM_PRP_VF_MEM: - ipu_ic_use_count++; - reg = __raw_readl(IPU_FS_PROC_FLOW1); - __raw_writel(reg | FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); + ipu->ic_use_count++; + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, reg | FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); if (params->mem_prp_vf_mem.graphics_combine_en) - g_sec_chan_en[IPU_CHAN_ID(channel)] = true; + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true; if (params->mem_prp_vf_mem.alpha_chan_en) - g_thrd_chan_en[IPU_CHAN_ID(channel)] = true; + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true; - _ipu_ic_init_prpvf(params, false); + _ipu_ic_init_prpvf(ipu, params, false); break; case MEM_VDI_PRP_VF_MEM: - if ((using_ic_dirct_ch == CSI_PRP_VF_MEM) || - (using_ic_dirct_ch == CSI_PRP_ENC_MEM)) { + if ((ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) || + (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM)) { ret = -EINVAL; goto err; } - using_ic_dirct_ch = MEM_VDI_PRP_VF_MEM; - ipu_ic_use_count++; - ipu_vdi_use_count++; - reg = __raw_readl(IPU_FS_PROC_FLOW1); + ipu->using_ic_dirct_ch = MEM_VDI_PRP_VF_MEM; + ipu->ic_use_count++; + ipu->vdi_use_count++; + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); reg &= ~FS_VDI_SRC_SEL_MASK; - __raw_writel(reg , IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, reg , IPU_FS_PROC_FLOW1); if (params->mem_prp_vf_mem.graphics_combine_en) - g_sec_chan_en[IPU_CHAN_ID(channel)] = true; - _ipu_ic_init_prpvf(params, false); - _ipu_vdi_init(channel, params); + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true; + _ipu_ic_init_prpvf(ipu, params, false); + _ipu_vdi_init(ipu, channel, params); break; case MEM_VDI_PRP_VF_MEM_P: - _ipu_vdi_init(channel, params); + _ipu_vdi_init(ipu, channel, params); break; case MEM_VDI_PRP_VF_MEM_N: - _ipu_vdi_init(channel, params); + _ipu_vdi_init(ipu, channel, params); break; case MEM_ROT_VF_MEM: - ipu_ic_use_count++; - ipu_rot_use_count++; - _ipu_ic_init_rotate_vf(params); + ipu->ic_use_count++; + ipu->rot_use_count++; + _ipu_ic_init_rotate_vf(ipu, params); break; case MEM_PRP_ENC_MEM: - ipu_ic_use_count++; - reg = __raw_readl(IPU_FS_PROC_FLOW1); - __raw_writel(reg | FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1); - _ipu_ic_init_prpenc(params, false); + ipu->ic_use_count++; + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, reg | FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1); + _ipu_ic_init_prpenc(ipu, params, false); break; case MEM_ROT_ENC_MEM: - ipu_ic_use_count++; - ipu_rot_use_count++; - _ipu_ic_init_rotate_enc(params); + ipu->ic_use_count++; + ipu->rot_use_count++; + _ipu_ic_init_rotate_enc(ipu, params); break; case MEM_PP_MEM: if (params->mem_pp_mem.graphics_combine_en) - g_sec_chan_en[IPU_CHAN_ID(channel)] = true; + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = true; if (params->mem_pp_mem.alpha_chan_en) - g_thrd_chan_en[IPU_CHAN_ID(channel)] = true; - _ipu_ic_init_pp(params); - ipu_ic_use_count++; + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true; + _ipu_ic_init_pp(ipu, params); + ipu->ic_use_count++; break; case MEM_ROT_PP_MEM: - _ipu_ic_init_rotate_pp(params); - ipu_ic_use_count++; - ipu_rot_use_count++; + _ipu_ic_init_rotate_pp(ipu, params); + ipu->ic_use_count++; + ipu->rot_use_count++; break; case MEM_DC_SYNC: if (params->mem_dc_sync.di > 1) { @@ -776,13 +932,13 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) goto err; } - g_dc_di_assignment[1] = params->mem_dc_sync.di; - _ipu_dc_init(1, params->mem_dc_sync.di, + ipu->dc_di_assignment[1] = params->mem_dc_sync.di; + _ipu_dc_init(ipu, 1, params->mem_dc_sync.di, 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++; + ipu->di_use_count[params->mem_dc_sync.di]++; + ipu->dc_use_count++; + ipu->dmfc_use_count++; break; case MEM_BG_SYNC: if (params->mem_dp_bg_sync.di > 1) { @@ -791,29 +947,29 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) } if (params->mem_dp_bg_sync.alpha_chan_en) - g_thrd_chan_en[IPU_CHAN_ID(channel)] = true; + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true; - g_dc_di_assignment[5] = params->mem_dp_bg_sync.di; - _ipu_dp_init(channel, params->mem_dp_bg_sync.in_pixel_fmt, + ipu->dc_di_assignment[5] = params->mem_dp_bg_sync.di; + _ipu_dp_init(ipu, 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, + _ipu_dc_init(ipu, 5, params->mem_dp_bg_sync.di, 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++; - ipu_dmfc_use_count++; + ipu->di_use_count[params->mem_dp_bg_sync.di]++; + ipu->dc_use_count++; + ipu->dp_use_count++; + ipu->dmfc_use_count++; break; case MEM_FG_SYNC: - _ipu_dp_init(channel, params->mem_dp_fg_sync.in_pixel_fmt, + _ipu_dp_init(ipu, channel, params->mem_dp_fg_sync.in_pixel_fmt, params->mem_dp_fg_sync.out_pixel_fmt); if (params->mem_dp_fg_sync.alpha_chan_en) - g_thrd_chan_en[IPU_CHAN_ID(channel)] = true; + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = true; - ipu_dc_use_count++; - ipu_dp_use_count++; - ipu_dmfc_use_count++; + ipu->dc_use_count++; + ipu->dp_use_count++; + ipu->dmfc_use_count++; break; case DIRECT_ASYNC0: if (params->direct_async.di > 1) { @@ -821,10 +977,10 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) goto err; } - g_dc_di_assignment[8] = params->direct_async.di; - _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++; + ipu->dc_di_assignment[8] = params->direct_async.di; + _ipu_dc_init(ipu, 8, params->direct_async.di, false, IPU_PIX_FMT_GENERIC); + ipu->di_use_count[params->direct_async.di]++; + ipu->dc_use_count++; break; case DIRECT_ASYNC1: if (params->direct_async.di > 1) { @@ -832,23 +988,23 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) goto err; } - g_dc_di_assignment[9] = params->direct_async.di; - _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++; + ipu->dc_di_assignment[9] = params->direct_async.di; + _ipu_dc_init(ipu, 9, params->direct_async.di, false, IPU_PIX_FMT_GENERIC); + ipu->di_use_count[params->direct_async.di]++; + ipu->dc_use_count++; break; default: - dev_err(g_ipu_dev, "Missing channel initialization\n"); + dev_err(ipu->dev, "Missing channel initialization\n"); break; } /* Enable IPU sub module */ - g_channel_init_mask |= 1L << IPU_CHAN_ID(channel); + ipu->channel_init_mask |= 1L << IPU_CHAN_ID(channel); - __raw_writel(ipu_conf, IPU_CONF); + ipu_cm_write(ipu, ipu_conf, IPU_CONF); err: - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return ret; } EXPORT_SYMBOL(ipu_init_channel); @@ -856,18 +1012,22 @@ EXPORT_SYMBOL(ipu_init_channel); /*! * This function is called to uninitialize a logical IPU channel. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID to uninit. */ -void ipu_uninit_channel(ipu_channel_t channel) +void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel) { unsigned long lock_flags; uint32_t reg; uint32_t in_dma, out_dma = 0; uint32_t ipu_conf; - if ((g_channel_init_mask & (1L << IPU_CHAN_ID(channel))) == 0) { - dev_err(g_ipu_dev, "Channel already uninitialized %d\n", + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); + + if ((ipu->channel_init_mask & (1L << IPU_CHAN_ID(channel))) == 0) { + dev_err(ipu->dev, "Channel already uninitialized %d\n", IPU_CHAN_ID(channel)); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return; } @@ -876,33 +1036,32 @@ void ipu_uninit_channel(ipu_channel_t channel) 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)) { - dev_err(g_ipu_dev, + if (idma_is_set(ipu, IDMAC_CHA_EN, in_dma) || + idma_is_set(ipu, IDMAC_CHA_EN, out_dma)) { + dev_err(ipu->dev, "Channel %d is not disabled, disable first\n", IPU_CHAN_ID(channel)); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return; } - spin_lock_irqsave(&ipu_lock, lock_flags); - - ipu_conf = __raw_readl(IPU_CONF); + ipu_conf = ipu_cm_read(ipu, IPU_CONF); /* Reset the double buffer */ - reg = __raw_readl(IPU_CHA_DB_MODE_SEL(in_dma)); - __raw_writel(reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma)); - reg = __raw_readl(IPU_CHA_DB_MODE_SEL(out_dma)); - __raw_writel(reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma)); + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(in_dma)); + ipu_cm_write(ipu, reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma)); + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(out_dma)); + ipu_cm_write(ipu, reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma)); /* Reset the triple buffer */ - reg = __raw_readl(IPU_CHA_TRB_MODE_SEL(in_dma)); - __raw_writel(reg & ~idma_mask(in_dma), IPU_CHA_TRB_MODE_SEL(in_dma)); - reg = __raw_readl(IPU_CHA_TRB_MODE_SEL(out_dma)); - __raw_writel(reg & ~idma_mask(out_dma), IPU_CHA_TRB_MODE_SEL(out_dma)); + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(in_dma)); + ipu_cm_write(ipu, reg & ~idma_mask(in_dma), IPU_CHA_TRB_MODE_SEL(in_dma)); + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(out_dma)); + ipu_cm_write(ipu, reg & ~idma_mask(out_dma), IPU_CHA_TRB_MODE_SEL(out_dma)); 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; + ipu->sec_chan_en[IPU_CHAN_ID(channel)] = false; + ipu->thrd_chan_en[IPU_CHAN_ID(channel)] = false; } switch (channel) { @@ -910,161 +1069,163 @@ void ipu_uninit_channel(ipu_channel_t channel) case CSI_MEM1: case CSI_MEM2: case CSI_MEM3: - ipu_smfc_use_count--; - if (g_ipu_csi_channel[0] == channel) { - g_ipu_csi_channel[0] = CHAN_NONE; - } else if (g_ipu_csi_channel[1] == channel) { - g_ipu_csi_channel[1] = CHAN_NONE; + ipu->smfc_use_count--; + if (ipu->csi_channel[0] == channel) { + ipu->csi_channel[0] = CHAN_NONE; + } else if (ipu->csi_channel[1] == channel) { + ipu->csi_channel[1] = CHAN_NONE; } break; case CSI_PRP_ENC_MEM: - ipu_ic_use_count--; - if (using_ic_dirct_ch == CSI_PRP_ENC_MEM) - using_ic_dirct_ch = 0; - _ipu_ic_uninit_prpenc(); - if (g_ipu_csi_channel[0] == channel) { - g_ipu_csi_channel[0] = CHAN_NONE; - } else if (g_ipu_csi_channel[1] == channel) { - g_ipu_csi_channel[1] = CHAN_NONE; + ipu->ic_use_count--; + if (ipu->using_ic_dirct_ch == CSI_PRP_ENC_MEM) + ipu->using_ic_dirct_ch = 0; + _ipu_ic_uninit_prpenc(ipu); + if (ipu->csi_channel[0] == channel) { + ipu->csi_channel[0] = CHAN_NONE; + } else if (ipu->csi_channel[1] == channel) { + ipu->csi_channel[1] = CHAN_NONE; } break; case CSI_PRP_VF_MEM: - ipu_ic_use_count--; - if (using_ic_dirct_ch == CSI_PRP_VF_MEM) - using_ic_dirct_ch = 0; - _ipu_ic_uninit_prpvf(); - if (g_ipu_csi_channel[0] == channel) { - g_ipu_csi_channel[0] = CHAN_NONE; - } else if (g_ipu_csi_channel[1] == channel) { - g_ipu_csi_channel[1] = CHAN_NONE; + ipu->ic_use_count--; + if (ipu->using_ic_dirct_ch == CSI_PRP_VF_MEM) + ipu->using_ic_dirct_ch = 0; + _ipu_ic_uninit_prpvf(ipu); + if (ipu->csi_channel[0] == channel) { + ipu->csi_channel[0] = CHAN_NONE; + } else if (ipu->csi_channel[1] == channel) { + ipu->csi_channel[1] = CHAN_NONE; } break; case MEM_PRP_VF_MEM: - ipu_ic_use_count--; - _ipu_ic_uninit_prpvf(); - reg = __raw_readl(IPU_FS_PROC_FLOW1); - __raw_writel(reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); + ipu->ic_use_count--; + _ipu_ic_uninit_prpvf(ipu); + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); break; case MEM_VDI_PRP_VF_MEM: - ipu_ic_use_count--; - ipu_vdi_use_count--; - if (using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) - using_ic_dirct_ch = 0; - _ipu_ic_uninit_prpvf(); - _ipu_vdi_uninit(); - reg = __raw_readl(IPU_FS_PROC_FLOW1); - __raw_writel(reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); + ipu->ic_use_count--; + ipu->vdi_use_count--; + if (ipu->using_ic_dirct_ch == MEM_VDI_PRP_VF_MEM) + ipu->using_ic_dirct_ch = 0; + _ipu_ic_uninit_prpvf(ipu); + _ipu_vdi_uninit(ipu); + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, 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--; - _ipu_ic_uninit_rotate_vf(); + ipu->rot_use_count--; + ipu->ic_use_count--; + _ipu_ic_uninit_rotate_vf(ipu); break; case MEM_PRP_ENC_MEM: - ipu_ic_use_count--; - _ipu_ic_uninit_prpenc(); - reg = __raw_readl(IPU_FS_PROC_FLOW1); - __raw_writel(reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1); + ipu->ic_use_count--; + _ipu_ic_uninit_prpenc(ipu); + reg = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1); break; case MEM_ROT_ENC_MEM: - ipu_rot_use_count--; - ipu_ic_use_count--; - _ipu_ic_uninit_rotate_enc(); + ipu->rot_use_count--; + ipu->ic_use_count--; + _ipu_ic_uninit_rotate_enc(ipu); break; case MEM_PP_MEM: - ipu_ic_use_count--; - _ipu_ic_uninit_pp(); + ipu->ic_use_count--; + _ipu_ic_uninit_pp(ipu); break; case MEM_ROT_PP_MEM: - ipu_rot_use_count--; - ipu_ic_use_count--; - _ipu_ic_uninit_rotate_pp(); + ipu->rot_use_count--; + ipu->ic_use_count--; + _ipu_ic_uninit_rotate_pp(ipu); break; case MEM_DC_SYNC: - _ipu_dc_uninit(1); - ipu_di_use_count[g_dc_di_assignment[1]]--; - ipu_dc_use_count--; - ipu_dmfc_use_count--; + _ipu_dc_uninit(ipu, 1); + ipu->di_use_count[ipu->dc_di_assignment[1]]--; + ipu->dc_use_count--; + ipu->dmfc_use_count--; break; case MEM_BG_SYNC: - _ipu_dp_uninit(channel); - _ipu_dc_uninit(5); - ipu_di_use_count[g_dc_di_assignment[5]]--; - ipu_dc_use_count--; - ipu_dp_use_count--; - ipu_dmfc_use_count--; + _ipu_dp_uninit(ipu, channel); + _ipu_dc_uninit(ipu, 5); + ipu->di_use_count[ipu->dc_di_assignment[5]]--; + ipu->dc_use_count--; + ipu->dp_use_count--; + ipu->dmfc_use_count--; break; case MEM_FG_SYNC: - _ipu_dp_uninit(channel); - ipu_dc_use_count--; - ipu_dp_use_count--; - ipu_dmfc_use_count--; + _ipu_dp_uninit(ipu, channel); + ipu->dc_use_count--; + ipu->dp_use_count--; + ipu->dmfc_use_count--; break; case DIRECT_ASYNC0: - _ipu_dc_uninit(8); - ipu_di_use_count[g_dc_di_assignment[8]]--; - ipu_dc_use_count--; + _ipu_dc_uninit(ipu, 8); + ipu->di_use_count[ipu->dc_di_assignment[8]]--; + ipu->dc_use_count--; break; case DIRECT_ASYNC1: - _ipu_dc_uninit(9); - ipu_di_use_count[g_dc_di_assignment[9]]--; - ipu_dc_use_count--; + _ipu_dc_uninit(ipu, 9); + ipu->di_use_count[ipu->dc_di_assignment[9]]--; + ipu->dc_use_count--; break; default: break; } - g_channel_init_mask &= ~(1L << IPU_CHAN_ID(channel)); + ipu->channel_init_mask &= ~(1L << IPU_CHAN_ID(channel)); - if (ipu_ic_use_count == 0) + if (ipu->ic_use_count == 0) ipu_conf &= ~IPU_CONF_IC_EN; - if (ipu_vdi_use_count == 0) { + 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) + if (ipu->rot_use_count == 0) ipu_conf &= ~IPU_CONF_ROT_EN; - if (ipu_dc_use_count == 0) + if (ipu->dc_use_count == 0) ipu_conf &= ~IPU_CONF_DC_EN; - if (ipu_dp_use_count == 0) + if (ipu->dp_use_count == 0) ipu_conf &= ~IPU_CONF_DP_EN; - if (ipu_dmfc_use_count == 0) + if (ipu->dmfc_use_count == 0) ipu_conf &= ~IPU_CONF_DMFC_EN; - if (ipu_di_use_count[0] == 0) { + if (ipu->di_use_count[0] == 0) { ipu_conf &= ~IPU_CONF_DI0_EN; } - if (ipu_di_use_count[1] == 0) { + if (ipu->di_use_count[1] == 0) { ipu_conf &= ~IPU_CONF_DI1_EN; } - if (ipu_smfc_use_count == 0) + if (ipu->smfc_use_count == 0) ipu_conf &= ~IPU_CONF_SMFC_EN; - __raw_writel(ipu_conf, IPU_CONF); + ipu_cm_write(ipu, ipu_conf, IPU_CONF); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); if (ipu_conf == 0) { - clk_disable(g_ipu_clk); - g_ipu_clk_enabled = false; + clk_disable(ipu->ipu_clk); + ipu->clk_enabled = false; } - WARN_ON(ipu_ic_use_count < 0); - WARN_ON(ipu_vdi_use_count < 0); - WARN_ON(ipu_rot_use_count < 0); - WARN_ON(ipu_dc_use_count < 0); - WARN_ON(ipu_dp_use_count < 0); - WARN_ON(ipu_dmfc_use_count < 0); - WARN_ON(ipu_smfc_use_count < 0); + WARN_ON(ipu->ic_use_count < 0); + WARN_ON(ipu->vdi_use_count < 0); + WARN_ON(ipu->rot_use_count < 0); + WARN_ON(ipu->dc_use_count < 0); + WARN_ON(ipu->dp_use_count < 0); + WARN_ON(ipu->dmfc_use_count < 0); + WARN_ON(ipu->smfc_use_count < 0); } EXPORT_SYMBOL(ipu_uninit_channel); /*! * This function is called to initialize buffer(s) for logical IPU channel. * + * @param ipu ipu handler + * * @param channel Input parameter for the logical channel ID. * * @param type Input parameter which buffer to initialize. @@ -1104,7 +1265,8 @@ EXPORT_SYMBOL(ipu_uninit_channel); * * @return Returns 0 on success or negative error code on fail */ -int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, +int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, + ipu_buffer_t type, uint32_t pixel_fmt, uint16_t width, uint16_t height, uint32_t stride, @@ -1126,128 +1288,128 @@ int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, stride = width * bytes_per_pixel(pixel_fmt); if (stride % 4) { - dev_err(g_ipu_dev, + dev_err(ipu->dev, "Stride not 32-bit aligned, stride = %d\n", stride); return -EINVAL; } /* IC & IRT channels' width must be multiple of 8 pixels */ if ((_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan)) && (width % 8)) { - dev_err(g_ipu_dev, "Width must be 8 pixel multiple\n"); + dev_err(ipu->dev, "Width must be 8 pixel multiple\n"); return -EINVAL; } /* IPUv3EX and IPUv3M support triple buffer */ if ((!_ipu_is_trb_chan(dma_chan)) && phyaddr_2) { - dev_err(g_ipu_dev, "Chan%d doesn't support triple buffer " + dev_err(ipu->dev, "Chan%d doesn't support triple buffer " "mode\n", dma_chan); return -EINVAL; } if (!phyaddr_1 && phyaddr_2) { - dev_err(g_ipu_dev, "Chan%d's buf1 physical addr is NULL for " + dev_err(ipu->dev, "Chan%d's buf1 physical addr is NULL for " "triple buffer mode\n", dma_chan); return -EINVAL; } /* Build parameter memory data for DMA channel */ - _ipu_ch_param_init(dma_chan, pixel_fmt, width, height, stride, u, v, 0, + _ipu_ch_param_init(ipu, dma_chan, pixel_fmt, width, height, stride, u, v, 0, phyaddr_0, phyaddr_1, phyaddr_2); /* Set correlative channel parameter of local alpha channel */ if ((_ipu_is_ic_graphic_chan(dma_chan) || _ipu_is_dp_graphic_chan(dma_chan)) && - (g_thrd_chan_en[IPU_CHAN_ID(channel)] == true)) { - _ipu_ch_param_set_alpha_use_separate_channel(dma_chan, true); - _ipu_ch_param_set_alpha_buffer_memory(dma_chan); - _ipu_ch_param_set_alpha_condition_read(dma_chan); + (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] == true)) { + _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, true); + _ipu_ch_param_set_alpha_buffer_memory(ipu, dma_chan); + _ipu_ch_param_set_alpha_condition_read(ipu, dma_chan); /* fix alpha width as 8 and burst size as 16*/ - _ipu_ch_params_set_alpha_width(dma_chan, 8); - _ipu_ch_param_set_burst_size(dma_chan, 16); + _ipu_ch_params_set_alpha_width(ipu, dma_chan, 8); + _ipu_ch_param_set_burst_size(ipu, dma_chan, 16); } else if (_ipu_is_ic_graphic_chan(dma_chan) && ipu_pixel_format_has_alpha(pixel_fmt)) - _ipu_ch_param_set_alpha_use_separate_channel(dma_chan, false); + _ipu_ch_param_set_alpha_use_separate_channel(ipu, dma_chan, false); if (rot_mode) - _ipu_ch_param_set_rotation(dma_chan, rot_mode); + _ipu_ch_param_set_rotation(ipu, dma_chan, rot_mode); /* IC and ROT channels have restriction of 8 or 16 pix burst length */ if (_ipu_is_ic_chan(dma_chan)) { if ((width % 16) == 0) - _ipu_ch_param_set_burst_size(dma_chan, 16); + _ipu_ch_param_set_burst_size(ipu, dma_chan, 16); else - _ipu_ch_param_set_burst_size(dma_chan, 8); + _ipu_ch_param_set_burst_size(ipu, dma_chan, 8); } else if (_ipu_is_irt_chan(dma_chan)) { - _ipu_ch_param_set_burst_size(dma_chan, 8); - _ipu_ch_param_set_block_mode(dma_chan); + _ipu_ch_param_set_burst_size(ipu, dma_chan, 8); + _ipu_ch_param_set_block_mode(ipu, dma_chan); } else if (_ipu_is_dmfc_chan(dma_chan)) { - burst_size = _ipu_ch_param_get_burst_size(dma_chan); - spin_lock_irqsave(&ipu_lock, lock_flags); - _ipu_dmfc_set_wait4eot(dma_chan, width); - _ipu_dmfc_set_burst_size(dma_chan, burst_size); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); + _ipu_dmfc_set_wait4eot(ipu, dma_chan, width); + _ipu_dmfc_set_burst_size(ipu, dma_chan, burst_size); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); } - if (_ipu_disp_chan_is_interlaced(channel) || - g_chan_is_interlaced[dma_chan]) - _ipu_ch_param_set_interlaced_scan(dma_chan); + if (_ipu_disp_chan_is_interlaced(ipu, channel) || + ipu->chan_is_interlaced[dma_chan]) + _ipu_ch_param_set_interlaced_scan(ipu, dma_chan); if (_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan)) { - burst_size = _ipu_ch_param_get_burst_size(dma_chan); - _ipu_ic_idma_init(dma_chan, width, height, burst_size, + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan); + _ipu_ic_idma_init(ipu, dma_chan, width, height, burst_size, rot_mode); } else if (_ipu_is_smfc_chan(dma_chan)) { - burst_size = _ipu_ch_param_get_burst_size(dma_chan); + burst_size = _ipu_ch_param_get_burst_size(ipu, dma_chan); if ((pixel_fmt == IPU_PIX_FMT_GENERIC) && - ((_ipu_ch_param_get_bpp(dma_chan) == 5) || - (_ipu_ch_param_get_bpp(dma_chan) == 3))) + ((_ipu_ch_param_get_bpp(ipu, dma_chan) == 5) || + (_ipu_ch_param_get_bpp(ipu, dma_chan) == 3))) burst_size = burst_size >> 4; else burst_size = burst_size >> 2; - _ipu_smfc_set_burst_size(channel, burst_size-1); + _ipu_smfc_set_burst_size(ipu, channel, burst_size-1); } - if (idma_is_set(IDMAC_CHA_PRI, dma_chan) && !cpu_is_mx53()) - _ipu_ch_param_set_high_priority(dma_chan); + if (idma_is_set(ipu, IDMAC_CHA_PRI, dma_chan) && !cpu_is_mx53()) + _ipu_ch_param_set_high_priority(ipu, dma_chan); - _ipu_ch_param_dump(dma_chan); + _ipu_ch_param_dump(ipu, dma_chan); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); if (phyaddr_2 && g_ipu_hw_rev >= 2) { - reg = __raw_readl(IPU_CHA_DB_MODE_SEL(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan)); reg &= ~idma_mask(dma_chan); - __raw_writel(reg, IPU_CHA_DB_MODE_SEL(dma_chan)); + ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan)); - reg = __raw_readl(IPU_CHA_TRB_MODE_SEL(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan)); reg |= idma_mask(dma_chan); - __raw_writel(reg, IPU_CHA_TRB_MODE_SEL(dma_chan)); + ipu_cm_write(ipu, reg, IPU_CHA_TRB_MODE_SEL(dma_chan)); /* Set IDMAC third buffer's cpmem number */ /* See __ipu_ch_get_third_buf_cpmem_num() for mapping */ - __raw_writel(0x00444047L, IDMAC_SUB_ADDR_4); - __raw_writel(0x46004241L, IDMAC_SUB_ADDR_3); - __raw_writel(0x00000045L, IDMAC_SUB_ADDR_1); + ipu_idmac_write(ipu, 0x00444047L, IDMAC_SUB_ADDR_4); + ipu_idmac_write(ipu, 0x46004241L, IDMAC_SUB_ADDR_3); + ipu_idmac_write(ipu, 0x00000045L, IDMAC_SUB_ADDR_1); /* Reset to buffer 0 */ - __raw_writel(tri_cur_buf_mask(dma_chan), + ipu_cm_write(ipu, tri_cur_buf_mask(dma_chan), IPU_CHA_TRIPLE_CUR_BUF(dma_chan)); } else { - reg = __raw_readl(IPU_CHA_TRB_MODE_SEL(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan)); reg &= ~idma_mask(dma_chan); - __raw_writel(reg, IPU_CHA_TRB_MODE_SEL(dma_chan)); + ipu_cm_write(ipu, reg, IPU_CHA_TRB_MODE_SEL(dma_chan)); - reg = __raw_readl(IPU_CHA_DB_MODE_SEL(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(dma_chan)); if (phyaddr_1) reg |= idma_mask(dma_chan); else reg &= ~idma_mask(dma_chan); - __raw_writel(reg, IPU_CHA_DB_MODE_SEL(dma_chan)); + ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(dma_chan)); /* Reset to buffer 0 */ - __raw_writel(idma_mask(dma_chan), + ipu_cm_write(ipu, idma_mask(dma_chan), IPU_CHA_CUR_BUF(dma_chan)); } - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } @@ -1257,6 +1419,7 @@ EXPORT_SYMBOL(ipu_init_channel_buffer); * This function is called to update the physical address of a buffer for * a logical IPU channel. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param type Input parameter which buffer to initialize. @@ -1269,8 +1432,8 @@ EXPORT_SYMBOL(ipu_init_channel_buffer); * @return This function returns 0 on success or negative error code on * fail. This function will fail if the buffer is set to ready. */ -int32_t ipu_update_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, - uint32_t bufNum, dma_addr_t phyaddr) +int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, + ipu_buffer_t type, uint32_t bufNum, dma_addr_t phyaddr) { uint32_t reg; int ret = 0; @@ -1279,21 +1442,21 @@ int32_t ipu_update_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, if (dma_chan == IDMA_CHAN_INVALID) return -EINVAL; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); if (bufNum == 0) - reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan)); else if (bufNum == 1) - reg = __raw_readl(IPU_CHA_BUF1_RDY(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan)); else - reg = __raw_readl(IPU_CHA_BUF2_RDY(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan)); if ((reg & idma_mask(dma_chan)) == 0) - _ipu_ch_param_set_buffer(dma_chan, bufNum, phyaddr); + _ipu_ch_param_set_buffer(ipu, dma_chan, bufNum, phyaddr); else ret = -EACCES; - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return ret; } EXPORT_SYMBOL(ipu_update_channel_buffer); @@ -1302,6 +1465,7 @@ EXPORT_SYMBOL(ipu_update_channel_buffer); /*! * This function is called to initialize a buffer for logical IPU channel. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param type Input parameter which buffer to initialize. @@ -1334,7 +1498,8 @@ EXPORT_SYMBOL(ipu_update_channel_buffer); * This function will fail if any buffer is set to ready. */ -int32_t ipu_update_channel_offset(ipu_channel_t channel, ipu_buffer_t type, +int32_t ipu_update_channel_offset(struct ipu_soc *ipu, + ipu_channel_t channel, ipu_buffer_t type, uint32_t pixel_fmt, uint16_t width, uint16_t height, uint32_t stride, @@ -1348,19 +1513,19 @@ int32_t ipu_update_channel_offset(ipu_channel_t channel, ipu_buffer_t type, if (dma_chan == IDMA_CHAN_INVALID) return -EINVAL; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - if ((__raw_readl(IPU_CHA_BUF0_RDY(dma_chan)) & idma_mask(dma_chan)) || - (__raw_readl(IPU_CHA_BUF1_RDY(dma_chan)) & idma_mask(dma_chan)) || - ((__raw_readl(IPU_CHA_BUF2_RDY(dma_chan)) & idma_mask(dma_chan)) && - (__raw_readl(IPU_CHA_TRB_MODE_SEL(dma_chan)) & idma_mask(dma_chan)) && + if ((ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan)) & idma_mask(dma_chan)) || + (ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan)) & idma_mask(dma_chan)) || + ((ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan)) & idma_mask(dma_chan)) && + (ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan)) & idma_mask(dma_chan)) && _ipu_is_trb_chan(dma_chan))) ret = -EACCES; else - _ipu_ch_offset_update(dma_chan, pixel_fmt, width, height, stride, + _ipu_ch_offset_update(ipu, dma_chan, pixel_fmt, width, height, stride, u, v, 0, vertical_offset, horizontal_offset); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return ret; } EXPORT_SYMBOL(ipu_update_channel_offset); @@ -1369,6 +1534,7 @@ EXPORT_SYMBOL(ipu_update_channel_offset); /*! * This function is called to set a channel's buffer as ready. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param type Input parameter which buffer to initialize. @@ -1378,8 +1544,8 @@ EXPORT_SYMBOL(ipu_update_channel_offset); * * @return Returns 0 on success or negative error code on fail */ -int32_t ipu_select_buffer(ipu_channel_t channel, ipu_buffer_t type, - uint32_t bufNum) +int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel, + ipu_buffer_t type, uint32_t bufNum) { uint32_t dma_chan = channel_2_dma(channel, type); unsigned long lock_flags; @@ -1388,17 +1554,17 @@ int32_t ipu_select_buffer(ipu_channel_t channel, ipu_buffer_t type, return -EINVAL; /* Mark buffer to be ready. */ - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); if (bufNum == 0) - __raw_writel(idma_mask(dma_chan), + ipu_cm_write(ipu, idma_mask(dma_chan), IPU_CHA_BUF0_RDY(dma_chan)); else if (bufNum == 1) - __raw_writel(idma_mask(dma_chan), + ipu_cm_write(ipu, idma_mask(dma_chan), IPU_CHA_BUF1_RDY(dma_chan)); else - __raw_writel(idma_mask(dma_chan), + ipu_cm_write(ipu, idma_mask(dma_chan), IPU_CHA_BUF2_RDY(dma_chan)); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } EXPORT_SYMBOL(ipu_select_buffer); @@ -1406,12 +1572,13 @@ EXPORT_SYMBOL(ipu_select_buffer); /*! * This function is called to set a channel's buffer as ready. * + * @param ipu ipu handler * @param bufNum Input parameter for which buffer number set to * ready state. * * @return Returns 0 on success or negative error code on fail */ -int32_t ipu_select_multi_vdi_buffer(uint32_t bufNum) +int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum) { uint32_t dma_chan = channel_2_dma(MEM_VDI_PRP_VF_MEM, IPU_INPUT_BUFFER); @@ -1422,12 +1589,12 @@ int32_t ipu_select_multi_vdi_buffer(uint32_t bufNum) unsigned long lock_flags; /* Mark buffers to be ready. */ - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); if (bufNum == 0) - __raw_writel(mask_bit, IPU_CHA_BUF0_RDY(dma_chan)); + ipu_cm_write(ipu, mask_bit, IPU_CHA_BUF0_RDY(dma_chan)); else - __raw_writel(mask_bit, IPU_CHA_BUF1_RDY(dma_chan)); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + ipu_cm_write(ipu, mask_bit, IPU_CHA_BUF1_RDY(dma_chan)); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } EXPORT_SYMBOL(ipu_select_multi_vdi_buffer); @@ -1447,6 +1614,7 @@ static int disp_src_sel[] = { 0, 6, 7, 8, 3, 4, 5, NA, NA, NA, * synchronization. The output of the source channel is linked to the input of * the destination channel. * + * @param ipu ipu handler * @param src_ch Input parameter for the logical channel ID of * the source channel. * @@ -1456,7 +1624,7 @@ static int disp_src_sel[] = { 0, 6, 7, 8, 3, 4, 5, NA, NA, NA, * @return This function returns 0 on success or negative error code on * fail. */ -int32_t ipu_link_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch) +int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch) { int retval = 0; unsigned long lock_flags; @@ -1465,12 +1633,12 @@ int32_t ipu_link_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch) uint32_t fs_proc_flow3; uint32_t fs_disp_flow1; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - fs_proc_flow1 = __raw_readl(IPU_FS_PROC_FLOW1); - fs_proc_flow2 = __raw_readl(IPU_FS_PROC_FLOW2); - fs_proc_flow3 = __raw_readl(IPU_FS_PROC_FLOW3); - fs_disp_flow1 = __raw_readl(IPU_FS_DISP_FLOW1); + fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); + fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2); + fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3); + fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1); switch (src_ch) { case CSI_MEM0: @@ -1634,13 +1802,13 @@ int32_t ipu_link_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch) goto err; } - __raw_writel(fs_proc_flow1, IPU_FS_PROC_FLOW1); - __raw_writel(fs_proc_flow2, IPU_FS_PROC_FLOW2); - __raw_writel(fs_proc_flow3, IPU_FS_PROC_FLOW3); - __raw_writel(fs_disp_flow1, IPU_FS_DISP_FLOW1); + ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2); + ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3); + ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1); err: - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return retval; } EXPORT_SYMBOL(ipu_link_channels); @@ -1649,6 +1817,7 @@ EXPORT_SYMBOL(ipu_link_channels); * This function unlinks 2 channels and disables automatic frame * synchronization. * + * @param ipu ipu handler * @param src_ch Input parameter for the logical channel ID of * the source channel. * @@ -1658,7 +1827,7 @@ EXPORT_SYMBOL(ipu_link_channels); * @return This function returns 0 on success or negative error code on * fail. */ -int32_t ipu_unlink_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch) +int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch) { int retval = 0; unsigned long lock_flags; @@ -1667,12 +1836,12 @@ int32_t ipu_unlink_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch) uint32_t fs_proc_flow3; uint32_t fs_disp_flow1; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - fs_proc_flow1 = __raw_readl(IPU_FS_PROC_FLOW1); - fs_proc_flow2 = __raw_readl(IPU_FS_PROC_FLOW2); - fs_proc_flow3 = __raw_readl(IPU_FS_PROC_FLOW3); - fs_disp_flow1 = __raw_readl(IPU_FS_DISP_FLOW1); + fs_proc_flow1 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW1); + fs_proc_flow2 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW2); + fs_proc_flow3 = ipu_cm_read(ipu, IPU_FS_PROC_FLOW3); + fs_disp_flow1 = ipu_cm_read(ipu, IPU_FS_DISP_FLOW1); switch (src_ch) { case CSI_MEM0: @@ -1764,13 +1933,13 @@ int32_t ipu_unlink_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch) goto err; } - __raw_writel(fs_proc_flow1, IPU_FS_PROC_FLOW1); - __raw_writel(fs_proc_flow2, IPU_FS_PROC_FLOW2); - __raw_writel(fs_proc_flow3, IPU_FS_PROC_FLOW3); - __raw_writel(fs_disp_flow1, IPU_FS_DISP_FLOW1); + ipu_cm_write(ipu, fs_proc_flow1, IPU_FS_PROC_FLOW1); + ipu_cm_write(ipu, fs_proc_flow2, IPU_FS_PROC_FLOW2); + ipu_cm_write(ipu, fs_proc_flow3, IPU_FS_PROC_FLOW3); + ipu_cm_write(ipu, fs_disp_flow1, IPU_FS_DISP_FLOW1); err: - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return retval; } EXPORT_SYMBOL(ipu_unlink_channels); @@ -1778,12 +1947,13 @@ EXPORT_SYMBOL(ipu_unlink_channels); /*! * This function check whether a logical channel was enabled. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @return This function returns 1 while request channel is enabled or * 0 for not enabled. */ -int32_t ipu_is_channel_busy(ipu_channel_t channel) +int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel) { uint32_t reg; uint32_t in_dma; @@ -1792,10 +1962,10 @@ int32_t ipu_is_channel_busy(ipu_channel_t channel) out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); - reg = __raw_readl(IDMAC_CHA_EN(in_dma)); + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma)); if (reg & idma_mask(in_dma)) return 1; - reg = __raw_readl(IDMAC_CHA_EN(out_dma)); + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma)); if (reg & idma_mask(out_dma)) return 1; return 0; @@ -1805,12 +1975,13 @@ EXPORT_SYMBOL(ipu_is_channel_busy); /*! * This function enables a logical channel. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @return This function returns 0 on success or negative error code on * fail. */ -int32_t ipu_enable_channel(ipu_channel_t channel) +int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel) { uint32_t reg; unsigned long lock_flags; @@ -1820,12 +1991,12 @@ int32_t ipu_enable_channel(ipu_channel_t channel) uint32_t sec_dma; uint32_t thrd_dma; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - if (g_channel_enable_mask & (1L << IPU_CHAN_ID(channel))) { - dev_err(g_ipu_dev, "Warning: channel already enabled %d\n", + if (ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) { + dev_err(ipu->dev, "Warning: channel already enabled %d\n", IPU_CHAN_ID(channel)); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return -EACCES; } @@ -1833,81 +2004,81 @@ int32_t ipu_enable_channel(ipu_channel_t channel) out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); - ipu_conf = __raw_readl(IPU_CONF); - if (ipu_di_use_count[0] > 0) { + ipu_conf = ipu_cm_read(ipu, IPU_CONF); + if (ipu->di_use_count[0] > 0) { ipu_conf |= IPU_CONF_DI0_EN; } - if (ipu_di_use_count[1] > 0) { + if (ipu->di_use_count[1] > 0) { ipu_conf |= IPU_CONF_DI1_EN; } - if (ipu_dp_use_count > 0) + if (ipu->dp_use_count > 0) ipu_conf |= IPU_CONF_DP_EN; - if (ipu_dc_use_count > 0) + if (ipu->dc_use_count > 0) ipu_conf |= IPU_CONF_DC_EN; - if (ipu_dmfc_use_count > 0) + if (ipu->dmfc_use_count > 0) ipu_conf |= IPU_CONF_DMFC_EN; - if (ipu_ic_use_count > 0) + if (ipu->ic_use_count > 0) ipu_conf |= IPU_CONF_IC_EN; - if (ipu_vdi_use_count > 0) { + 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) + if (ipu->rot_use_count > 0) ipu_conf |= IPU_CONF_ROT_EN; - if (ipu_smfc_use_count > 0) + if (ipu->smfc_use_count > 0) ipu_conf |= IPU_CONF_SMFC_EN; - __raw_writel(ipu_conf, IPU_CONF); + ipu_cm_write(ipu, 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)); + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(in_dma)); + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma)); } if (idma_is_valid(out_dma)) { - reg = __raw_readl(IDMAC_CHA_EN(out_dma)); - __raw_writel(reg | idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma)); + ipu_idmac_write(ipu, reg | idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); } - if ((g_sec_chan_en[IPU_CHAN_ID(channel)]) && + if ((ipu->sec_chan_en[IPU_CHAN_ID(channel)]) && ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM) || (channel == MEM_VDI_PRP_VF_MEM))) { sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER); - reg = __raw_readl(IDMAC_CHA_EN(sec_dma)); - __raw_writel(reg | idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma)); + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma)); + ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma)); } - if ((g_thrd_chan_en[IPU_CHAN_ID(channel)]) && + if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) && ((channel == MEM_PP_MEM) || (channel == MEM_PRP_VF_MEM))) { thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER); - reg = __raw_readl(IDMAC_CHA_EN(thrd_dma)); - __raw_writel(reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma)); + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma)); + ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma)); sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER); - reg = __raw_readl(IDMAC_SEP_ALPHA); - __raw_writel(reg | idma_mask(sec_dma), IDMAC_SEP_ALPHA); - } else if ((g_thrd_chan_en[IPU_CHAN_ID(channel)]) && + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA); + ipu_idmac_write(ipu, reg | idma_mask(sec_dma), IDMAC_SEP_ALPHA); + } else if ((ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) && ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))) { thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER); - reg = __raw_readl(IDMAC_CHA_EN(thrd_dma)); - __raw_writel(reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma)); - reg = __raw_readl(IDMAC_SEP_ALPHA); - __raw_writel(reg | idma_mask(in_dma), IDMAC_SEP_ALPHA); + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma)); + ipu_idmac_write(ipu, reg | idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma)); + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA); + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_SEP_ALPHA); } if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_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)); + reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma)); + ipu_idmac_write(ipu, reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma)); - _ipu_dp_dc_enable(channel); + _ipu_dp_dc_enable(ipu, 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)) - _ipu_ic_enable_task(channel); + _ipu_ic_enable_task(ipu, channel); - g_channel_enable_mask |= 1L << IPU_CHAN_ID(channel); + ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(channel); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } @@ -1916,6 +2087,7 @@ EXPORT_SYMBOL(ipu_enable_channel); /*! * This function check buffer ready for a logical channel. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param type Input parameter which buffer to clear. @@ -1924,7 +2096,7 @@ EXPORT_SYMBOL(ipu_enable_channel); * ready state. * */ -int32_t ipu_check_buffer_ready(ipu_channel_t channel, ipu_buffer_t type, +int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type, uint32_t bufNum) { uint32_t dma_chan = channel_2_dma(channel, type); @@ -1934,11 +2106,11 @@ int32_t ipu_check_buffer_ready(ipu_channel_t channel, ipu_buffer_t type, return -EINVAL; if (bufNum == 0) - reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(dma_chan)); else if (bufNum == 1) - reg = __raw_readl(IPU_CHA_BUF1_RDY(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(dma_chan)); else - reg = __raw_readl(IPU_CHA_BUF2_RDY(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_BUF2_RDY(dma_chan)); if (reg & idma_mask(dma_chan)) return 1; @@ -1950,6 +2122,7 @@ EXPORT_SYMBOL(ipu_check_buffer_ready); /*! * This function clear buffer ready for a logical channel. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param type Input parameter which buffer to clear. @@ -1958,7 +2131,7 @@ EXPORT_SYMBOL(ipu_check_buffer_ready); * ready state. * */ -void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type, +void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type, uint32_t bufNum) { unsigned long lock_flags; @@ -1967,26 +2140,26 @@ void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type, if (!idma_is_valid(dma_ch)) return; - spin_lock_irqsave(&ipu_lock, lock_flags); - __raw_writel(0xF0300000, IPU_GPR); /* write one to clear */ + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); + ipu_cm_write(ipu, 0xF0300000, IPU_GPR); /* write one to clear */ if (bufNum == 0) { - if (idma_is_set(IPU_CHA_BUF0_RDY, dma_ch)) { - __raw_writel(idma_mask(dma_ch), + 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) { - if (idma_is_set(IPU_CHA_BUF1_RDY, dma_ch)) { - __raw_writel(idma_mask(dma_ch), + 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 { - if (idma_is_set(IPU_CHA_BUF2_RDY, dma_ch)) { - __raw_writel(idma_mask(dma_ch), + 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)); } } - __raw_writel(0x0, IPU_GPR); /* write one to set */ - spin_unlock_irqrestore(&ipu_lock, lock_flags); + ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */ + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); } EXPORT_SYMBOL(ipu_clear_buffer_ready); @@ -2001,6 +2174,7 @@ static irqreturn_t disable_chan_irq_handler(int irq, void *dev_id) /*! * This function disables a logical channel. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param wait_for_stop Flag to set whether to wait for channel end @@ -2009,7 +2183,7 @@ static irqreturn_t disable_chan_irq_handler(int irq, void *dev_id) * @return This function returns 0 on success or negative error code on * fail. */ -int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop) +int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop) { uint32_t reg; unsigned long lock_flags; @@ -2018,30 +2192,30 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop) uint32_t sec_dma = NO_DMA; uint32_t thrd_dma = NO_DMA; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - if ((g_channel_enable_mask & (1L << IPU_CHAN_ID(channel))) == 0) { - dev_err(g_ipu_dev, "Channel already disabled %d\n", + if ((ipu->channel_enable_mask & (1L << IPU_CHAN_ID(channel))) == 0) { + dev_err(ipu->dev, "Channel already disabled %d\n", IPU_CHAN_ID(channel)); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return -EACCES; } - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); /* Get input and output dma channels */ out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); if ((idma_is_valid(in_dma) && - !idma_is_set(IDMAC_CHA_EN, in_dma)) + !idma_is_set(ipu, IDMAC_CHA_EN, in_dma)) && (idma_is_valid(out_dma) && - !idma_is_set(IDMAC_CHA_EN, out_dma))) + !idma_is_set(ipu, IDMAC_CHA_EN, out_dma))) return -EINVAL; - if (g_sec_chan_en[IPU_CHAN_ID(channel)]) + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)]) sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER); - if (g_thrd_chan_en[IPU_CHAN_ID(channel)]) { + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)]) { sec_dma = channel_2_dma(channel, IPU_GRAPH_IN_BUFFER); thrd_dma = channel_2_dma(channel, IPU_ALPHA_IN_BUFFER); } @@ -2049,9 +2223,9 @@ 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_disp_set_window_pos(ipu, channel, 0, 0); - _ipu_dp_dc_disable(channel, false); + _ipu_dp_dc_disable(ipu, channel, false); /* * wait for BG channel EOF then disable FG-IDMAC, @@ -2060,126 +2234,127 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop) if (channel == MEM_FG_SYNC) { int timeout = 50; - __raw_writel(IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF), + ipu_cm_write(ipu, 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) { + while ((ipu_cm_read(ipu, 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"); + dev_err(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) || - (g_sec_chan_en[IPU_CHAN_ID(channel)] && - idma_is_set(IDMAC_CHA_BUSY, sec_dma)) || - (g_thrd_chan_en[IPU_CHAN_ID(channel)] && - idma_is_set(IDMAC_CHA_BUSY, thrd_dma))) { + while (idma_is_set(ipu, IDMAC_CHA_BUSY, in_dma) || + idma_is_set(ipu, IDMAC_CHA_BUSY, out_dma) || + (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && + idma_is_set(ipu, IDMAC_CHA_BUSY, sec_dma)) || + (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && + idma_is_set(ipu, IDMAC_CHA_BUSY, thrd_dma))) { uint32_t ret, irq = 0xffffffff; DECLARE_COMPLETION_ONSTACK(disable_comp); - if (idma_is_set(IDMAC_CHA_BUSY, out_dma)) + if (idma_is_set(ipu, IDMAC_CHA_BUSY, out_dma)) irq = out_dma; - if (g_sec_chan_en[IPU_CHAN_ID(channel)] && - idma_is_set(IDMAC_CHA_BUSY, sec_dma)) + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && + idma_is_set(ipu, IDMAC_CHA_BUSY, sec_dma)) irq = sec_dma; - if (g_thrd_chan_en[IPU_CHAN_ID(channel)] && - idma_is_set(IDMAC_CHA_BUSY, thrd_dma)) + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && + idma_is_set(ipu, IDMAC_CHA_BUSY, thrd_dma)) irq = thrd_dma; - if (idma_is_set(IDMAC_CHA_BUSY, in_dma)) + if (idma_is_set(ipu, IDMAC_CHA_BUSY, in_dma)) irq = in_dma; if (irq == 0xffffffff) { - dev_err(g_ipu_dev, "warning: no channel busy, break\n"); + dev_err(ipu->dev, "warning: no channel busy, break\n"); break; } - ret = ipu_request_irq(irq, disable_chan_irq_handler, 0, NULL, &disable_comp); + + ret = ipu_request_irq(ipu, irq, disable_chan_irq_handler, 0, NULL, &disable_comp); if (ret < 0) { - dev_err(g_ipu_dev, "irq %d in use\n", irq); + dev_err(ipu->dev, "irq %d in use\n", irq); break; } else { ret = wait_for_completion_timeout(&disable_comp, msecs_to_jiffies(200)); - ipu_free_irq(irq, &disable_comp); + ipu_free_irq(ipu, irq, &disable_comp); if (ret == 0) { - ipu_dump_registers(); - dev_err(g_ipu_dev, "warning: disable ipu dma channel %d during its busy state\n", irq); + ipu_dump_registers(ipu); + dev_err(ipu->dev, "warning: disable ipu dma channel %d during its busy state\n", irq); break; } } } } - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->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)); + reg = ipu_idmac_read(ipu, IDMAC_WM_EN(in_dma)); + ipu_idmac_write(ipu, 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)) - _ipu_ic_disable_task(channel); + _ipu_ic_disable_task(ipu, channel); /* Disable DMA channel(s) */ 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)); - __raw_writel(idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma)); - __raw_writel(tri_cur_buf_mask(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)); + ipu_cm_write(ipu, idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma)); + ipu_cm_write(ipu, tri_cur_buf_mask(in_dma), IPU_CHA_TRIPLE_CUR_BUF(in_dma)); } if (idma_is_valid(out_dma)) { - reg = __raw_readl(IDMAC_CHA_EN(out_dma)); - __raw_writel(reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); - __raw_writel(idma_mask(out_dma), IPU_CHA_CUR_BUF(out_dma)); - __raw_writel(tri_cur_buf_mask(out_dma), + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(out_dma)); + ipu_idmac_write(ipu, reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); + ipu_cm_write(ipu, idma_mask(out_dma), IPU_CHA_CUR_BUF(out_dma)); + ipu_cm_write(ipu, tri_cur_buf_mask(out_dma), IPU_CHA_TRIPLE_CUR_BUF(out_dma)); } - if (g_sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) { - reg = __raw_readl(IDMAC_CHA_EN(sec_dma)); - __raw_writel(reg & ~idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma)); - __raw_writel(idma_mask(sec_dma), IPU_CHA_CUR_BUF(sec_dma)); + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) { + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(sec_dma)); + ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_CHA_EN(sec_dma)); + ipu_cm_write(ipu, idma_mask(sec_dma), IPU_CHA_CUR_BUF(sec_dma)); } - if (g_thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) { - reg = __raw_readl(IDMAC_CHA_EN(thrd_dma)); - __raw_writel(reg & ~idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma)); + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) { + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(thrd_dma)); + ipu_idmac_write(ipu, reg & ~idma_mask(thrd_dma), IDMAC_CHA_EN(thrd_dma)); if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC) { - reg = __raw_readl(IDMAC_SEP_ALPHA); - __raw_writel(reg & ~idma_mask(in_dma), IDMAC_SEP_ALPHA); + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA); + ipu_idmac_write(ipu, reg & ~idma_mask(in_dma), IDMAC_SEP_ALPHA); } else { - reg = __raw_readl(IDMAC_SEP_ALPHA); - __raw_writel(reg & ~idma_mask(sec_dma), IDMAC_SEP_ALPHA); + reg = ipu_idmac_read(ipu, IDMAC_SEP_ALPHA); + ipu_idmac_write(ipu, reg & ~idma_mask(sec_dma), IDMAC_SEP_ALPHA); } - __raw_writel(idma_mask(thrd_dma), IPU_CHA_CUR_BUF(thrd_dma)); + ipu_cm_write(ipu, idma_mask(thrd_dma), IPU_CHA_CUR_BUF(thrd_dma)); } - g_channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel)); + ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel)); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->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); - ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 1); - ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 2); + ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 0); + ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 1); + ipu_clear_buffer_ready(ipu, channel, IPU_VIDEO_IN_BUFFER, 2); } if (idma_is_valid(out_dma)) { - ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 0); - ipu_clear_buffer_ready(channel, IPU_OUTPUT_BUFFER, 1); + ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 0); + ipu_clear_buffer_ready(ipu, channel, IPU_OUTPUT_BUFFER, 1); } - if (g_sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) { - ipu_clear_buffer_ready(channel, IPU_GRAPH_IN_BUFFER, 0); - ipu_clear_buffer_ready(channel, IPU_GRAPH_IN_BUFFER, 1); + if (ipu->sec_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(sec_dma)) { + ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 0); + ipu_clear_buffer_ready(ipu, channel, IPU_GRAPH_IN_BUFFER, 1); } - if (g_thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) { - ipu_clear_buffer_ready(channel, IPU_ALPHA_IN_BUFFER, 0); - ipu_clear_buffer_ready(channel, IPU_ALPHA_IN_BUFFER, 1); + if (ipu->thrd_chan_en[IPU_CHAN_ID(channel)] && idma_is_valid(thrd_dma)) { + ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 0); + ipu_clear_buffer_ready(ipu, channel, IPU_ALPHA_IN_BUFFER, 1); } return 0; @@ -2189,32 +2364,33 @@ EXPORT_SYMBOL(ipu_disable_channel); /*! * This function enables CSI. * + * @param ipu ipu handler * @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) +int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi) { uint32_t reg; unsigned long lock_flags; if (csi > 1) { - dev_err(g_ipu_dev, "Wrong csi num_%d\n", csi); + dev_err(ipu->dev, "Wrong csi num_%d\n", csi); return -EINVAL; } - spin_lock_irqsave(&ipu_lock, lock_flags); - ipu_csi_use_count[csi]++; + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); + ipu->csi_use_count[csi]++; - if (ipu_csi_use_count[csi] == 1) { - reg = __raw_readl(IPU_CONF); + if (ipu->csi_use_count[csi] == 1) { + reg = ipu_cm_read(ipu, IPU_CONF); if (csi == 0) - __raw_writel(reg | IPU_CONF_CSI0_EN, IPU_CONF); + ipu_cm_write(ipu, reg | IPU_CONF_CSI0_EN, IPU_CONF); else - __raw_writel(reg | IPU_CONF_CSI1_EN, IPU_CONF); + ipu_cm_write(ipu, reg | IPU_CONF_CSI1_EN, IPU_CONF); } - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } EXPORT_SYMBOL(ipu_enable_csi); @@ -2222,38 +2398,40 @@ EXPORT_SYMBOL(ipu_enable_csi); /*! * This function disables CSI. * + * @param ipu ipu handler * @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) +int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi) { uint32_t reg; unsigned long lock_flags; if (csi > 1) { - dev_err(g_ipu_dev, "Wrong csi num_%d\n", csi); + dev_err(ipu->dev, "Wrong csi num_%d\n", csi); return -EINVAL; } - spin_lock_irqsave(&ipu_lock, lock_flags); - ipu_csi_use_count[csi]--; + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); + ipu->csi_use_count[csi]--; - if (ipu_csi_use_count[csi] == 0) { - reg = __raw_readl(IPU_CONF); + if (ipu->csi_use_count[csi] == 0) { + reg = ipu_cm_read(ipu, IPU_CONF); if (csi == 0) - __raw_writel(reg & ~IPU_CONF_CSI0_EN, IPU_CONF); + ipu_cm_write(ipu, reg & ~IPU_CONF_CSI0_EN, IPU_CONF); else - __raw_writel(reg & ~IPU_CONF_CSI1_EN, IPU_CONF); + ipu_cm_write(ipu, reg & ~IPU_CONF_CSI1_EN, IPU_CONF); } - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } EXPORT_SYMBOL(ipu_disable_csi); static irqreturn_t ipu_irq_handler(int irq, void *desc) { + struct ipu_soc *ipu = desc; int i; uint32_t line; irqreturn_t result = IRQ_NONE; @@ -2264,33 +2442,33 @@ static irqreturn_t ipu_irq_handler(int irq, void *desc) for (i = 0;; i++) { if (err_reg[i] == 0) break; - int_stat = __raw_readl(IPU_INT_STAT(err_reg[i])); - int_stat &= __raw_readl(IPU_INT_CTRL(err_reg[i])); + int_stat = ipu_cm_read(ipu, IPU_INT_STAT(err_reg[i])); + int_stat &= ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i])); if (int_stat) { - __raw_writel(int_stat, IPU_INT_STAT(err_reg[i])); - dev_err(g_ipu_dev, + ipu_cm_write(ipu, int_stat, IPU_INT_STAT(err_reg[i])); + dev_err(ipu->dev, "IPU Error - IPU_INT_STAT_%d = 0x%08X\n", err_reg[i], int_stat); /* Disable interrupts so we only get error once */ int_stat = - __raw_readl(IPU_INT_CTRL(err_reg[i])) & ~int_stat; - __raw_writel(int_stat, IPU_INT_CTRL(err_reg[i])); + ipu_cm_read(ipu, IPU_INT_CTRL(err_reg[i])) & ~int_stat; + ipu_cm_write(ipu, int_stat, IPU_INT_CTRL(err_reg[i])); } } for (i = 0;; i++) { if (int_reg[i] == 0) break; - int_stat = __raw_readl(IPU_INT_STAT(int_reg[i])); - int_stat &= __raw_readl(IPU_INT_CTRL(int_reg[i])); - __raw_writel(int_stat, IPU_INT_STAT(int_reg[i])); + int_stat = ipu_cm_read(ipu, IPU_INT_STAT(int_reg[i])); + int_stat &= ipu_cm_read(ipu, IPU_INT_CTRL(int_reg[i])); + ipu_cm_write(ipu, int_stat, IPU_INT_STAT(int_reg[i])); while ((line = ffs(int_stat)) != 0) { line--; int_stat &= ~(1UL << line); line += (int_reg[i] - 1) * 32; result |= - ipu_irq_list[line].handler(line, - ipu_irq_list[line]. + ipu->irq_list[line].handler(line, + ipu->irq_list[line]. dev_id); } } @@ -2302,26 +2480,27 @@ static irqreturn_t ipu_irq_handler(int irq, void *desc) * This function enables the interrupt for the specified interrupt line. * The interrupt lines are defined in \b ipu_irq_line enum. * + * @param ipu ipu handler * @param irq Interrupt line to enable interrupt for. * */ -void ipu_enable_irq(uint32_t irq) +void ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq) { uint32_t reg; unsigned long lock_flags; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - reg = __raw_readl(IPUIRQ_2_CTRLREG(irq)); + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq)); reg |= IPUIRQ_2_MASK(irq); - __raw_writel(reg, IPUIRQ_2_CTRLREG(irq)); + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq)); - spin_unlock_irqrestore(&ipu_lock, lock_flags); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } EXPORT_SYMBOL(ipu_enable_irq); @@ -2329,25 +2508,27 @@ EXPORT_SYMBOL(ipu_enable_irq); * This function disables the interrupt for the specified interrupt line. * The interrupt lines are defined in \b ipu_irq_line enum. * + * @param ipu ipu handler * @param irq Interrupt line to disable interrupt for. * */ -void ipu_disable_irq(uint32_t irq) +void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq) { uint32_t reg; unsigned long lock_flags; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); + + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - reg = __raw_readl(IPUIRQ_2_CTRLREG(irq)); + reg = ipu_cm_read(ipu, IPUIRQ_2_CTRLREG(irq)); reg &= ~IPUIRQ_2_MASK(irq); - __raw_writel(reg, IPUIRQ_2_CTRLREG(irq)); + ipu_cm_write(ipu, reg, IPUIRQ_2_CTRLREG(irq)); - spin_unlock_irqrestore(&ipu_lock, lock_flags); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } EXPORT_SYMBOL(ipu_disable_irq); @@ -2355,18 +2536,19 @@ EXPORT_SYMBOL(ipu_disable_irq); * This function clears the interrupt for the specified interrupt line. * The interrupt lines are defined in \b ipu_irq_line enum. * + * @param ipu ipu handler * @param irq Interrupt line to clear interrupt for. * */ -void ipu_clear_irq(uint32_t irq) +void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq) { - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - __raw_writel(IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq)); + ipu_cm_write(ipu, IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq)); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); } EXPORT_SYMBOL(ipu_clear_irq); @@ -2374,22 +2556,23 @@ EXPORT_SYMBOL(ipu_clear_irq); * This function returns the current interrupt status for the specified * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum. * + * @param ipu ipu handler * @param irq Interrupt line to get status for. * * @return Returns true if the interrupt is pending/asserted or false if * the interrupt is not pending. */ -bool ipu_get_irq_status(uint32_t irq) +bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq) { uint32_t reg; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - reg = __raw_readl(IPUIRQ_2_STATREG(irq)); + reg = ipu_cm_read(ipu, IPUIRQ_2_STATREG(irq)); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); if (reg & IPUIRQ_2_MASK(irq)) return true; @@ -2402,6 +2585,7 @@ EXPORT_SYMBOL(ipu_get_irq_status); * This function registers an interrupt handler function for the specified * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum. * + * @param ipu ipu handler * @param irq Interrupt line to get status for. * * @param handler Input parameter for address of the handler @@ -2418,7 +2602,7 @@ EXPORT_SYMBOL(ipu_get_irq_status); * @return This function returns 0 on success or negative error code on * fail. */ -int ipu_request_irq(uint32_t irq, +int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq, irqreturn_t(*handler) (int, void *), uint32_t irq_flags, const char *devname, void *dev_id) { @@ -2426,23 +2610,23 @@ int ipu_request_irq(uint32_t irq, BUG_ON(irq >= IPU_IRQ_COUNT); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - if (ipu_irq_list[irq].handler != NULL) { - dev_err(g_ipu_dev, + if (ipu->irq_list[irq].handler != NULL) { + dev_err(ipu->dev, "handler already installed on irq %d\n", irq); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return -EINVAL; } - ipu_irq_list[irq].handler = handler; - ipu_irq_list[irq].flags = irq_flags; - ipu_irq_list[irq].dev_id = dev_id; - ipu_irq_list[irq].name = devname; + ipu->irq_list[irq].handler = handler; + ipu->irq_list[irq].flags = irq_flags; + ipu->irq_list[irq].dev_id = dev_id; + ipu->irq_list[irq].name = devname; - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); - ipu_enable_irq(irq); /* enable the interrupt */ + ipu_enable_irq(ipu, irq); /* enable the interrupt */ return 0; } @@ -2452,6 +2636,7 @@ EXPORT_SYMBOL(ipu_request_irq); * This function unregisters an interrupt handler for the specified interrupt * line. The interrupt lines are defined in \b ipu_irq_line enum. * + * @param ipu ipu handler * @param irq Interrupt line to get status for. * * @param dev_id Input parameter for pointer of data to be passed @@ -2459,16 +2644,16 @@ EXPORT_SYMBOL(ipu_request_irq); * ipu_request_irq(). * */ -void ipu_free_irq(uint32_t irq, void *dev_id) +void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id) { - ipu_disable_irq(irq); /* disable the interrupt */ + ipu_disable_irq(ipu, irq); /* disable the interrupt */ - if (ipu_irq_list[irq].dev_id == dev_id) - ipu_irq_list[irq].handler = NULL; + if (ipu->irq_list[irq].dev_id == dev_id) + ipu->irq_list[irq].handler = NULL; } EXPORT_SYMBOL(ipu_free_irq); -uint32_t ipu_get_cur_buffer_idx(ipu_channel_t channel, ipu_buffer_t type) +uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type) { uint32_t reg, dma_chan; @@ -2476,13 +2661,13 @@ uint32_t ipu_get_cur_buffer_idx(ipu_channel_t channel, ipu_buffer_t type) if (!idma_is_valid(dma_chan)) return -EINVAL; - reg = __raw_readl(IPU_CHA_TRB_MODE_SEL(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_TRB_MODE_SEL(dma_chan)); if ((reg & idma_mask(dma_chan)) && _ipu_is_trb_chan(dma_chan)) { - reg = __raw_readl(IPU_CHA_TRIPLE_CUR_BUF(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_TRIPLE_CUR_BUF(dma_chan)); return (reg & tri_cur_buf_mask(dma_chan)) >> tri_cur_buf_shift(dma_chan); } else { - reg = __raw_readl(IPU_CHA_CUR_BUF(dma_chan)); + reg = ipu_cm_read(ipu, IPU_CHA_CUR_BUF(dma_chan)); if (reg & idma_mask(dma_chan)) return 1; else @@ -2491,10 +2676,10 @@ uint32_t ipu_get_cur_buffer_idx(ipu_channel_t channel, ipu_buffer_t type) } EXPORT_SYMBOL(ipu_get_cur_buffer_idx); -uint32_t _ipu_channel_status(ipu_channel_t channel) +uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel) { uint32_t stat = 0; - uint32_t task_stat_reg = __raw_readl(IPU_PROC_TASK_STAT); + uint32_t task_stat_reg = ipu_cm_read(ipu, IPU_PROC_TASK_STAT); switch (channel) { case MEM_PRP_VF_MEM: @@ -2530,7 +2715,7 @@ uint32_t _ipu_channel_status(ipu_channel_t channel) return stat; } -int32_t ipu_swap_channel(ipu_channel_t from_ch, ipu_channel_t to_ch) +int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch) { uint32_t reg; unsigned long lock_flags; @@ -2539,34 +2724,34 @@ int32_t ipu_swap_channel(ipu_channel_t from_ch, ipu_channel_t to_ch) int to_dma = channel_2_dma(to_ch, IPU_INPUT_BUFFER); /* enable target channel */ - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - reg = __raw_readl(IDMAC_CHA_EN(to_dma)); - __raw_writel(reg | idma_mask(to_dma), IDMAC_CHA_EN(to_dma)); + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(to_dma)); + ipu_idmac_write(ipu, reg | idma_mask(to_dma), IDMAC_CHA_EN(to_dma)); - g_channel_enable_mask |= 1L << IPU_CHAN_ID(to_ch); + ipu->channel_enable_mask |= 1L << IPU_CHAN_ID(to_ch); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); /* switch dp dc */ - _ipu_dp_dc_disable(from_ch, true); + _ipu_dp_dc_disable(ipu, from_ch, true); /* disable source channel */ - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - reg = __raw_readl(IDMAC_CHA_EN(from_dma)); - __raw_writel(reg & ~idma_mask(from_dma), IDMAC_CHA_EN(from_dma)); - __raw_writel(idma_mask(from_dma), IPU_CHA_CUR_BUF(from_dma)); - __raw_writel(tri_cur_buf_mask(from_dma), + reg = ipu_idmac_read(ipu, IDMAC_CHA_EN(from_dma)); + ipu_idmac_write(ipu, reg & ~idma_mask(from_dma), IDMAC_CHA_EN(from_dma)); + ipu_cm_write(ipu, idma_mask(from_dma), IPU_CHA_CUR_BUF(from_dma)); + ipu_cm_write(ipu, tri_cur_buf_mask(from_dma), IPU_CHA_TRIPLE_CUR_BUF(from_dma)); - g_channel_enable_mask &= ~(1L << IPU_CHAN_ID(from_ch)); + ipu->channel_enable_mask &= ~(1L << IPU_CHAN_ID(from_ch)); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); - ipu_clear_buffer_ready(from_ch, IPU_VIDEO_IN_BUFFER, 0); - ipu_clear_buffer_ready(from_ch, IPU_VIDEO_IN_BUFFER, 1); - ipu_clear_buffer_ready(from_ch, IPU_VIDEO_IN_BUFFER, 2); + ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 0); + ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 1); + ipu_clear_buffer_ready(ipu, from_ch, IPU_VIDEO_IN_BUFFER, 2); return 0; } @@ -2647,9 +2832,9 @@ bool ipu_pixel_format_has_alpha(uint32_t fmt) return false; } -void ipu_set_csc_coefficients(ipu_channel_t channel, int32_t param[][3]) +void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]) { - _ipu_dp_set_csc_coefficients(channel, param); + _ipu_dp_set_csc_coefficients(ipu, channel, param); } EXPORT_SYMBOL(ipu_set_csc_coefficients); @@ -2657,6 +2842,7 @@ static int ipu_suspend(struct platform_device *pdev, pm_message_t state) { struct imx_ipuv3_platform_data *plat_data = pdev->dev.platform_data; +#if 0 if (g_ipu_clk_enabled) { /* save and disable enabled channels*/ idma_enable_reg[0] = __raw_readl(IDMAC_CHA_EN(0)); @@ -2738,6 +2924,7 @@ static int ipu_suspend(struct platform_device *pdev, pm_message_t state) buf_ready_reg[8] = __raw_readl(IPU_CHA_BUF2_RDY(0)); buf_ready_reg[9] = __raw_readl(IPU_CHA_BUF2_RDY(32)); } +#endif if (plat_data->pg) plat_data->pg(1); @@ -2752,6 +2939,7 @@ static int ipu_resume(struct platform_device *pdev) if (plat_data->pg) plat_data->pg(0); +#if 0 if (g_ipu_clk_enabled) { /* restore buf ready regs */ @@ -2817,6 +3005,7 @@ static int ipu_resume(struct platform_device *pdev) __raw_writel(0x18800001L, IDMAC_CHA_PRI(0)); clk_disable(g_ipu_clk); } +#endif return 0; } diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c index e3994fafd9d6..5e92fbba53c3 100644 --- a/drivers/mxc/ipu3/ipu_disp.c +++ b/drivers/mxc/ipu3/ipu_disp.c @@ -31,15 +31,6 @@ #include "ipu_regs.h" #include "ipu_param_mem.h" -enum csc_type_t { - RGB2YUV = 0, - YUV2RGB, - RGB2RGB, - YUV2YUV, - CSC_NONE, - CSC_NUM -}; - struct dp_csc_param_t { int mode; void *coeff; @@ -54,9 +45,8 @@ struct dp_csc_param_t { #define DC_DISP_ID_ASYNC 3 int dmfc_type_setup; -static int dmfc_size_28, dmfc_size_29, dmfc_size_24, dmfc_size_27, dmfc_size_23; -void _ipu_dmfc_init(int dmfc_type, int first) +void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first) { u32 dmfc_wr_chan, dmfc_dp_chan; @@ -67,9 +57,9 @@ void _ipu_dmfc_init(int dmfc_type, int first) dmfc_type_setup = dmfc_type; /* disable DMFC-IC channel*/ - __raw_writel(0x2, DMFC_IC_CTRL); + ipu_dmfc_write(ipu, 0x2, DMFC_IC_CTRL); } else if (dmfc_type_setup >= DMFC_HIGH_RESOLUTION_DC) { - printk(KERN_DEBUG "DMFC high resolution has set, will not change\n"); + dev_dbg(ipu->dev, "DMFC high resolution has set, will not change\n"); return; } else dmfc_type_setup = dmfc_type; @@ -80,61 +70,61 @@ void _ipu_dmfc_init(int dmfc_type, int first) * 5F - segement 6, 7; * 1C, 2C and 6B, 6F unused; */ - printk(KERN_INFO "IPU DMFC DC HIGH RESOLUTION: 1(0~3), 5B(4,5), 5F(6,7)\n"); + dev_info(ipu->dev, "IPU DMFC DC HIGH RESOLUTION: 1(0~3), 5B(4,5), 5F(6,7)\n"); dmfc_wr_chan = 0x00000088; dmfc_dp_chan = 0x00009694; - dmfc_size_28 = 256*4; - dmfc_size_29 = 0; - dmfc_size_24 = 0; - dmfc_size_27 = 128*4; - dmfc_size_23 = 128*4; + ipu->dmfc_size_28 = 256*4; + ipu->dmfc_size_29 = 0; + ipu->dmfc_size_24 = 0; + ipu->dmfc_size_27 = 128*4; + ipu->dmfc_size_23 = 128*4; } else if (dmfc_type == DMFC_HIGH_RESOLUTION_DP) { /* 1 - segment 0, 1; * 5B - segement 2~5; * 5F - segement 6,7; * 1C, 2C and 6B, 6F unused; */ - printk(KERN_INFO "IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)\n"); + dev_info(ipu->dev, "IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)\n"); dmfc_wr_chan = 0x00000090; dmfc_dp_chan = 0x0000968a; - dmfc_size_28 = 128*4; - dmfc_size_29 = 0; - dmfc_size_24 = 0; - dmfc_size_27 = 128*4; - dmfc_size_23 = 256*4; + ipu->dmfc_size_28 = 128*4; + ipu->dmfc_size_29 = 0; + ipu->dmfc_size_24 = 0; + ipu->dmfc_size_27 = 128*4; + ipu->dmfc_size_23 = 256*4; } else if (dmfc_type == DMFC_HIGH_RESOLUTION_ONLY_DP) { /* 5B - segement 0~3; * 5F - segement 4~7; * 1, 1C, 2C and 6B, 6F unused; */ - printk(KERN_INFO "IPU DMFC ONLY-DP HIGH RESOLUTION: 5B(0~3), 5F(4~7)\n"); + dev_info(ipu->dev, "IPU DMFC ONLY-DP HIGH RESOLUTION: 5B(0~3), 5F(4~7)\n"); dmfc_wr_chan = 0x00000000; dmfc_dp_chan = 0x00008c88; - dmfc_size_28 = 0; - dmfc_size_29 = 0; - dmfc_size_24 = 0; - dmfc_size_27 = 256*4; - dmfc_size_23 = 256*4; + ipu->dmfc_size_28 = 0; + ipu->dmfc_size_29 = 0; + ipu->dmfc_size_24 = 0; + ipu->dmfc_size_27 = 256*4; + ipu->dmfc_size_23 = 256*4; } else { /* 1 - segment 0, 1; * 5B - segement 4, 5; * 5F - segement 6, 7; * 1C, 2C and 6B, 6F unused; */ - printk(KERN_INFO "IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)\n"); + dev_info(ipu->dev, "IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)\n"); dmfc_wr_chan = 0x00000090; dmfc_dp_chan = 0x00009694; - dmfc_size_28 = 128*4; - dmfc_size_29 = 0; - dmfc_size_24 = 0; - dmfc_size_27 = 128*4; - dmfc_size_23 = 128*4; + ipu->dmfc_size_28 = 128*4; + ipu->dmfc_size_29 = 0; + ipu->dmfc_size_24 = 0; + ipu->dmfc_size_27 = 128*4; + ipu->dmfc_size_23 = 128*4; } - __raw_writel(dmfc_wr_chan, DMFC_WR_CHAN); - __raw_writel(0x202020F6, DMFC_WR_CHAN_DEF); - __raw_writel(dmfc_dp_chan, DMFC_DP_CHAN); + ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN); + ipu_dmfc_write(ipu, 0x202020F6, DMFC_WR_CHAN_DEF); + ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN); /* Enable chan 5 watermark set at 5 bursts and clear at 7 bursts */ - __raw_writel(0x2020F6F6, DMFC_DP_CHAN_DEF); + ipu_dmfc_write(ipu, 0x2020F6F6, DMFC_DP_CHAN_DEF); } static int __init dmfc_setup(char *options) @@ -146,51 +136,51 @@ static int __init dmfc_setup(char *options) } __setup("dmfc=", dmfc_setup); -void _ipu_dmfc_set_wait4eot(int dma_chan, int width) +void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width) { - u32 dmfc_gen1 = __raw_readl(DMFC_GENERAL1); + u32 dmfc_gen1 = ipu_dmfc_read(ipu, DMFC_GENERAL1); if (width >= HIGH_RESOLUTION_WIDTH) { if (dma_chan == 23) - _ipu_dmfc_init(DMFC_HIGH_RESOLUTION_DP, 0); + _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DP, 0); else if (dma_chan == 28) - _ipu_dmfc_init(DMFC_HIGH_RESOLUTION_DC, 0); + _ipu_dmfc_init(ipu, DMFC_HIGH_RESOLUTION_DC, 0); } if (dma_chan == 23) { /*5B*/ - if (dmfc_size_23/width > 3) + if (ipu->dmfc_size_23/width > 3) dmfc_gen1 |= 1UL << 20; else dmfc_gen1 &= ~(1UL << 20); } else if (dma_chan == 24) { /*6B*/ - if (dmfc_size_24/width > 1) + if (ipu->dmfc_size_24/width > 1) dmfc_gen1 |= 1UL << 22; else dmfc_gen1 &= ~(1UL << 22); } else if (dma_chan == 27) { /*5F*/ - if (dmfc_size_27/width > 2) + if (ipu->dmfc_size_27/width > 2) dmfc_gen1 |= 1UL << 21; else dmfc_gen1 &= ~(1UL << 21); } else if (dma_chan == 28) { /*1*/ - if (dmfc_size_28/width > 2) + if (ipu->dmfc_size_28/width > 2) dmfc_gen1 |= 1UL << 16; else dmfc_gen1 &= ~(1UL << 16); } else if (dma_chan == 29) { /*6F*/ - if (dmfc_size_29/width > 1) + if (ipu->dmfc_size_29/width > 1) dmfc_gen1 |= 1UL << 23; else dmfc_gen1 &= ~(1UL << 23); } - __raw_writel(dmfc_gen1, DMFC_GENERAL1); + ipu_dmfc_write(ipu, dmfc_gen1, DMFC_GENERAL1); } -void _ipu_dmfc_set_burst_size(int dma_chan, int burst_size) +void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size) { - u32 dmfc_wr_chan = __raw_readl(DMFC_WR_CHAN); - u32 dmfc_dp_chan = __raw_readl(DMFC_DP_CHAN); + u32 dmfc_wr_chan = ipu_dmfc_read(ipu, DMFC_WR_CHAN); + u32 dmfc_dp_chan = ipu_dmfc_read(ipu, DMFC_DP_CHAN); int dmfc_bs = 0; switch (burst_size) { @@ -205,7 +195,7 @@ void _ipu_dmfc_set_burst_size(int dma_chan, int burst_size) dmfc_bs = 0xc0; break; default: - dev_err(g_ipu_dev, "Unsupported burst size %d\n", + dev_err(ipu->dev, "Unsupported burst size %d\n", burst_size); return; } @@ -221,34 +211,36 @@ void _ipu_dmfc_set_burst_size(int dma_chan, int burst_size) dmfc_wr_chan |= dmfc_bs; } - __raw_writel(dmfc_wr_chan, DMFC_WR_CHAN); - __raw_writel(dmfc_dp_chan, DMFC_DP_CHAN); + ipu_dmfc_write(ipu, dmfc_wr_chan, DMFC_WR_CHAN); + ipu_dmfc_write(ipu, dmfc_dp_chan, DMFC_DP_CHAN); } -static void _ipu_di_data_wave_config(int di, - int wave_gen, - int access_size, int component_size) +static void _ipu_di_data_wave_config(struct ipu_soc *ipu, + int di, int wave_gen, + int access_size, int component_size) { u32 reg; reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) | (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET); - __raw_writel(reg, DI_DW_GEN(di, wave_gen)); + ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen)); } -static void _ipu_di_data_pin_config(int di, int wave_gen, int di_pin, int set, - int up, int down) +static void _ipu_di_data_pin_config(struct ipu_soc *ipu, + int di, int wave_gen, int di_pin, int set, + int up, int down) { u32 reg; - reg = __raw_readl(DI_DW_GEN(di, wave_gen)); + reg = ipu_di_read(ipu, di, DI_DW_GEN(wave_gen)); reg &= ~(0x3 << (di_pin * 2)); reg |= set << (di_pin * 2); - __raw_writel(reg, DI_DW_GEN(di, wave_gen)); + ipu_di_write(ipu, di, reg, DI_DW_GEN(wave_gen)); - __raw_writel((down << 16) | up, DI_DW_SET(di, wave_gen, set)); + ipu_di_write(ipu, di, (down << 16) | up, DI_DW_SET(wave_gen, set)); } -static void _ipu_di_sync_config(int di, int wave_gen, +static void _ipu_di_sync_config(struct ipu_soc *ipu, + int di, int wave_gen, int run_count, int run_src, int offset_count, int offset_src, int repeat_count, int cnt_clr_src, @@ -261,13 +253,13 @@ static void _ipu_di_sync_config(int di, int wave_gen, if ((run_count >= 0x1000) || (offset_count >= 0x1000) || (repeat_count >= 0x1000) || (cnt_up >= 0x400) || (cnt_down >= 0x400)) { - dev_err(g_ipu_dev, "DI%d counters out of range.\n", di); + dev_err(ipu->dev, "DI%d counters out of range.\n", di); return; } reg = (run_count << 19) | (++run_src << 16) | (offset_count << 3) | ++offset_src; - __raw_writel(reg, DI_SW_GEN0(di, wave_gen)); + ipu_di_write(ipu, di, reg, DI_SW_GEN0(wave_gen)); reg = (cnt_polarity_gen_en << 29) | (++cnt_clr_src << 25) | (++cnt_polarity_trigger_src << 12) | (++cnt_polarity_clr_src << 9); reg |= (cnt_down << 16) | cnt_up; @@ -275,17 +267,18 @@ static void _ipu_di_sync_config(int di, int wave_gen, /* Enable auto reload */ reg |= 0x10000000; } - __raw_writel(reg, DI_SW_GEN1(di, wave_gen)); - reg = __raw_readl(DI_STP_REP(di, wave_gen)); + ipu_di_write(ipu, di, reg, DI_SW_GEN1(wave_gen)); + reg = ipu_di_read(ipu, di, DI_STP_REP(wave_gen)); reg &= ~(0xFFFF << (16 * ((wave_gen - 1) & 0x1))); reg |= repeat_count << (16 * ((wave_gen - 1) & 0x1)); - __raw_writel(reg, DI_STP_REP(di, wave_gen)); + ipu_di_write(ipu, di, reg, DI_STP_REP(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) +static void _ipu_dc_map_link(struct ipu_soc *ipu, + 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; @@ -294,37 +287,39 @@ static void _ipu_dc_map_link(int current_map, u32 reg; ptr = (ptr_2 << 10) + (ptr_1 << 5) + ptr_0; - reg = __raw_readl(DC_MAP_CONF_PTR(current_map)); + reg = ipu_dc_read(ipu, 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)); + ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(current_map)); } -static void _ipu_dc_map_config(int map, int byte_num, int offset, int mask) +static void _ipu_dc_map_config(struct ipu_soc *ipu, + int map, int byte_num, int offset, int mask) { int ptr = map * 3 + byte_num; u32 reg; - reg = __raw_readl(DC_MAP_CONF_VAL(ptr)); + reg = ipu_dc_read(ipu, DC_MAP_CONF_VAL(ptr)); reg &= ~(0xFFFF << (16 * (ptr & 0x1))); reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1)); - __raw_writel(reg, DC_MAP_CONF_VAL(ptr)); + ipu_dc_write(ipu, reg, DC_MAP_CONF_VAL(ptr)); - reg = __raw_readl(DC_MAP_CONF_PTR(map)); + reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map)); reg &= ~(0x1F << ((16 * (map & 0x1)) + (5 * byte_num))); reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num)); - __raw_writel(reg, DC_MAP_CONF_PTR(map)); + ipu_dc_write(ipu, reg, DC_MAP_CONF_PTR(map)); } -static void _ipu_dc_map_clear(int map) +static void _ipu_dc_map_clear(struct ipu_soc *ipu, int map) { - u32 reg = __raw_readl(DC_MAP_CONF_PTR(map)); - __raw_writel(reg & ~(0xFFFF << (16 * (map & 0x1))), + u32 reg = ipu_dc_read(ipu, DC_MAP_CONF_PTR(map)); + ipu_dc_write(ipu, reg & ~(0xFFFF << (16 * (map & 0x1))), DC_MAP_CONF_PTR(map)); } -static void _ipu_dc_write_tmpl(int word, u32 opcode, u32 operand, int map, - int wave, int glue, int sync, int stop) +static void _ipu_dc_write_tmpl(struct ipu_soc *ipu, + int word, u32 opcode, u32 operand, int map, + int wave, int glue, int sync, int stop) { u32 reg; @@ -333,38 +328,39 @@ static void _ipu_dc_write_tmpl(int word, u32 opcode, u32 operand, int map, reg |= (glue << 4); reg |= (++wave << 11); reg |= ((operand & 0x1FFFF) << 15); - __raw_writel(reg, ipu_dc_tmpl_reg + word * 2); + ipu_dc_tmpl_write(ipu, reg, word * 2); reg = (operand >> 17); reg |= opcode << 7; reg |= (stop << 9); - __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1); + ipu_dc_tmpl_write(ipu, 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); + ipu_dc_tmpl_write(ipu, reg, word * 2); reg = (operand >> 12); reg |= opcode << 4; reg |= (stop << 9); - __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1); + ipu_dc_tmpl_write(ipu, reg, word * 2 + 1); } } -static void _ipu_dc_link_event(int chan, int event, int addr, int priority) +static void _ipu_dc_link_event(struct ipu_soc *ipu, + int chan, int event, int addr, int priority) { u32 reg; u32 address_shift; if (event < DC_EVEN_UGDE0) { - reg = __raw_readl(DC_RL_CH(chan, event)); + reg = ipu_dc_read(ipu, 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)); + ipu_dc_write(ipu, reg, DC_RL_CH(chan, event)); } else { - reg = __raw_readl(DC_UGDE_0((event - DC_EVEN_UGDE0) / 2)); + reg = ipu_dc_read(ipu, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2)); if ((event - DC_EVEN_UGDE0) & 0x1) { reg &= ~(0x2FF << 16); reg |= (addr << 16); @@ -379,7 +375,7 @@ static void _ipu_dc_link_event(int chan, int event, int addr, int priority) 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)); + ipu_dc_write(ipu, reg, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2)); } } @@ -438,49 +434,48 @@ static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = { {{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, {0, 0}, {0, 0}, {0, 0} } }; -static enum csc_type_t fg_csc_type = CSC_NONE, bg_csc_type = CSC_NONE; -static int color_key_4rgb = 1; - -void __ipu_dp_csc_setup(int dp, struct dp_csc_param_t dp_csc_param, - bool srm_mode_update) +void __ipu_dp_csc_setup(struct ipu_soc *ipu, + int dp, struct dp_csc_param_t dp_csc_param, + bool srm_mode_update) { u32 reg; const int (*coeff)[5][3]; if (dp_csc_param.mode >= 0) { - reg = __raw_readl(DP_COM_CONF(dp)); + reg = ipu_dp_read(ipu, DP_COM_CONF(dp)); reg &= ~DP_COM_CONF_CSC_DEF_MASK; reg |= dp_csc_param.mode; - __raw_writel(reg, DP_COM_CONF(dp)); + ipu_dp_write(ipu, reg, DP_COM_CONF(dp)); } coeff = dp_csc_param.coeff; if (coeff) { - __raw_writel(mask_a((*coeff)[0][0]) | + ipu_dp_write(ipu, mask_a((*coeff)[0][0]) | (mask_a((*coeff)[0][1]) << 16), DP_CSC_A_0(dp)); - __raw_writel(mask_a((*coeff)[0][2]) | + ipu_dp_write(ipu, mask_a((*coeff)[0][2]) | (mask_a((*coeff)[1][0]) << 16), DP_CSC_A_1(dp)); - __raw_writel(mask_a((*coeff)[1][1]) | + ipu_dp_write(ipu, mask_a((*coeff)[1][1]) | (mask_a((*coeff)[1][2]) << 16), DP_CSC_A_2(dp)); - __raw_writel(mask_a((*coeff)[2][0]) | + ipu_dp_write(ipu, mask_a((*coeff)[2][0]) | (mask_a((*coeff)[2][1]) << 16), DP_CSC_A_3(dp)); - __raw_writel(mask_a((*coeff)[2][2]) | + ipu_dp_write(ipu, mask_a((*coeff)[2][2]) | (mask_b((*coeff)[3][0]) << 16) | ((*coeff)[4][0] << 30), DP_CSC_0(dp)); - __raw_writel(mask_b((*coeff)[3][1]) | ((*coeff)[4][1] << 14) | + ipu_dp_write(ipu, mask_b((*coeff)[3][1]) | ((*coeff)[4][1] << 14) | (mask_b((*coeff)[3][2]) << 16) | ((*coeff)[4][2] << 30), DP_CSC_1(dp)); } if (srm_mode_update) { - reg = __raw_readl(IPU_SRM_PRI2) | 0x8; - __raw_writel(reg, IPU_SRM_PRI2); + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8; + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); } } -int _ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt, - uint32_t out_pixel_fmt) +int _ipu_dp_init(struct ipu_soc *ipu, + ipu_channel_t channel, uint32_t in_pixel_fmt, + uint32_t out_pixel_fmt) { int in_fmt, out_fmt; int dp; @@ -506,41 +501,41 @@ int _ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt, if (partial) { if (in_fmt == RGB) { if (out_fmt == RGB) - fg_csc_type = RGB2RGB; + ipu->fg_csc_type = RGB2RGB; else - fg_csc_type = RGB2YUV; + ipu->fg_csc_type = RGB2YUV; } else { if (out_fmt == RGB) - fg_csc_type = YUV2RGB; + ipu->fg_csc_type = YUV2RGB; else - fg_csc_type = YUV2YUV; + ipu->fg_csc_type = YUV2YUV; } } else { if (in_fmt == RGB) { if (out_fmt == RGB) - bg_csc_type = RGB2RGB; + ipu->bg_csc_type = RGB2RGB; else - bg_csc_type = RGB2YUV; + ipu->bg_csc_type = RGB2YUV; } else { if (out_fmt == RGB) - bg_csc_type = YUV2RGB; + ipu->bg_csc_type = YUV2RGB; else - bg_csc_type = YUV2YUV; + ipu->bg_csc_type = YUV2YUV; } } /* Transform color key from rgb to yuv if CSC is enabled */ - reg = __raw_readl(DP_COM_CONF(dp)); - if (color_key_4rgb && (reg & DP_COM_CONF_GWCKE) && - (((fg_csc_type == RGB2YUV) && (bg_csc_type == YUV2YUV)) || - ((fg_csc_type == YUV2YUV) && (bg_csc_type == RGB2YUV)) || - ((fg_csc_type == YUV2YUV) && (bg_csc_type == YUV2YUV)) || - ((fg_csc_type == YUV2RGB) && (bg_csc_type == YUV2RGB)))) { + reg = ipu_dp_read(ipu, DP_COM_CONF(dp)); + if (ipu->color_key_4rgb && (reg & DP_COM_CONF_GWCKE) && + (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) || + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) || + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) || + ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB)))) { int red, green, blue; int y, u, v; - uint32_t color_key = __raw_readl(DP_GRAPH_WIND_CTRL(dp)) & 0xFFFFFFL; + uint32_t color_key = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFFFFFFL; - dev_dbg(g_ipu_dev, "_ipu_dp_init color key 0x%x need change to yuv fmt!\n", color_key); + dev_dbg(ipu->dev, "_ipu_dp_init color key 0x%x need change to yuv fmt!\n", color_key); red = (color_key >> 16) & 0xFF; green = (color_key >> 8) & 0xFF; @@ -551,19 +546,19 @@ int _ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt, v = _rgb_to_yuv(2, red, green, blue); color_key = (y << 16) | (u << 8) | v; - reg = __raw_readl(DP_GRAPH_WIND_CTRL(dp)) & 0xFF000000L; - __raw_writel(reg | color_key, DP_GRAPH_WIND_CTRL(dp)); - color_key_4rgb = 0; + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(dp)) & 0xFF000000L; + ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(dp)); + ipu->color_key_4rgb = false; - dev_dbg(g_ipu_dev, "_ipu_dp_init color key change to yuv fmt 0x%x!\n", color_key); + dev_dbg(ipu->dev, "_ipu_dp_init color key change to yuv fmt 0x%x!\n", color_key); } - __ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], true); + __ipu_dp_csc_setup(ipu, dp, dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type], true); return 0; } -void _ipu_dp_uninit(ipu_channel_t channel) +void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel) { int dp; int partial = false; @@ -582,53 +577,53 @@ void _ipu_dp_uninit(ipu_channel_t channel) } if (partial) - fg_csc_type = CSC_NONE; + ipu->fg_csc_type = CSC_NONE; else - bg_csc_type = CSC_NONE; + ipu->bg_csc_type = CSC_NONE; - __ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], false); + __ipu_dp_csc_setup(ipu, dp, dp_csc_array[ipu->bg_csc_type][ipu->fg_csc_type], false); } -void _ipu_dc_init(int dc_chan, int di, bool interlaced, uint32_t pixel_fmt) +void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt) { u32 reg = 0; if ((dc_chan == 1) || (dc_chan == 5)) { if (interlaced) { - _ipu_dc_link_event(dc_chan, DC_EVT_NL, 0, 3); - _ipu_dc_link_event(dc_chan, DC_EVT_EOL, 0, 2); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 0, 1); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 3); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 2); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 1); } else { if (di) { - _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); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 2, 3); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 3, 2); + _ipu_dc_link_event(ipu, 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); + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 9, 5); + _ipu_dc_link_event(ipu, 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); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 5, 3); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 6, 2); + _ipu_dc_link_event(ipu, 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(ipu, dc_chan, DC_ODD_UGDE0, 10, 5); + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 11, 5); } } } - _ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NFIELD, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_EOF, 0, 0); - _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(ipu, dc_chan, DC_EVT_NF, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0); reg = 0x2; reg |= DC_DISP_ID_SYNC(di) << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET; @@ -637,63 +632,63 @@ void _ipu_dc_init(int dc_chan, int di, bool interlaced, uint32_t pixel_fmt) reg |= DC_WR_CH_CONF_FIELD_MODE; } else if ((dc_chan == 8) || (dc_chan == 9)) { /* async channels */ - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_0, 0x64, 1); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_1, 0x64, 1); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0x64, 1); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0x64, 1); reg = 0x3; reg |= DC_DISP_ID_SERIAL << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET; } - __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan)); - __raw_writel(0x00000000, DC_WR_CH_ADDR(dc_chan)); + ipu_dc_write(ipu, 0x00000000, DC_WR_CH_ADDR(dc_chan)); - __raw_writel(0x00000084, DC_GEN); + ipu_dc_write(ipu, 0x00000084, DC_GEN); } -void _ipu_dc_uninit(int dc_chan) +void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan) { if ((dc_chan == 1) || (dc_chan == 5)) { - _ipu_dc_link_event(dc_chan, DC_EVT_NL, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_EOL, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NFIELD, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_EOF, 0, 0); - _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); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NL, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOL, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NF, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NFIELD, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOF, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_EOFIELD, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE0, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVEN_UGDE0, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_ODD_UGDE1, 0, 0); + _ipu_dc_link_event(ipu, 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); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_W_0, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_W_1, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_0, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_1, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_R_0, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_R_1, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_R_0, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_R_1, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_R_0, 0, 0); - _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_R_1, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_0, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_W_1, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_0, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_W_1, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_0, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_ADDR_R_1, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_0, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_CHAN_R_1, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_0, 0, 0); + _ipu_dc_link_event(ipu, dc_chan, DC_EVT_NEW_DATA_R_1, 0, 0); } } -int _ipu_disp_chan_is_interlaced(ipu_channel_t channel) +int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel) { if (channel == MEM_DC_SYNC) - return !!(__raw_readl(DC_WR_CH_CONF_1) & + return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_1) & DC_WR_CH_CONF_FIELD_MODE); else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC)) - return !!(__raw_readl(DC_WR_CH_CONF_5) & + return !!(ipu_dc_read(ipu, DC_WR_CH_CONF_5) & DC_WR_CH_CONF_FIELD_MODE); return 0; } -void _ipu_dp_dc_enable(ipu_channel_t channel) +void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel) { int di; uint32_t reg; @@ -711,36 +706,35 @@ void _ipu_dp_dc_enable(ipu_channel_t channel) if (channel == MEM_FG_SYNC) { /* Enable FG channel */ - reg = __raw_readl(DP_COM_CONF(DP_SYNC)); - __raw_writel(reg | DP_COM_CONF_FG_EN, DP_COM_CONF(DP_SYNC)); + reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC)); + ipu_dp_write(ipu, reg | DP_COM_CONF_FG_EN, DP_COM_CONF(DP_SYNC)); - reg = __raw_readl(IPU_SRM_PRI2) | 0x8; - __raw_writel(reg, IPU_SRM_PRI2); + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8; + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); return; } - di = g_dc_di_assignment[dc_chan]; + di = ipu->dc_di_assignment[dc_chan]; /* Make sure other DC sync channel is not assigned same DI */ - reg = __raw_readl(DC_WR_CH_CONF(6 - dc_chan)); + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(6 - dc_chan)); if ((di << 2) == (reg & DC_WR_CH_CONF_PROG_DI_ID)) { reg &= ~DC_WR_CH_CONF_PROG_DI_ID; reg |= di ? 0 : DC_WR_CH_CONF_PROG_DI_ID; - __raw_writel(reg, DC_WR_CH_CONF(6 - dc_chan)); + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan)); } - reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan)); reg |= 4 << DC_WR_CH_CONF_PROG_TYPE_OFFSET; - __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan)); - clk_enable(g_pixel_clk[di]); + clk_enable(&ipu->pixel_clk[di]); } -static bool dc_swap; - static irqreturn_t dc_irq_handler(int irq, void *dev_id) { - struct completion *comp = dev_id; + struct ipu_soc *ipu = dev_id; + struct completion *comp = &ipu->dc_comp; uint32_t reg; uint32_t dc_chan; @@ -749,24 +743,24 @@ static irqreturn_t dc_irq_handler(int irq, void *dev_id) else dc_chan = 5; - if (!dc_swap) { - reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); + if (!ipu->dc_swap) { + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan)); reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; - __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan)); - reg = __raw_readl(IPU_DISP_GEN); - if (g_dc_di_assignment[dc_chan]) + reg = ipu_cm_read(ipu, IPU_DISP_GEN); + if (ipu->dc_di_assignment[dc_chan]) reg &= ~DI1_COUNTER_RELEASE; else reg &= ~DI0_COUNTER_RELEASE; - __raw_writel(reg, IPU_DISP_GEN); + ipu_cm_write(ipu, reg, IPU_DISP_GEN); } complete(comp); return IRQ_HANDLED; } -void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap) +void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap) { int ret; unsigned long lock_flags; @@ -775,9 +769,8 @@ void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap) uint32_t dc_chan; int irq = 0; int timeout = 50; - DECLARE_COMPLETION_ONSTACK(dc_comp); - dc_swap = swap; + ipu->dc_swap = swap; if (channel == MEM_DC_SYNC) { dc_chan = 1; @@ -789,24 +782,24 @@ void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap) /* Disable FG channel */ dc_chan = 5; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - reg = __raw_readl(DP_COM_CONF(DP_SYNC)); + reg = ipu_dp_read(ipu, DP_COM_CONF(DP_SYNC)); csc = reg & DP_COM_CONF_CSC_DEF_MASK; if (csc == DP_COM_CONF_CSC_DEF_FG) reg &= ~DP_COM_CONF_CSC_DEF_MASK; reg &= ~DP_COM_CONF_FG_EN; - __raw_writel(reg, DP_COM_CONF(DP_SYNC)); + ipu_dp_write(ipu, reg, DP_COM_CONF(DP_SYNC)); - reg = __raw_readl(IPU_SRM_PRI2) | 0x8; - __raw_writel(reg, IPU_SRM_PRI2); + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8; + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); - __raw_writel(IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END), + ipu_cm_write(ipu, IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END), IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END)); - while ((__raw_readl(IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END)) & + while ((ipu_cm_read(ipu, IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END)) & IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END)) == 0) { msleep(2); timeout -= 2; @@ -818,113 +811,99 @@ void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap) return; } - if (!dc_swap) - __raw_writel(IPUIRQ_2_MASK(IPU_IRQ_VSYNC_PRE_0 - + g_dc_di_assignment[dc_chan]), - IPUIRQ_2_STATREG(IPU_IRQ_VSYNC_PRE_0 - + g_dc_di_assignment[dc_chan])); - ipu_clear_irq(irq); - ret = ipu_request_irq(irq, dc_irq_handler, 0, NULL, &dc_comp); + init_completion(&ipu->dc_comp); + ipu_clear_irq(ipu, irq); + ret = ipu_request_irq(ipu, irq, dc_irq_handler, 0, NULL, ipu); if (ret < 0) { - dev_err(g_ipu_dev, "DC irq %d in use\n", irq); + dev_err(ipu->dev, "DC irq %d in use\n", irq); return; } - ret = wait_for_completion_timeout(&dc_comp, msecs_to_jiffies(50)); - - dev_dbg(g_ipu_dev, "DC stop timeout - %d * 10ms\n", 5 - ret); - ipu_free_irq(irq, &dc_comp); + ret = wait_for_completion_timeout(&ipu->dc_comp, msecs_to_jiffies(50)); + ipu_free_irq(ipu, irq, ipu); + dev_dbg(ipu->dev, "DC stop timeout - %d * 10ms\n", 5 - ret); - if (dc_swap) { - spin_lock_irqsave(&ipu_lock, lock_flags); + if (ipu->dc_swap) { + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); /* Swap DC channel 1 and 5 settings, and disable old dc chan */ - reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); - __raw_writel(reg, DC_WR_CH_CONF(6 - dc_chan)); + reg = ipu_dc_read(ipu, DC_WR_CH_CONF(dc_chan)); + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(6 - dc_chan)); reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; reg ^= DC_WR_CH_CONF_PROG_DI_ID; - __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); - spin_unlock_irqrestore(&ipu_lock, lock_flags); - } else { + ipu_dc_write(ipu, reg, DC_WR_CH_CONF(dc_chan)); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + } else /* 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]]); - - if (__raw_readl(IPUIRQ_2_STATREG(IPU_IRQ_VSYNC_PRE_0 - + g_dc_di_assignment[dc_chan])) & - IPUIRQ_2_MASK(IPU_IRQ_VSYNC_PRE_0 - + g_dc_di_assignment[dc_chan])) - dev_dbg(g_ipu_dev, - "VSyncPre occurred before DI%d disable\n", - g_dc_di_assignment[dc_chan]); - } + clk_disable(&ipu->pixel_clk[ipu->dc_di_assignment[dc_chan]]); } -void _ipu_init_dc_mappings(void) +void _ipu_init_dc_mappings(struct ipu_soc *ipu) { /* IPU_PIX_FMT_RGB24 */ - _ipu_dc_map_clear(0); - _ipu_dc_map_config(0, 0, 7, 0xFF); - _ipu_dc_map_config(0, 1, 15, 0xFF); - _ipu_dc_map_config(0, 2, 23, 0xFF); + _ipu_dc_map_clear(ipu, 0); + _ipu_dc_map_config(ipu, 0, 0, 7, 0xFF); + _ipu_dc_map_config(ipu, 0, 1, 15, 0xFF); + _ipu_dc_map_config(ipu, 0, 2, 23, 0xFF); /* IPU_PIX_FMT_RGB666 */ - _ipu_dc_map_clear(1); - _ipu_dc_map_config(1, 0, 5, 0xFC); - _ipu_dc_map_config(1, 1, 11, 0xFC); - _ipu_dc_map_config(1, 2, 17, 0xFC); + _ipu_dc_map_clear(ipu, 1); + _ipu_dc_map_config(ipu, 1, 0, 5, 0xFC); + _ipu_dc_map_config(ipu, 1, 1, 11, 0xFC); + _ipu_dc_map_config(ipu, 1, 2, 17, 0xFC); /* IPU_PIX_FMT_YUV444 */ - _ipu_dc_map_clear(2); - _ipu_dc_map_config(2, 0, 15, 0xFF); - _ipu_dc_map_config(2, 1, 23, 0xFF); - _ipu_dc_map_config(2, 2, 7, 0xFF); + _ipu_dc_map_clear(ipu, 2); + _ipu_dc_map_config(ipu, 2, 0, 15, 0xFF); + _ipu_dc_map_config(ipu, 2, 1, 23, 0xFF); + _ipu_dc_map_config(ipu, 2, 2, 7, 0xFF); /* IPU_PIX_FMT_RGB565 */ - _ipu_dc_map_clear(3); - _ipu_dc_map_config(3, 0, 4, 0xF8); - _ipu_dc_map_config(3, 1, 10, 0xFC); - _ipu_dc_map_config(3, 2, 15, 0xF8); + _ipu_dc_map_clear(ipu, 3); + _ipu_dc_map_config(ipu, 3, 0, 4, 0xF8); + _ipu_dc_map_config(ipu, 3, 1, 10, 0xFC); + _ipu_dc_map_config(ipu, 3, 2, 15, 0xF8); /* IPU_PIX_FMT_LVDS666 */ - _ipu_dc_map_clear(4); - _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_dc_map_clear(ipu, 4); + _ipu_dc_map_config(ipu, 4, 0, 5, 0xFC); + _ipu_dc_map_config(ipu, 4, 1, 13, 0xFC); + _ipu_dc_map_config(ipu, 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_dc_map_clear(ipu, 5); + _ipu_dc_map_config(ipu, 5, 0, 7, 0xFF); + _ipu_dc_map_config(ipu, 5, 1, 0, 0x0); + _ipu_dc_map_config(ipu, 5, 2, 15, 0xFF); + _ipu_dc_map_clear(ipu, 6); + _ipu_dc_map_config(ipu, 6, 0, 0, 0x0); + _ipu_dc_map_config(ipu, 6, 1, 7, 0xFF); + _ipu_dc_map_config(ipu, 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_dc_map_clear(ipu, 7); + _ipu_dc_map_link(ipu, 7, 6, 0, 6, 1, 6, 2); + _ipu_dc_map_clear(ipu, 8); + _ipu_dc_map_link(ipu, 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_dc_map_clear(ipu, 9); + _ipu_dc_map_link(ipu, 9, 5, 2, 5, 1, 5, 0); + _ipu_dc_map_clear(ipu, 10); + _ipu_dc_map_link(ipu, 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); + _ipu_dc_map_clear(ipu, 11); + _ipu_dc_map_link(ipu, 11, 5, 1, 5, 2, 5, 0); + _ipu_dc_map_clear(ipu, 12); + _ipu_dc_map_link(ipu, 12, 5, 2, 5, 1, 5, 0); /* IPU_PIX_FMT_GBR24 */ - _ipu_dc_map_clear(13); - _ipu_dc_map_link(13, 0, 2, 0, 0, 0, 1); + _ipu_dc_map_clear(ipu, 13); + _ipu_dc_map_link(ipu, 13, 0, 2, 0, 0, 0, 1); /* IPU_PIX_FMT_BGR24 */ - _ipu_dc_map_clear(14); - _ipu_dc_map_link(14, 0, 2, 0, 1, 0, 0); + _ipu_dc_map_clear(ipu, 14); + _ipu_dc_map_link(ipu, 14, 0, 2, 0, 1, 0, 0); } int _ipu_pixfmt_to_map(uint32_t fmt) @@ -962,6 +941,7 @@ int _ipu_pixfmt_to_map(uint32_t fmt) * This function sets the colorspace for of dp. * modes. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param param If it's not NULL, update the csc table @@ -969,7 +949,7 @@ int _ipu_pixfmt_to_map(uint32_t fmt) * * @return N/A */ -void _ipu_dp_set_csc_coefficients(ipu_channel_t channel, int32_t param[][3]) +void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]) { int dp; struct dp_csc_param_t dp_csc_param; @@ -985,14 +965,14 @@ void _ipu_dp_set_csc_coefficients(ipu_channel_t channel, int32_t param[][3]) dp_csc_param.mode = -1; dp_csc_param.coeff = param; - __ipu_dp_csc_setup(dp, dp_csc_param, true); + __ipu_dp_csc_setup(ipu, dp, dp_csc_param, true); } /*! * This function is called to adapt synchronous LCD panel to IPU restriction. * */ -void adapt_panel_to_ipu_restricitions(uint16_t *v_start_width, +void adapt_panel_to_ipu_restricitions(struct ipu_soc *ipu, uint16_t *v_start_width, uint16_t *v_sync_width, uint16_t *v_end_width) { @@ -1005,14 +985,15 @@ void adapt_panel_to_ipu_restricitions(uint16_t *v_start_width, *v_end_width = 2; *v_sync_width = *v_sync_width - diff; } else - dev_err(g_ipu_dev, "WARNING: try to adapt timming, but failed\n"); - dev_err(g_ipu_dev, "WARNING: adapt panel end blank lines\n"); + dev_err(ipu->dev, "WARNING: try to adapt timming, but failed\n"); + dev_err(ipu->dev, "WARNING: adapt panel end blank lines\n"); } } /*! * This function is called to initialize a synchronous LCD panel. * + * @param ipu ipu handler * @param disp The DI the panel is attached to. * * @param pixel_clk Desired pixel clock frequency in Hz. @@ -1046,7 +1027,7 @@ void adapt_panel_to_ipu_restricitions(uint16_t *v_start_width, * @return This function returns 0 on success or negative error code on * fail. */ -int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, +int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp, uint32_t pixel_clk, uint16_t width, uint16_t height, uint32_t pixel_fmt, uint16_t h_start_width, uint16_t h_sync_width, @@ -1064,234 +1045,239 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, int map; struct clk *di_parent; - dev_dbg(g_ipu_dev, "panel size = %d x %d\n", width, height); + dev_dbg(ipu->dev, "panel size = %d x %d\n", width, height); if ((v_sync_width == 0) || (h_sync_width == 0)) return EINVAL; - adapt_panel_to_ipu_restricitions(&v_start_width, &v_sync_width, &v_end_width); + adapt_panel_to_ipu_restricitions(ipu, &v_start_width, &v_sync_width, &v_end_width); h_total = width + h_sync_width + h_start_width + h_end_width; v_total = height + v_sync_width + v_start_width + v_end_width; /* Init clocking */ - dev_dbg(g_ipu_dev, "pixel clk = %d\n", pixel_clk); - - /*clear DI*/ - __raw_writel((1 << 21), DI_GENERAL(disp)); + dev_dbg(ipu->dev, "pixel clk = %d\n", pixel_clk); - di_parent = clk_get_parent(g_di_clk[disp]); + di_parent = clk_get_parent(ipu->di_clk[disp]); if (clk_get(NULL, "tve_clk") == di_parent || clk_get(NULL, "ldb_di0_clk") == di_parent || clk_get(NULL, "ldb_di1_clk") == di_parent) { /* if di clk parent is tve/ldb, then keep it;*/ - dev_dbg(g_ipu_dev, "use special clk parent\n"); - clk_set_parent(g_pixel_clk[disp], g_di_clk[disp]); + dev_dbg(ipu->dev, "use special clk parent\n"); + clk_set_parent(&ipu->pixel_clk[disp], ipu->di_clk[disp]); } else { /* try ipu clk first*/ - dev_dbg(g_ipu_dev, "try ipu internal clk\n"); - clk_set_parent(g_pixel_clk[disp], g_ipu_clk); - rounded_pixel_clk = clk_round_rate(g_pixel_clk[disp], pixel_clk); + dev_dbg(ipu->dev, "try ipu internal clk\n"); + clk_set_parent(&ipu->pixel_clk[disp], ipu->ipu_clk); + rounded_pixel_clk = clk_round_rate(&ipu->pixel_clk[disp], pixel_clk); /* * we will only use 1/2 fraction for ipu clk, * so if the clk rate is not fit, try ext clk. */ if (!sig.int_clk && - ((rounded_pixel_clk >= pixel_clk + pixel_clk/16) || - (rounded_pixel_clk <= pixel_clk - pixel_clk/16))) { - dev_dbg(g_ipu_dev, "try ipu ext di clk\n"); - 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); - rounded_pixel_clk = - clk_round_rate(g_di_clk[disp], pixel_clk); - clk_set_rate(g_di_clk[disp], rounded_pixel_clk); - clk_set_parent(g_pixel_clk[disp], g_di_clk[disp]); + ((rounded_pixel_clk >= pixel_clk + pixel_clk/200) || + (rounded_pixel_clk <= pixel_clk - pixel_clk/200))) { + dev_dbg(ipu->dev, "try ipu ext di clk\n"); + if (clk_get_usecount(di_parent)) + dev_warn(ipu->dev, + "ext di clk already in use, go back to internal clk\n"); + else { + 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); + rounded_pixel_clk = + clk_round_rate(ipu->di_clk[disp], pixel_clk); + clk_set_rate(ipu->di_clk[disp], rounded_pixel_clk); + clk_set_parent(&ipu->pixel_clk[disp], ipu->di_clk[disp]); + } } } - rounded_pixel_clk = clk_round_rate(g_pixel_clk[disp], pixel_clk); - clk_set_rate(g_pixel_clk[disp], rounded_pixel_clk); + rounded_pixel_clk = clk_round_rate(&ipu->pixel_clk[disp], pixel_clk); + clk_set_rate(&ipu->pixel_clk[disp], rounded_pixel_clk); msleep(5); /* Get integer portion of divider */ - div = clk_get_rate(clk_get_parent(g_pixel_clk[disp])) / rounded_pixel_clk; + div = clk_get_rate(clk_get_parent(&ipu->pixel_clk[disp])) / rounded_pixel_clk; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - _ipu_di_data_wave_config(disp, SYNC_WAVE, div - 1, div - 1); - _ipu_di_data_pin_config(disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2); + _ipu_di_data_wave_config(ipu, disp, SYNC_WAVE, div - 1, div - 1); + _ipu_di_data_pin_config(ipu, disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2); map = _ipu_pixfmt_to_map(pixel_fmt); if (map < 0) { - dev_dbg(g_ipu_dev, "IPU_DISP: No MAP\n"); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + dev_dbg(ipu->dev, "IPU_DISP: No MAP\n"); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return -EINVAL; } - di_gen = __raw_readl(DI_GENERAL(disp)); + /*clear DI*/ + di_gen = ipu_di_read(ipu, disp, DI_GENERAL); + ipu_di_write(ipu, disp, + di_gen & (0x3 << 20), DI_GENERAL); if (sig.interlaced) { if (g_ipu_hw_rev >= 2) { /* Setup internal HSYNC waveform */ - _ipu_di_sync_config( - disp, /* display */ - 1, /* counter */ + _ipu_di_sync_config(ipu, + disp, /* display */ + 1, /* counter */ h_total/2 - 1, /* run count */ - DI_SYNC_CLK, /* run_resolution */ - 0, /* offset */ + DI_SYNC_CLK, /* run_resolution */ + 0, /* offset */ DI_SYNC_NONE, /* offset resolution */ - 0, /* repeat count */ + 0, /* repeat count */ DI_SYNC_NONE, /* CNT_CLR_SEL */ - 0, /* CNT_POLARITY_GEN_EN */ + 0, /* CNT_POLARITY_GEN_EN */ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */ - 0, /* COUNT UP */ - 0 /* COUNT DOWN */ + 0, /* COUNT UP */ + 0 /* COUNT DOWN */ ); /* Field 1 VSYNC waveform */ - _ipu_di_sync_config( - disp, /* display */ - 2, /* counter */ - h_total - 1, /* run count */ - DI_SYNC_CLK, /* run_resolution */ - 0, /* offset */ + _ipu_di_sync_config(ipu, + disp, /* display */ + 2, /* counter */ + h_total - 1, /* run count */ + DI_SYNC_CLK, /* run_resolution */ + 0, /* offset */ DI_SYNC_NONE, /* offset resolution */ - 0, /* repeat count */ + 0, /* repeat count */ DI_SYNC_NONE, /* CNT_CLR_SEL */ - 0, /* CNT_POLARITY_GEN_EN */ + 0, /* CNT_POLARITY_GEN_EN */ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */ - 0, /* COUNT UP */ - 2*div /* COUNT DOWN */ + 0, /* COUNT UP */ + 2*div /* COUNT DOWN */ ); /* Setup internal HSYNC waveform */ - _ipu_di_sync_config( - disp, /* display */ - 3, /* counter */ + _ipu_di_sync_config(ipu, + disp, /* display */ + 3, /* counter */ v_total*2 - 1, /* run count */ DI_SYNC_INT_HSYNC, /* run_resolution */ - 1, /* offset */ + 1, /* offset */ DI_SYNC_INT_HSYNC, /* offset resolution */ - 0, /* repeat count */ + 0, /* repeat count */ DI_SYNC_NONE, /* CNT_CLR_SEL */ - 0, /* CNT_POLARITY_GEN_EN */ + 0, /* CNT_POLARITY_GEN_EN */ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */ - 0, /* COUNT UP */ - 2*div /* COUNT DOWN */ + 0, /* COUNT UP */ + 2*div /* COUNT DOWN */ ); /* Active Field ? */ - _ipu_di_sync_config( - disp, /* display */ - 4, /* counter */ + _ipu_di_sync_config(ipu, + disp, /* display */ + 4, /* counter */ v_total/2 - 1, /* run count */ DI_SYNC_HSYNC, /* run_resolution */ v_start_width, /* offset */ DI_SYNC_HSYNC, /* offset resolution */ - 2, /* repeat count */ + 2, /* repeat count */ DI_SYNC_VSYNC, /* CNT_CLR_SEL */ - 0, /* CNT_POLARITY_GEN_EN */ + 0, /* CNT_POLARITY_GEN_EN */ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */ - 0, /* COUNT UP */ - 0 /* COUNT DOWN */ + 0, /* COUNT UP */ + 0 /* COUNT DOWN */ ); /* Active Line */ - _ipu_di_sync_config( - disp, /* display */ - 5, /* counter */ - 0, /* run count */ + _ipu_di_sync_config(ipu, + disp, /* display */ + 5, /* counter */ + 0, /* run count */ DI_SYNC_HSYNC, /* run_resolution */ - 0, /* offset */ + 0, /* offset */ DI_SYNC_NONE, /* offset resolution */ - height/2, /* repeat count */ - 4, /* CNT_CLR_SEL */ - 0, /* CNT_POLARITY_GEN_EN */ + height/2, /* repeat count */ + 4, /* CNT_CLR_SEL */ + 0, /* CNT_POLARITY_GEN_EN */ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */ - 0, /* COUNT UP */ - 0 /* COUNT DOWN */ + 0, /* COUNT UP */ + 0 /* COUNT DOWN */ ); /* Field 0 VSYNC waveform */ - _ipu_di_sync_config( - disp, /* display */ - 6, /* counter */ + _ipu_di_sync_config(ipu, + disp, /* display */ + 6, /* counter */ v_total - 1, /* run count */ DI_SYNC_HSYNC, /* run_resolution */ - 0, /* offset */ + 0, /* offset */ DI_SYNC_NONE, /* offset resolution */ - 0, /* repeat count */ + 0, /* repeat count */ DI_SYNC_NONE, /* CNT_CLR_SEL */ - 0, /* CNT_POLARITY_GEN_EN */ + 0, /* CNT_POLARITY_GEN_EN */ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */ - 0, /* COUNT UP */ - 0 /* COUNT DOWN */ + 0, /* COUNT UP */ + 0 /* COUNT DOWN */ ); /* DC VSYNC waveform */ vsync_cnt = 7; - _ipu_di_sync_config( - disp, /* display */ - 7, /* counter */ + _ipu_di_sync_config(ipu, + disp, /* display */ + 7, /* counter */ v_total/2 - 1, /* run count */ DI_SYNC_HSYNC, /* run_resolution */ - 9, /* offset */ + 9, /* offset */ DI_SYNC_HSYNC, /* offset resolution */ - 2, /* repeat count */ + 2, /* repeat count */ DI_SYNC_VSYNC, /* CNT_CLR_SEL */ - 0, /* CNT_POLARITY_GEN_EN */ + 0, /* CNT_POLARITY_GEN_EN */ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */ - 0, /* COUNT UP */ - 0 /* COUNT DOWN */ + 0, /* COUNT UP */ + 0 /* COUNT DOWN */ ); /* active pixel waveform */ - _ipu_di_sync_config( - disp, /* display */ - 8, /* counter */ - 0, /* run count */ + _ipu_di_sync_config(ipu, + disp, /* display */ + 8, /* counter */ + 0, /* run count */ DI_SYNC_CLK, /* run_resolution */ - h_start_width, /* offset */ + h_start_width, /* offset */ DI_SYNC_CLK, /* offset resolution */ - width, /* repeat count */ - 5, /* CNT_CLR_SEL */ - 0, /* CNT_POLARITY_GEN_EN */ + width, /* repeat count */ + 5, /* CNT_CLR_SEL */ + 0, /* CNT_POLARITY_GEN_EN */ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */ - 0, /* COUNT UP */ - 0 /* COUNT DOWN */ + 0, /* COUNT UP */ + 0 /* COUNT DOWN */ ); /* Second VSYNC */ - _ipu_di_sync_config( - disp, /* display */ - 9, /* counter */ + _ipu_di_sync_config(ipu, + disp, /* display */ + 9, /* counter */ v_total - 1, /* run count */ DI_SYNC_INT_HSYNC, /* run_resolution */ - v_total/2, /* offset */ + v_total/2, /* offset */ DI_SYNC_INT_HSYNC, /* offset resolution */ - 0, /* repeat count */ + 0, /* repeat count */ DI_SYNC_HSYNC, /* CNT_CLR_SEL */ - 0, /* CNT_POLARITY_GEN_EN */ + 0, /* CNT_POLARITY_GEN_EN */ DI_SYNC_NONE, /* CNT_POLARITY_CLR_SEL */ DI_SYNC_NONE, /* CNT_POLARITY_TRIGGER_SEL */ - 0, /* COUNT UP */ - 2*div /* COUNT DOWN */ + 0, /* COUNT UP */ + 2*div /* COUNT DOWN */ ); /* set gentime select and tag sel */ - reg = __raw_readl(DI_SW_GEN1(disp, 9)); + reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9)); reg &= 0x1FFFFFFF; reg |= (3-1)<<29 | 0x00008000; - __raw_writel(reg, DI_SW_GEN1(disp, 9)); + ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9)); - __raw_writel(v_total / 2 - 1, DI_SCR_CONF(disp)); + ipu_di_write(ipu, disp, v_total / 2 - 1, DI_SCR_CONF); /* set y_sel = 1 */ di_gen |= 0x10000000; @@ -1299,7 +1285,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, di_gen |= DI_GEN_POLARITY_8; } else { /* Setup internal HSYNC waveform */ - _ipu_di_sync_config(disp, 1, h_total - 1, DI_SYNC_CLK, + _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); @@ -1312,65 +1298,65 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, v_total += v_start_width + v_end_width; /* Field 1 VSYNC waveform */ - _ipu_di_sync_config(disp, 2, v_total - 1, 1, + _ipu_di_sync_config(ipu, disp, 2, v_total - 1, 1, field0_offset, field0_offset ? 1 : DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 4); /* Setup internal HSYNC waveform */ - _ipu_di_sync_config(disp, 3, h_total - 1, DI_SYNC_CLK, + _ipu_di_sync_config(ipu, disp, 3, h_total - 1, DI_SYNC_CLK, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 4); /* Active Field ? */ - _ipu_di_sync_config(disp, 4, + _ipu_di_sync_config(ipu, disp, 4, field0_offset ? field0_offset : field1_offset - 2, 1, v_start_width + v_sync_width, 1, 2, 2, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); /* Active Line */ - _ipu_di_sync_config(disp, 5, 0, 1, + _ipu_di_sync_config(ipu, disp, 5, 0, 1, 0, DI_SYNC_NONE, height / 2, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); /* Field 0 VSYNC waveform */ - _ipu_di_sync_config(disp, 6, v_total - 1, 1, + _ipu_di_sync_config(ipu, disp, 6, v_total - 1, 1, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); /* DC VSYNC waveform */ vsync_cnt = 7; - _ipu_di_sync_config(disp, 7, 0, 1, + _ipu_di_sync_config(ipu, disp, 7, 0, 1, field1_offset, field1_offset ? 1 : DI_SYNC_NONE, 1, 2, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); /* active pixel waveform */ - _ipu_di_sync_config(disp, 8, 0, DI_SYNC_CLK, + _ipu_di_sync_config(ipu, disp, 8, 0, DI_SYNC_CLK, h_sync_width + h_start_width, DI_SYNC_CLK, width, 5, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); /* ??? */ - _ipu_di_sync_config(disp, 9, v_total - 1, 2, + _ipu_di_sync_config(ipu, disp, 9, v_total - 1, 2, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 6, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); - reg = __raw_readl(DI_SW_GEN1(disp, 9)); + reg = ipu_di_read(ipu, disp, DI_SW_GEN1(9)); reg |= 0x8000; - __raw_writel(reg, DI_SW_GEN1(disp, 9)); + ipu_di_write(ipu, disp, reg, DI_SW_GEN1(9)); - __raw_writel(v_sync_width + v_start_width + - v_end_width + height / 2 - 1, DI_SCR_CONF(disp)); + ipu_di_write(ipu, disp, v_sync_width + v_start_width + + v_end_width + height / 2 - 1, DI_SCR_CONF); } /* Init template microcode */ - _ipu_dc_write_tmpl(0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1); + _ipu_dc_write_tmpl(ipu, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1); if (sig.Hsync_pol) di_gen |= DI_GEN_POLARITY_3; @@ -1378,29 +1364,29 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, di_gen |= DI_GEN_POLARITY_2; } else { /* Setup internal HSYNC waveform */ - _ipu_di_sync_config(disp, 1, h_total - 1, DI_SYNC_CLK, + _ipu_di_sync_config(ipu, disp, 1, h_total - 1, DI_SYNC_CLK, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); /* Setup external (delayed) HSYNC waveform */ - _ipu_di_sync_config(disp, DI_SYNC_HSYNC, h_total - 1, + _ipu_di_sync_config(ipu, disp, DI_SYNC_HSYNC, h_total - 1, DI_SYNC_CLK, div * v_to_h_sync, DI_SYNC_CLK, 0, DI_SYNC_NONE, 1, DI_SYNC_NONE, DI_SYNC_CLK, 0, h_sync_width * 2); /* Setup VSYNC waveform */ vsync_cnt = DI_SYNC_VSYNC; - _ipu_di_sync_config(disp, DI_SYNC_VSYNC, v_total - 1, + _ipu_di_sync_config(ipu, disp, DI_SYNC_VSYNC, v_total - 1, DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 1, DI_SYNC_NONE, DI_SYNC_INT_HSYNC, 0, v_sync_width * 2); - __raw_writel(v_total - 1, DI_SCR_CONF(disp)); + ipu_di_write(ipu, disp, v_total - 1, DI_SCR_CONF); /* Setup active data waveform to sync with DC */ - _ipu_di_sync_config(disp, 4, 0, DI_SYNC_HSYNC, + _ipu_di_sync_config(ipu, disp, 4, 0, DI_SYNC_HSYNC, v_sync_width + v_start_width, DI_SYNC_HSYNC, height, DI_SYNC_VSYNC, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); - _ipu_di_sync_config(disp, 5, 0, DI_SYNC_CLK, + _ipu_di_sync_config(ipu, disp, 5, 0, DI_SYNC_CLK, h_sync_width + h_start_width, DI_SYNC_CLK, width, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); @@ -1408,7 +1394,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, /* set VGA delayed hsync/vsync no matter VGA enabled */ if (disp) { /* couter 7 for VGA delay HSYNC */ - _ipu_di_sync_config(disp, 7, + _ipu_di_sync_config(ipu, disp, 7, h_total - 1, DI_SYNC_CLK, 18, DI_SYNC_CLK, 0, DI_SYNC_NONE, @@ -1416,7 +1402,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, 0, h_sync_width * 2); /* couter 8 for VGA delay VSYNC */ - _ipu_di_sync_config(disp, 8, + _ipu_di_sync_config(ipu, disp, 8, v_total - 1, DI_SYNC_INT_HSYNC, 1, DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE, @@ -1425,23 +1411,23 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, } /* reset all unused counters */ - __raw_writel(0, DI_SW_GEN0(disp, 6)); - __raw_writel(0, DI_SW_GEN1(disp, 6)); + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(6)); + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(6)); if (!disp) { - __raw_writel(0, DI_SW_GEN0(disp, 7)); - __raw_writel(0, DI_SW_GEN1(disp, 7)); - __raw_writel(0, DI_STP_REP(disp, 7)); - __raw_writel(0, DI_SW_GEN0(disp, 8)); - __raw_writel(0, DI_SW_GEN1(disp, 8)); - __raw_writel(0, DI_STP_REP(disp, 8)); + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(7)); + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(7)); + ipu_di_write(ipu, disp, 0, DI_STP_REP(7)); + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(8)); + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(8)); + ipu_di_write(ipu, disp, 0, DI_STP_REP(8)); } - __raw_writel(0, DI_SW_GEN0(disp, 9)); - __raw_writel(0, DI_SW_GEN1(disp, 9)); - __raw_writel(0, DI_STP_REP(disp, 9)); + ipu_di_write(ipu, disp, 0, DI_SW_GEN0(9)); + ipu_di_write(ipu, disp, 0, DI_SW_GEN1(9)); + ipu_di_write(ipu, disp, 0, DI_STP_REP(9)); - reg = __raw_readl(DI_STP_REP(disp, 6)); + reg = ipu_di_read(ipu, disp, DI_STP_REP(6)); reg &= 0x0000FFFF; - __raw_writel(reg, DI_STP_REP(disp, 6)); + ipu_di_write(ipu, disp, reg, DI_STP_REP(6)); /* Init template microcode */ if (disp) { @@ -1449,27 +1435,27 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, (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); + _ipu_dc_write_tmpl(ipu, 8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1); + _ipu_dc_write_tmpl(ipu, 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(ipu, (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); + _ipu_dc_write_tmpl(ipu, 2, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1); + _ipu_dc_write_tmpl(ipu, 3, WRG, 0, map, SYNC_WAVE, 4, 5, 1); + _ipu_dc_write_tmpl(ipu, 4, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1); } else { 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); + _ipu_dc_write_tmpl(ipu, 10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1); + _ipu_dc_write_tmpl(ipu, 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(ipu, 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); + _ipu_dc_write_tmpl(ipu, 5, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1); + _ipu_dc_write_tmpl(ipu, 6, WRG, 0, map, SYNC_WAVE, 4, 5, 1); + _ipu_dc_write_tmpl(ipu, 7, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1); } if (sig.Hsync_pol) { @@ -1493,54 +1479,57 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, if (!sig.clk_pol) di_gen |= DI_GEN_POLARITY_DISP_CLK; - __raw_writel(di_gen, DI_GENERAL(disp)); + ipu_di_write(ipu, disp, di_gen, DI_GENERAL); - __raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET) | - 0x00000002, DI_SYNC_AS_GEN(disp)); - reg = __raw_readl(DI_POL(disp)); + ipu_di_write(ipu, disp, (--vsync_cnt << DI_VSYNC_SEL_OFFSET) | + 0x00000002, DI_SYNC_AS_GEN); + reg = ipu_di_read(ipu, disp, DI_POL); reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15); if (sig.enable_pol) reg |= DI_POL_DRDY_POLARITY_15; if (sig.data_pol) reg |= DI_POL_DRDY_DATA_POLARITY; - __raw_writel(reg, DI_POL(disp)); + ipu_di_write(ipu, disp, reg, DI_POL); - __raw_writel(width, DC_DISP_CONF2(DC_DISP_ID_SYNC(disp))); + ipu_dc_write(ipu, width, DC_DISP_CONF2(DC_DISP_ID_SYNC(disp))); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } EXPORT_SYMBOL(ipu_init_sync_panel); -void ipu_uninit_sync_panel(int disp) +void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp) { unsigned long lock_flags; uint32_t reg; uint32_t di_gen; - spin_lock_irqsave(&ipu_lock, lock_flags); + if ((disp != 0) || (disp != 1)) + return; - di_gen = __raw_readl(DI_GENERAL(disp)); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); + + di_gen = ipu_di_read(ipu, disp, DI_GENERAL); di_gen |= 0x3ff | DI_GEN_POLARITY_DISP_CLK; - __raw_writel(di_gen, DI_GENERAL(disp)); + ipu_di_write(ipu, disp, di_gen, DI_GENERAL); - reg = __raw_readl(DI_POL(disp)); + reg = ipu_di_read(ipu, disp, DI_POL); reg |= 0x3ffffff; - __raw_writel(reg, DI_POL(disp)); + ipu_di_write(ipu, disp, reg, DI_POL); - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); } EXPORT_SYMBOL(ipu_uninit_sync_panel); -int ipu_init_async_panel(int disp, int type, uint32_t cycle_time, +int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time, uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig) { unsigned long lock_flags; int map; u32 ser_conf = 0; u32 div; - u32 di_clk = clk_get_rate(g_ipu_clk); + u32 di_clk = clk_get_rate(ipu->ipu_clk); /* round up cycle_time, then calcalate the divider using scaled math */ cycle_time += (1000000000UL / di_clk) - 1; @@ -1550,23 +1539,23 @@ int ipu_init_async_panel(int disp, int type, uint32_t cycle_time, if (map < 0) return -EINVAL; - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); if (type == IPU_PANEL_SERIAL) { - __raw_writel((div << 24) | ((sig.ifc_width - 1) << 4), - DI_DW_GEN(disp, ASYNC_SER_WAVE)); + ipu_di_write(ipu, disp, (div << 24) | ((sig.ifc_width - 1) << 4), + DI_DW_GEN(ASYNC_SER_WAVE)); - _ipu_di_data_pin_config(disp, ASYNC_SER_WAVE, DI_PIN_CS, + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_CS, 0, 0, (div * 2) + 1); - _ipu_di_data_pin_config(disp, ASYNC_SER_WAVE, DI_PIN_SER_CLK, + _ipu_di_data_pin_config(ipu, disp, ASYNC_SER_WAVE, DI_PIN_SER_CLK, 1, div, div * 2); - _ipu_di_data_pin_config(disp, ASYNC_SER_WAVE, DI_PIN_SER_RS, + _ipu_di_data_pin_config(ipu, 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, 1); + _ipu_dc_write_tmpl(ipu, 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)); + ipu_dc_write(ipu, 0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL)); if (sig.clk_pol) ser_conf |= DI_SER_CONF_SERIAL_CLK_POL; @@ -1576,10 +1565,10 @@ int ipu_init_async_panel(int disp, int type, uint32_t cycle_time, ser_conf |= DI_SER_CONF_SERIAL_RS_POL; if (sig.cs_pol) ser_conf |= DI_SER_CONF_SERIAL_CS_POL; - __raw_writel(ser_conf, DI_SER_CONF(disp)); + ipu_di_write(ipu, disp, ser_conf, DI_SER_CONF); } - spin_unlock_irqrestore(&ipu_lock, lock_flags); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); return 0; } EXPORT_SYMBOL(ipu_init_async_panel); @@ -1589,6 +1578,7 @@ EXPORT_SYMBOL(ipu_init_async_panel); * modes. This function also sets the DP graphic plane according to the * parameter of IPUv3 DP channel. * + * @param ipu ipu handler * @param channel IPUv3 DP channel * * @param enable Boolean to enable or disable global alpha @@ -1598,8 +1588,8 @@ EXPORT_SYMBOL(ipu_init_async_panel); * * @return Returns 0 on success or negative error code on fail */ -int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, bool enable, - uint8_t alpha) +int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel, + bool enable, uint8_t alpha) { uint32_t reg; uint32_t flow; @@ -1621,36 +1611,36 @@ int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, bool enable, else bg_chan = false; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); if (bg_chan) { - reg = __raw_readl(DP_COM_CONF(flow)); - __raw_writel(reg & ~DP_COM_CONF_GWSEL, DP_COM_CONF(flow)); + reg = ipu_dp_read(ipu, DP_COM_CONF(flow)); + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWSEL, DP_COM_CONF(flow)); } else { - reg = __raw_readl(DP_COM_CONF(flow)); - __raw_writel(reg | DP_COM_CONF_GWSEL, DP_COM_CONF(flow)); + reg = ipu_dp_read(ipu, DP_COM_CONF(flow)); + ipu_dp_write(ipu, reg | DP_COM_CONF_GWSEL, DP_COM_CONF(flow)); } if (enable) { - reg = __raw_readl(DP_GRAPH_WIND_CTRL(flow)) & 0x00FFFFFFL; - __raw_writel(reg | ((uint32_t) alpha << 24), + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0x00FFFFFFL; + ipu_dp_write(ipu, reg | ((uint32_t) alpha << 24), DP_GRAPH_WIND_CTRL(flow)); - reg = __raw_readl(DP_COM_CONF(flow)); - __raw_writel(reg | DP_COM_CONF_GWAM, DP_COM_CONF(flow)); + reg = ipu_dp_read(ipu, DP_COM_CONF(flow)); + ipu_dp_write(ipu, reg | DP_COM_CONF_GWAM, DP_COM_CONF(flow)); } else { - reg = __raw_readl(DP_COM_CONF(flow)); - __raw_writel(reg & ~DP_COM_CONF_GWAM, DP_COM_CONF(flow)); + reg = ipu_dp_read(ipu, DP_COM_CONF(flow)); + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWAM, DP_COM_CONF(flow)); } - reg = __raw_readl(IPU_SRM_PRI2) | 0x8; - __raw_writel(reg, IPU_SRM_PRI2); + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8; + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); - spin_unlock_irqrestore(&ipu_lock, lock_flags); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); return 0; } @@ -1659,6 +1649,7 @@ EXPORT_SYMBOL(ipu_disp_set_global_alpha); /*! * This function sets the transparent color key for SDC graphic plane. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param enable Boolean to enable or disable color key @@ -1667,8 +1658,8 @@ EXPORT_SYMBOL(ipu_disp_set_global_alpha); * * @return Returns 0 on success or negative error code on fail */ -int32_t ipu_disp_set_color_key(ipu_channel_t channel, bool enable, - uint32_t color_key) +int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel, + bool enable, uint32_t color_key) { uint32_t reg, flow; int y, u, v; @@ -1684,19 +1675,19 @@ int32_t ipu_disp_set_color_key(ipu_channel_t channel, bool enable, else return -EINVAL; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - color_key_4rgb = 1; + ipu->color_key_4rgb = true; /* Transform color key from rgb to yuv if CSC is enabled */ - if (((fg_csc_type == RGB2YUV) && (bg_csc_type == YUV2YUV)) || - ((fg_csc_type == YUV2YUV) && (bg_csc_type == RGB2YUV)) || - ((fg_csc_type == YUV2YUV) && (bg_csc_type == YUV2YUV)) || - ((fg_csc_type == YUV2RGB) && (bg_csc_type == YUV2RGB))) { + if (((ipu->fg_csc_type == RGB2YUV) && (ipu->bg_csc_type == YUV2YUV)) || + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == RGB2YUV)) || + ((ipu->fg_csc_type == YUV2YUV) && (ipu->bg_csc_type == YUV2YUV)) || + ((ipu->fg_csc_type == YUV2RGB) && (ipu->bg_csc_type == YUV2RGB))) { - dev_dbg(g_ipu_dev, "color key 0x%x need change to yuv fmt\n", color_key); + dev_dbg(ipu->dev, "color key 0x%x need change to yuv fmt\n", color_key); red = (color_key >> 16) & 0xFF; green = (color_key >> 8) & 0xFF; @@ -1707,28 +1698,28 @@ int32_t ipu_disp_set_color_key(ipu_channel_t channel, bool enable, v = _rgb_to_yuv(2, red, green, blue); color_key = (y << 16) | (u << 8) | v; - color_key_4rgb = 0; + ipu->color_key_4rgb = false; - dev_dbg(g_ipu_dev, "color key change to yuv fmt 0x%x\n", color_key); + dev_dbg(ipu->dev, "color key change to yuv fmt 0x%x\n", color_key); } if (enable) { - reg = __raw_readl(DP_GRAPH_WIND_CTRL(flow)) & 0xFF000000L; - __raw_writel(reg | color_key, DP_GRAPH_WIND_CTRL(flow)); + reg = ipu_dp_read(ipu, DP_GRAPH_WIND_CTRL(flow)) & 0xFF000000L; + ipu_dp_write(ipu, reg | color_key, DP_GRAPH_WIND_CTRL(flow)); - reg = __raw_readl(DP_COM_CONF(flow)); - __raw_writel(reg | DP_COM_CONF_GWCKE, DP_COM_CONF(flow)); + reg = ipu_dp_read(ipu, DP_COM_CONF(flow)); + ipu_dp_write(ipu, reg | DP_COM_CONF_GWCKE, DP_COM_CONF(flow)); } else { - reg = __raw_readl(DP_COM_CONF(flow)); - __raw_writel(reg & ~DP_COM_CONF_GWCKE, DP_COM_CONF(flow)); + reg = ipu_dp_read(ipu, DP_COM_CONF(flow)); + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GWCKE, DP_COM_CONF(flow)); } - reg = __raw_readl(IPU_SRM_PRI2) | 0x8; - __raw_writel(reg, IPU_SRM_PRI2); + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8; + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); - spin_unlock_irqrestore(&ipu_lock, lock_flags); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); return 0; } @@ -1737,6 +1728,7 @@ EXPORT_SYMBOL(ipu_disp_set_color_key); /*! * This function sets the gamma correction for DP output. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param enable Boolean to enable or disable gamma correction. @@ -1747,7 +1739,7 @@ EXPORT_SYMBOL(ipu_disp_set_color_key); * * @return Returns 0 on success or negative error code on fail */ -int32_t ipu_disp_set_gamma_correction(ipu_channel_t channel, bool enable, int constk[], int slopek[]) +int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable, int constk[], int slopek[]) { uint32_t reg, flow, i; unsigned long lock_flags; @@ -1761,32 +1753,32 @@ int32_t ipu_disp_set_gamma_correction(ipu_channel_t channel, bool enable, int co else return -EINVAL; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); for (i = 0; i < 8; i++) - __raw_writel((constk[2*i] & 0x1ff) | ((constk[2*i+1] & 0x1ff) << 16), DP_GAMMA_C(flow, i)); + ipu_dp_write(ipu, (constk[2*i] & 0x1ff) | ((constk[2*i+1] & 0x1ff) << 16), DP_GAMMA_C(flow, i)); for (i = 0; i < 4; i++) - __raw_writel((slopek[4*i] & 0xff) | ((slopek[4*i+1] & 0xff) << 8) | + ipu_dp_write(ipu, (slopek[4*i] & 0xff) | ((slopek[4*i+1] & 0xff) << 8) | ((slopek[4*i+2] & 0xff) << 16) | ((slopek[4*i+3] & 0xff) << 24), DP_GAMMA_S(flow, i)); - reg = __raw_readl(DP_COM_CONF(flow)); + reg = ipu_dp_read(ipu, DP_COM_CONF(flow)); if (enable) { - if ((bg_csc_type == RGB2YUV) || (bg_csc_type == YUV2YUV)) + if ((ipu->bg_csc_type == RGB2YUV) || (ipu->bg_csc_type == YUV2YUV)) reg |= DP_COM_CONF_GAMMA_YUV_EN; else reg &= ~DP_COM_CONF_GAMMA_YUV_EN; - __raw_writel(reg | DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow)); + ipu_dp_write(ipu, reg | DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow)); } else - __raw_writel(reg & ~DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow)); + ipu_dp_write(ipu, reg & ~DP_COM_CONF_GAMMA_EN, DP_COM_CONF(flow)); - reg = __raw_readl(IPU_SRM_PRI2) | 0x8; - __raw_writel(reg, IPU_SRM_PRI2); + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) | 0x8; + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); - spin_unlock_irqrestore(&ipu_lock, lock_flags); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); return 0; } @@ -1796,6 +1788,7 @@ EXPORT_SYMBOL(ipu_disp_set_gamma_correction); * This function sets the window position of the foreground or background plane. * modes. * + * @param ipu ipu handler * @param channel Input parameter for the logical channel ID. * * @param x_pos The X coordinate position to place window at. @@ -1806,8 +1799,8 @@ EXPORT_SYMBOL(ipu_disp_set_gamma_correction); * * @return Returns 0 on success or negative error code on fail */ -int32_t ipu_disp_set_window_pos(ipu_channel_t channel, int16_t x_pos, - int16_t y_pos) +int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, + int16_t x_pos, int16_t y_pos) { u32 reg; unsigned long lock_flags; @@ -1826,34 +1819,34 @@ int32_t ipu_disp_set_window_pos(ipu_channel_t channel, int16_t x_pos, } else return -EINVAL; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - __raw_writel((x_pos << 16) | y_pos, DP_FG_POS(flow)); + ipu_dp_write(ipu, (x_pos << 16) | y_pos, DP_FG_POS(flow)); - if (ipu_is_channel_busy(channel)) { + if (ipu_is_channel_busy(ipu, channel)) { /* controled by FSU if channel enabled */ - reg = __raw_readl(IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift)); + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift)); reg |= (0x1 << dp_srm_shift); - __raw_writel(reg, IPU_SRM_PRI2); + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); } else { /* disable auto swap, controled by MCU if channel disabled */ - reg = __raw_readl(IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift)); - __raw_writel(reg, IPU_SRM_PRI2); + reg = ipu_cm_read(ipu, IPU_SRM_PRI2) & (~(0x3 << dp_srm_shift)); + ipu_cm_write(ipu, reg, IPU_SRM_PRI2); } - spin_unlock_irqrestore(&ipu_lock, lock_flags); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); return 0; } 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) +int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, + int16_t *x_pos, int16_t *y_pos) { u32 reg; unsigned long lock_flags; @@ -1868,43 +1861,51 @@ int32_t ipu_disp_get_window_pos(ipu_channel_t channel, int16_t *x_pos, else return -EINVAL; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); - spin_lock_irqsave(&ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_enable(ipu->ipu_clk); + spin_lock_irqsave(&ipu->ipu_lock, lock_flags); - reg = __raw_readl(DP_FG_POS(flow)); + reg = ipu_dp_read(ipu, 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); + spin_unlock_irqrestore(&ipu->ipu_lock, lock_flags); + if (!ipu->clk_enabled) + clk_disable(ipu->ipu_clk); return 0; } EXPORT_SYMBOL(ipu_disp_get_window_pos); -void ipu_disp_direct_write(ipu_channel_t channel, u32 value, u32 offset) +void ipu_disp_direct_write(struct ipu_soc *ipu, ipu_channel_t channel, u32 value, u32 offset) { if (channel == DIRECT_ASYNC0) - __raw_writel(value, ipu_disp_base[0] + offset); + writel(value, ipu->disp_base[0] + offset); else if (channel == DIRECT_ASYNC1) - __raw_writel(value, ipu_disp_base[1] + offset); + writel(value, ipu->disp_base[1] + offset); } EXPORT_SYMBOL(ipu_disp_direct_write); -void ipu_reset_disp_panel(void) +void ipu_reset_disp_panel(struct ipu_soc *ipu) { uint32_t tmp; - tmp = __raw_readl(DI_GENERAL(1)); - __raw_writel(tmp | 0x08, DI_GENERAL(1)); + tmp = ipu_di_read(ipu, 1, DI_GENERAL); + ipu_di_write(ipu, 1, tmp | 0x08, DI_GENERAL); msleep(10); /* tRES >= 100us */ - tmp = __raw_readl(DI_GENERAL(1)); - __raw_writel(tmp & ~0x08, DI_GENERAL(1)); + tmp = ipu_di_read(ipu, 1, DI_GENERAL); + ipu_di_write(ipu, 1, tmp & ~0x08, DI_GENERAL); msleep(60); return; } EXPORT_SYMBOL(ipu_reset_disp_panel); + +void __devinit ipu_disp_init(struct ipu_soc *ipu) +{ + ipu->fg_csc_type = ipu->bg_csc_type = CSC_NONE; + ipu->color_key_4rgb = true; + _ipu_init_dc_mappings(ipu); + _ipu_dmfc_init(ipu, DMFC_NORMAL, 1); +} diff --git a/drivers/mxc/ipu3/ipu_ic.c b/drivers/mxc/ipu3/ipu_ic.c index 77a67bf8e9c8..27cf2d4bc8db 100644 --- a/drivers/mxc/ipu3/ipu_ic.c +++ b/drivers/mxc/ipu3/ipu_ic.c @@ -36,29 +36,30 @@ enum { IC_TASK_POST_PROCESSOR }; -static void _init_csc(uint8_t ic_task, ipu_color_space_t in_format, +static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format, ipu_color_space_t out_format, int csc_index); -static bool _calc_resize_coeffs(uint32_t inSize, uint32_t outSize, +static bool _calc_resize_coeffs(struct ipu_soc *ipu, + uint32_t inSize, uint32_t outSize, uint32_t *resizeCoeff, uint32_t *downsizeCoeff); -void _ipu_vdi_set_top_field_man(bool top_field_0) +void _ipu_vdi_set_top_field_man(struct ipu_soc *ipu, bool top_field_0) { uint32_t reg; - reg = __raw_readl(VDI_C); + reg = ipu_vdi_read(ipu, VDI_C); if (top_field_0) reg &= ~VDI_C_TOP_FIELD_MAN_1; else reg |= VDI_C_TOP_FIELD_MAN_1; - __raw_writel(reg, VDI_C); + ipu_vdi_write(ipu, reg, VDI_C); } -void _ipu_vdi_set_motion(ipu_motion_sel motion_sel) +void _ipu_vdi_set_motion(struct ipu_soc *ipu, ipu_motion_sel motion_sel) { uint32_t reg; - reg = __raw_readl(VDI_C); + reg = ipu_vdi_read(ipu, VDI_C); reg &= ~(VDI_C_MOT_SEL_FULL | VDI_C_MOT_SEL_MED | VDI_C_MOT_SEL_LOW); if (motion_sel == HIGH_MOTION) reg |= VDI_C_MOT_SEL_FULL; @@ -67,27 +68,27 @@ void _ipu_vdi_set_motion(ipu_motion_sel motion_sel) else reg |= VDI_C_MOT_SEL_LOW; - __raw_writel(reg, VDI_C); + ipu_vdi_write(ipu, reg, VDI_C); } -void ic_dump_register(void) +void ic_dump_register(struct ipu_soc *ipu) { - printk(KERN_DEBUG "IC_CONF = \t0x%08X\n", __raw_readl(IC_CONF)); + printk(KERN_DEBUG "IC_CONF = \t0x%08X\n", ipu_ic_read(ipu, IC_CONF)); printk(KERN_DEBUG "IC_PRP_ENC_RSC = \t0x%08X\n", - __raw_readl(IC_PRP_ENC_RSC)); + ipu_ic_read(ipu, IC_PRP_ENC_RSC)); printk(KERN_DEBUG "IC_PRP_VF_RSC = \t0x%08X\n", - __raw_readl(IC_PRP_VF_RSC)); - printk(KERN_DEBUG "IC_PP_RSC = \t0x%08X\n", __raw_readl(IC_PP_RSC)); - printk(KERN_DEBUG "IC_IDMAC_1 = \t0x%08X\n", __raw_readl(IC_IDMAC_1)); - printk(KERN_DEBUG "IC_IDMAC_2 = \t0x%08X\n", __raw_readl(IC_IDMAC_2)); - printk(KERN_DEBUG "IC_IDMAC_3 = \t0x%08X\n", __raw_readl(IC_IDMAC_3)); + ipu_ic_read(ipu, IC_PRP_VF_RSC)); + printk(KERN_DEBUG "IC_PP_RSC = \t0x%08X\n", ipu_ic_read(ipu, IC_PP_RSC)); + printk(KERN_DEBUG "IC_IDMAC_1 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_1)); + printk(KERN_DEBUG "IC_IDMAC_2 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_2)); + printk(KERN_DEBUG "IC_IDMAC_3 = \t0x%08X\n", ipu_ic_read(ipu, IC_IDMAC_3)); } -void _ipu_ic_enable_task(ipu_channel_t channel) +void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel) { uint32_t ic_conf; - ic_conf = __raw_readl(IC_CONF); + ic_conf = ipu_ic_read(ipu, IC_CONF); switch (channel) { case CSI_PRP_VF_MEM: case MEM_PRP_VF_MEM: @@ -115,14 +116,14 @@ void _ipu_ic_enable_task(ipu_channel_t channel) default: break; } - __raw_writel(ic_conf, IC_CONF); + ipu_ic_write(ipu, ic_conf, IC_CONF); } -void _ipu_ic_disable_task(ipu_channel_t channel) +void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel) { uint32_t ic_conf; - ic_conf = __raw_readl(IC_CONF); + ic_conf = ipu_ic_read(ipu, IC_CONF); switch (channel) { case CSI_PRP_VF_MEM: case MEM_PRP_VF_MEM: @@ -150,17 +151,17 @@ void _ipu_ic_disable_task(ipu_channel_t channel) default: break; } - __raw_writel(ic_conf, IC_CONF); + ipu_ic_write(ipu, ic_conf, IC_CONF); } -void _ipu_vdi_init(ipu_channel_t channel, ipu_channel_params_t *params) +void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params) { uint32_t reg; uint32_t pixel_fmt; reg = ((params->mem_prp_vf_mem.in_height-1) << 16) | (params->mem_prp_vf_mem.in_width-1); - __raw_writel(reg, VDI_FSIZE); + ipu_vdi_write(ipu, reg, VDI_FSIZE); /* Full motion, only vertical filter is used Burst size is 4 accesses */ @@ -172,7 +173,7 @@ void _ipu_vdi_init(ipu_channel_t channel, ipu_channel_params_t *params) else pixel_fmt = VDI_C_CH_420; - reg = __raw_readl(VDI_C); + reg = ipu_vdi_read(ipu, VDI_C); reg |= pixel_fmt; switch (channel) { case MEM_VDI_PRP_VF_MEM: @@ -187,34 +188,34 @@ void _ipu_vdi_init(ipu_channel_t channel, ipu_channel_params_t *params) default: break; } - __raw_writel(reg, VDI_C); + ipu_vdi_write(ipu, reg, VDI_C); if (params->mem_prp_vf_mem.field_fmt == V4L2_FIELD_INTERLACED_TB) - _ipu_vdi_set_top_field_man(false); + _ipu_vdi_set_top_field_man(ipu, false); else if (params->mem_prp_vf_mem.field_fmt == V4L2_FIELD_INTERLACED_BT) - _ipu_vdi_set_top_field_man(true); + _ipu_vdi_set_top_field_man(ipu, true); - _ipu_vdi_set_motion(params->mem_prp_vf_mem.motion_sel); + _ipu_vdi_set_motion(ipu, params->mem_prp_vf_mem.motion_sel); - reg = __raw_readl(IC_CONF); + reg = ipu_ic_read(ipu, IC_CONF); reg &= ~IC_CONF_RWS_EN; - __raw_writel(reg, IC_CONF); + ipu_ic_write(ipu, reg, IC_CONF); } -void _ipu_vdi_uninit(void) +void _ipu_vdi_uninit(struct ipu_soc *ipu) { - __raw_writel(0, VDI_FSIZE); - __raw_writel(0, VDI_C); + ipu_vdi_write(ipu, 0, VDI_FSIZE); + ipu_vdi_write(ipu, 0, VDI_C); } -void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi) +void _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params, bool src_is_csi) { uint32_t reg, ic_conf; uint32_t downsizeCoeff, resizeCoeff; ipu_color_space_t in_fmt, out_fmt; /* Setup vertical resizing */ - _calc_resize_coeffs(params->mem_prp_vf_mem.in_height, + _calc_resize_coeffs(ipu, params->mem_prp_vf_mem.in_height, params->mem_prp_vf_mem.out_height, &resizeCoeff, &downsizeCoeff); reg = (downsizeCoeff << 30) | (resizeCoeff << 16); @@ -222,16 +223,16 @@ 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.outh_resize_ratio)) { - _calc_resize_coeffs(params->mem_prp_vf_mem.in_width, + _calc_resize_coeffs(ipu, 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.outh_resize_ratio; - __raw_writel(reg, IC_PRP_VF_RSC); + ipu_ic_write(ipu, reg, IC_PRP_VF_RSC); - ic_conf = __raw_readl(IC_CONF); + ic_conf = ipu_ic_read(ipu, IC_CONF); /* Setup color space conversion */ in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_pixel_fmt); @@ -239,14 +240,14 @@ void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi) if (in_fmt == RGB) { if ((out_fmt == YCbCr) || (out_fmt == YUV)) { /* Enable RGB->YCBCR CSC1 */ - _init_csc(IC_TASK_VIEWFINDER, RGB, out_fmt, 1); + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 1); ic_conf |= IC_CONF_PRPVF_CSC1; } } if ((in_fmt == YCbCr) || (in_fmt == YUV)) { if (out_fmt == RGB) { /* Enable YCBCR->RGB CSC1 */ - _init_csc(IC_TASK_VIEWFINDER, YCbCr, RGB, 1); + _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 1); ic_conf |= IC_CONF_PRPVF_CSC1; } else { /* TODO: Support YUV<->YCbCr conversion? */ @@ -258,7 +259,7 @@ void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi) if (!(ic_conf & IC_CONF_PRPVF_CSC1)) { /* need transparent CSC1 conversion */ - _init_csc(IC_TASK_VIEWFINDER, RGB, RGB, 1); + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, RGB, 1); ic_conf |= IC_CONF_PRPVF_CSC1; /* Enable RGB->RGB CSC */ } in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_g_pixel_fmt); @@ -266,14 +267,14 @@ void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi) if (in_fmt == RGB) { if ((out_fmt == YCbCr) || (out_fmt == YUV)) { /* Enable RGB->YCBCR CSC2 */ - _init_csc(IC_TASK_VIEWFINDER, RGB, out_fmt, 2); + _init_csc(ipu, IC_TASK_VIEWFINDER, RGB, out_fmt, 2); ic_conf |= IC_CONF_PRPVF_CSC2; } } if ((in_fmt == YCbCr) || (in_fmt == YUV)) { if (out_fmt == RGB) { /* Enable YCBCR->RGB CSC2 */ - _init_csc(IC_TASK_VIEWFINDER, YCbCr, RGB, 2); + _init_csc(ipu, IC_TASK_VIEWFINDER, YCbCr, RGB, 2); ic_conf |= IC_CONF_PRPVF_CSC2; } else { /* TODO: Support YUV<->YCbCr conversion? */ @@ -282,16 +283,16 @@ void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi) if (params->mem_prp_vf_mem.global_alpha_en) { ic_conf |= IC_CONF_IC_GLB_LOC_A; - reg = __raw_readl(IC_CMBP_1); + reg = ipu_ic_read(ipu, IC_CMBP_1); reg &= ~(0xff); reg |= params->mem_prp_vf_mem.alpha; - __raw_writel(reg, IC_CMBP_1); + ipu_ic_write(ipu, reg, IC_CMBP_1); } else ic_conf &= ~IC_CONF_IC_GLB_LOC_A; if (params->mem_prp_vf_mem.key_color_en) { ic_conf |= IC_CONF_KEY_COLOR_EN; - __raw_writel(params->mem_prp_vf_mem.key_color, + ipu_ic_write(ipu, params->mem_prp_vf_mem.key_color, IC_CMBP_2); } else ic_conf &= ~IC_CONF_KEY_COLOR_EN; @@ -304,39 +305,39 @@ void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi) else ic_conf |= IC_CONF_RWS_EN; - __raw_writel(ic_conf, IC_CONF); + ipu_ic_write(ipu, ic_conf, IC_CONF); } -void _ipu_ic_uninit_prpvf(void) +void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu) { uint32_t reg; - reg = __raw_readl(IC_CONF); + reg = ipu_ic_read(ipu, IC_CONF); reg &= ~(IC_CONF_PRPVF_EN | IC_CONF_PRPVF_CMB | IC_CONF_PRPVF_CSC2 | IC_CONF_PRPVF_CSC1); - __raw_writel(reg, IC_CONF); + ipu_ic_write(ipu, reg, IC_CONF); } -void _ipu_ic_init_rotate_vf(ipu_channel_params_t *params) +void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params) { } -void _ipu_ic_uninit_rotate_vf(void) +void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu) { uint32_t reg; - reg = __raw_readl(IC_CONF); + reg = ipu_ic_read(ipu, IC_CONF); reg &= ~IC_CONF_PRPVF_ROT_EN; - __raw_writel(reg, IC_CONF); + ipu_ic_write(ipu, reg, IC_CONF); } -void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi) +void _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params, bool src_is_csi) { uint32_t reg, ic_conf; uint32_t downsizeCoeff, resizeCoeff; ipu_color_space_t in_fmt, out_fmt; /* Setup vertical resizing */ - _calc_resize_coeffs(params->mem_prp_enc_mem.in_height, + _calc_resize_coeffs(ipu, params->mem_prp_enc_mem.in_height, params->mem_prp_enc_mem.out_height, &resizeCoeff, &downsizeCoeff); reg = (downsizeCoeff << 30) | (resizeCoeff << 16); @@ -344,16 +345,16 @@ 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.outh_resize_ratio)) { - _calc_resize_coeffs(params->mem_prp_enc_mem.in_width, + _calc_resize_coeffs(ipu, 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.outh_resize_ratio; - __raw_writel(reg, IC_PRP_ENC_RSC); + ipu_ic_write(ipu, reg, IC_PRP_ENC_RSC); - ic_conf = __raw_readl(IC_CONF); + ic_conf = ipu_ic_read(ipu, IC_CONF); /* Setup color space conversion */ in_fmt = format_to_colorspace(params->mem_prp_enc_mem.in_pixel_fmt); @@ -361,14 +362,14 @@ void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi) if (in_fmt == RGB) { if ((out_fmt == YCbCr) || (out_fmt == YUV)) { /* Enable RGB->YCBCR CSC1 */ - _init_csc(IC_TASK_ENCODER, RGB, out_fmt, 1); + _init_csc(ipu, IC_TASK_ENCODER, RGB, out_fmt, 1); ic_conf |= IC_CONF_PRPENC_CSC1; } } if ((in_fmt == YCbCr) || (in_fmt == YUV)) { if (out_fmt == RGB) { /* Enable YCBCR->RGB CSC1 */ - _init_csc(IC_TASK_ENCODER, YCbCr, RGB, 1); + _init_csc(ipu, IC_TASK_ENCODER, YCbCr, RGB, 1); ic_conf |= IC_CONF_PRPENC_CSC1; } else { /* TODO: Support YUV<->YCbCr conversion? */ @@ -380,32 +381,32 @@ void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi) else ic_conf |= IC_CONF_RWS_EN; - __raw_writel(ic_conf, IC_CONF); + ipu_ic_write(ipu, ic_conf, IC_CONF); } -void _ipu_ic_uninit_prpenc(void) +void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu) { uint32_t reg; - reg = __raw_readl(IC_CONF); + reg = ipu_ic_read(ipu, IC_CONF); reg &= ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1); - __raw_writel(reg, IC_CONF); + ipu_ic_write(ipu, reg, IC_CONF); } -void _ipu_ic_init_rotate_enc(ipu_channel_params_t *params) +void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params) { } -void _ipu_ic_uninit_rotate_enc(void) +void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu) { uint32_t reg; - reg = __raw_readl(IC_CONF); + reg = ipu_ic_read(ipu, IC_CONF); reg &= ~(IC_CONF_PRPENC_ROT_EN); - __raw_writel(reg, IC_CONF); + ipu_ic_write(ipu, reg, IC_CONF); } -void _ipu_ic_init_pp(ipu_channel_params_t *params) +void _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params) { uint32_t reg, ic_conf; uint32_t downsizeCoeff, resizeCoeff; @@ -413,7 +414,7 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params) /* Setup vertical resizing */ if (!(params->mem_pp_mem.outv_resize_ratio)) { - _calc_resize_coeffs(params->mem_pp_mem.in_height, + _calc_resize_coeffs(ipu, params->mem_pp_mem.in_height, params->mem_pp_mem.out_height, &resizeCoeff, &downsizeCoeff); reg = (downsizeCoeff << 30) | (resizeCoeff << 16); @@ -424,7 +425,7 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params) /* Setup horizontal resizing */ /* Upadeted for IC split case */ if (!(params->mem_pp_mem.outh_resize_ratio)) { - _calc_resize_coeffs(params->mem_pp_mem.in_width, + _calc_resize_coeffs(ipu, params->mem_pp_mem.in_width, params->mem_pp_mem.out_width, &resizeCoeff, &downsizeCoeff); reg |= (downsizeCoeff << 14) | resizeCoeff; @@ -432,9 +433,9 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params) reg |= params->mem_pp_mem.outh_resize_ratio; } - __raw_writel(reg, IC_PP_RSC); + ipu_ic_write(ipu, reg, IC_PP_RSC); - ic_conf = __raw_readl(IC_CONF); + ic_conf = ipu_ic_read(ipu, IC_CONF); /* Setup color space conversion */ in_fmt = format_to_colorspace(params->mem_pp_mem.in_pixel_fmt); @@ -442,14 +443,14 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params) if (in_fmt == RGB) { if ((out_fmt == YCbCr) || (out_fmt == YUV)) { /* Enable RGB->YCBCR CSC1 */ - _init_csc(IC_TASK_POST_PROCESSOR, RGB, out_fmt, 1); + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 1); ic_conf |= IC_CONF_PP_CSC1; } } if ((in_fmt == YCbCr) || (in_fmt == YUV)) { if (out_fmt == RGB) { /* Enable YCBCR->RGB CSC1 */ - _init_csc(IC_TASK_POST_PROCESSOR, YCbCr, RGB, 1); + _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 1); ic_conf |= IC_CONF_PP_CSC1; } else { /* TODO: Support YUV<->YCbCr conversion? */ @@ -461,7 +462,7 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params) if (!(ic_conf & IC_CONF_PP_CSC1)) { /* need transparent CSC1 conversion */ - _init_csc(IC_TASK_POST_PROCESSOR, RGB, RGB, 1); + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, RGB, 1); ic_conf |= IC_CONF_PP_CSC1; /* Enable RGB->RGB CSC */ } @@ -470,14 +471,14 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params) if (in_fmt == RGB) { if ((out_fmt == YCbCr) || (out_fmt == YUV)) { /* Enable RGB->YCBCR CSC2 */ - _init_csc(IC_TASK_POST_PROCESSOR, RGB, out_fmt, 2); + _init_csc(ipu, IC_TASK_POST_PROCESSOR, RGB, out_fmt, 2); ic_conf |= IC_CONF_PP_CSC2; } } if ((in_fmt == YCbCr) || (in_fmt == YUV)) { if (out_fmt == RGB) { /* Enable YCBCR->RGB CSC2 */ - _init_csc(IC_TASK_POST_PROCESSOR, YCbCr, RGB, 2); + _init_csc(ipu, IC_TASK_POST_PROCESSOR, YCbCr, RGB, 2); ic_conf |= IC_CONF_PP_CSC2; } else { /* TODO: Support YUV<->YCbCr conversion? */ @@ -486,16 +487,16 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params) if (params->mem_pp_mem.global_alpha_en) { ic_conf |= IC_CONF_IC_GLB_LOC_A; - reg = __raw_readl(IC_CMBP_1); + reg = ipu_ic_read(ipu, IC_CMBP_1); reg &= ~(0xff00); reg |= (params->mem_pp_mem.alpha << 8); - __raw_writel(reg, IC_CMBP_1); + ipu_ic_write(ipu, reg, IC_CMBP_1); } else ic_conf &= ~IC_CONF_IC_GLB_LOC_A; if (params->mem_pp_mem.key_color_en) { ic_conf |= IC_CONF_KEY_COLOR_EN; - __raw_writel(params->mem_pp_mem.key_color, + ipu_ic_write(ipu, params->mem_pp_mem.key_color, IC_CMBP_2); } else ic_conf &= ~IC_CONF_KEY_COLOR_EN; @@ -503,40 +504,41 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params) ic_conf &= ~IC_CONF_PP_CMB; } - __raw_writel(ic_conf, IC_CONF); + ipu_ic_write(ipu, ic_conf, IC_CONF); } -void _ipu_ic_uninit_pp(void) +void _ipu_ic_uninit_pp(struct ipu_soc *ipu) { uint32_t reg; - reg = __raw_readl(IC_CONF); + reg = ipu_ic_read(ipu, IC_CONF); reg &= ~(IC_CONF_PP_EN | IC_CONF_PP_CSC1 | IC_CONF_PP_CSC2 | IC_CONF_PP_CMB); - __raw_writel(reg, IC_CONF); + ipu_ic_write(ipu, reg, IC_CONF); } -void _ipu_ic_init_rotate_pp(ipu_channel_params_t *params) +void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params) { } -void _ipu_ic_uninit_rotate_pp(void) +void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu) { uint32_t reg; - reg = __raw_readl(IC_CONF); + reg = ipu_ic_read(ipu, IC_CONF); reg &= ~IC_CONF_PP_ROT_EN; - __raw_writel(reg, IC_CONF); + ipu_ic_write(ipu, reg, IC_CONF); } -int _ipu_ic_idma_init(int dma_chan, uint16_t width, uint16_t height, - int burst_size, ipu_rotate_mode_t rot) +int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan, + uint16_t width, uint16_t height, + int burst_size, ipu_rotate_mode_t rot) { u32 ic_idmac_1, ic_idmac_2, ic_idmac_3; u32 temp_rot = bitrev8(rot) >> 5; bool need_hor_flip = false; if ((burst_size != 8) && (burst_size != 16)) { - dev_dbg(g_ipu_dev, "Illegal burst length for IC\n"); + dev_dbg(ipu->dev, "Illegal burst length for IC\n"); return -EINVAL; } @@ -546,9 +548,9 @@ int _ipu_ic_idma_init(int dma_chan, uint16_t width, uint16_t height, if (temp_rot & 0x2) /* Need horizontal flip */ need_hor_flip = true; - ic_idmac_1 = __raw_readl(IC_IDMAC_1); - ic_idmac_2 = __raw_readl(IC_IDMAC_2); - ic_idmac_3 = __raw_readl(IC_IDMAC_3); + ic_idmac_1 = ipu_ic_read(ipu, IC_IDMAC_1); + ic_idmac_2 = ipu_ic_read(ipu, IC_IDMAC_2); + ic_idmac_3 = ipu_ic_read(ipu, IC_IDMAC_3); if (dma_chan == 22) { /* PP output - CB2 */ if (burst_size == 16) ic_idmac_1 |= IC_IDMAC_1_CB2_BURST_16; @@ -565,7 +567,6 @@ int _ipu_ic_idma_init(int dma_chan, uint16_t width, uint16_t height, ic_idmac_3 &= ~IC_IDMAC_3_PP_WIDTH_MASK; ic_idmac_3 |= width << IC_IDMAC_3_PP_WIDTH_OFFSET; - } else if (dma_chan == 11) { /* PP Input - CB5 */ if (burst_size == 16) ic_idmac_1 |= IC_IDMAC_1_CB5_BURST_16; @@ -639,14 +640,14 @@ int _ipu_ic_idma_init(int dma_chan, uint16_t width, uint16_t height, ic_idmac_1 &= ~IC_IDMAC_1_CB4_BURST_16; } - __raw_writel(ic_idmac_1, IC_IDMAC_1); - __raw_writel(ic_idmac_2, IC_IDMAC_2); - __raw_writel(ic_idmac_3, IC_IDMAC_3); + ipu_ic_write(ipu, ic_idmac_1, IC_IDMAC_1); + ipu_ic_write(ipu, ic_idmac_2, IC_IDMAC_2); + ipu_ic_write(ipu, ic_idmac_3, IC_IDMAC_3); return 0; } -static void _init_csc(uint8_t ic_task, ipu_color_space_t in_format, +static void _init_csc(struct ipu_soc *ipu, uint8_t ic_task, ipu_color_space_t in_format, ipu_color_space_t out_format, int csc_index) { @@ -683,17 +684,17 @@ static void _init_csc(uint8_t ic_task, ipu_color_space_t in_format, uint32_t *base = NULL; if (ic_task == IC_TASK_ENCODER) { - base = ipu_tpmem_base + 0x2008 / 4; + base = ipu->tpmem_base + 0x2008 / 4; } else if (ic_task == IC_TASK_VIEWFINDER) { if (csc_index == 1) - base = ipu_tpmem_base + 0x4028 / 4; + base = ipu->tpmem_base + 0x4028 / 4; else - base = ipu_tpmem_base + 0x4040 / 4; + base = ipu->tpmem_base + 0x4040 / 4; } else if (ic_task == IC_TASK_POST_PROCESSOR) { if (csc_index == 1) - base = ipu_tpmem_base + 0x6060 / 4; + base = ipu->tpmem_base + 0x6060 / 4; else - base = ipu_tpmem_base + 0x6078 / 4; + base = ipu->tpmem_base + 0x6078 / 4; } else { BUG(); } @@ -703,76 +704,77 @@ static void _init_csc(uint8_t ic_task, ipu_color_space_t in_format, param = (ycbcr2rgb_coeff[3][0] << 27) | (ycbcr2rgb_coeff[0][0] << 18) | (ycbcr2rgb_coeff[1][1] << 9) | ycbcr2rgb_coeff[2][2]; - __raw_writel(param, base++); + writel(param, base++); /* scale = 2, sat = 0 */ param = (ycbcr2rgb_coeff[3][0] >> 5) | (2L << (40 - 32)); - __raw_writel(param, base++); + writel(param, base++); param = (ycbcr2rgb_coeff[3][1] << 27) | (ycbcr2rgb_coeff[0][1] << 18) | (ycbcr2rgb_coeff[1][0] << 9) | ycbcr2rgb_coeff[2][0]; - __raw_writel(param, base++); + writel(param, base++); param = (ycbcr2rgb_coeff[3][1] >> 5); - __raw_writel(param, base++); + writel(param, base++); param = (ycbcr2rgb_coeff[3][2] << 27) | (ycbcr2rgb_coeff[0][2] << 18) | (ycbcr2rgb_coeff[1][2] << 9) | ycbcr2rgb_coeff[2][1]; - __raw_writel(param, base++); + writel(param, base++); param = (ycbcr2rgb_coeff[3][2] >> 5); - __raw_writel(param, base++); + writel(param, base++); } else if ((in_format == RGB) && (out_format == YCbCr)) { /* Init CSC (RGB->YCbCr) */ param = (rgb2ycbcr_coeff[3][0] << 27) | (rgb2ycbcr_coeff[0][0] << 18) | (rgb2ycbcr_coeff[1][1] << 9) | rgb2ycbcr_coeff[2][2]; - __raw_writel(param, base++); + writel(param, base++); /* scale = 1, sat = 0 */ param = (rgb2ycbcr_coeff[3][0] >> 5) | (1UL << 8); - __raw_writel(param, base++); + writel(param, base++); param = (rgb2ycbcr_coeff[3][1] << 27) | (rgb2ycbcr_coeff[0][1] << 18) | (rgb2ycbcr_coeff[1][0] << 9) | rgb2ycbcr_coeff[2][0]; - __raw_writel(param, base++); + writel(param, base++); param = (rgb2ycbcr_coeff[3][1] >> 5); - __raw_writel(param, base++); + writel(param, base++); param = (rgb2ycbcr_coeff[3][2] << 27) | (rgb2ycbcr_coeff[0][2] << 18) | (rgb2ycbcr_coeff[1][2] << 9) | rgb2ycbcr_coeff[2][1]; - __raw_writel(param, base++); + writel(param, base++); param = (rgb2ycbcr_coeff[3][2] >> 5); - __raw_writel(param, base++); + writel(param, base++); } else if ((in_format == RGB) && (out_format == RGB)) { /* Init CSC */ param = (rgb2rgb_coeff[3][0] << 27) | (rgb2rgb_coeff[0][0] << 18) | (rgb2rgb_coeff[1][1] << 9) | rgb2rgb_coeff[2][2]; - __raw_writel(param, base++); + writel(param, base++); /* scale = 2, sat = 0 */ param = (rgb2rgb_coeff[3][0] >> 5) | (2UL << 8); - __raw_writel(param, base++); + writel(param, base++); param = (rgb2rgb_coeff[3][1] << 27) | (rgb2rgb_coeff[0][1] << 18) | (rgb2rgb_coeff[1][0] << 9) | rgb2rgb_coeff[2][0]; - __raw_writel(param, base++); + writel(param, base++); param = (rgb2rgb_coeff[3][1] >> 5); - __raw_writel(param, base++); + writel(param, base++); param = (rgb2rgb_coeff[3][2] << 27) | (rgb2rgb_coeff[0][2] << 18) | (rgb2rgb_coeff[1][2] << 9) | rgb2rgb_coeff[2][1]; - __raw_writel(param, base++); + writel(param, base++); param = (rgb2rgb_coeff[3][2] >> 5); - __raw_writel(param, base++); + writel(param, base++); } else { - dev_err(g_ipu_dev, "Unsupported color space conversion\n"); + dev_err(ipu->dev, "Unsupported color space conversion\n"); } } -static bool _calc_resize_coeffs(uint32_t inSize, uint32_t outSize, +static bool _calc_resize_coeffs(struct ipu_soc *ipu, + uint32_t inSize, uint32_t outSize, uint32_t *resizeCoeff, uint32_t *downsizeCoeff) { @@ -804,11 +806,11 @@ static bool _calc_resize_coeffs(uint32_t inSize, uint32_t outSize, where M = 2^13, SI - input size, SO - output size */ *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1); if (*resizeCoeff >= 16384L) { - dev_err(g_ipu_dev, "Warning! Overflow on resize coeff.\n"); + dev_err(ipu->dev, "Warning! Overflow on resize coeff.\n"); *resizeCoeff = 0x3FFF; } - dev_dbg(g_ipu_dev, "resizing from %u -> %u pixels, " + dev_dbg(ipu->dev, "resizing from %u -> %u pixels, " "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize, *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0, ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff); @@ -816,18 +818,18 @@ static bool _calc_resize_coeffs(uint32_t inSize, uint32_t outSize, return true; } -void _ipu_vdi_toggle_top_field_man() +void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu) { uint32_t reg; uint32_t mask_reg; - reg = __raw_readl(VDI_C); + reg = ipu_vdi_read(ipu, VDI_C); mask_reg = reg & VDI_C_TOP_FIELD_MAN_1; if (mask_reg == VDI_C_TOP_FIELD_MAN_1) reg &= ~VDI_C_TOP_FIELD_MAN_1; else reg |= VDI_C_TOP_FIELD_MAN_1; - __raw_writel(reg, VDI_C); + ipu_vdi_write(ipu, reg, VDI_C); } diff --git a/drivers/mxc/ipu3/ipu_param_mem.h b/drivers/mxc/ipu3/ipu_param_mem.h index fbe15f9927a8..734cb7f95c9b 100644 --- a/drivers/mxc/ipu3/ipu_param_mem.h +++ b/drivers/mxc/ipu3/ipu_param_mem.h @@ -27,7 +27,7 @@ struct ipu_ch_param { struct ipu_ch_param_word word[2]; }; -#define ipu_ch_param_addr(ch) (((struct ipu_ch_param *)ipu_cpmem_base) + (ch)) +#define ipu_ch_param_addr(ipu, ch) (((struct ipu_ch_param *)ipu->cpmem_base) + (ch)) #define _param_word(base, w) \ (((struct ipu_ch_param *)(base))->word[(w)].data) @@ -116,48 +116,48 @@ static inline void _ipu_ch_params_set_packing(struct ipu_ch_param *p, ipu_ch_param_set_field(p, 1, 143, 5, alpha_offset); } -static inline void _ipu_ch_param_dump(int ch) +static inline void _ipu_ch_param_dump(struct ipu_soc *ipu, int ch) { - struct ipu_ch_param *p = ipu_ch_param_addr(ch); - pr_debug("ch %d word 0 - %08X %08X %08X %08X %08X\n", ch, + struct ipu_ch_param *p = ipu_ch_param_addr(ipu, ch); + dev_dbg(ipu->dev, "ch %d word 0 - %08X %08X %08X %08X %08X\n", ch, p->word[0].data[0], p->word[0].data[1], p->word[0].data[2], p->word[0].data[3], p->word[0].data[4]); - pr_debug("ch %d word 1 - %08X %08X %08X %08X %08X\n", ch, + dev_dbg(ipu->dev, "ch %d word 1 - %08X %08X %08X %08X %08X\n", ch, p->word[1].data[0], p->word[1].data[1], p->word[1].data[2], p->word[1].data[3], p->word[1].data[4]); - pr_debug("PFS 0x%x, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 85, 4)); - pr_debug("BPP 0x%x, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 107, 3)); - pr_debug("NPB 0x%x\n", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 78, 7)); - - pr_debug("FW %d, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 125, 13)); - pr_debug("FH %d, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 138, 12)); - pr_debug("Stride %d\n", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14)); - - pr_debug("Width0 %d+1, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 116, 3)); - pr_debug("Width1 %d+1, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 119, 3)); - pr_debug("Width2 %d+1, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 122, 3)); - pr_debug("Width3 %d+1, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 125, 3)); - pr_debug("Offset0 %d, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 128, 5)); - pr_debug("Offset1 %d, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 133, 5)); - pr_debug("Offset2 %d, ", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 138, 5)); - pr_debug("Offset3 %d\n", - ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 143, 5)); + dev_dbg(ipu->dev, "PFS 0x%x, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 85, 4)); + dev_dbg(ipu->dev, "BPP 0x%x, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 0, 107, 3)); + dev_dbg(ipu->dev, "NPB 0x%x\n", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 78, 7)); + + dev_dbg(ipu->dev, "FW %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 0, 125, 13)); + dev_dbg(ipu->dev, "FH %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 0, 138, 12)); + dev_dbg(ipu->dev, "Stride %d\n", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 102, 14)); + + dev_dbg(ipu->dev, "Width0 %d+1, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 116, 3)); + dev_dbg(ipu->dev, "Width1 %d+1, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 119, 3)); + dev_dbg(ipu->dev, "Width2 %d+1, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 122, 3)); + dev_dbg(ipu->dev, "Width3 %d+1, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 125, 3)); + dev_dbg(ipu->dev, "Offset0 %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 128, 5)); + dev_dbg(ipu->dev, "Offset1 %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 133, 5)); + dev_dbg(ipu->dev, "Offset2 %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 138, 5)); + dev_dbg(ipu->dev, "Offset3 %d\n", + ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 143, 5)); } -static inline void _ipu_ch_param_init(int ch, +static inline void _ipu_ch_param_init(struct ipu_soc *ipu, int ch, uint32_t pixel_fmt, uint32_t width, uint32_t height, uint32_t stride, uint32_t u, uint32_t v, @@ -185,10 +185,10 @@ static inline void _ipu_ch_param_init(int ch, ipu_ch_param_set_field(¶ms, 1, 0, 29, addr0 >> 3); ipu_ch_param_set_field(¶ms, 1, 29, 29, addr1 >> 3); if (addr0%8) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's EBA0 is not 8-byte aligned\n", ch); if (addr1%8) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's EBA1 is not 8-byte aligned\n", ch); switch (pixel_fmt) { @@ -331,7 +331,7 @@ static inline void _ipu_ch_param_init(int ch, } break; default: - dev_err(g_ipu_dev, "mxc ipu: unimplemented pixel format\n"); + dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n"); break; } /*set burst size to 16*/ @@ -348,23 +348,23 @@ static inline void _ipu_ch_param_init(int ch, /* UBO and VBO are 22-bit and 8-byte aligned */ if (u_offset/8 > 0x3fffff) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's U offset exceeds IPU limitation\n", ch); if (v_offset/8 > 0x3fffff) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's V offset exceeds IPU limitation\n", ch); if (u_offset%8) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's U offset is not 8-byte aligned\n", ch); if (v_offset%8) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's V offset is not 8-byte aligned\n", ch); ipu_ch_param_set_field(¶ms, 0, 46, 22, u_offset / 8); ipu_ch_param_set_field(¶ms, 0, 68, 22, v_offset / 8); - pr_debug("initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ch)); - memcpy(ipu_ch_param_addr(ch), ¶ms, sizeof(params)); + dev_dbg(ipu->dev, "initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ipu, ch)); + memcpy(ipu_ch_param_addr(ipu, ch), ¶ms, sizeof(params)); if (addr2) { ipu_ch_param_set_field(¶ms, 1, 0, 29, addr2 >> 3); ipu_ch_param_set_field(¶ms, 1, 29, 29, 0); @@ -373,39 +373,40 @@ static inline void _ipu_ch_param_init(int ch, if (sub_ch <= 0) return; - pr_debug("initializing idma ch %d @ %p sub cpmem\n", ch, - ipu_ch_param_addr(sub_ch)); - memcpy(ipu_ch_param_addr(sub_ch), ¶ms, sizeof(params)); + dev_dbg(ipu->dev, "initializing idma ch %d @ %p sub cpmem\n", ch, + ipu_ch_param_addr(ipu, sub_ch)); + memcpy(ipu_ch_param_addr(ipu, sub_ch), ¶ms, sizeof(params)); } }; -static inline void _ipu_ch_param_set_burst_size(uint32_t ch, +static inline void _ipu_ch_param_set_burst_size(struct ipu_soc *ipu, + uint32_t ch, uint16_t burst_pixels) { int32_t sub_ch = 0; - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 78, 7, + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 78, 7, burst_pixels - 1); sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); if (sub_ch <= 0) return; - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 1, 78, 7, + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 78, 7, burst_pixels - 1); }; -static inline int _ipu_ch_param_get_burst_size(uint32_t ch) +static inline int _ipu_ch_param_get_burst_size(struct ipu_soc *ipu, uint32_t ch) { - return ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 78, 7) + 1; + return ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 78, 7) + 1; }; -static inline int _ipu_ch_param_get_bpp(uint32_t ch) +static inline int _ipu_ch_param_get_bpp(struct ipu_soc *ipu, uint32_t ch) { - return ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 107, 3); + return ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 0, 107, 3); }; -static inline void _ipu_ch_param_set_buffer(uint32_t ch, int bufNum, - dma_addr_t phyaddr) +static inline void _ipu_ch_param_set_buffer(struct ipu_soc *ipu, uint32_t ch, + int bufNum, dma_addr_t phyaddr) { if (bufNum == 2) { ch = __ipu_ch_get_third_buf_cpmem_num(ch); @@ -414,45 +415,46 @@ static inline void _ipu_ch_param_set_buffer(uint32_t ch, int bufNum, bufNum = 0; } - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 29 * bufNum, 29, + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 29 * bufNum, 29, phyaddr / 8); }; -static inline void _ipu_ch_param_set_rotation(uint32_t ch, +static inline void _ipu_ch_param_set_rotation(struct ipu_soc *ipu, uint32_t ch, ipu_rotate_mode_t rot) { u32 temp_rot = bitrev8(rot) >> 5; int32_t sub_ch = 0; - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 119, 3, temp_rot); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 0, 119, 3, temp_rot); sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); if (sub_ch <= 0) return; - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 0, 119, 3, temp_rot); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 0, 119, 3, temp_rot); }; -static inline void _ipu_ch_param_set_block_mode(uint32_t ch) +static inline void _ipu_ch_param_set_block_mode(struct ipu_soc *ipu, uint32_t ch) { int32_t sub_ch = 0; - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 117, 2, 1); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 0, 117, 2, 1); sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); if (sub_ch <= 0) return; - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 0, 117, 2, 1); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 0, 117, 2, 1); }; -static inline void _ipu_ch_param_set_alpha_use_separate_channel(uint32_t ch, +static inline void _ipu_ch_param_set_alpha_use_separate_channel(struct ipu_soc *ipu, + uint32_t ch, bool option) { int32_t sub_ch = 0; if (option) { - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 89, 1, 1); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 1); } else { - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 89, 1, 0); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 89, 1, 0); } sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); @@ -460,25 +462,25 @@ static inline void _ipu_ch_param_set_alpha_use_separate_channel(uint32_t ch, return; if (option) { - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 1, 89, 1, 1); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 1); } else { - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 1, 89, 1, 0); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 89, 1, 0); } }; -static inline void _ipu_ch_param_set_alpha_condition_read(uint32_t ch) +static inline void _ipu_ch_param_set_alpha_condition_read(struct ipu_soc *ipu, uint32_t ch) { int32_t sub_ch = 0; - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 149, 1, 1); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 149, 1, 1); sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); if (sub_ch <= 0) return; - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 1, 149, 1, 1); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 149, 1, 1); }; -static inline void _ipu_ch_param_set_alpha_buffer_memory(uint32_t ch) +static inline void _ipu_ch_param_set_alpha_buffer_memory(struct ipu_soc *ipu, uint32_t ch) { int alp_mem_idx; int32_t sub_ch = 0; @@ -497,65 +499,66 @@ static inline void _ipu_ch_param_set_alpha_buffer_memory(uint32_t ch) alp_mem_idx = 2; break; default: - dev_err(g_ipu_dev, "unsupported correlative channel of local " + dev_err(ipu->dev, "unsupported correlative channel of local " "alpha channel\n"); return; } - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 90, 3, alp_mem_idx); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 90, 3, alp_mem_idx); sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); if (sub_ch <= 0) return; - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 1, 90, 3, alp_mem_idx); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 90, 3, alp_mem_idx); }; -static inline void _ipu_ch_param_set_interlaced_scan(uint32_t ch) +static inline void _ipu_ch_param_set_interlaced_scan(struct ipu_soc *ipu, uint32_t ch) { u32 stride; int32_t sub_ch = 0; sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); - ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 113, 1, 1); + ipu_ch_param_set_field(ipu_ch_param_addr(ipu, ch), 0, 113, 1, 1); if (sub_ch > 0) - ipu_ch_param_set_field(ipu_ch_param_addr(sub_ch), 0, 113, 1, 1); - stride = ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14) + 1; + ipu_ch_param_set_field(ipu_ch_param_addr(ipu, sub_ch), 0, 113, 1, 1); + stride = ipu_ch_param_read_field(ipu_ch_param_addr(ipu, ch), 1, 102, 14) + 1; /* ILO is 20-bit and 8-byte aligned */ if (stride/8 > 0xfffff) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's ILO exceeds IPU limitation\n", ch); if (stride%8) - dev_warn(g_ipu_dev, + dev_warn(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); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 58, 20, stride / 8); if (sub_ch > 0) - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 1, 58, 20, + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 58, 20, stride / 8); stride *= 2; - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 102, 14, stride - 1); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 102, 14, stride - 1); if (sub_ch > 0) - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 1, 102, 14, + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 102, 14, stride - 1); }; -static inline void _ipu_ch_param_set_high_priority(uint32_t ch) +static inline void _ipu_ch_param_set_high_priority(struct ipu_soc *ipu, uint32_t ch) { int32_t sub_ch = 0; - ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 93, 2, 1); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 1, 93, 2, 1); sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); if (sub_ch <= 0) return; - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 1, 93, 2, 1); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 1, 93, 2, 1); }; /* IDMAC U/V offset changing support */ /* U and V input is not affected, */ /* the update is done by new calculation according to */ /* vertical_offset and horizontal_offset */ -static inline void _ipu_ch_offset_update(int ch, +static inline void _ipu_ch_offset_update(struct ipu_soc *ipu, + int ch, uint32_t pixel_fmt, uint32_t width, uint32_t height, @@ -677,7 +680,7 @@ static inline void _ipu_ch_offset_update(int ch, break; default: - dev_err(g_ipu_dev, "mxc ipu: unimplemented pixel format\n"); + dev_err(ipu->dev, "mxc ipu: unimplemented pixel format\n"); break; } @@ -691,38 +694,38 @@ static inline void _ipu_ch_offset_update(int ch, /* UBO and VBO are 22-bit and 8-byte aligned */ if (u_offset/8 > 0x3fffff) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's U offset exceeds IPU limitation\n", ch); if (v_offset/8 > 0x3fffff) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's V offset exceeds IPU limitation\n", ch); if (u_offset%8) - dev_warn(g_ipu_dev, + dev_warn(ipu->dev, "IDMAC%d's U offset is not 8-byte aligned\n", ch); if (v_offset%8) - dev_warn(g_ipu_dev, + dev_warn(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); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 0, 46, 22, u_offset / 8); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, ch), 0, 68, 22, v_offset / 8); sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); if (sub_ch <= 0) return; - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 0, 46, 22, u_offset / 8); - ipu_ch_param_mod_field(ipu_ch_param_addr(sub_ch), 0, 68, 22, v_offset / 8); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 0, 46, 22, u_offset / 8); + ipu_ch_param_mod_field(ipu_ch_param_addr(ipu, sub_ch), 0, 68, 22, v_offset / 8); }; -static inline void _ipu_ch_params_set_alpha_width(uint32_t ch, int alpha_width) +static inline void _ipu_ch_params_set_alpha_width(struct ipu_soc *ipu, uint32_t ch, int alpha_width) { int32_t sub_ch = 0; - ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 125, 3, alpha_width - 1); + ipu_ch_param_set_field(ipu_ch_param_addr(ipu, ch), 1, 125, 3, alpha_width - 1); sub_ch = __ipu_ch_get_third_buf_cpmem_num(ch); if (sub_ch <= 0) return; - ipu_ch_param_set_field(ipu_ch_param_addr(sub_ch), 1, 125, 3, alpha_width - 1); + ipu_ch_param_set_field(ipu_ch_param_addr(ipu, sub_ch), 1, 125, 3, alpha_width - 1); }; #endif diff --git a/drivers/mxc/ipu3/ipu_prv.h b/drivers/mxc/ipu3/ipu_prv.h index ec27264c47e3..9d009fc02fd8 100644 --- a/drivers/mxc/ipu3/ipu_prv.h +++ b/drivers/mxc/ipu3/ipu_prv.h @@ -15,25 +15,97 @@ #include <linux/types.h> #include <linux/device.h> -#include <linux/clk.h> +#include <mach/clock.h> #include <linux/interrupt.h> #include <linux/fsl_devices.h> /* Globals */ -extern struct device *g_ipu_dev; -extern spinlock_t ipu_lock; -extern bool g_ipu_clk_enabled; -extern struct clk *g_ipu_clk; -extern struct clk *g_di_clk[2]; -extern struct clk *g_pixel_clk[2]; -extern struct clk *g_csi_clk[2]; -extern unsigned char g_dc_di_assignment[]; -extern int g_ipu_hw_rev; extern int dmfc_type_setup; #define IDMA_CHAN_INVALID 0xFF #define HIGH_RESOLUTION_WIDTH 1024 +struct ipu_irq_node { + irqreturn_t(*handler) (int, void *); /*!< the ISR */ + const char *name; /*!< device associated with the interrupt */ + void *dev_id; /*!< some unique information for the ISR */ + __u32 flags; /*!< not used */ +}; + +enum csc_type_t { + RGB2YUV = 0, + YUV2RGB, + RGB2RGB, + YUV2YUV, + CSC_NONE, + CSC_NUM +}; + +struct ipu_soc { + /*clk*/ + struct clk *ipu_clk; + bool clk_enabled; + struct clk *di_clk[2]; + struct clk *csi_clk[2]; + struct clk pixel_clk[2]; + + /*irq*/ + int irq_sync; + int irq_err; + struct ipu_irq_node irq_list[IPU_IRQ_COUNT]; + + /*reg*/ + u32 *cm_reg; + u32 *idmac_reg; + u32 *dp_reg; + u32 *ic_reg; + u32 *dc_reg; + u32 *dc_tmpl_reg; + u32 *dmfc_reg; + u32 *di_reg[2]; + u32 *smfc_reg; + u32 *csi_reg[2]; + u32 *cpmem_base; + u32 *tpmem_base; + u32 *disp_base[2]; + u32 *vdi_reg; + + spinlock_t ipu_lock; + struct device *dev; + + ipu_channel_t csi_channel[2]; + ipu_channel_t using_ic_dirct_ch; + unsigned char dc_di_assignment[10]; + bool sec_chan_en[24]; + bool thrd_chan_en[24]; + bool chan_is_interlaced[52]; + uint32_t channel_init_mask; + uint32_t channel_enable_mask; + + /*use count*/ + int dc_use_count; + int dp_use_count; + int dmfc_use_count; + int smfc_use_count; + int ic_use_count; + int rot_use_count; + int vdi_use_count; + int di_use_count[2]; + int csi_use_count[2]; + + int dmfc_size_28; + int dmfc_size_29; + int dmfc_size_24; + int dmfc_size_27; + int dmfc_size_23; + + enum csc_type_t fg_csc_type; + enum csc_type_t bg_csc_type; + bool color_key_4rgb; + bool dc_swap; + struct completion dc_comp; +}; + struct ipu_channel { u8 video_in_dma; u8 alpha_in_dma; @@ -48,56 +120,178 @@ enum ipu_dmfc_type { DMFC_HIGH_RESOLUTION_ONLY_DP, }; +static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->cm_reg + offset); +} + +static inline void ipu_cm_write(struct ipu_soc *ipu, + u32 value, unsigned offset) +{ + writel(value, ipu->cm_reg + offset); +} + +static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->idmac_reg + offset); +} + +static inline void ipu_idmac_write(struct ipu_soc *ipu, + u32 value, unsigned offset) +{ + writel(value, ipu->idmac_reg + offset); +} + +static inline u32 ipu_dc_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->dc_reg + offset); +} + +static inline void ipu_dc_write(struct ipu_soc *ipu, + u32 value, unsigned offset) +{ + writel(value, ipu->dc_reg + offset); +} + +static inline u32 ipu_dc_tmpl_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->dc_tmpl_reg + offset); +} + +static inline void ipu_dc_tmpl_write(struct ipu_soc *ipu, + u32 value, unsigned offset) +{ + writel(value, ipu->dc_tmpl_reg + offset); +} + +static inline u32 ipu_dmfc_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->dmfc_reg + offset); +} + +static inline void ipu_dmfc_write(struct ipu_soc *ipu, + u32 value, unsigned offset) +{ + writel(value, ipu->dmfc_reg + offset); +} + +static inline u32 ipu_dp_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->dp_reg + offset); +} + +static inline void ipu_dp_write(struct ipu_soc *ipu, + u32 value, unsigned offset) +{ + writel(value, ipu->dp_reg + offset); +} + +static inline u32 ipu_di_read(struct ipu_soc *ipu, int di, unsigned offset) +{ + return readl(ipu->di_reg[di] + offset); +} + +static inline void ipu_di_write(struct ipu_soc *ipu, int di, + u32 value, unsigned offset) +{ + writel(value, ipu->di_reg[di] + offset); +} + +static inline u32 ipu_csi_read(struct ipu_soc *ipu, int csi, unsigned offset) +{ + return readl(ipu->csi_reg[csi] + offset); +} + +static inline void ipu_csi_write(struct ipu_soc *ipu, int csi, + u32 value, unsigned offset) +{ + writel(value, ipu->csi_reg[csi] + offset); +} + +static inline u32 ipu_smfc_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->smfc_reg + offset); +} + +static inline void ipu_smfc_write(struct ipu_soc *ipu, + u32 value, unsigned offset) +{ + writel(value, ipu->smfc_reg + offset); +} + +static inline u32 ipu_vdi_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->vdi_reg + offset); +} + +static inline void ipu_vdi_write(struct ipu_soc *ipu, + u32 value, unsigned offset) +{ + writel(value, ipu->vdi_reg + offset); +} + +static inline u32 ipu_ic_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->ic_reg + offset); +} + +static inline void ipu_ic_write(struct ipu_soc *ipu, + u32 value, unsigned offset) +{ + writel(value, ipu->ic_reg + offset); +} + int register_ipu_device(void); ipu_color_space_t format_to_colorspace(uint32_t fmt); bool ipu_pixel_format_has_alpha(uint32_t fmt); -void ipu_dump_registers(void); +void ipu_dump_registers(struct ipu_soc *ipu); -uint32_t _ipu_channel_status(ipu_channel_t channel); +uint32_t _ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel); -void _ipu_init_dc_mappings(void); -int _ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt, +void ipu_disp_init(struct ipu_soc *ipu); +void _ipu_init_dc_mappings(struct ipu_soc *ipu); +int _ipu_dp_init(struct ipu_soc *ipu, 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, 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); -void _ipu_dmfc_init(int dmfc_type, int first); -void _ipu_dmfc_set_wait4eot(int dma_chan, int width); -void _ipu_dmfc_set_burst_size(int dma_chan, int burst_size); -int _ipu_disp_chan_is_interlaced(ipu_channel_t channel); - -void _ipu_ic_enable_task(ipu_channel_t channel); -void _ipu_ic_disable_task(ipu_channel_t channel); -void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi); -void _ipu_vdi_init(ipu_channel_t channel, ipu_channel_params_t *params); -void _ipu_vdi_uninit(void); -void _ipu_ic_uninit_prpvf(void); -void _ipu_ic_init_rotate_vf(ipu_channel_params_t *params); -void _ipu_ic_uninit_rotate_vf(void); -void _ipu_ic_init_csi(ipu_channel_params_t *params); -void _ipu_ic_uninit_csi(void); -void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi); -void _ipu_ic_uninit_prpenc(void); -void _ipu_ic_init_rotate_enc(ipu_channel_params_t *params); -void _ipu_ic_uninit_rotate_enc(void); -void _ipu_ic_init_pp(ipu_channel_params_t *params); -void _ipu_ic_uninit_pp(void); -void _ipu_ic_init_rotate_pp(ipu_channel_params_t *params); -void _ipu_ic_uninit_rotate_pp(void); -int _ipu_ic_idma_init(int dma_chan, uint16_t width, uint16_t height, +void _ipu_dp_uninit(struct ipu_soc *ipu, ipu_channel_t channel); +void _ipu_dc_init(struct ipu_soc *ipu, int dc_chan, int di, bool interlaced, uint32_t pixel_fmt); +void _ipu_dc_uninit(struct ipu_soc *ipu, int dc_chan); +void _ipu_dp_dc_enable(struct ipu_soc *ipu, ipu_channel_t channel); +void _ipu_dp_dc_disable(struct ipu_soc *ipu, ipu_channel_t channel, bool swap); +void _ipu_dmfc_init(struct ipu_soc *ipu, int dmfc_type, int first); +void _ipu_dmfc_set_wait4eot(struct ipu_soc *ipu, int dma_chan, int width); +void _ipu_dmfc_set_burst_size(struct ipu_soc *ipu, int dma_chan, int burst_size); +int _ipu_disp_chan_is_interlaced(struct ipu_soc *ipu, ipu_channel_t channel); + +void _ipu_ic_enable_task(struct ipu_soc *ipu, ipu_channel_t channel); +void _ipu_ic_disable_task(struct ipu_soc *ipu, ipu_channel_t channel); +void _ipu_ic_init_prpvf(struct ipu_soc *ipu, ipu_channel_params_t *params, bool src_is_csi); +void _ipu_vdi_init(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params); +void _ipu_vdi_uninit(struct ipu_soc *ipu); +void _ipu_ic_uninit_prpvf(struct ipu_soc *ipu); +void _ipu_ic_init_rotate_vf(struct ipu_soc *ipu, ipu_channel_params_t *params); +void _ipu_ic_uninit_rotate_vf(struct ipu_soc *ipu); +void _ipu_ic_init_csi(struct ipu_soc *ipu, ipu_channel_params_t *params); +void _ipu_ic_uninit_csi(struct ipu_soc *ipu); +void _ipu_ic_init_prpenc(struct ipu_soc *ipu, ipu_channel_params_t *params, bool src_is_csi); +void _ipu_ic_uninit_prpenc(struct ipu_soc *ipu); +void _ipu_ic_init_rotate_enc(struct ipu_soc *ipu, ipu_channel_params_t *params); +void _ipu_ic_uninit_rotate_enc(struct ipu_soc *ipu); +void _ipu_ic_init_pp(struct ipu_soc *ipu, ipu_channel_params_t *params); +void _ipu_ic_uninit_pp(struct ipu_soc *ipu); +void _ipu_ic_init_rotate_pp(struct ipu_soc *ipu, ipu_channel_params_t *params); +void _ipu_ic_uninit_rotate_pp(struct ipu_soc *ipu); +int _ipu_ic_idma_init(struct ipu_soc *ipu, int dma_chan, uint16_t width, uint16_t height, int burst_size, ipu_rotate_mode_t rot); -void _ipu_vdi_toggle_top_field_man(void); -int _ipu_csi_init(ipu_channel_t channel, uint32_t csi); -void ipu_csi_set_test_generator(bool active, uint32_t r_value, +void _ipu_vdi_toggle_top_field_man(struct ipu_soc *ipu); +int _ipu_csi_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t csi); +void ipu_csi_set_test_generator(struct ipu_soc *ipu, bool active, uint32_t r_value, uint32_t g_value, uint32_t b_value, uint32_t pix_clk, uint32_t csi); -void _ipu_csi_ccir_err_detection_enable(uint32_t csi); -void _ipu_csi_ccir_err_detection_disable(uint32_t csi); -void _ipu_smfc_init(ipu_channel_t channel, uint32_t mipi_id, uint32_t csi); -void _ipu_smfc_set_burst_size(ipu_channel_t channel, uint32_t bs); -void _ipu_dp_set_csc_coefficients(ipu_channel_t channel, int32_t param[][3]); +void _ipu_csi_ccir_err_detection_enable(struct ipu_soc *ipu, uint32_t csi); +void _ipu_csi_ccir_err_detection_disable(struct ipu_soc *ipu, uint32_t csi); +void _ipu_smfc_init(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t mipi_id, uint32_t csi); +void _ipu_smfc_set_burst_size(struct ipu_soc *ipu, ipu_channel_t channel, uint32_t bs); +void _ipu_dp_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]); #endif /* __INCLUDE_IPU_PRV_H__ */ diff --git a/drivers/mxc/ipu3/ipu_regs.h b/drivers/mxc/ipu3/ipu_regs.h index 5c94c7b935a8..c63c93231135 100644 --- a/drivers/mxc/ipu3/ipu_regs.h +++ b/drivers/mxc/ipu3/ipu_regs.h @@ -21,11 +21,21 @@ #ifndef __IPU_REGS_INCLUDED__ #define __IPU_REGS_INCLUDED__ +/* + * hw_rev 2: IPUV3DEX + * hw_rev 3: IPUV3M + * hw_rev 4: IPUV3H + */ +extern int g_ipu_hw_rev; + #define IPU_DISP0_BASE 0x00000000 #define IPU_MCU_T_DEFAULT 8 -#define IPU_DISP1_BASE (IPU_MCU_T_DEFAULT << 25) -#define IPU_REG_BASE 0x1E000000 +#define IPU_DISP1_BASE ({g_ipu_hw_rev < 4 ? \ + (IPU_MCU_T_DEFAULT << 25) : \ + (0x00000000); }) +#define IPUV3DEX_REG_BASE 0x1E000000 #define IPUV3M_REG_BASE 0x06000000 +#define IPUV3H_REG_BASE 0x00200000 #define IPU_CM_REG_BASE 0x00000000 #define IPU_IDMAC_REG_BASE 0x00008000 @@ -41,52 +51,45 @@ #define IPU_DC_REG_BASE 0x00058000 #define IPU_DMFC_REG_BASE 0x00060000 #define IPU_VDI_REG_BASE 0x00068000 -#define IPU_CPMEM_REG_BASE 0x01000000 +#define IPU_CPMEM_REG_BASE ({g_ipu_hw_rev >= 4 ? \ + (0x00100000) : \ + (0x01000000); }) #define IPU_LUT_REG_BASE 0x01020000 -#define IPU_SRM_REG_BASE 0x01040000 -#define IPU_TPM_REG_BASE 0x01060000 -#define IPU_DC_TMPL_REG_BASE 0x01080000 +#define IPU_SRM_REG_BASE ({g_ipu_hw_rev >= 4 ? \ + (0x00140000) : \ + (0x01040000); }) +#define IPU_TPM_REG_BASE ({g_ipu_hw_rev >= 4 ? \ + (0x00160000) : \ + (0x01060000); }) +#define IPU_DC_TMPL_REG_BASE ({g_ipu_hw_rev >= 4 ? \ + (0x00180000) : \ + (0x01080000); }) #define IPU_ISP_TBPR_REG_BASE 0x010C0000 - -extern u32 *ipu_cm_reg; -extern u32 *ipu_idmac_reg; -extern u32 *ipu_dp_reg; -extern u32 *ipu_ic_reg; -extern u32 *ipu_dc_reg; -extern u32 *ipu_dc_tmpl_reg; -extern u32 *ipu_dmfc_reg; -extern u32 *ipu_di_reg[]; -extern u32 *ipu_smfc_reg; -extern u32 *ipu_csi_reg[]; -extern u32 *ipu_tpmem_base; -extern u32 *ipu_disp_base[]; -extern u32 *ipu_vdi_reg; - /* Register addresses */ /* IPU Common registers */ -#define IPU_CONF (ipu_cm_reg) - -#define IPU_SRM_PRI1 (ipu_cm_reg + 0x00A0/4) -#define IPU_SRM_PRI2 (ipu_cm_reg + 0x00A4/4) -#define IPU_FS_PROC_FLOW1 (ipu_cm_reg + 0x00A8/4) -#define IPU_FS_PROC_FLOW2 (ipu_cm_reg + 0x00AC/4) -#define IPU_FS_PROC_FLOW3 (ipu_cm_reg + 0x00B0/4) -#define IPU_FS_DISP_FLOW1 (ipu_cm_reg + 0x00B4/4) -#define IPU_FS_DISP_FLOW2 (ipu_cm_reg + 0x00B8/4) -#define IPU_SKIP (ipu_cm_reg + 0x00BC/4) -#define IPU_DISP_ALT_CONF (ipu_cm_reg + 0x00C0/4) -#define IPU_DISP_GEN (ipu_cm_reg + 0x00C4/4) -#define IPU_DISP_ALT1 (ipu_cm_reg + 0x00C8/4) -#define IPU_DISP_ALT2 (ipu_cm_reg + 0x00CC/4) -#define IPU_DISP_ALT3 (ipu_cm_reg + 0x00D0/4) -#define IPU_DISP_ALT4 (ipu_cm_reg + 0x00D4/4) -#define IPU_SNOOP (ipu_cm_reg + 0x00D8/4) -#define IPU_MEM_RST (ipu_cm_reg + 0x00DC/4) -#define IPU_PM (ipu_cm_reg + 0x00E0/4) -#define IPU_GPR (ipu_cm_reg + 0x00E4/4) -#define IPU_CHA_DB_MODE_SEL(ch) (ipu_cm_reg + 0x0150/4 + (ch / 32)) -#define IPU_ALT_CHA_DB_MODE_SEL(ch) (ipu_cm_reg + 0x0168/4 + (ch / 32)) +#define IPU_CONF (0) + +#define IPU_SRM_PRI1 (0x00A0/4) +#define IPU_SRM_PRI2 (0x00A4/4) +#define IPU_FS_PROC_FLOW1 (0x00A8/4) +#define IPU_FS_PROC_FLOW2 (0x00AC/4) +#define IPU_FS_PROC_FLOW3 (0x00B0/4) +#define IPU_FS_DISP_FLOW1 (0x00B4/4) +#define IPU_FS_DISP_FLOW2 (0x00B8/4) +#define IPU_SKIP (0x00BC/4) +#define IPU_DISP_ALT_CONF (0x00C0/4) +#define IPU_DISP_GEN (0x00C4/4) +#define IPU_DISP_ALT1 (0x00C8/4) +#define IPU_DISP_ALT2 (0x00CC/4) +#define IPU_DISP_ALT3 (0x00D0/4) +#define IPU_DISP_ALT4 (0x00D4/4) +#define IPU_SNOOP (0x00D8/4) +#define IPU_MEM_RST (0x00DC/4) +#define IPU_PM (0x00E0/4) +#define IPU_GPR (0x00E4/4) +#define IPU_CHA_DB_MODE_SEL(ch) (0x0150/4 + (ch / 32)) +#define IPU_ALT_CHA_DB_MODE_SEL(ch) (0x0168/4 + (ch / 32)) /* * IPUv3D doesn't support triple buffer, so point * IPU_CHA_TRB_MODE_SEL, IPU_CHA_TRIPLE_CUR_BUF and @@ -94,166 +97,166 @@ extern u32 *ipu_vdi_reg; * IPU_ALT_CUR_BUF0 for IPUv3D. */ #define IPU_CHA_TRB_MODE_SEL(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0178/4 + (ch / 32)) : \ - (ipu_cm_reg + 0x012C/4); }) + (0x0178/4 + (ch / 32)) : \ + (0x012C/4); }) #define IPU_CHA_TRIPLE_CUR_BUF(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0258/4 + ((ch*2) / 32)) : \ - (ipu_cm_reg + 0x012C/4); }) + (0x0258/4 + ((ch*2) / 32)) : \ + (0x012C/4); }) #define IPU_CHA_BUF2_RDY(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0288/4 + (ch / 32)) : \ - (ipu_cm_reg + 0x012C/4); }) + (0x0288/4 + (ch / 32)) : \ + (0x012C/4); }) #define IPU_CHA_CUR_BUF(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x023C/4 + (ch / 32)) : \ - (ipu_cm_reg + 0x0124/4 + (ch / 32)); }) + (0x023C/4 + (ch / 32)) : \ + (0x0124/4 + (ch / 32)); }) #define IPU_ALT_CUR_BUF0 ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0244/4) : \ - (ipu_cm_reg + 0x012C/4); }) + (0x0244/4) : \ + (0x012C/4); }) #define IPU_ALT_CUR_BUF1 ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0248/4) : \ - (ipu_cm_reg + 0x0130/4); }) + (0x0248/4) : \ + (0x0130/4); }) #define IPU_SRM_STAT ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x024C/4) : \ - (ipu_cm_reg + 0x0134/4); }) + (0x024C/4) : \ + (0x0134/4); }) #define IPU_PROC_TASK_STAT ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0250/4) : \ - (ipu_cm_reg + 0x0138/4); }) + (0x0250/4) : \ + (0x0138/4); }) #define IPU_DISP_TASK_STAT ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0254/4) : \ - (ipu_cm_reg + 0x013C/4); }) + (0x0254/4) : \ + (0x013C/4); }) #define IPU_CHA_BUF0_RDY(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0268/4 + (ch / 32)) : \ - (ipu_cm_reg + 0x0140/4 + (ch / 32)); }) + (0x0268/4 + (ch / 32)) : \ + (0x0140/4 + (ch / 32)); }) #define IPU_CHA_BUF1_RDY(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0270/4 + (ch / 32)) : \ - (ipu_cm_reg + 0x0148/4 + (ch / 32)); }) + (0x0270/4 + (ch / 32)) : \ + (0x0148/4 + (ch / 32)); }) #define IPU_ALT_CHA_BUF0_RDY(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0278/4 + (ch / 32)) : \ - (ipu_cm_reg + 0x0158/4 + (ch / 32)); }) + (0x0278/4 + (ch / 32)) : \ + (0x0158/4 + (ch / 32)); }) #define IPU_ALT_CHA_BUF1_RDY(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0280/4 + (ch / 32)) : \ - (ipu_cm_reg + 0x0160/4 + (ch / 32)); }) + (0x0280/4 + (ch / 32)) : \ + (0x0160/4 + (ch / 32)); }) -#define IPU_INT_CTRL(n) (ipu_cm_reg + 0x003C/4 + ((n) - 1)) +#define IPU_INT_CTRL(n) (0x003C/4 + ((n) - 1)) #define IPU_INT_CTRL_IRQ(irq) IPU_INT_CTRL(((irq) / 32)) #define IPU_INT_STAT_IRQ(irq) IPU_INT_STAT(((irq) / 32)) #define IPU_INT_STAT(n) ({g_ipu_hw_rev >= 2 ? \ - (ipu_cm_reg + 0x0200/4 + ((n) - 1)) : \ - (ipu_cm_reg + 0x00E8/4 + ((n) - 1)); }) + (0x0200/4 + ((n) - 1)) : \ + (0x00E8/4 + ((n) - 1)); }) #define IPUIRQ_2_STATREG(irq) (IPU_INT_STAT(1) + ((irq) / 32)) #define IPUIRQ_2_CTRLREG(irq) (IPU_INT_CTRL(1) + ((irq) / 32)) #define IPUIRQ_2_MASK(irq) (1UL << ((irq) & 0x1F)) -#define VDI_FSIZE (ipu_vdi_reg) -#define VDI_C (ipu_vdi_reg + 0x0004/4) +#define VDI_FSIZE (0) +#define VDI_C (0x0004/4) /* CMOS Sensor Interface Registers */ -#define CSI_SENS_CONF(csi) (ipu_csi_reg[csi]) -#define CSI_SENS_FRM_SIZE(csi) (ipu_csi_reg[csi] + 0x0004/4) -#define CSI_ACT_FRM_SIZE(csi) (ipu_csi_reg[csi] + 0x0008/4) -#define CSI_OUT_FRM_CTRL(csi) (ipu_csi_reg[csi] + 0x000C/4) -#define CSI_TST_CTRL(csi) (ipu_csi_reg[csi] + 0x0010/4) -#define CSI_CCIR_CODE_1(csi) (ipu_csi_reg[csi] + 0x0014/4) -#define CSI_CCIR_CODE_2(csi) (ipu_csi_reg[csi] + 0x0018/4) -#define CSI_CCIR_CODE_3(csi) (ipu_csi_reg[csi] + 0x001C/4) -#define CSI_MIPI_DI(csi) (ipu_csi_reg[csi] + 0x0020/4) -#define CSI_SKIP(csi) (ipu_csi_reg[csi] + 0x0024/4) -#define CSI_CPD_CTRL(csi) (ipu_csi_reg[csi] + 0x0028/4) -#define CSI_CPD_RC(csi, n) (ipu_csi_reg[csi] + 0x002C/4 + n) -#define CSI_CPD_RS(csi, n) (ipu_csi_reg[csi] + 0x004C/4 + n) -#define CSI_CPD_GRC(csi, n) (ipu_csi_reg[csi] + 0x005C/4 + n) -#define CSI_CPD_GRS(csi, n) (ipu_csi_reg[csi] + 0x007C/4 + n) -#define CSI_CPD_GBC(csi, n) (ipu_csi_reg[csi] + 0x008C/4 + n) -#define CSI_CPD_GBS(csi, n) (ipu_csi_reg[csi] + 0x00AC/4 + n) -#define CSI_CPD_BC(csi, n) (ipu_csi_reg[csi] + 0x00BC/4 + n) -#define CSI_CPD_BS(csi, n) (ipu_csi_reg[csi] + 0x00DC/4 + n) -#define CSI_CPD_OFFSET1(csi) (ipu_csi_reg[csi] + 0x00EC/4) -#define CSI_CPD_OFFSET2(csi) (ipu_csi_reg[csi] + 0x00F0/4) +#define CSI_SENS_CONF (0) +#define CSI_SENS_FRM_SIZE (0x0004/4) +#define CSI_ACT_FRM_SIZE (0x0008/4) +#define CSI_OUT_FRM_CTRL (0x000C/4) +#define CSI_TST_CTRL (0x0010/4) +#define CSI_CCIR_CODE_1 (0x0014/4) +#define CSI_CCIR_CODE_2 (0x0018/4) +#define CSI_CCIR_CODE_3 (0x001C/4) +#define CSI_MIPI_DI (0x0020/4) +#define CSI_SKIP (0x0024/4) +#define CSI_CPD_CTRL (0x0028/4) +#define CSI_CPD_RC(n) (0x002C/4 + n) +#define CSI_CPD_RS(n) (0x004C/4 + n) +#define CSI_CPD_GRC(n) (0x005C/4 + n) +#define CSI_CPD_GRS(n) (0x007C/4 + n) +#define CSI_CPD_GBC(n) (0x008C/4 + n) +#define CSI_CPD_GBS(n) (0x00AC/4 + n) +#define CSI_CPD_BC(n) (0x00BC/4 + n) +#define CSI_CPD_BS(n) (0x00DC/4 + n) +#define CSI_CPD_OFFSET1 (0x00EC/4) +#define CSI_CPD_OFFSET2 (0x00F0/4) /*SMFC Registers */ -#define SMFC_MAP (ipu_smfc_reg) -#define SMFC_WMC (ipu_smfc_reg + 0x0004/4) -#define SMFC_BS (ipu_smfc_reg + 0x0008/4) +#define SMFC_MAP (0) +#define SMFC_WMC (0x0004/4) +#define SMFC_BS (0x0008/4) /* Image Converter Registers */ -#define IC_CONF (ipu_ic_reg) -#define IC_PRP_ENC_RSC (ipu_ic_reg + 0x0004/4) -#define IC_PRP_VF_RSC (ipu_ic_reg + 0x0008/4) -#define IC_PP_RSC (ipu_ic_reg + 0x000C/4) -#define IC_CMBP_1 (ipu_ic_reg + 0x0010/4) -#define IC_CMBP_2 (ipu_ic_reg + 0x0014/4) -#define IC_IDMAC_1 (ipu_ic_reg + 0x0018/4) -#define IC_IDMAC_2 (ipu_ic_reg + 0x001C/4) -#define IC_IDMAC_3 (ipu_ic_reg + 0x0020/4) -#define IC_IDMAC_4 (ipu_ic_reg + 0x0024/4) - -#define IDMAC_CONF (ipu_idmac_reg + 0x0000) -#define IDMAC_CHA_EN(ch) (ipu_idmac_reg + 0x0004/4 + (ch/32)) -#define IDMAC_SEP_ALPHA (ipu_idmac_reg + 0x000C/4) -#define IDMAC_ALT_SEP_ALPHA (ipu_idmac_reg + 0x0010/4) -#define IDMAC_CHA_PRI(ch) (ipu_idmac_reg + 0x0014/4 + (ch/32)) -#define IDMAC_WM_EN(ch) (ipu_idmac_reg + 0x001C/4 + (ch/32)) +#define IC_CONF 0 +#define IC_PRP_ENC_RSC (0x0004/4) +#define IC_PRP_VF_RSC (0x0008/4) +#define IC_PP_RSC (0x000C/4) +#define IC_CMBP_1 (0x0010/4) +#define IC_CMBP_2 (0x0014/4) +#define IC_IDMAC_1 (0x0018/4) +#define IC_IDMAC_2 (0x001C/4) +#define IC_IDMAC_3 (0x0020/4) +#define IC_IDMAC_4 (0x0024/4) + +#define IDMAC_CONF (0x0000) +#define IDMAC_CHA_EN(ch) (0x0004/4 + (ch/32)) +#define IDMAC_SEP_ALPHA (0x000C/4) +#define IDMAC_ALT_SEP_ALPHA (0x0010/4) +#define IDMAC_CHA_PRI(ch) (0x0014/4 + (ch/32)) +#define IDMAC_WM_EN(ch) (0x001C/4 + (ch/32)) #define IDMAC_CH_LOCK_EN_1 ({g_ipu_hw_rev >= 2 ? \ - (ipu_idmac_reg + 0x0024/4) : 0; }) + (0x0024/4) : 0; }) #define IDMAC_CH_LOCK_EN_2 ({g_ipu_hw_rev >= 2 ? \ - (ipu_idmac_reg + 0x0028/4) : \ - (ipu_idmac_reg + 0x0024/4); }) + (0x0028/4) : \ + (0x0024/4); }) #define IDMAC_SUB_ADDR_0 ({g_ipu_hw_rev >= 2 ? \ - (ipu_idmac_reg + 0x002C/4) : \ - (ipu_idmac_reg + 0x0028/4); }) + (0x002C/4) : \ + (0x0028/4); }) #define IDMAC_SUB_ADDR_1 ({g_ipu_hw_rev >= 2 ? \ - (ipu_idmac_reg + 0x0030/4) : \ - (ipu_idmac_reg + 0x002C/4); }) + (0x0030/4) : \ + (0x002C/4); }) #define IDMAC_SUB_ADDR_2 ({g_ipu_hw_rev >= 2 ? \ - (ipu_idmac_reg + 0x0034/4) : \ - (ipu_idmac_reg + 0x0030/4); }) + (0x0034/4) : \ + (0x0030/4); }) /* * IPUv3D doesn't support IDMAC_SUB_ADDR_3 and IDMAC_SUB_ADDR_4, * so point them to readonly IDMAC_CHA_BUSY1 for IPUv3D. */ #define IDMAC_SUB_ADDR_3 ({g_ipu_hw_rev >= 2 ? \ - (ipu_idmac_reg + 0x0038/4) : \ - (ipu_idmac_reg + 0x0040/4); }) + (0x0038/4) : \ + (0x0040/4); }) #define IDMAC_SUB_ADDR_4 ({g_ipu_hw_rev >= 2 ? \ - (ipu_idmac_reg + 0x003c/4) : \ - (ipu_idmac_reg + 0x0040/4); }) + (0x003c/4) : \ + (0x0040/4); }) #define IDMAC_BAND_EN(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_idmac_reg + 0x0040/4 + (ch/32)) : \ - (ipu_idmac_reg + 0x0034/4 + (ch/32)); }) + (0x0040/4 + (ch/32)) : \ + (0x0034/4 + (ch/32)); }) #define IDMAC_CHA_BUSY(ch) ({g_ipu_hw_rev >= 2 ? \ - (ipu_idmac_reg + 0x0100/4 + (ch/32)) : \ - (ipu_idmac_reg + 0x0040/4 + (ch/32)); }) - -#define DI_GENERAL(di) (ipu_di_reg[di]) -#define DI_BS_CLKGEN0(di) (ipu_di_reg[di] + 0x0004/4) -#define DI_BS_CLKGEN1(di) (ipu_di_reg[di] + 0x0008/4) - -#define DI_SW_GEN0(di, gen) (ipu_di_reg[di] + 0x000C/4 + (gen - 1)) -#define DI_SW_GEN1(di, gen) (ipu_di_reg[di] + 0x0030/4 + (gen - 1)) -#define DI_STP_REP(di, gen) (ipu_di_reg[di] + 0x0148/4 + (gen - 1)/2) -#define DI_SYNC_AS_GEN(di) (ipu_di_reg[di] + 0x0054/4) -#define DI_DW_GEN(di, gen) (ipu_di_reg[di] + 0x0058/4 + gen) -#define DI_DW_SET(di, gen, set) (ipu_di_reg[di] + 0x0088/4 + gen + 0xC*set) -#define DI_SER_CONF(di) (ipu_di_reg[di] + 0x015C/4) -#define DI_SSC(di) (ipu_di_reg[di] + 0x0160/4) -#define DI_POL(di) (ipu_di_reg[di] + 0x0164/4) -#define DI_AW0(di) (ipu_di_reg[di] + 0x0168/4) -#define DI_AW1(di) (ipu_di_reg[di] + 0x016C/4) -#define DI_SCR_CONF(di) (ipu_di_reg[di] + 0x0170/4) -#define DI_STAT(di) (ipu_di_reg[di] + 0x0174/4) - -#define DMFC_RD_CHAN (ipu_dmfc_reg) -#define DMFC_WR_CHAN (ipu_dmfc_reg + 0x0004/4) -#define DMFC_WR_CHAN_DEF (ipu_dmfc_reg + 0x0008/4) -#define DMFC_DP_CHAN (ipu_dmfc_reg + 0x000C/4) -#define DMFC_DP_CHAN_DEF (ipu_dmfc_reg + 0x0010/4) -#define DMFC_GENERAL1 (ipu_dmfc_reg + 0x0014/4) -#define DMFC_GENERAL2 (ipu_dmfc_reg + 0x0018/4) -#define DMFC_IC_CTRL (ipu_dmfc_reg + 0x001C/4) -#define DMFC_STAT (ipu_dmfc_reg + 0x0020/4) - -#define DC_MAP_CONF_PTR(n) (ipu_dc_reg + 0x0108/4 + n/2) -#define DC_MAP_CONF_VAL(n) (ipu_dc_reg + 0x0144/4 + n/2) + (0x0100/4 + (ch/32)) : \ + (0x0040/4 + (ch/32)); }) + +#define DI_GENERAL (0) +#define DI_BS_CLKGEN0 (0x0004/4) +#define DI_BS_CLKGEN1 (0x0008/4) + +#define DI_SW_GEN0(gen) (0x000C/4 + (gen - 1)) +#define DI_SW_GEN1(gen) (0x0030/4 + (gen - 1)) +#define DI_STP_REP(gen) (0x0148/4 + (gen - 1)/2) +#define DI_SYNC_AS_GEN (0x0054/4) +#define DI_DW_GEN(gen) (0x0058/4 + gen) +#define DI_DW_SET(gen, set) (0x0088/4 + gen + 0xC*set) +#define DI_SER_CONF (0x015C/4) +#define DI_SSC (0x0160/4) +#define DI_POL (0x0164/4) +#define DI_AW0 (0x0168/4) +#define DI_AW1 (0x016C/4) +#define DI_SCR_CONF (0x0170/4) +#define DI_STAT (0x0174/4) + +#define DMFC_RD_CHAN (0) +#define DMFC_WR_CHAN (0x0004/4) +#define DMFC_WR_CHAN_DEF (0x0008/4) +#define DMFC_DP_CHAN (0x000C/4) +#define DMFC_DP_CHAN_DEF (0x0010/4) +#define DMFC_GENERAL1 (0x0014/4) +#define DMFC_GENERAL2 (0x0018/4) +#define DMFC_IC_CTRL (0x001C/4) +#define DMFC_STAT (0x0020/4) + +#define DC_MAP_CONF_PTR(n) (0x0108/4 + n/2) +#define DC_MAP_CONF_VAL(n) (0x0144/4 + n/2) #define _RL_CH_2_OFFSET(ch) ((ch == 0) ? 8 : ( \ (ch == 1) ? 0x24 : ( \ @@ -262,7 +265,7 @@ extern u32 *ipu_vdi_reg; (ch == 6) ? 0x80 : ( \ (ch == 8) ? 0x9C : ( \ (ch == 9) ? 0xBC : (-1)))))))) -#define DC_RL_CH(ch, evt) (ipu_dc_reg + _RL_CH_2_OFFSET(ch)/4 + evt/2) +#define DC_RL_CH(ch, evt) (_RL_CH_2_OFFSET(ch)/4 + evt/2) #define DC_EVT_NF 0 #define DC_EVT_NL 1 @@ -301,36 +304,36 @@ extern u32 *ipu_vdi_reg; 0, 0x1C, 0x38, 0x54, 0x58, 0x5C, 0x78, 0, 0x94, 0xB4}; \ _offset[ch]; \ }) -#define DC_WR_CH_CONF(ch) (ipu_dc_reg + dc_ch_offset(ch)/4) -#define DC_WR_CH_ADDR(ch) (ipu_dc_reg + dc_ch_offset(ch)/4 + 4/4) - -#define DC_WR_CH_CONF_1 (ipu_dc_reg + 0x001C/4) -#define DC_WR_CH_ADDR_1 (ipu_dc_reg + 0x0020/4) -#define DC_WR_CH_CONF_5 (ipu_dc_reg + 0x005C/4) -#define DC_WR_CH_ADDR_5 (ipu_dc_reg + 0x0060/4) -#define DC_GEN (ipu_dc_reg + 0x00D4/4) -#define DC_DISP_CONF1(disp) (ipu_dc_reg + 0x00D8/4 + disp) -#define DC_DISP_CONF2(disp) (ipu_dc_reg + 0x00E8/4 + disp) -#define DC_STAT (ipu_dc_reg + 0x01C8/4) -#define DC_UGDE_0(evt) (ipu_dc_reg + 0x0174/4 + evt*4) -#define DC_UGDE_1(evt) (ipu_dc_reg + 0x0178/4 + evt*4) -#define DC_UGDE_2(evt) (ipu_dc_reg + 0x017C/4 + evt*4) -#define DC_UGDE_3(evt) (ipu_dc_reg + 0x0180/4 + evt*4) +#define DC_WR_CH_CONF(ch) (dc_ch_offset(ch)/4) +#define DC_WR_CH_ADDR(ch) (dc_ch_offset(ch)/4 + 4/4) + +#define DC_WR_CH_CONF_1 (0x001C/4) +#define DC_WR_CH_ADDR_1 (0x0020/4) +#define DC_WR_CH_CONF_5 (0x005C/4) +#define DC_WR_CH_ADDR_5 (0x0060/4) +#define DC_GEN (0x00D4/4) +#define DC_DISP_CONF1(disp) (0x00D8/4 + disp) +#define DC_DISP_CONF2(disp) (0x00E8/4 + disp) +#define DC_STAT (0x01C8/4) +#define DC_UGDE_0(evt) (0x0174/4 + evt*4) +#define DC_UGDE_1(evt) (0x0178/4 + evt*4) +#define DC_UGDE_2(evt) (0x017C/4 + evt*4) +#define DC_UGDE_3(evt) (0x0180/4 + evt*4) #define DP_SYNC 0 #define DP_ASYNC0 0x60 #define DP_ASYNC1 0xBC -#define DP_COM_CONF(flow) (ipu_dp_reg + flow/4) -#define DP_GRAPH_WIND_CTRL(flow) (ipu_dp_reg + 0x0004/4 + flow/4) -#define DP_FG_POS(flow) (ipu_dp_reg + 0x0008/4 + flow/4) -#define DP_GAMMA_C(flow, i) (ipu_dp_reg + 0x0014/4 + flow/4 + i) -#define DP_GAMMA_S(flow, i) (ipu_dp_reg + 0x0034/4 + flow/4 + i) -#define DP_CSC_A_0(flow) (ipu_dp_reg + 0x0044/4 + flow/4) -#define DP_CSC_A_1(flow) (ipu_dp_reg + 0x0048/4 + flow/4) -#define DP_CSC_A_2(flow) (ipu_dp_reg + 0x004C/4 + flow/4) -#define DP_CSC_A_3(flow) (ipu_dp_reg + 0x0050/4 + flow/4) -#define DP_CSC_0(flow) (ipu_dp_reg + 0x0054/4 + flow/4) -#define DP_CSC_1(flow) (ipu_dp_reg + 0x0058/4 + flow/4) +#define DP_COM_CONF(flow) (flow/4) +#define DP_GRAPH_WIND_CTRL(flow) (0x0004/4 + flow/4) +#define DP_FG_POS(flow) (0x0008/4 + flow/4) +#define DP_GAMMA_C(flow, i) (0x0014/4 + flow/4 + i) +#define DP_GAMMA_S(flow, i) (0x0034/4 + flow/4 + i) +#define DP_CSC_A_0(flow) (0x0044/4 + flow/4) +#define DP_CSC_A_1(flow) (0x0048/4 + flow/4) +#define DP_CSC_A_2(flow) (0x004C/4 + flow/4) +#define DP_CSC_A_3(flow) (0x0050/4 + flow/4) +#define DP_CSC_0(flow) (0x0054/4 + flow/4) +#define DP_CSC_1(flow) (0x0058/4 + flow/4) enum { IPU_CONF_CSI0_EN = 0x00000001, |