summaryrefslogtreecommitdiff
path: root/drivers/mxc/ipu3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/ipu3')
-rw-r--r--drivers/mxc/ipu3/ipu_capture.c118
-rw-r--r--drivers/mxc/ipu3/ipu_common.c40
-rw-r--r--drivers/mxc/ipu3/ipu_disp.c142
-rw-r--r--drivers/mxc/ipu3/ipu_regs.h1
4 files changed, 88 insertions, 213 deletions
diff --git a/drivers/mxc/ipu3/ipu_capture.c b/drivers/mxc/ipu3/ipu_capture.c
index b9967135eac1..e801705f8fe9 100644
--- a/drivers/mxc/ipu3/ipu_capture.c
+++ b/drivers/mxc/ipu3/ipu_capture.c
@@ -26,7 +26,6 @@
#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"
@@ -94,12 +93,6 @@ 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));
@@ -185,13 +178,36 @@ 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) {
- clk_enable(g_csi_clk[csi]);
+ 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
+ // CCWMX51 - Both CSIs from master clock 0
+ clk_enable(g_csi_clk[0]);
if (wait == true)
msleep(10);
} else {
- clk_disable(g_csi_clk[csi]);
+ 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
+ // CCWMX51 - Both CSIs from master clock 0
+ clk_disable(g_csi_clk[0]);
}
return 0;
@@ -210,12 +226,6 @@ 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));
@@ -237,12 +247,6 @@ 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));
@@ -263,12 +267,6 @@ 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));
@@ -291,12 +289,6 @@ 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));
@@ -317,12 +309,6 @@ 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));
@@ -343,12 +329,6 @@ 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));
@@ -369,12 +349,6 @@ 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));
@@ -401,12 +375,6 @@ 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));
@@ -442,12 +410,6 @@ 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));
@@ -464,12 +426,6 @@ 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));
@@ -495,12 +451,6 @@ 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));
@@ -558,12 +508,6 @@ 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));
@@ -601,12 +545,6 @@ 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));
@@ -674,12 +612,6 @@ 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 b1b8a8b39ae1..eae3b549d765 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -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] = plat_data->csi_clk[0];
- g_csi_clk[1] = plat_data->csi_clk[1];
+ g_csi_clk[0] = clk_get(&pdev->dev, "csi_mclk1");
+ g_csi_clk[1] = clk_get(&pdev->dev, "csi_mclk2");
__raw_writel(0x807FFFFF, IPU_MEM_RST);
while (__raw_readl(IPU_MEM_RST) & 0x80000000) ;
@@ -1883,29 +1883,29 @@ 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);
+ int timeout = 50;
+ int irq;
_ipu_dp_dc_disable(channel, false);
/*
- * wait for BG channel EOF then disable FG-IDMAC,
- * it avoid FG NFB4EOF error.
+ * wait for display channel EOF then disable IDMAC,
+ * it avoid 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;
- }
- }
+ if (channel == MEM_BG_SYNC)
+ irq = IPU_IRQ_BG_SYNC_EOF;
+ if (channel == MEM_FG_SYNC)
+ irq = IPU_IRQ_FG_SYNC_EOF;
+ else
+ irq = IPU_IRQ_DC_SYNC_EOF;
+ __raw_writel(IPUIRQ_2_MASK(irq),
+ IPUIRQ_2_STATREG(irq));
+ while ((__raw_readl(IPUIRQ_2_STATREG(irq)) &
+ IPUIRQ_2_MASK(irq)) == 0) {
+ msleep(10);
+ timeout -= 10;
+ if (timeout <= 0)
+ break;
}
} else if (wait_for_stop) {
while (idma_is_set(IDMAC_CHA_BUSY, in_dma) ||
diff --git a/drivers/mxc/ipu3/ipu_disp.c b/drivers/mxc/ipu3/ipu_disp.c
index 14dde404990b..7ce04d8bca9e 100644
--- a/drivers/mxc/ipu3/ipu_disp.c
+++ b/drivers/mxc/ipu3/ipu_disp.c
@@ -318,34 +318,22 @@ 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 stop)
+ int wave, int glue, int sync)
{
u32 reg;
-
- 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);
- }
+ 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);
}
static void _ipu_dc_link_event(int chan, int event, int addr, int priority)
@@ -735,26 +723,6 @@ 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;
@@ -838,6 +806,19 @@ 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 {
+ 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]]);
@@ -1062,13 +1043,9 @@ 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 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) {
+ /* 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)) {
di_parent = clk_get_parent(g_di_clk[disp]);
if (strcmp(di_parent->name, "tve_clk") != 0 &&
strcmp(di_parent->name, "ldb_di0_clk") != 0 &&
@@ -1117,7 +1094,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
di_gen = __raw_readl(DI_GENERAL(disp));
if (sig.interlaced) {
- if (g_ipu_hw_rev >= 2) {
+ if (cpu_is_mx51_rev(CHIP_REV_2_0)) {
/* Setup internal HSYNC waveform */
_ipu_di_sync_config(
disp, /* display */
@@ -1357,7 +1334,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, 1);
+ _ipu_dc_write_tmpl(0, WROD(0), 0, map, SYNC_WAVE, 0, 8);
if (sig.Hsync_pol)
di_gen |= DI_GEN_POLARITY_3;
@@ -1424,27 +1401,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(8, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5);
+ _ipu_dc_write_tmpl(9, WROD(0), 0, map, SYNC_WAVE, 0, 5);
/* 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);
+ _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);
} 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(10, WROD(0), 0, (map - 1), SYNC_WAVE, 0, 5);
+ _ipu_dc_write_tmpl(11, WROD(0), 0, map, SYNC_WAVE, 0, 5);
/* 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);
+ _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 (sig.Hsync_pol)
@@ -1531,7 +1508,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, 1);
+ _ipu_dc_write_tmpl(0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0);
/* Configure DC for serial panel */
__raw_writel(0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL));
@@ -1808,39 +1785,6 @@ 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_regs.h b/drivers/mxc/ipu3/ipu_regs.h
index 4a78e14df560..19fde8846aa7 100644
--- a/drivers/mxc/ipu3/ipu_regs.h
+++ b/drivers/mxc/ipu3/ipu_regs.h
@@ -664,6 +664,5 @@ enum di_sync_wave {
/* DC template opcodes */
#define WROD(lf) (0x18 | (lf << 1))
-#define WRG (0x01)
#endif