summaryrefslogtreecommitdiff
path: root/drivers/mxc/ipu3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/ipu3')
-rw-r--r--drivers/mxc/ipu3/ipu_calc_stripes_sizes.c2
-rw-r--r--drivers/mxc/ipu3/ipu_capture.c130
-rw-r--r--drivers/mxc/ipu3/ipu_common.c184
-rw-r--r--drivers/mxc/ipu3/ipu_device.c25
-rw-r--r--drivers/mxc/ipu3/ipu_disp.c364
-rw-r--r--drivers/mxc/ipu3/ipu_ic.c39
-rw-r--r--drivers/mxc/ipu3/ipu_param_mem.h55
-rw-r--r--drivers/mxc/ipu3/ipu_prv.h4
-rw-r--r--drivers/mxc/ipu3/ipu_regs.h11
9 files changed, 597 insertions, 217 deletions
diff --git a/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c b/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
index 6a29c90fe095..5d5e0b9155a0 100644
--- a/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
+++ b/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
@@ -260,7 +260,7 @@ int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
input_frame_width >> 1;
left->output_width = right->output_width = right->output_column =
output_frame_width >> 1;
- left->input_column = right->input_column = 0;
+ left->input_column = 0;
div = _do_div(((((u64)irr_steps) << 32) *
(right->input_width - 1)), (right->output_width - 1));
left->irr = right->irr = truncate(0, div, 1);
diff --git a/drivers/mxc/ipu3/ipu_capture.c b/drivers/mxc/ipu3/ipu_capture.c
index 5d084ab37b0b..b9967135eac1 100644
--- a/drivers/mxc/ipu3/ipu_capture.c
+++ b/drivers/mxc/ipu3/ipu_capture.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/ipu.h>
#include <linux/clk.h>
+#include <mach/mxc_dvfs.h>
#include "ipu_prv.h"
#include "ipu_regs.h"
@@ -93,6 +94,12 @@ ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt,
cfg_param.force_eof << CSI_SENS_CONF_FORCE_EOF_SHIFT |
cfg_param.data_en_pol << CSI_SENS_CONF_DATA_EN_POL_SHIFT;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
__raw_writel(data, CSI_SENS_CONF(csi));
@@ -101,11 +108,18 @@ ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt,
__raw_writel((width - 1) | (height - 1) << 16, CSI_SENS_FRM_SIZE(csi));
/* Set CCIR registers */
- if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) ||
- (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED)) {
- _ipu_csi_ccir_err_detection_enable(csi);
+ if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) {
__raw_writel(0x40030, CSI_CCIR_CODE_1(csi));
__raw_writel(0xFF0000, CSI_CCIR_CODE_3(csi));
+ } else if (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED) {
+ _ipu_csi_ccir_err_detection_enable(csi);
+ /* Field0BlankEnd = 0x7, Field0BlankStart = 0x3,
+ Field0ActiveEnd = 0x5, Field0ActiveStart = 0x1 */
+ __raw_writel(0xD07DF, CSI_CCIR_CODE_1(csi));
+ /* Field1BlankEnd = 0x6, Field1BlankStart = 0x2,
+ Field1ActiveEnd = 0x4, Field1ActiveStart = 0 */
+ __raw_writel(0x40596, CSI_CCIR_CODE_2(csi));
+ __raw_writel(0xFF0000, CSI_CCIR_CODE_3(csi));
} else if ((cfg_param.clk_mode ==
IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR) ||
(cfg_param.clk_mode ==
@@ -171,34 +185,13 @@ int _ipu_csi_mclk_set(uint32_t pixel_clk, uint32_t csi)
*/
int ipu_csi_enable_mclk(int csi, bool flag, bool wait)
{
- struct clk *clk;
if (flag) {
- if (cpu_is_mx53()) {
- if (csi == 0) {
- clk = clk_get(NULL, "ssi_ext1_clk");
- clk_enable(clk);
- clk_put(clk);
- } else {
- pr_err("invalid csi num %d\n", csi);
- return -EINVAL;
- }
- } else
- clk_enable(g_csi_clk[csi]);
+ clk_enable(g_csi_clk[csi]);
if (wait == true)
msleep(10);
} else {
- if (cpu_is_mx53()) {
- if (csi == 0) {
- clk = clk_get(NULL, "ssi_ext1_clk");
- clk_disable(clk);
- clk_put(clk);
- } else {
- pr_err("invalid csi num %d\n", csi);
- return -EINVAL;
- }
- } else
- clk_disable(g_csi_clk[csi]);
+ clk_disable(g_csi_clk[csi]);
}
return 0;
@@ -217,6 +210,12 @@ void ipu_csi_get_window_size(uint32_t *width, uint32_t *height, uint32_t csi)
uint32_t reg;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
reg = __raw_readl(CSI_ACT_FRM_SIZE(csi));
@@ -238,6 +237,12 @@ void ipu_csi_set_window_size(uint32_t width, uint32_t height, uint32_t csi)
{
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
__raw_writel((width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE(csi));
@@ -258,6 +263,12 @@ void ipu_csi_set_window_pos(uint32_t left, uint32_t top, uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -280,6 +291,12 @@ void _ipu_csi_horizontal_downsize_enable(uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -300,6 +317,12 @@ void _ipu_csi_horizontal_downsize_disable(uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -320,6 +343,12 @@ void _ipu_csi_vertical_downsize_enable(uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -340,6 +369,12 @@ void _ipu_csi_vertical_downsize_disable(uint32_t csi)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_OUT_FRM_CTRL(csi));
@@ -366,6 +401,12 @@ void ipu_csi_set_test_generator(bool active, uint32_t r_value,
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_TST_CTRL(csi));
@@ -401,6 +442,12 @@ void _ipu_csi_ccir_err_detection_enable(uint32_t csi)
{
uint32_t temp;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
temp = __raw_readl(CSI_CCIR_CODE_1(csi));
temp |= CSI_CCIR_ERR_DET_EN;
__raw_writel(temp, CSI_CCIR_CODE_1(csi));
@@ -417,6 +464,12 @@ void _ipu_csi_ccir_err_detection_disable(uint32_t csi)
{
uint32_t temp;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
temp = __raw_readl(CSI_CCIR_CODE_1(csi));
temp &= ~CSI_CCIR_ERR_DET_EN;
__raw_writel(temp, CSI_CCIR_CODE_1(csi));
@@ -442,6 +495,12 @@ int _ipu_csi_set_mipi_di(uint32_t num, uint32_t di_val, uint32_t csi)
goto err;
}
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_MIPI_DI(csi));
@@ -499,6 +558,12 @@ int _ipu_csi_set_skip_isp(uint32_t skip, uint32_t max_ratio, uint32_t csi)
goto err;
}
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_SKIP(csi));
@@ -536,6 +601,12 @@ int _ipu_csi_set_skip_smfc(uint32_t skip, uint32_t max_ratio,
goto err;
}
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(CSI_SKIP(csi));
@@ -585,7 +656,6 @@ void _ipu_smfc_init(ipu_channel_t channel, uint32_t mipi_id, uint32_t csi)
default:
return;
}
-
__raw_writel(temp, SMFC_MAP);
}
@@ -604,6 +674,12 @@ void _ipu_smfc_set_wmc(ipu_channel_t channel, bool set, uint32_t level)
uint32_t temp;
unsigned long lock_flags;
+ if (g_ipu_clk_enabled == false) {
+ stop_dvfs_per();
+ g_ipu_clk_enabled = true;
+ clk_enable(g_ipu_clk);
+ }
+
spin_lock_irqsave(&ipu_lock, lock_flags);
temp = __raw_readl(SMFC_WMC);
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index 68be542e8370..b1b8a8b39ae1 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -52,8 +52,8 @@ unsigned char g_dc_di_assignment[10];
ipu_channel_t g_ipu_csi_channel[2];
int g_ipu_irq[2];
int g_ipu_hw_rev;
-bool g_sec_chan_en[22];
-bool g_thrd_chan_en[21];
+bool g_sec_chan_en[24];
+bool g_thrd_chan_en[24];
uint32_t g_channel_init_mask;
uint32_t g_channel_enable_mask;
DEFINE_SPINLOCK(ipu_lock);
@@ -354,8 +354,8 @@ static int ipu_probe(struct platform_device *pdev)
g_di_clk[0] = plat_data->di_clk[0];
g_di_clk[1] = plat_data->di_clk[1];
- g_csi_clk[0] = clk_get(&pdev->dev, "csi_mclk1");
- g_csi_clk[1] = clk_get(&pdev->dev, "csi_mclk2");
+ g_csi_clk[0] = plat_data->csi_clk[0];
+ g_csi_clk[1] = plat_data->csi_clk[1];
__raw_writel(0x807FFFFF, IPU_MEM_RST);
while (__raw_readl(IPU_MEM_RST) & 0x80000000) ;
@@ -372,7 +372,7 @@ static int ipu_probe(struct platform_device *pdev)
_ipu_dmfc_init(DMFC_NORMAL, 1);
/* Set sync refresh channels and CSI->mem channel as high priority */
- __raw_writel(0x18800001L, IDMAC_CHA_PRI(0));
+ __raw_writel(0x18800003L, IDMAC_CHA_PRI(0));
/* Set MCU_T to divide MCU access window into 2 */
__raw_writel(0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN);
@@ -415,7 +415,10 @@ int ipu_remove(struct platform_device *pdev)
void ipu_dump_registers(void)
{
+ printk(KERN_DEBUG "--------------------------------------------\n");
printk(KERN_DEBUG "IPU_CONF = \t0x%08X\n", __raw_readl(IPU_CONF));
+ printk(KERN_DEBUG "SMFC_MAP = \t0x%08X\n", __raw_readl(SMFC_MAP));
+ printk(KERN_DEBUG "SMFC_WMC = \t0x%08X\n", __raw_readl(SMFC_WMC));
printk(KERN_DEBUG "IDMAC_CONF = \t0x%08X\n", __raw_readl(IDMAC_CONF));
printk(KERN_DEBUG "IDMAC_CHA_EN1 = \t0x%08X\n",
__raw_readl(IDMAC_CHA_EN(0)));
@@ -451,6 +454,25 @@ void ipu_dump_registers(void)
__raw_readl(IPU_FS_PROC_FLOW3));
printk(KERN_DEBUG "IPU_FS_DISP_FLOW1 = \t0x%08X\n",
__raw_readl(IPU_FS_DISP_FLOW1));
+
+ printk(KERN_DEBUG "IPU_INT_CTRL_1 = \t0x%08X\n", __raw_readl(IPU_INT_CTRL (1)));
+ printk(KERN_DEBUG "IPU_INT_STAT_1 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (1)));
+ printk(KERN_DEBUG "IPU_INT_STAT_2 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (2)));
+ printk(KERN_DEBUG "IPU_INT_STAT_3 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (3)));
+ printk(KERN_DEBUG "IPU_INT_STAT_4 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (4)));
+ printk(KERN_DEBUG "IPU_INT_STAT_5 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (5)));
+ printk(KERN_DEBUG "IPU_INT_STAT_6 = \t0x%08X\n", __raw_readl(IPU_INT_STAT (6)));
+
+ printk(KERN_DEBUG "CSI0_SENS_CONF = \t0x%08X\n", __raw_readl(CSI_SENS_CONF (0)));
+ printk(KERN_DEBUG "CSI0_SENS_FRM_SIZE = \t0x%08X\n", __raw_readl(CSI_SENS_FRM_SIZE(0)));
+ printk(KERN_DEBUG "CSI0_ACT_FRM_SIZE = \t0x%08X\n", __raw_readl(CSI_ACT_FRM_SIZE(0)));
+ printk(KERN_DEBUG "CSI0_SKIP = \t0x%08X\n", __raw_readl(CSI_SKIP(0)));
+
+ printk(KERN_DEBUG "CSI1_SENS_CONF = \t0x%08X\n", __raw_readl(CSI_SENS_CONF (1)));
+ printk(KERN_DEBUG "CSI1_SENS_FRM_SIZE = \t0x%08X\n", __raw_readl(CSI_SENS_FRM_SIZE(1)));
+ printk(KERN_DEBUG "CSI1_ACT_FRM_SIZE = \t0x%08X\n", __raw_readl(CSI_ACT_FRM_SIZE(1)));
+ printk(KERN_DEBUG "CSI1_SKIP = \t0x%08X\n", __raw_readl(CSI_SKIP(1)));
+ printk(KERN_DEBUG "--------------------------------------------\n");
}
/*!
@@ -660,7 +682,8 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
g_dc_di_assignment[1] = params->mem_dc_sync.di;
_ipu_dc_init(1, params->mem_dc_sync.di,
- params->mem_dc_sync.interlaced);
+ params->mem_dc_sync.interlaced,
+ params->mem_dc_sync.out_pixel_fmt);
ipu_di_use_count[params->mem_dc_sync.di]++;
ipu_dc_use_count++;
ipu_dmfc_use_count++;
@@ -678,7 +701,8 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
_ipu_dp_init(channel, params->mem_dp_bg_sync.in_pixel_fmt,
params->mem_dp_bg_sync.out_pixel_fmt);
_ipu_dc_init(5, params->mem_dp_bg_sync.di,
- params->mem_dp_bg_sync.interlaced);
+ params->mem_dp_bg_sync.interlaced,
+ params->mem_dp_bg_sync.out_pixel_fmt);
ipu_di_use_count[params->mem_dp_bg_sync.di]++;
ipu_dc_use_count++;
ipu_dp_use_count++;
@@ -702,7 +726,7 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
}
g_dc_di_assignment[8] = params->direct_async.di;
- _ipu_dc_init(8, params->direct_async.di, false);
+ _ipu_dc_init(8, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
ipu_di_use_count[params->direct_async.di]++;
ipu_dc_use_count++;
break;
@@ -713,7 +737,7 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
}
g_dc_di_assignment[9] = params->direct_async.di;
- _ipu_dc_init(9, params->direct_async.di, false);
+ _ipu_dc_init(9, params->direct_async.di, false, IPU_PIX_FMT_GENERIC);
ipu_di_use_count[params->direct_async.di]++;
ipu_dc_use_count++;
break;
@@ -724,31 +748,8 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
/* Enable IPU sub module */
g_channel_init_mask |= 1L << IPU_CHAN_ID(channel);
- if (ipu_ic_use_count == 1)
- ipu_conf |= IPU_CONF_IC_EN;
- if (ipu_vdi_use_count == 1) {
- ipu_conf |= IPU_CONF_VDI_EN;
- ipu_conf |= IPU_CONF_IC_INPUT;
- }
- if (ipu_rot_use_count == 1)
- ipu_conf |= IPU_CONF_ROT_EN;
- if (ipu_dc_use_count == 1)
- ipu_conf |= IPU_CONF_DC_EN;
- if (ipu_dp_use_count == 1)
- ipu_conf |= IPU_CONF_DP_EN;
- if (ipu_dmfc_use_count == 1)
- ipu_conf |= IPU_CONF_DMFC_EN;
- if (ipu_di_use_count[0] == 1) {
- ipu_conf |= IPU_CONF_DI0_EN;
- }
- if (ipu_di_use_count[1] == 1) {
- ipu_conf |= IPU_CONF_DI1_EN;
- }
- if (ipu_smfc_use_count == 1)
- ipu_conf |= IPU_CONF_SMFC_EN;
__raw_writel(ipu_conf, IPU_CONF);
-
err:
spin_unlock_irqrestore(&ipu_lock, lock_flags);
return ret;
@@ -775,8 +776,8 @@ void ipu_uninit_channel(ipu_channel_t channel)
/* Make sure channel is disabled */
/* Get input and output dma channels */
- in_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
- out_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
+ in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER);
+ out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER);
if (idma_is_set(IDMAC_CHA_EN, in_dma) ||
idma_is_set(IDMAC_CHA_EN, out_dma)) {
@@ -796,8 +797,10 @@ void ipu_uninit_channel(ipu_channel_t channel)
reg = __raw_readl(IPU_CHA_DB_MODE_SEL(out_dma));
__raw_writel(reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma));
- g_sec_chan_en[IPU_CHAN_ID(channel)] = false;
- g_thrd_chan_en[IPU_CHAN_ID(channel)] = false;
+ if (_ipu_is_ic_chan(in_dma) || _ipu_is_dp_graphic_chan(in_dma)) {
+ g_sec_chan_en[IPU_CHAN_ID(channel)] = false;
+ g_thrd_chan_en[IPU_CHAN_ID(channel)] = false;
+ }
switch (channel) {
case CSI_MEM0:
@@ -849,6 +852,9 @@ void ipu_uninit_channel(ipu_channel_t channel)
reg = __raw_readl(IPU_FS_PROC_FLOW1);
__raw_writel(reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1);
break;
+ case MEM_VDI_PRP_VF_MEM_P:
+ case MEM_VDI_PRP_VF_MEM_N:
+ break;
case MEM_ROT_VF_MEM:
ipu_rot_use_count--;
ipu_ic_use_count--;
@@ -913,6 +919,7 @@ void ipu_uninit_channel(ipu_channel_t channel)
if (ipu_ic_use_count == 0)
ipu_conf &= ~IPU_CONF_IC_EN;
if (ipu_vdi_use_count == 0) {
+ ipu_conf &= ~IPU_CONF_ISP_EN;
ipu_conf &= ~IPU_CONF_VDI_EN;
ipu_conf &= ~IPU_CONF_IC_INPUT;
}
@@ -1239,8 +1246,6 @@ int32_t ipu_select_buffer(ipu_channel_t channel, ipu_buffer_t type,
__raw_writel(idma_mask(dma_chan) | reg,
IPU_CHA_BUF1_RDY(dma_chan));
}
- if (channel == MEM_VDI_PRP_VF_MEM)
- _ipu_vdi_toggle_top_field_man();
return 0;
}
EXPORT_SYMBOL(ipu_select_buffer);
@@ -1269,10 +1274,9 @@ int32_t ipu_select_multi_vdi_buffer(uint32_t bufNum)
__raw_writel(mask_bit | reg, IPU_CHA_BUF0_RDY(dma_chan));
} else {
/*Mark buffer 1 as ready. */
- reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan));
+ reg = __raw_readl(IPU_CHA_BUF1_RDY(dma_chan));
__raw_writel(mask_bit | reg, IPU_CHA_BUF1_RDY(dma_chan));
}
- _ipu_vdi_toggle_top_field_man();
return 0;
}
EXPORT_SYMBOL(ipu_select_multi_vdi_buffer);
@@ -1282,7 +1286,7 @@ static int proc_dest_sel[] =
{ 0, 1, 1, 3, 5, 5, 4, 7, 8, 9, 10, 11, 12, 14, 15, 16,
0, 1, 1, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 14, 31 };
static int proc_src_sel[] = { 0, 6, 7, 6, 7, 8, 5, NA, NA, NA,
- NA, NA, NA, NA, NA, 1, 2, 3, 4, 7, 8, NA, NA, NA };
+ NA, NA, NA, NA, NA, 1, 2, 3, 4, 7, 8, NA, 8, NA };
static int disp_src_sel[] = { 0, 6, 7, 8, 3, 4, 5, NA, NA, NA,
NA, NA, NA, NA, NA, 1, NA, 2, NA, 3, 4, 4, 4, 4 };
@@ -1659,6 +1663,7 @@ int32_t ipu_enable_channel(ipu_channel_t channel)
{
uint32_t reg;
unsigned long lock_flags;
+ uint32_t ipu_conf;
uint32_t in_dma;
uint32_t out_dma;
uint32_t sec_dma;
@@ -1675,6 +1680,32 @@ int32_t ipu_enable_channel(ipu_channel_t channel)
spin_lock_irqsave(&ipu_lock, lock_flags);
+ ipu_conf = __raw_readl(IPU_CONF);
+ if (ipu_di_use_count[0] > 0) {
+ ipu_conf |= IPU_CONF_DI0_EN;
+ }
+ if (ipu_di_use_count[1] > 0) {
+ ipu_conf |= IPU_CONF_DI1_EN;
+ }
+ if (ipu_dp_use_count > 0)
+ ipu_conf |= IPU_CONF_DP_EN;
+ if (ipu_dc_use_count > 0)
+ ipu_conf |= IPU_CONF_DC_EN;
+ if (ipu_dmfc_use_count > 0)
+ ipu_conf |= IPU_CONF_DMFC_EN;
+ if (ipu_ic_use_count > 0)
+ ipu_conf |= IPU_CONF_IC_EN;
+ if (ipu_vdi_use_count > 0) {
+ ipu_conf |= IPU_CONF_ISP_EN;
+ ipu_conf |= IPU_CONF_VDI_EN;
+ ipu_conf |= IPU_CONF_IC_INPUT;
+ }
+ if (ipu_rot_use_count > 0)
+ ipu_conf |= IPU_CONF_ROT_EN;
+ if (ipu_smfc_use_count > 0)
+ ipu_conf |= IPU_CONF_SMFC_EN;
+ __raw_writel(ipu_conf, IPU_CONF);
+
if (idma_is_valid(in_dma)) {
reg = __raw_readl(IDMAC_CHA_EN(in_dma));
__raw_writel(reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma));
@@ -1710,8 +1741,11 @@ int32_t ipu_enable_channel(ipu_channel_t channel)
}
if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) ||
- (channel == MEM_FG_SYNC))
+ (channel == MEM_FG_SYNC)) {
+ reg = __raw_readl(IDMAC_WM_EN(in_dma));
+ __raw_writel(reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma));
_ipu_dp_dc_enable(channel);
+ }
if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
_ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma))
@@ -1726,6 +1760,38 @@ int32_t ipu_enable_channel(ipu_channel_t channel)
EXPORT_SYMBOL(ipu_enable_channel);
/*!
+ * This function check buffer ready for a logical channel.
+ *
+ * @param channel Input parameter for the logical channel ID.
+ *
+ * @param type Input parameter which buffer to clear.
+ *
+ * @param bufNum Input parameter for which buffer number clear
+ * ready state.
+ *
+ */
+int32_t ipu_check_buffer_busy(ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum)
+{
+ uint32_t dma_chan = channel_2_dma(channel, type);
+ uint32_t reg;
+
+ if (dma_chan == IDMA_CHAN_INVALID)
+ return -EINVAL;
+
+ if (bufNum == 0)
+ reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan));
+ else
+ reg = __raw_readl(IPU_CHA_BUF1_RDY(dma_chan));
+
+ if (reg & idma_mask(dma_chan))
+ return 1;
+ else
+ return 0;
+}
+EXPORT_SYMBOL(ipu_check_buffer_busy);
+
+/*!
* This function clear buffer ready for a logical channel.
*
* @param channel Input parameter for the logical channel ID.
@@ -1817,7 +1883,30 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop)
if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
(channel == MEM_DC_SYNC)) {
+ if (channel == MEM_FG_SYNC)
+ ipu_disp_set_window_pos(channel, 0, 0);
+
_ipu_dp_dc_disable(channel, false);
+
+ /*
+ * wait for BG channel EOF then disable FG-IDMAC,
+ * it avoid FG NFB4EOF error.
+ */
+ if (channel == MEM_FG_SYNC) {
+ int timeout = 50;
+
+ __raw_writel(IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF),
+ IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF));
+ while ((__raw_readl(IPUIRQ_2_STATREG(IPU_IRQ_BG_SYNC_EOF)) &
+ IPUIRQ_2_MASK(IPU_IRQ_BG_SYNC_EOF)) == 0) {
+ msleep(10);
+ timeout -= 10;
+ if (timeout <= 0) {
+ dev_err(g_ipu_dev, "warning: wait for bg sync eof timeout\n");
+ break;
+ }
+ }
+ }
} else if (wait_for_stop) {
while (idma_is_set(IDMAC_CHA_BUSY, in_dma) ||
idma_is_set(IDMAC_CHA_BUSY, out_dma) ||
@@ -1861,6 +1950,12 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop)
spin_lock_irqsave(&ipu_lock, lock_flags);
+ if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) ||
+ (channel == MEM_DC_SYNC)) {
+ reg = __raw_readl(IDMAC_WM_EN(in_dma));
+ __raw_writel(reg & ~idma_mask(in_dma), IDMAC_WM_EN(in_dma));
+ }
+
/* Disable IC task */
if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) ||
_ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma))
@@ -1897,8 +1992,6 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop)
g_channel_enable_mask &= ~(1L << IPU_CHAN_ID(channel));
- spin_unlock_irqrestore(&ipu_lock, lock_flags);
-
/* Set channel buffers NOT to be ready */
if (idma_is_valid(in_dma)) {
ipu_clear_buffer_ready(channel, IPU_VIDEO_IN_BUFFER, 0);
@@ -1917,6 +2010,8 @@ int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop)
ipu_clear_buffer_ready(channel, IPU_ALPHA_IN_BUFFER, 1);
}
+ spin_unlock_irqrestore(&ipu_lock, lock_flags);
+
return 0;
}
EXPORT_SYMBOL(ipu_disable_channel);
@@ -2029,7 +2124,6 @@ static irqreturn_t ipu_irq_handler(int irq, void *desc)
dev_id);
}
}
-
return result;
}
diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c
index 27455fe26ab6..bf71ea833f58 100644
--- a/drivers/mxc/ipu3/ipu_device.c
+++ b/drivers/mxc/ipu3/ipu_device.c
@@ -124,7 +124,6 @@ static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
(&parm, (ipu_channel_buf_parm *) arg,
sizeof(ipu_channel_buf_parm)))
return -EFAULT;
-
ret =
ipu_init_channel_buffer(
parm.channel, parm.type,
@@ -183,6 +182,17 @@ static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
}
break;
+ case IPU_SELECT_MULTI_VDI_BUFFER:
+ {
+ uint32_t parm;
+ if (copy_from_user
+ (&parm, (uint32_t *) arg,
+ sizeof(uint32_t)))
+ return -EFAULT;
+
+ ret = ipu_select_multi_vdi_buffer(parm);
+ }
+ break;
case IPU_LINK_CHANNELS:
{
ipu_channel_link link;
@@ -225,7 +235,6 @@ static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
(&info, (ipu_channel_info *) arg,
sizeof(ipu_channel_info)))
return -EFAULT;
-
ret = ipu_disable_channel(info.channel,
info.stop);
}
@@ -435,7 +444,7 @@ static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
static int mxc_ipu_mmap(struct file *file, struct vm_area_struct *vma)
{
-// vma->vm_page_prot = pgprot_writethru(vma->vm_page_prot);
+ vma->vm_page_prot = pgprot_writethru(vma->vm_page_prot);
if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
@@ -452,12 +461,20 @@ static int mxc_ipu_release(struct inode *inode, struct file *file)
return 0;
}
+int mxc_ipu_fsync(struct file *filp, struct dentry *dentry, int datasync)
+{
+ flush_cache_all();
+ outer_flush_all();
+ return 0;
+}
+
static struct file_operations mxc_ipu_fops = {
.owner = THIS_MODULE,
.open = mxc_ipu_open,
.mmap = mxc_ipu_mmap,
.release = mxc_ipu_release,
- .ioctl = mxc_ipu_ioctl
+ .ioctl = mxc_ipu_ioctl,
+ .fsync = mxc_ipu_fsync
};
int register_ipu_device()
diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c
index 00c5008d149f..14dde404990b 100644
--- a/drivers/mxc/ipu3/ipu_disp.c
+++ b/drivers/mxc/ipu3/ipu_disp.c
@@ -147,6 +147,37 @@ static int __init dmfc_setup(char *options)
}
__setup("dmfc=", dmfc_setup);
+static bool _ipu_update_dmfc_used_size(int dma_chan, int width, int dmfc_size)
+{
+ u32 fifo_size_5f = 1;
+ u32 dmfc_dp_chan = __raw_readl(DMFC_DP_CHAN);
+
+ if ((width > 352) && (dmfc_size == (256 * 4)))
+ fifo_size_5f = 1;
+ else if (width > 176)
+ fifo_size_5f = 2;
+ else if (width > 88)
+ fifo_size_5f = 3;
+ else if (width > 44)
+ fifo_size_5f = 4;
+ else if (width > 22)
+ fifo_size_5f = 5;
+ else if (width > 11)
+ fifo_size_5f = 6;
+ else if (width > 6)
+ fifo_size_5f = 7;
+ else
+ return false;
+
+ if (dma_chan == 27) {
+ dmfc_dp_chan &= ~DMFC_FIFO_SIZE_5F;
+ dmfc_dp_chan |= fifo_size_5f << 11;
+ __raw_writel(dmfc_dp_chan, DMFC_DP_CHAN);
+ }
+
+ return true;
+}
+
void _ipu_dmfc_set_wait4eot(int dma_chan, int width)
{
u32 dmfc_gen1 = __raw_readl(DMFC_GENERAL1);
@@ -169,7 +200,7 @@ void _ipu_dmfc_set_wait4eot(int dma_chan, int width)
else
dmfc_gen1 &= ~(1UL << 22);
} else if (dma_chan == 27) { /*5F*/
- if (dmfc_size_27/width > 2)
+ if (!_ipu_update_dmfc_used_size(dma_chan, width, dmfc_size_27))
dmfc_gen1 |= 1UL << 21;
else
dmfc_gen1 &= ~(1UL << 21);
@@ -245,6 +276,24 @@ static void _ipu_di_sync_config(int di, int wave_gen,
__raw_writel(reg, DI_STP_REP(di, wave_gen));
}
+static void _ipu_dc_map_link(int current_map,
+ int base_map_0, int buf_num_0,
+ int base_map_1, int buf_num_1,
+ int base_map_2, int buf_num_2)
+{
+ int ptr_0 = base_map_0 * 3 + buf_num_0;
+ int ptr_1 = base_map_1 * 3 + buf_num_1;
+ int ptr_2 = base_map_2 * 3 + buf_num_2;
+ int ptr;
+ u32 reg;
+ ptr = (ptr_2 << 10) + (ptr_1 << 5) + ptr_0;
+
+ reg = __raw_readl(DC_MAP_CONF_PTR(current_map));
+ reg &= ~(0x1F << ((16 * (current_map & 0x1))));
+ reg |= ptr << ((16 * (current_map & 0x1)));
+ __raw_writel(reg, DC_MAP_CONF_PTR(current_map));
+}
+
static void _ipu_dc_map_config(int map, int byte_num, int offset, int mask)
{
int ptr = map * 3 + byte_num;
@@ -269,32 +318,63 @@ static void _ipu_dc_map_clear(int map)
}
static void _ipu_dc_write_tmpl(int word, u32 opcode, u32 operand, int map,
- int wave, int glue, int sync)
+ int wave, int glue, int sync, int stop)
{
u32 reg;
- int stop = 1;
-
- reg = sync;
- reg |= (glue << 4);
- reg |= (++wave << 11);
- reg |= (++map << 15);
- reg |= (operand << 20) & 0xFFF00000;
- __raw_writel(reg, ipu_dc_tmpl_reg + word * 2);
-
- reg = (operand >> 12);
- reg |= opcode << 4;
- reg |= (stop << 9);
- __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1);
+
+ if (opcode == WRG) {
+ reg = sync;
+ reg |= (glue << 4);
+ reg |= (++wave << 11);
+ reg |= ((operand & 0x1FFFF) << 15);
+ __raw_writel(reg, ipu_dc_tmpl_reg + word * 2);
+
+ reg = (operand >> 17);
+ reg |= opcode << 7;
+ reg |= (stop << 9);
+ __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1);
+ } else {
+ reg = sync;
+ reg |= (glue << 4);
+ reg |= (++wave << 11);
+ reg |= (++map << 15);
+ reg |= (operand << 20) & 0xFFF00000;
+ __raw_writel(reg, ipu_dc_tmpl_reg + word * 2);
+
+ reg = (operand >> 12);
+ reg |= opcode << 4;
+ reg |= (stop << 9);
+ __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1);
+ }
}
static void _ipu_dc_link_event(int chan, int event, int addr, int priority)
{
u32 reg;
-
- reg = __raw_readl(DC_RL_CH(chan, event));
- reg &= ~(0xFFFF << (16 * (event & 0x1)));
- reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
- __raw_writel(reg, DC_RL_CH(chan, event));
+ u32 address_shift;
+ if (event < DC_EVEN_UGDE0) {
+ reg = __raw_readl(DC_RL_CH(chan, event));
+ reg &= ~(0xFFFF << (16 * (event & 0x1)));
+ reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
+ __raw_writel(reg, DC_RL_CH(chan, event));
+ } else {
+ reg = __raw_readl(DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
+ if ((event - DC_EVEN_UGDE0) & 0x1) {
+ reg &= ~(0x2FF << 16);
+ reg |= (addr << 16);
+ reg |= priority ? (2 << 24) : 0x0;
+ } else {
+ reg &= ~0xFC00FFFF;
+ if (priority)
+ chan = (chan >> 1) +
+ ((((chan & 0x1) + ((chan & 0x2) >> 1))) | (chan >> 3));
+ else
+ chan = 0x7;
+ address_shift = ((event - DC_EVEN_UGDE0) >> 1) ? 7 : 8;
+ reg |= (addr << address_shift) | (priority << 3) | chan;
+ }
+ __raw_writel(reg, DC_UGDE_0((event - DC_EVEN_UGDE0) / 2));
+ }
}
/* Y = R * 1.200 + G * 2.343 + B * .453 + 0.250;
@@ -503,7 +583,7 @@ void _ipu_dp_uninit(ipu_channel_t channel)
__ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], false);
}
-void _ipu_dc_init(int dc_chan, int di, bool interlaced)
+void _ipu_dc_init(int dc_chan, int di, bool interlaced, uint32_t pixel_fmt)
{
u32 reg = 0;
@@ -517,10 +597,24 @@ void _ipu_dc_init(int dc_chan, int di, bool interlaced)
_ipu_dc_link_event(dc_chan, DC_EVT_NL, 2, 3);
_ipu_dc_link_event(dc_chan, DC_EVT_EOL, 3, 2);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 4, 1);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_link_event(dc_chan, DC_ODD_UGDE1, 9, 5);
+ _ipu_dc_link_event(dc_chan, DC_EVEN_UGDE1, 8, 5);
+ }
} else {
_ipu_dc_link_event(dc_chan, DC_EVT_NL, 5, 3);
_ipu_dc_link_event(dc_chan, DC_EVT_EOL, 6, 2);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 7, 1);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_link_event(dc_chan, DC_ODD_UGDE0, 10, 5);
+ _ipu_dc_link_event(dc_chan, DC_EVEN_UGDE0, 11, 5);
+ }
}
}
_ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0);
@@ -562,6 +656,10 @@ void _ipu_dc_uninit(int dc_chan)
_ipu_dc_link_event(dc_chan, DC_EVT_EOFIELD, 0, 0);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN, 0, 0);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR, 0, 0);
+ _ipu_dc_link_event(dc_chan, DC_ODD_UGDE0, 0, 0);
+ _ipu_dc_link_event(dc_chan, DC_EVEN_UGDE0, 0, 0);
+ _ipu_dc_link_event(dc_chan, DC_ODD_UGDE1, 0, 0);
+ _ipu_dc_link_event(dc_chan, DC_EVEN_UGDE1, 0, 0);
} else if ((dc_chan == 8) || (dc_chan == 9)) {
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0);
_ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0);
@@ -637,6 +735,26 @@ static bool dc_swap;
static irqreturn_t dc_irq_handler(int irq, void *dev_id)
{
struct completion *comp = dev_id;
+ uint32_t reg;
+ uint32_t dc_chan;
+
+ if (irq == IPU_IRQ_DC_FC_1)
+ dc_chan = 1;
+ else
+ dc_chan = 5;
+
+ if (!dc_swap) {
+ reg = __raw_readl(DC_WR_CH_CONF(dc_chan));
+ reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
+ __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
+
+ reg = __raw_readl(IPU_DISP_GEN);
+ if (g_dc_di_assignment[dc_chan])
+ reg &= ~DI1_COUNTER_RELEASE;
+ else
+ reg &= ~DI0_COUNTER_RELEASE;
+ __raw_writel(reg, IPU_DISP_GEN);
+ }
complete(comp);
return IRQ_HANDLED;
@@ -689,29 +807,6 @@ void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap)
if (timeout <= 0)
break;
}
-
- timeout = 50;
-
- /*
- * Wait for DC triple buffer to empty,
- * this check is useful for tv overlay.
- */
- if (g_dc_di_assignment[dc_chan] == 0)
- while ((__raw_readl(DC_STAT) & 0x00000002)
- != 0x00000002) {
- msleep(2);
- timeout -= 2;
- if (timeout <= 0)
- break;
- }
- else if (g_dc_di_assignment[dc_chan] == 1)
- while ((__raw_readl(DC_STAT) & 0x00000020)
- != 0x00000020) {
- msleep(2);
- timeout -= 2;
- if (timeout <= 0)
- break;
- }
return;
} else {
return;
@@ -743,39 +838,6 @@ void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap)
__raw_writel(reg, DC_WR_CH_CONF(dc_chan));
spin_unlock_irqrestore(&ipu_lock, lock_flags);
} else {
- timeout = 50;
-
- /* Wait for DC triple buffer to empty */
- if (g_dc_di_assignment[dc_chan] == 0)
- while ((__raw_readl(DC_STAT) & 0x00000002)
- != 0x00000002) {
- msleep(2);
- timeout -= 2;
- if (timeout <= 0)
- break;
- }
- else if (g_dc_di_assignment[dc_chan] == 1)
- while ((__raw_readl(DC_STAT) & 0x00000020)
- != 0x00000020) {
- msleep(2);
- timeout -= 2;
- if (timeout <= 0)
- break;
- }
-
- spin_lock_irqsave(&ipu_lock, lock_flags);
- reg = __raw_readl(DC_WR_CH_CONF(dc_chan));
- reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
- __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
-
- reg = __raw_readl(IPU_DISP_GEN);
- if (g_dc_di_assignment[dc_chan])
- reg &= ~DI1_COUNTER_RELEASE;
- else
- reg &= ~DI0_COUNTER_RELEASE;
- __raw_writel(reg, IPU_DISP_GEN);
-
- spin_unlock_irqrestore(&ipu_lock, lock_flags);
/* Clock is already off because it must be done quickly, but
we need to fix the ref count */
clk_disable(g_pixel_clk[g_dc_di_assignment[dc_chan]]);
@@ -821,6 +883,34 @@ void _ipu_init_dc_mappings(void)
_ipu_dc_map_config(4, 0, 5, 0xFC);
_ipu_dc_map_config(4, 1, 13, 0xFC);
_ipu_dc_map_config(4, 2, 21, 0xFC);
+
+ /* IPU_PIX_FMT_VYUY 16bit width */
+ _ipu_dc_map_clear(5);
+ _ipu_dc_map_config(5, 0, 7, 0xFF);
+ _ipu_dc_map_config(5, 1, 0, 0x0);
+ _ipu_dc_map_config(5, 2, 15, 0xFF);
+ _ipu_dc_map_clear(6);
+ _ipu_dc_map_config(6, 0, 0, 0x0);
+ _ipu_dc_map_config(6, 1, 7, 0xFF);
+ _ipu_dc_map_config(6, 2, 15, 0xFF);
+
+ /* IPU_PIX_FMT_UYUV 16bit width */
+ _ipu_dc_map_clear(7);
+ _ipu_dc_map_link(7, 6, 0, 6, 1, 6, 2);
+ _ipu_dc_map_clear(8);
+ _ipu_dc_map_link(8, 5, 0, 5, 1, 5, 2);
+
+ /* IPU_PIX_FMT_YUYV 16bit width */
+ _ipu_dc_map_clear(9);
+ _ipu_dc_map_link(9, 5, 2, 5, 1, 5, 0);
+ _ipu_dc_map_clear(10);
+ _ipu_dc_map_link(10, 5, 1, 5, 2, 5, 0);
+
+ /* IPU_PIX_FMT_YVYU 16bit width */
+ _ipu_dc_map_clear(11);
+ _ipu_dc_map_link(11, 5, 1, 5, 2, 5, 0);
+ _ipu_dc_map_clear(12);
+ _ipu_dc_map_link(12, 5, 2, 5, 1, 5, 0);
}
int _ipu_pixfmt_to_map(uint32_t fmt)
@@ -837,6 +927,14 @@ int _ipu_pixfmt_to_map(uint32_t fmt)
return 3;
case IPU_PIX_FMT_LVDS666:
return 4;
+ case IPU_PIX_FMT_VYUY:
+ return 6;
+ case IPU_PIX_FMT_UYVY:
+ return 8;
+ case IPU_PIX_FMT_YUYV:
+ return 10;
+ case IPU_PIX_FMT_YVYU:
+ return 12;
}
return -1;
@@ -964,22 +1062,22 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
dev_dbg(g_ipu_dev, "pixel clk = %d\n", pixel_clk);
if (sig.ext_clk) {
- /* Set the PLL to be an even multiple of the pixel clock. not round div for tvout*/
- if ((clk_get_usecount(g_pixel_clk[0]) == 0) &&
- (clk_get_usecount(g_pixel_clk[1]) == 0)) {
+ /*
+ * Set the PLL to be an even multiple of the pixel clock.
+ * Not round div for tvout and ldb.
+ * Did not consider both DI come from the same ext clk, if
+ * meet such case, ext clk rate should be set specially.
+ */
+ if (clk_get_usecount(g_pixel_clk[disp]) == 0) {
di_parent = clk_get_parent(g_di_clk[disp]);
- if (strcmp(di_parent->name, "tve_clk") != 0) {
- rounded_pixel_clk =
- clk_round_rate(g_pixel_clk[disp], pixel_clk);
- div = clk_get_rate(di_parent) / rounded_pixel_clk;
- if (div % 2)
- div++;
-
- if (clk_get_rate(di_parent) != div * rounded_pixel_clk)
- clk_set_rate(di_parent, div * rounded_pixel_clk);
- msleep(10);
- clk_set_rate(g_di_clk[disp], 2 * rounded_pixel_clk);
- msleep(10);
+ if (strcmp(di_parent->name, "tve_clk") != 0 &&
+ strcmp(di_parent->name, "ldb_di0_clk") != 0 &&
+ strcmp(di_parent->name, "ldb_di1_clk") != 0) {
+ rounded_pixel_clk = pixel_clk * 2;
+ while (rounded_pixel_clk < 150000000)
+ rounded_pixel_clk += pixel_clk * 2;
+ clk_set_rate(di_parent, rounded_pixel_clk);
+ clk_set_rate(g_di_clk[disp], pixel_clk);
}
}
clk_set_parent(g_pixel_clk[disp], g_di_clk[disp]);
@@ -1019,7 +1117,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
di_gen = __raw_readl(DI_GENERAL(disp));
if (sig.interlaced) {
- if (cpu_is_mx51_rev(CHIP_REV_2_0)) {
+ if (g_ipu_hw_rev >= 2) {
/* Setup internal HSYNC waveform */
_ipu_di_sync_config(
disp, /* display */
@@ -1259,7 +1357,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
}
/* Init template microcode */
- _ipu_dc_write_tmpl(0, WROD(0), 0, map, SYNC_WAVE, 0, 8);
+ _ipu_dc_write_tmpl(0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
if (sig.Hsync_pol)
di_gen |= DI_GEN_POLARITY_3;
@@ -1322,13 +1420,31 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
/* Init template microcode */
if (disp) {
- _ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5);
- _ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5);
- _ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_write_tmpl(8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
+ _ipu_dc_write_tmpl(9, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
+ /* configure user events according to DISP NUM */
+ __raw_writel((width - 1), DC_UGDE_3(disp));
+ }
+ _ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
+ _ipu_dc_write_tmpl(3, WRG, 0, map, SYNC_WAVE, 4, 5, 1);
+ _ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
} else {
- _ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5);
- _ipu_dc_write_tmpl(6, WROD(0), 0, map, SYNC_WAVE, 4, 5);
- _ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY)) {
+ _ipu_dc_write_tmpl(10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5, 1);
+ _ipu_dc_write_tmpl(11, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
+ /* configure user events according to DISP NUM */
+ __raw_writel(width - 1, DC_UGDE_3(disp));
+ }
+ _ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5, 1);
+ _ipu_dc_write_tmpl(6, WRG, 0, map, SYNC_WAVE, 4, 5, 1);
+ _ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5, 1);
}
if (sig.Hsync_pol)
@@ -1340,6 +1456,19 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
/* Set the clock to stop at counter 6. */
di_gen |= 0x6000000;
}
+ /* changinc DISP_CLK polarity: it can be wrong for some applications */
+ if ((pixel_fmt == IPU_PIX_FMT_YUYV) ||
+ (pixel_fmt == IPU_PIX_FMT_UYVY) ||
+ (pixel_fmt == IPU_PIX_FMT_YVYU) ||
+ (pixel_fmt == IPU_PIX_FMT_VYUY))
+ di_gen |= 0x00020000;
+ else {
+ /* Configure accordingly to the received configuration */
+ if (sig.clk_pol)
+ di_gen |= 0x00020000;
+ else
+ di_gen &= ~0x00020000;
+ }
__raw_writel(di_gen, DI_GENERAL(disp));
@@ -1402,7 +1531,7 @@ int ipu_init_async_panel(int disp, int type, uint32_t cycle_time,
_ipu_di_data_pin_config(disp, ASYNC_SER_WAVE, DI_PIN_SER_RS,
2, 0, 0);
- _ipu_dc_write_tmpl(0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0);
+ _ipu_dc_write_tmpl(0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0, 1);
/* Configure DC for serial panel */
__raw_writel(0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL));
@@ -1679,6 +1808,39 @@ int32_t ipu_disp_set_window_pos(ipu_channel_t channel, int16_t x_pos,
}
EXPORT_SYMBOL(ipu_disp_set_window_pos);
+int32_t ipu_disp_get_window_pos(ipu_channel_t channel, int16_t *x_pos,
+ int16_t *y_pos)
+{
+ u32 reg;
+ unsigned long lock_flags;
+ uint32_t flow = 0;
+
+ if (channel == MEM_FG_SYNC)
+ flow = DP_SYNC;
+ else if (channel == MEM_FG_ASYNC0)
+ flow = DP_ASYNC0;
+ else if (channel == MEM_FG_ASYNC1)
+ flow = DP_ASYNC1;
+ else
+ return -EINVAL;
+
+ if (!g_ipu_clk_enabled)
+ clk_enable(g_ipu_clk);
+ spin_lock_irqsave(&ipu_lock, lock_flags);
+
+ reg = __raw_readl(DP_FG_POS(flow));
+
+ *x_pos = (reg >> 16) & 0x7FF;
+ *y_pos = reg & 0x7FF;
+
+ spin_unlock_irqrestore(&ipu_lock, lock_flags);
+ if (!g_ipu_clk_enabled)
+ clk_disable(g_ipu_clk);
+
+ return 0;
+}
+EXPORT_SYMBOL(ipu_disp_get_window_pos);
+
void ipu_disp_direct_write(ipu_channel_t channel, u32 value, u32 offset)
{
if (channel == DIRECT_ASYNC0)
diff --git a/drivers/mxc/ipu3/ipu_ic.c b/drivers/mxc/ipu3/ipu_ic.c
index 564fab0b699a..78c3a9228941 100644
--- a/drivers/mxc/ipu3/ipu_ic.c
+++ b/drivers/mxc/ipu3/ipu_ic.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -157,7 +157,6 @@ void _ipu_vdi_init(ipu_channel_t channel, ipu_channel_params_t *params)
{
uint32_t reg;
uint32_t pixel_fmt;
- bool top_field_0;
reg = ((params->mem_prp_vf_mem.in_height-1) << 16) |
(params->mem_prp_vf_mem.in_width-1);
@@ -186,19 +185,7 @@ void _ipu_vdi_init(ipu_channel_t channel, ipu_channel_params_t *params)
}
__raw_writel(reg, VDI_C);
- /* MED_MOTION and LOW_MOTION algorithm that are using 3 fields
- * should start presenting using the 2nd field.
- */
- if (((params->mem_prp_vf_mem.field_fmt == V4L2_FIELD_INTERLACED_TB) &&
- (params->mem_prp_vf_mem.motion_sel != HIGH_MOTION)) ||
- ((params->mem_prp_vf_mem.field_fmt == V4L2_FIELD_INTERLACED_BT) &&
- (params->mem_prp_vf_mem.motion_sel == HIGH_MOTION)))
- top_field_0 = false;
- else
- top_field_0 = true;
-
- /* Buffer selection toggle the value therefore init val is inverted. */
- _ipu_vdi_set_top_field_man(!top_field_0);
+ _ipu_vdi_set_top_field_man(false);
_ipu_vdi_set_motion(params->mem_prp_vf_mem.motion_sel);
@@ -227,13 +214,13 @@ void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi)
/* Setup horizontal resizing */
/* Upadeted for IC split case */
- if (!(params->mem_prp_vf_mem.out_resize_ratio)) {
+ if (!(params->mem_prp_vf_mem.outh_resize_ratio)) {
_calc_resize_coeffs(params->mem_prp_vf_mem.in_width,
params->mem_prp_vf_mem.out_width,
&resizeCoeff, &downsizeCoeff);
reg |= (downsizeCoeff << 14) | resizeCoeff;
} else
- reg |= params->mem_prp_vf_mem.out_resize_ratio;
+ reg |= params->mem_prp_vf_mem.outh_resize_ratio;
__raw_writel(reg, IC_PRP_VF_RSC);
@@ -349,13 +336,13 @@ void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi)
/* Setup horizontal resizing */
/* Upadeted for IC split case */
- if (!(params->mem_prp_enc_mem.out_resize_ratio)) {
+ if (!(params->mem_prp_enc_mem.outh_resize_ratio)) {
_calc_resize_coeffs(params->mem_prp_enc_mem.in_width,
params->mem_prp_enc_mem.out_width,
&resizeCoeff, &downsizeCoeff);
reg |= (downsizeCoeff << 14) | resizeCoeff;
} else
- reg |= params->mem_prp_enc_mem.out_resize_ratio;
+ reg |= params->mem_prp_enc_mem.outh_resize_ratio;
__raw_writel(reg, IC_PRP_ENC_RSC);
@@ -387,6 +374,8 @@ void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi)
ic_conf |= IC_CONF_RWS_EN;
__raw_writel(ic_conf, IC_CONF);
+
+// ic_dump_register();
}
void _ipu_ic_uninit_prpenc(void)
@@ -418,20 +407,24 @@ void _ipu_ic_init_pp(ipu_channel_params_t *params)
ipu_color_space_t in_fmt, out_fmt;
/* Setup vertical resizing */
- _calc_resize_coeffs(params->mem_pp_mem.in_height,
+ if (!(params->mem_pp_mem.outv_resize_ratio)) {
+ _calc_resize_coeffs(params->mem_pp_mem.in_height,
params->mem_pp_mem.out_height,
&resizeCoeff, &downsizeCoeff);
- reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
+ reg = (downsizeCoeff << 30) | (resizeCoeff << 16);
+ } else {
+ reg = (params->mem_pp_mem.outv_resize_ratio) << 16;
+ }
/* Setup horizontal resizing */
/* Upadeted for IC split case */
- if (!(params->mem_pp_mem.out_resize_ratio)) {
+ if (!(params->mem_pp_mem.outh_resize_ratio)) {
_calc_resize_coeffs(params->mem_pp_mem.in_width,
params->mem_pp_mem.out_width,
&resizeCoeff, &downsizeCoeff);
reg |= (downsizeCoeff << 14) | resizeCoeff;
} else {
- reg |= params->mem_pp_mem.out_resize_ratio;
+ reg |= params->mem_pp_mem.outh_resize_ratio;
}
__raw_writel(reg, IC_PP_RSC);
diff --git a/drivers/mxc/ipu3/ipu_param_mem.h b/drivers/mxc/ipu3/ipu_param_mem.h
index dab3b617db1c..30e6dc1005ba 100644
--- a/drivers/mxc/ipu3/ipu_param_mem.h
+++ b/drivers/mxc/ipu3/ipu_param_mem.h
@@ -155,8 +155,15 @@ static inline void _ipu_ch_param_init(int ch,
ipu_ch_param_set_field(&params, 1, 102, 14, stride - 1);
}
+ /* EBA is 8-byte aligned */
ipu_ch_param_set_field(&params, 1, 0, 29, addr0 >> 3);
ipu_ch_param_set_field(&params, 1, 29, 29, addr1 >> 3);
+ if (addr0%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's EBA0 is not 8-byte aligned\n", ch);
+ if (addr1%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's EBA1 is not 8-byte aligned\n", ch);
switch (pixel_fmt) {
case IPU_PIX_FMT_GENERIC:
@@ -210,13 +217,14 @@ static inline void _ipu_ch_param_init(int ch,
case IPU_PIX_FMT_ABGR32:
ipu_ch_param_set_field(&params, 0, 107, 3, 0); /* bits/pixel */
ipu_ch_param_set_field(&params, 1, 85, 4, 7); /* pix format */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
_ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
break;
case IPU_PIX_FMT_UYVY:
ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
ipu_ch_param_set_field(&params, 1, 85, 4, 0xA); /* pix format */
- ipu_ch_param_set_field(&params, 1, 78, 7, 15); /* burst size */
+ ipu_ch_param_set_field(&params, 1, 78, 7, 31); /* burst size */
break;
case IPU_PIX_FMT_YUYV:
ipu_ch_param_set_field(&params, 0, 107, 3, 3); /* bits/pixel */
@@ -289,13 +297,19 @@ static inline void _ipu_ch_param_init(int ch,
v_offset = v;
}
- /* UBO and VBO are 22-bit */
+ /* UBO and VBO are 22-bit and 8-byte aligned */
if (u_offset/8 > 0x3fffff)
- dev_err(g_ipu_dev,
- "The value of U offset exceeds IPU limitation\n");
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's U offset exceeds IPU limitation\n", ch);
if (v_offset/8 > 0x3fffff)
- dev_err(g_ipu_dev,
- "The value of V offset exceeds IPU limitation\n");
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's V offset exceeds IPU limitation\n", ch);
+ if (u_offset%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's U offset is not 8-byte aligned\n", ch);
+ if (v_offset%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's V offset is not 8-byte aligned\n", ch);
ipu_ch_param_set_field(&params, 0, 46, 22, u_offset / 8);
ipu_ch_param_set_field(&params, 0, 68, 22, v_offset / 8);
@@ -386,6 +400,13 @@ static inline void _ipu_ch_param_set_interlaced_scan(uint32_t ch)
u32 stride;
ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 113, 1, 1);
stride = ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14) + 1;
+ /* ILO is 20-bit and 8-byte aligned */
+ if (stride/8 > 0xfffff)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's ILO exceeds IPU limitation\n", ch);
+ if (stride%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's ILO is not 8-byte aligned\n", ch);
ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 58, 20, stride / 8);
stride *= 2;
ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 102, 14, stride - 1);
@@ -442,7 +463,7 @@ static inline void _ipu_ch_offset_update(int ch,
(uv_stride * vertical_offset / 2) +
horizontal_offset / 2;
v_offset = u_offset + (uv_stride * height / 2);
- u_fix = u ? (u + (uv_stride * vertical_offset) +
+ u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
(horizontal_offset / 2) -
(stride * vertical_offset) - (horizontal_offset)) :
u_offset;
@@ -493,9 +514,9 @@ static inline void _ipu_ch_offset_update(int ch,
uv_stride = stride;
u_offset = stride * (height - vertical_offset - 1) +
(stride - horizontal_offset) +
- (uv_stride * vertical_offset) +
+ (uv_stride * vertical_offset / 2) +
horizontal_offset;
- u_fix = u ? (u + (uv_stride * vertical_offset) +
+ u_fix = u ? (u + (uv_stride * vertical_offset / 2) +
horizontal_offset -
(stride * vertical_offset) - (horizontal_offset)) :
u_offset;
@@ -514,13 +535,19 @@ static inline void _ipu_ch_offset_update(int ch,
if (v_fix > v_offset)
v_offset = v_fix;
- /* UBO and VBO are 22-bit */
+ /* UBO and VBO are 22-bit and 8-byte aligned */
if (u_offset/8 > 0x3fffff)
- dev_err(g_ipu_dev,
- "The value of U offset exceeds IPU limitation\n");
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's U offset exceeds IPU limitation\n", ch);
if (v_offset/8 > 0x3fffff)
- dev_err(g_ipu_dev,
- "The value of V offset exceeds IPU limitation\n");
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's V offset exceeds IPU limitation\n", ch);
+ if (u_offset%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's U offset is not 8-byte aligned\n", ch);
+ if (v_offset%8)
+ dev_warn(g_ipu_dev,
+ "IDMAC%d's V offset is not 8-byte aligned\n", ch);
ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 46, 22, u_offset / 8);
ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 68, 22, v_offset / 8);
diff --git a/drivers/mxc/ipu3/ipu_prv.h b/drivers/mxc/ipu3/ipu_prv.h
index 213ded04c87d..4e62b256889f 100644
--- a/drivers/mxc/ipu3/ipu_prv.h
+++ b/drivers/mxc/ipu3/ipu_prv.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2010 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -60,7 +60,7 @@ void _ipu_init_dc_mappings(void);
int _ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt,
uint32_t out_pixel_fmt);
void _ipu_dp_uninit(ipu_channel_t channel);
-void _ipu_dc_init(int dc_chan, int di, bool interlaced);
+void _ipu_dc_init(int dc_chan, int di, bool interlaced, uint32_t pixel_fmt);
void _ipu_dc_uninit(int dc_chan);
void _ipu_dp_dc_enable(ipu_channel_t channel);
void _ipu_dp_dc_disable(ipu_channel_t channel, bool swap);
diff --git a/drivers/mxc/ipu3/ipu_regs.h b/drivers/mxc/ipu3/ipu_regs.h
index 2438df60a0ce..4a78e14df560 100644
--- a/drivers/mxc/ipu3/ipu_regs.h
+++ b/drivers/mxc/ipu3/ipu_regs.h
@@ -261,6 +261,14 @@ extern u32 *ipu_vdi_reg;
#define DC_EVT_NEW_CHAN_R_1 9
#define DC_EVT_NEW_DATA_R_0 10
#define DC_EVT_NEW_DATA_R_1 11
+#define DC_EVEN_UGDE0 12
+#define DC_ODD_UGDE0 13
+#define DC_EVEN_UGDE1 14
+#define DC_ODD_UGDE1 15
+#define DC_EVEN_UGDE2 16
+#define DC_ODD_UGDE2 17
+#define DC_EVEN_UGDE3 18
+#define DC_ODD_UGDE3 19
#define dc_ch_offset(ch) \
({ \
@@ -627,6 +635,8 @@ enum {
VDI_C_VWM3_CLR_2 = 0x02000000,
VDI_C_TOP_FIELD_MAN_1 = 0x40000000,
VDI_C_TOP_FIELD_AUTO_1 = 0x80000000,
+
+ DMFC_FIFO_SIZE_5F = 0x00003800,
};
enum di_pins {
@@ -654,5 +664,6 @@ enum di_sync_wave {
/* DC template opcodes */
#define WROD(lf) (0x18 | (lf << 1))
+#define WRG (0x01)
#endif