summaryrefslogtreecommitdiff
path: root/drivers/mxc/ipu3/ipu_disp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mxc/ipu3/ipu_disp.c')
-rw-r--r--drivers/mxc/ipu3/ipu_disp.c364
1 files changed, 263 insertions, 101 deletions
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)