1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#include <common.h>
33#include <linux/types.h>
34#include <asm/errno.h>
35#include <asm/io.h>
36#include <asm/arch/imx-regs.h>
37#include <asm/arch/sys_proto.h>
38#include "ipu.h"
39#include "ipu_regs.h"
40
41enum csc_type_t {
42 RGB2YUV = 0,
43 YUV2RGB,
44 RGB2RGB,
45 YUV2YUV,
46 CSC_NONE,
47 CSC_NUM
48};
49
50struct dp_csc_param_t {
51 int mode;
52 void *coeff;
53};
54
55#define SYNC_WAVE 0
56
57
58#define DC_DISP_ID_SYNC(di) (di)
59#define DC_DISP_ID_SERIAL 2
60#define DC_DISP_ID_ASYNC 3
61
62int dmfc_type_setup;
63static int dmfc_size_28, dmfc_size_29, dmfc_size_24, dmfc_size_27, dmfc_size_23;
64int g_di1_tvout;
65
66extern struct clk *g_ipu_clk;
67extern struct clk *g_di_clk[2];
68extern struct clk *g_pixel_clk[2];
69
70extern unsigned char g_ipu_clk_enabled;
71extern unsigned char g_dc_di_assignment[];
72
73void ipu_dmfc_init(int dmfc_type, int first)
74{
75 u32 dmfc_wr_chan, dmfc_dp_chan;
76
77 if (first) {
78 if (dmfc_type_setup > dmfc_type)
79 dmfc_type = dmfc_type_setup;
80 else
81 dmfc_type_setup = dmfc_type;
82
83
84 __raw_writel(0x2, DMFC_IC_CTRL);
85 } else if (dmfc_type_setup >= DMFC_HIGH_RESOLUTION_DC) {
86 printf("DMFC high resolution has set, will not change\n");
87 return;
88 } else
89 dmfc_type_setup = dmfc_type;
90
91 if (dmfc_type == DMFC_HIGH_RESOLUTION_DC) {
92
93
94
95
96
97 debug("IPU DMFC DC HIGH RES: 1(0~3), 5B(4,5), 5F(6,7)\n");
98 dmfc_wr_chan = 0x00000088;
99 dmfc_dp_chan = 0x00009694;
100 dmfc_size_28 = 256 * 4;
101 dmfc_size_29 = 0;
102 dmfc_size_24 = 0;
103 dmfc_size_27 = 128 * 4;
104 dmfc_size_23 = 128 * 4;
105 } else if (dmfc_type == DMFC_HIGH_RESOLUTION_DP) {
106
107
108
109
110
111 debug("IPU DMFC DP HIGH RES: 1(0,1), 5B(2~5), 5F(6,7)\n");
112 dmfc_wr_chan = 0x00000090;
113 dmfc_dp_chan = 0x0000968a;
114 dmfc_size_28 = 128 * 4;
115 dmfc_size_29 = 0;
116 dmfc_size_24 = 0;
117 dmfc_size_27 = 128 * 4;
118 dmfc_size_23 = 256 * 4;
119 } else if (dmfc_type == DMFC_HIGH_RESOLUTION_ONLY_DP) {
120
121
122
123
124 debug("IPU DMFC ONLY-DP HIGH RES: 5B(0~3), 5F(4~7)\n");
125 dmfc_wr_chan = 0x00000000;
126 dmfc_dp_chan = 0x00008c88;
127 dmfc_size_28 = 0;
128 dmfc_size_29 = 0;
129 dmfc_size_24 = 0;
130 dmfc_size_27 = 256 * 4;
131 dmfc_size_23 = 256 * 4;
132 } else {
133
134
135
136
137
138 debug("IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)\n");
139 dmfc_wr_chan = 0x00000090;
140 dmfc_dp_chan = 0x00009694;
141 dmfc_size_28 = 128 * 4;
142 dmfc_size_29 = 0;
143 dmfc_size_24 = 0;
144 dmfc_size_27 = 128 * 4;
145 dmfc_size_23 = 128 * 4;
146 }
147 __raw_writel(dmfc_wr_chan, DMFC_WR_CHAN);
148 __raw_writel(0x202020F6, DMFC_WR_CHAN_DEF);
149 __raw_writel(dmfc_dp_chan, DMFC_DP_CHAN);
150
151 __raw_writel(0x2020F6F6, DMFC_DP_CHAN_DEF);
152}
153
154void ipu_dmfc_set_wait4eot(int dma_chan, int width)
155{
156 u32 dmfc_gen1 = __raw_readl(DMFC_GENERAL1);
157
158 if (width >= HIGH_RESOLUTION_WIDTH) {
159 if (dma_chan == 23)
160 ipu_dmfc_init(DMFC_HIGH_RESOLUTION_DP, 0);
161 else if (dma_chan == 28)
162 ipu_dmfc_init(DMFC_HIGH_RESOLUTION_DC, 0);
163 }
164
165 if (dma_chan == 23) {
166 if (dmfc_size_23 / width > 3)
167 dmfc_gen1 |= 1UL << 20;
168 else
169 dmfc_gen1 &= ~(1UL << 20);
170 } else if (dma_chan == 24) {
171 if (dmfc_size_24 / width > 1)
172 dmfc_gen1 |= 1UL << 22;
173 else
174 dmfc_gen1 &= ~(1UL << 22);
175 } else if (dma_chan == 27) {
176 if (dmfc_size_27 / width > 2)
177 dmfc_gen1 |= 1UL << 21;
178 else
179 dmfc_gen1 &= ~(1UL << 21);
180 } else if (dma_chan == 28) {
181 if (dmfc_size_28 / width > 2)
182 dmfc_gen1 |= 1UL << 16;
183 else
184 dmfc_gen1 &= ~(1UL << 16);
185 } else if (dma_chan == 29) {
186 if (dmfc_size_29 / width > 1)
187 dmfc_gen1 |= 1UL << 23;
188 else
189 dmfc_gen1 &= ~(1UL << 23);
190 }
191
192 __raw_writel(dmfc_gen1, DMFC_GENERAL1);
193}
194
195static void ipu_di_data_wave_config(int di,
196 int wave_gen,
197 int access_size, int component_size)
198{
199 u32 reg;
200 reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) |
201 (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET);
202 __raw_writel(reg, DI_DW_GEN(di, wave_gen));
203}
204
205static void ipu_di_data_pin_config(int di, int wave_gen, int di_pin, int set,
206 int up, int down)
207{
208 u32 reg;
209
210 reg = __raw_readl(DI_DW_GEN(di, wave_gen));
211 reg &= ~(0x3 << (di_pin * 2));
212 reg |= set << (di_pin * 2);
213 __raw_writel(reg, DI_DW_GEN(di, wave_gen));
214
215 __raw_writel((down << 16) | up, DI_DW_SET(di, wave_gen, set));
216}
217
218static void ipu_di_sync_config(int di, int wave_gen,
219 int run_count, int run_src,
220 int offset_count, int offset_src,
221 int repeat_count, int cnt_clr_src,
222 int cnt_polarity_gen_en,
223 int cnt_polarity_clr_src,
224 int cnt_polarity_trigger_src,
225 int cnt_up, int cnt_down)
226{
227 u32 reg;
228
229 if ((run_count >= 0x1000) || (offset_count >= 0x1000) ||
230 (repeat_count >= 0x1000) ||
231 (cnt_up >= 0x400) || (cnt_down >= 0x400)) {
232 printf("DI%d counters out of range.\n", di);
233 return;
234 }
235
236 reg = (run_count << 19) | (++run_src << 16) |
237 (offset_count << 3) | ++offset_src;
238 __raw_writel(reg, DI_SW_GEN0(di, wave_gen));
239 reg = (cnt_polarity_gen_en << 29) | (++cnt_clr_src << 25) |
240 (++cnt_polarity_trigger_src << 12) | (++cnt_polarity_clr_src << 9);
241 reg |= (cnt_down << 16) | cnt_up;
242 if (repeat_count == 0) {
243
244 reg |= 0x10000000;
245 }
246 __raw_writel(reg, DI_SW_GEN1(di, wave_gen));
247 reg = __raw_readl(DI_STP_REP(di, wave_gen));
248 reg &= ~(0xFFFF << (16 * ((wave_gen - 1) & 0x1)));
249 reg |= repeat_count << (16 * ((wave_gen - 1) & 0x1));
250 __raw_writel(reg, DI_STP_REP(di, wave_gen));
251}
252
253static void ipu_dc_map_config(int map, int byte_num, int offset, int mask)
254{
255 int ptr = map * 3 + byte_num;
256 u32 reg;
257
258 reg = __raw_readl(DC_MAP_CONF_VAL(ptr));
259 reg &= ~(0xFFFF << (16 * (ptr & 0x1)));
260 reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1));
261 __raw_writel(reg, DC_MAP_CONF_VAL(ptr));
262
263 reg = __raw_readl(DC_MAP_CONF_PTR(map));
264 reg &= ~(0x1F << ((16 * (map & 0x1)) + (5 * byte_num)));
265 reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num));
266 __raw_writel(reg, DC_MAP_CONF_PTR(map));
267}
268
269static void ipu_dc_map_clear(int map)
270{
271 u32 reg = __raw_readl(DC_MAP_CONF_PTR(map));
272 __raw_writel(reg & ~(0xFFFF << (16 * (map & 0x1))),
273 DC_MAP_CONF_PTR(map));
274}
275
276static void ipu_dc_write_tmpl(int word, u32 opcode, u32 operand, int map,
277 int wave, int glue, int sync)
278{
279 u32 reg;
280 int stop = 1;
281
282 reg = sync;
283 reg |= (glue << 4);
284 reg |= (++wave << 11);
285 reg |= (++map << 15);
286 reg |= (operand << 20) & 0xFFF00000;
287 __raw_writel(reg, ipu_dc_tmpl_reg + word * 2);
288
289 reg = (operand >> 12);
290 reg |= opcode << 4;
291 reg |= (stop << 9);
292 __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1);
293}
294
295static void ipu_dc_link_event(int chan, int event, int addr, int priority)
296{
297 u32 reg;
298
299 reg = __raw_readl(DC_RL_CH(chan, event));
300 reg &= ~(0xFFFF << (16 * (event & 0x1)));
301 reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
302 __raw_writel(reg, DC_RL_CH(chan, event));
303}
304
305
306
307
308
309static const int rgb2ycbcr_coeff[5][3] = {
310 {0x4D, 0x96, 0x1D},
311 {0x3D5, 0x3AB, 0x80},
312 {0x80, 0x395, 0x3EB},
313 {0x0000, 0x0200, 0x0200},
314 {0x2, 0x2, 0x2},
315};
316
317
318
319
320
321static const int ycbcr2rgb_coeff[5][3] = {
322 {0x095, 0x000, 0x0CC},
323 {0x095, 0x3CE, 0x398},
324 {0x095, 0x0FF, 0x000},
325 {0x3E42, 0x010A, 0x3DD6},
326 {0x1, 0x1, 0x1},
327};
328
329#define mask_a(a) ((u32)(a) & 0x3FF)
330#define mask_b(b) ((u32)(b) & 0x3FFF)
331
332
333static int rgb_to_yuv(int n, int red, int green, int blue)
334{
335 int c;
336 c = red * rgb2ycbcr_coeff[n][0];
337 c += green * rgb2ycbcr_coeff[n][1];
338 c += blue * rgb2ycbcr_coeff[n][2];
339 c /= 16;
340 c += rgb2ycbcr_coeff[3][n] * 4;
341 c += 8;
342 c /= 16;
343 if (c < 0)
344 c = 0;
345 if (c > 255)
346 c = 255;
347 return c;
348}
349
350
351
352
353
354static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = {
355 {
356 {DP_COM_CONF_CSC_DEF_BOTH, &rgb2ycbcr_coeff},
357 {0, 0},
358 {0, 0},
359 {DP_COM_CONF_CSC_DEF_BG, &rgb2ycbcr_coeff},
360 {DP_COM_CONF_CSC_DEF_BG, &rgb2ycbcr_coeff}
361 },
362 {
363 {0, 0},
364 {DP_COM_CONF_CSC_DEF_BOTH, &ycbcr2rgb_coeff},
365 {DP_COM_CONF_CSC_DEF_BG, &ycbcr2rgb_coeff},
366 {0, 0},
367 {DP_COM_CONF_CSC_DEF_BG, &ycbcr2rgb_coeff}
368 },
369 {
370 {0, 0},
371 {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff},
372 {0, 0},
373 {0, 0},
374 {0, 0}
375 },
376 {
377 {DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff},
378 {0, 0},
379 {0, 0},
380 {0, 0},
381 {0, 0}
382 },
383 {
384 {DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff},
385 {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff},
386 {0, 0},
387 {0, 0},
388 {0, 0}
389 }
390};
391
392static enum csc_type_t fg_csc_type = CSC_NONE, bg_csc_type = CSC_NONE;
393static int color_key_4rgb = 1;
394
395void ipu_dp_csc_setup(int dp, struct dp_csc_param_t dp_csc_param,
396 unsigned char srm_mode_update)
397{
398 u32 reg;
399 const int (*coeff)[5][3];
400
401 if (dp_csc_param.mode >= 0) {
402 reg = __raw_readl(DP_COM_CONF(dp));
403 reg &= ~DP_COM_CONF_CSC_DEF_MASK;
404 reg |= dp_csc_param.mode;
405 __raw_writel(reg, DP_COM_CONF(dp));
406 }
407
408 coeff = dp_csc_param.coeff;
409
410 if (coeff) {
411 __raw_writel(mask_a((*coeff)[0][0]) |
412 (mask_a((*coeff)[0][1]) << 16), DP_CSC_A_0(dp));
413 __raw_writel(mask_a((*coeff)[0][2]) |
414 (mask_a((*coeff)[1][0]) << 16), DP_CSC_A_1(dp));
415 __raw_writel(mask_a((*coeff)[1][1]) |
416 (mask_a((*coeff)[1][2]) << 16), DP_CSC_A_2(dp));
417 __raw_writel(mask_a((*coeff)[2][0]) |
418 (mask_a((*coeff)[2][1]) << 16), DP_CSC_A_3(dp));
419 __raw_writel(mask_a((*coeff)[2][2]) |
420 (mask_b((*coeff)[3][0]) << 16) |
421 ((*coeff)[4][0] << 30), DP_CSC_0(dp));
422 __raw_writel(mask_b((*coeff)[3][1]) | ((*coeff)[4][1] << 14) |
423 (mask_b((*coeff)[3][2]) << 16) |
424 ((*coeff)[4][2] << 30), DP_CSC_1(dp));
425 }
426
427 if (srm_mode_update) {
428 reg = __raw_readl(IPU_SRM_PRI2) | 0x8;
429 __raw_writel(reg, IPU_SRM_PRI2);
430 }
431}
432
433int ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt,
434 uint32_t out_pixel_fmt)
435{
436 int in_fmt, out_fmt;
437 int dp;
438 int partial = 0;
439 uint32_t reg;
440
441 if (channel == MEM_FG_SYNC) {
442 dp = DP_SYNC;
443 partial = 1;
444 } else if (channel == MEM_BG_SYNC) {
445 dp = DP_SYNC;
446 partial = 0;
447 } else if (channel == MEM_BG_ASYNC0) {
448 dp = DP_ASYNC0;
449 partial = 0;
450 } else {
451 return -EINVAL;
452 }
453
454 in_fmt = format_to_colorspace(in_pixel_fmt);
455 out_fmt = format_to_colorspace(out_pixel_fmt);
456
457 if (partial) {
458 if (in_fmt == RGB) {
459 if (out_fmt == RGB)
460 fg_csc_type = RGB2RGB;
461 else
462 fg_csc_type = RGB2YUV;
463 } else {
464 if (out_fmt == RGB)
465 fg_csc_type = YUV2RGB;
466 else
467 fg_csc_type = YUV2YUV;
468 }
469 } else {
470 if (in_fmt == RGB) {
471 if (out_fmt == RGB)
472 bg_csc_type = RGB2RGB;
473 else
474 bg_csc_type = RGB2YUV;
475 } else {
476 if (out_fmt == RGB)
477 bg_csc_type = YUV2RGB;
478 else
479 bg_csc_type = YUV2YUV;
480 }
481 }
482
483
484 reg = __raw_readl(DP_COM_CONF(dp));
485 if (color_key_4rgb && (reg & DP_COM_CONF_GWCKE) &&
486 (((fg_csc_type == RGB2YUV) && (bg_csc_type == YUV2YUV)) ||
487 ((fg_csc_type == YUV2YUV) && (bg_csc_type == RGB2YUV)) ||
488 ((fg_csc_type == YUV2YUV) && (bg_csc_type == YUV2YUV)) ||
489 ((fg_csc_type == YUV2RGB) && (bg_csc_type == YUV2RGB)))) {
490 int red, green, blue;
491 int y, u, v;
492 uint32_t color_key = __raw_readl(DP_GRAPH_WIND_CTRL(dp)) &
493 0xFFFFFFL;
494
495 debug("_ipu_dp_init color key 0x%x need change to yuv fmt!\n",
496 color_key);
497
498 red = (color_key >> 16) & 0xFF;
499 green = (color_key >> 8) & 0xFF;
500 blue = color_key & 0xFF;
501
502 y = rgb_to_yuv(0, red, green, blue);
503 u = rgb_to_yuv(1, red, green, blue);
504 v = rgb_to_yuv(2, red, green, blue);
505 color_key = (y << 16) | (u << 8) | v;
506
507 reg = __raw_readl(DP_GRAPH_WIND_CTRL(dp)) & 0xFF000000L;
508 __raw_writel(reg | color_key, DP_GRAPH_WIND_CTRL(dp));
509 color_key_4rgb = 0;
510
511 debug("_ipu_dp_init color key change to yuv fmt 0x%x!\n",
512 color_key);
513 }
514
515 ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], 1);
516
517 return 0;
518}
519
520void ipu_dp_uninit(ipu_channel_t channel)
521{
522 int dp;
523 int partial = 0;
524
525 if (channel == MEM_FG_SYNC) {
526 dp = DP_SYNC;
527 partial = 1;
528 } else if (channel == MEM_BG_SYNC) {
529 dp = DP_SYNC;
530 partial = 0;
531 } else if (channel == MEM_BG_ASYNC0) {
532 dp = DP_ASYNC0;
533 partial = 0;
534 } else {
535 return;
536 }
537
538 if (partial)
539 fg_csc_type = CSC_NONE;
540 else
541 bg_csc_type = CSC_NONE;
542
543 ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], 0);
544}
545
546void ipu_dc_init(int dc_chan, int di, unsigned char interlaced)
547{
548 u32 reg = 0;
549
550 if ((dc_chan == 1) || (dc_chan == 5)) {
551 if (interlaced) {
552 ipu_dc_link_event(dc_chan, DC_EVT_NL, 0, 3);
553 ipu_dc_link_event(dc_chan, DC_EVT_EOL, 0, 2);
554 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 0, 1);
555 } else {
556 if (di) {
557 ipu_dc_link_event(dc_chan, DC_EVT_NL, 2, 3);
558 ipu_dc_link_event(dc_chan, DC_EVT_EOL, 3, 2);
559 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA,
560 4, 1);
561 } else {
562 ipu_dc_link_event(dc_chan, DC_EVT_NL, 5, 3);
563 ipu_dc_link_event(dc_chan, DC_EVT_EOL, 6, 2);
564 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA,
565 7, 1);
566 }
567 }
568 ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0);
569 ipu_dc_link_event(dc_chan, DC_EVT_NFIELD, 0, 0);
570 ipu_dc_link_event(dc_chan, DC_EVT_EOF, 0, 0);
571 ipu_dc_link_event(dc_chan, DC_EVT_EOFIELD, 0, 0);
572 ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN, 0, 0);
573 ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR, 0, 0);
574
575 reg = 0x2;
576 reg |= DC_DISP_ID_SYNC(di) << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
577 reg |= di << 2;
578 if (interlaced)
579 reg |= DC_WR_CH_CONF_FIELD_MODE;
580 } else if ((dc_chan == 8) || (dc_chan == 9)) {
581
582 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_0, 0x64, 1);
583 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_1, 0x64, 1);
584
585 reg = 0x3;
586 reg |= DC_DISP_ID_SERIAL << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET;
587 }
588 __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
589
590 __raw_writel(0x00000000, DC_WR_CH_ADDR(dc_chan));
591
592 __raw_writel(0x00000084, DC_GEN);
593}
594
595void ipu_dc_uninit(int dc_chan)
596{
597 if ((dc_chan == 1) || (dc_chan == 5)) {
598 ipu_dc_link_event(dc_chan, DC_EVT_NL, 0, 0);
599 ipu_dc_link_event(dc_chan, DC_EVT_EOL, 0, 0);
600 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 0, 0);
601 ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0);
602 ipu_dc_link_event(dc_chan, DC_EVT_NFIELD, 0, 0);
603 ipu_dc_link_event(dc_chan, DC_EVT_EOF, 0, 0);
604 ipu_dc_link_event(dc_chan, DC_EVT_EOFIELD, 0, 0);
605 ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN, 0, 0);
606 ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR, 0, 0);
607 } else if ((dc_chan == 8) || (dc_chan == 9)) {
608 ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0);
609 ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0);
610 ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_W_0, 0, 0);
611 ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_W_1, 0, 0);
612 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_0, 0, 0);
613 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_1, 0, 0);
614 ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_R_0, 0, 0);
615 ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_R_1, 0, 0);
616 ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_R_0, 0, 0);
617 ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_R_1, 0, 0);
618 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_R_0, 0, 0);
619 ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_R_1, 0, 0);
620 }
621}
622
623int ipu_chan_is_interlaced(ipu_channel_t channel)
624{
625 if (channel == MEM_DC_SYNC)
626 return !!(__raw_readl(DC_WR_CH_CONF_1) &
627 DC_WR_CH_CONF_FIELD_MODE);
628 else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC))
629 return !!(__raw_readl(DC_WR_CH_CONF_5) &
630 DC_WR_CH_CONF_FIELD_MODE);
631 return 0;
632}
633
634void ipu_dp_dc_enable(ipu_channel_t channel)
635{
636 int di;
637 uint32_t reg;
638 uint32_t dc_chan;
639
640 if (channel == MEM_FG_SYNC)
641 dc_chan = 5;
642 if (channel == MEM_DC_SYNC)
643 dc_chan = 1;
644 else if (channel == MEM_BG_SYNC)
645 dc_chan = 5;
646 else
647 return;
648
649 if (channel == MEM_FG_SYNC) {
650
651 reg = __raw_readl(DP_COM_CONF(DP_SYNC));
652 __raw_writel(reg | DP_COM_CONF_FG_EN, DP_COM_CONF(DP_SYNC));
653
654 reg = __raw_readl(IPU_SRM_PRI2) | 0x8;
655 __raw_writel(reg, IPU_SRM_PRI2);
656 return;
657 }
658
659 di = g_dc_di_assignment[dc_chan];
660
661
662 reg = __raw_readl(DC_WR_CH_CONF(6 - dc_chan));
663 if ((di << 2) == (reg & DC_WR_CH_CONF_PROG_DI_ID)) {
664 reg &= ~DC_WR_CH_CONF_PROG_DI_ID;
665 reg |= di ? 0 : DC_WR_CH_CONF_PROG_DI_ID;
666 __raw_writel(reg, DC_WR_CH_CONF(6 - dc_chan));
667 }
668
669 reg = __raw_readl(DC_WR_CH_CONF(dc_chan));
670 reg |= 4 << DC_WR_CH_CONF_PROG_TYPE_OFFSET;
671 __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
672
673 clk_enable(g_pixel_clk[di]);
674}
675
676static unsigned char dc_swap;
677
678void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap)
679{
680 uint32_t reg;
681 uint32_t csc;
682 uint32_t dc_chan = 0;
683 int timeout = 50;
684
685 dc_swap = swap;
686
687 if (channel == MEM_DC_SYNC) {
688 dc_chan = 1;
689 } else if (channel == MEM_BG_SYNC) {
690 dc_chan = 5;
691 } else if (channel == MEM_FG_SYNC) {
692
693 dc_chan = 5;
694
695 reg = __raw_readl(DP_COM_CONF(DP_SYNC));
696 csc = reg & DP_COM_CONF_CSC_DEF_MASK;
697 if (csc == DP_COM_CONF_CSC_DEF_FG)
698 reg &= ~DP_COM_CONF_CSC_DEF_MASK;
699
700 reg &= ~DP_COM_CONF_FG_EN;
701 __raw_writel(reg, DP_COM_CONF(DP_SYNC));
702
703 reg = __raw_readl(IPU_SRM_PRI2) | 0x8;
704 __raw_writel(reg, IPU_SRM_PRI2);
705
706 timeout = 50;
707
708
709
710
711
712 if (g_dc_di_assignment[dc_chan] == 0)
713 while ((__raw_readl(DC_STAT) & 0x00000002)
714 != 0x00000002) {
715 udelay(2000);
716 timeout -= 2;
717 if (timeout <= 0)
718 break;
719 }
720 else if (g_dc_di_assignment[dc_chan] == 1)
721 while ((__raw_readl(DC_STAT) & 0x00000020)
722 != 0x00000020) {
723 udelay(2000);
724 timeout -= 2;
725 if (timeout <= 0)
726 break;
727 }
728 return;
729 } else {
730 return;
731 }
732
733 if (dc_swap) {
734
735 reg = __raw_readl(DC_WR_CH_CONF(dc_chan));
736 __raw_writel(reg, DC_WR_CH_CONF(6 - dc_chan));
737 reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
738 reg ^= DC_WR_CH_CONF_PROG_DI_ID;
739 __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
740 } else {
741 timeout = 50;
742
743
744 if (g_dc_di_assignment[dc_chan] == 0)
745 while ((__raw_readl(DC_STAT) & 0x00000002)
746 != 0x00000002) {
747 udelay(2000);
748 timeout -= 2;
749 if (timeout <= 0)
750 break;
751 }
752 else if (g_dc_di_assignment[dc_chan] == 1)
753 while ((__raw_readl(DC_STAT) & 0x00000020)
754 != 0x00000020) {
755 udelay(2000);
756 timeout -= 2;
757 if (timeout <= 0)
758 break;
759 }
760
761 reg = __raw_readl(DC_WR_CH_CONF(dc_chan));
762 reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
763 __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
764
765 reg = __raw_readl(IPU_DISP_GEN);
766 if (g_dc_di_assignment[dc_chan])
767 reg &= ~DI1_COUNTER_RELEASE;
768 else
769 reg &= ~DI0_COUNTER_RELEASE;
770 __raw_writel(reg, IPU_DISP_GEN);
771
772
773
774 clk_disable(g_pixel_clk[g_dc_di_assignment[dc_chan]]);
775 }
776}
777
778void ipu_init_dc_mappings(void)
779{
780
781 ipu_dc_map_clear(0);
782 ipu_dc_map_config(0, 0, 7, 0xFF);
783 ipu_dc_map_config(0, 1, 15, 0xFF);
784 ipu_dc_map_config(0, 2, 23, 0xFF);
785
786
787 ipu_dc_map_clear(1);
788 ipu_dc_map_config(1, 0, 5, 0xFC);
789 ipu_dc_map_config(1, 1, 11, 0xFC);
790 ipu_dc_map_config(1, 2, 17, 0xFC);
791
792
793 ipu_dc_map_clear(2);
794 ipu_dc_map_config(2, 0, 15, 0xFF);
795 ipu_dc_map_config(2, 1, 23, 0xFF);
796 ipu_dc_map_config(2, 2, 7, 0xFF);
797
798
799 ipu_dc_map_clear(3);
800 ipu_dc_map_config(3, 0, 4, 0xF8);
801 ipu_dc_map_config(3, 1, 10, 0xFC);
802 ipu_dc_map_config(3, 2, 15, 0xF8);
803
804
805 ipu_dc_map_clear(4);
806 ipu_dc_map_config(4, 0, 5, 0xFC);
807 ipu_dc_map_config(4, 1, 13, 0xFC);
808 ipu_dc_map_config(4, 2, 21, 0xFC);
809}
810
811int ipu_pixfmt_to_map(uint32_t fmt)
812{
813 switch (fmt) {
814 case IPU_PIX_FMT_GENERIC:
815 case IPU_PIX_FMT_RGB24:
816 return 0;
817 case IPU_PIX_FMT_RGB666:
818 return 1;
819 case IPU_PIX_FMT_YUV444:
820 return 2;
821 case IPU_PIX_FMT_RGB565:
822 return 3;
823 case IPU_PIX_FMT_LVDS666:
824 return 4;
825 }
826
827 return -1;
828}
829
830
831
832
833void adapt_panel_to_ipu_restricitions(uint32_t *pixel_clk,
834 uint16_t width, uint16_t height,
835 uint16_t h_start_width,
836 uint16_t h_end_width,
837 uint16_t v_start_width,
838 uint16_t *v_end_width)
839{
840 if (*v_end_width < 2) {
841 uint16_t total_width = width + h_start_width + h_end_width;
842 uint16_t total_height_old = height + v_start_width +
843 (*v_end_width);
844 uint16_t total_height_new = height + v_start_width + 2;
845 *v_end_width = 2;
846 *pixel_clk = (*pixel_clk) * total_width * total_height_new /
847 (total_width * total_height_old);
848 printf("WARNING: adapt panel end blank lines\n");
849 }
850}
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
890 uint16_t width, uint16_t height,
891 uint32_t pixel_fmt,
892 uint16_t h_start_width, uint16_t h_sync_width,
893 uint16_t h_end_width, uint16_t v_start_width,
894 uint16_t v_sync_width, uint16_t v_end_width,
895 uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig)
896{
897 uint32_t reg;
898 uint32_t di_gen, vsync_cnt;
899 uint32_t div, rounded_pixel_clk;
900 uint32_t h_total, v_total;
901 int map;
902 struct clk *di_parent;
903
904 debug("panel size = %d x %d\n", width, height);
905
906 if ((v_sync_width == 0) || (h_sync_width == 0))
907 return EINVAL;
908
909 adapt_panel_to_ipu_restricitions(&pixel_clk, width, height,
910 h_start_width, h_end_width,
911 v_start_width, &v_end_width);
912 h_total = width + h_sync_width + h_start_width + h_end_width;
913 v_total = height + v_sync_width + v_start_width + v_end_width;
914
915
916 debug("pixel clk = %d\n", pixel_clk);
917
918 if (sig.ext_clk) {
919 if (!(g_di1_tvout && (disp == 1))) {
920
921
922
923
924 if ((clk_get_usecount(g_pixel_clk[0]) == 0) &&
925 (clk_get_usecount(g_pixel_clk[1]) == 0)) {
926 di_parent = clk_get_parent(g_di_clk[disp]);
927 rounded_pixel_clk =
928 clk_round_rate(g_pixel_clk[disp],
929 pixel_clk);
930 div = clk_get_rate(di_parent) /
931 rounded_pixel_clk;
932 if (div % 2)
933 div++;
934 if (clk_get_rate(di_parent) != div *
935 rounded_pixel_clk)
936 clk_set_rate(di_parent,
937 div * rounded_pixel_clk);
938 udelay(10000);
939 clk_set_rate(g_di_clk[disp],
940 2 * rounded_pixel_clk);
941 udelay(10000);
942 }
943 }
944 clk_set_parent(g_pixel_clk[disp], g_di_clk[disp]);
945 } else {
946 if (clk_get_usecount(g_pixel_clk[disp]) != 0)
947 clk_set_parent(g_pixel_clk[disp], g_ipu_clk);
948 }
949 rounded_pixel_clk = clk_round_rate(g_pixel_clk[disp], pixel_clk);
950 clk_set_rate(g_pixel_clk[disp], rounded_pixel_clk);
951 udelay(5000);
952
953 div = clk_get_rate(clk_get_parent(g_pixel_clk[disp])) /
954 rounded_pixel_clk;
955
956 ipu_di_data_wave_config(disp, SYNC_WAVE, div - 1, div - 1);
957 ipu_di_data_pin_config(disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2);
958
959 map = ipu_pixfmt_to_map(pixel_fmt);
960 if (map < 0) {
961 debug("IPU_DISP: No MAP\n");
962 return -EINVAL;
963 }
964
965 di_gen = __raw_readl(DI_GENERAL(disp));
966
967 if (sig.interlaced) {
968
969 ipu_di_sync_config(
970 disp,
971 1,
972 h_total / 2 - 1,
973 DI_SYNC_CLK,
974 0,
975 DI_SYNC_NONE,
976 0,
977 DI_SYNC_NONE,
978 0,
979 DI_SYNC_NONE,
980 DI_SYNC_NONE,
981 0,
982 0
983 );
984
985
986 ipu_di_sync_config(
987 disp,
988 2,
989 h_total - 1,
990 DI_SYNC_CLK,
991 0,
992 DI_SYNC_NONE,
993 0,
994 DI_SYNC_NONE,
995 0,
996 DI_SYNC_NONE,
997 DI_SYNC_NONE,
998 0,
999 4
1000 );
1001
1002
1003 ipu_di_sync_config(
1004 disp,
1005 3,
1006 v_total * 2 - 1,
1007 DI_SYNC_INT_HSYNC,
1008 1,
1009 DI_SYNC_INT_HSYNC,
1010 0,
1011 DI_SYNC_NONE,
1012 0,
1013 DI_SYNC_NONE,
1014 DI_SYNC_NONE,
1015 0,
1016 4
1017 );
1018
1019
1020 ipu_di_sync_config(
1021 disp,
1022 4,
1023 v_total / 2 - 1,
1024 DI_SYNC_HSYNC,
1025 v_start_width,
1026 DI_SYNC_HSYNC,
1027 2,
1028 DI_SYNC_VSYNC,
1029 0,
1030 DI_SYNC_NONE,
1031 DI_SYNC_NONE,
1032 0,
1033 0
1034 );
1035
1036
1037 ipu_di_sync_config(
1038 disp,
1039 5,
1040 0,
1041 DI_SYNC_HSYNC,
1042 0,
1043 DI_SYNC_NONE,
1044 height / 2,
1045 4,
1046 0,
1047 DI_SYNC_NONE,
1048 DI_SYNC_NONE,
1049 0,
1050 0
1051 );
1052
1053
1054 ipu_di_sync_config(
1055 disp,
1056 6,
1057 v_total - 1,
1058 DI_SYNC_HSYNC,
1059 0,
1060 DI_SYNC_NONE,
1061 0,
1062 DI_SYNC_NONE,
1063 0,
1064 DI_SYNC_NONE,
1065 DI_SYNC_NONE,
1066 0,
1067 0
1068 );
1069
1070
1071 vsync_cnt = 7;
1072 ipu_di_sync_config(
1073 disp,
1074 7,
1075 v_total / 2 - 1,
1076 DI_SYNC_HSYNC,
1077 9,
1078 DI_SYNC_HSYNC,
1079 2,
1080 DI_SYNC_VSYNC,
1081 0,
1082 DI_SYNC_NONE,
1083 DI_SYNC_NONE,
1084 0,
1085 0
1086 );
1087
1088
1089 ipu_di_sync_config(
1090 disp,
1091 8,
1092 0,
1093 DI_SYNC_CLK,
1094 h_start_width,
1095 DI_SYNC_CLK,
1096 width,
1097 5,
1098 0,
1099 DI_SYNC_NONE,
1100 DI_SYNC_NONE,
1101 0,
1102 0
1103 );
1104
1105 ipu_di_sync_config(
1106 disp,
1107 9,
1108 v_total - 1,
1109 DI_SYNC_INT_HSYNC,
1110 v_total / 2,
1111 DI_SYNC_INT_HSYNC,
1112 0,
1113 DI_SYNC_HSYNC,
1114 0,
1115 DI_SYNC_NONE,
1116 DI_SYNC_NONE,
1117 0,
1118 4
1119 );
1120
1121
1122 reg = __raw_readl(DI_SW_GEN1(disp, 9));
1123 reg &= 0x1FFFFFFF;
1124 reg |= (3 - 1)<<29 | 0x00008000;
1125 __raw_writel(reg, DI_SW_GEN1(disp, 9));
1126
1127 __raw_writel(v_total / 2 - 1, DI_SCR_CONF(disp));
1128
1129
1130 di_gen |= 0x10000000;
1131 di_gen |= DI_GEN_POLARITY_5;
1132 di_gen |= DI_GEN_POLARITY_8;
1133 } else {
1134
1135 ipu_di_sync_config(disp, 1, h_total - 1, DI_SYNC_CLK,
1136 0, DI_SYNC_NONE, 0, DI_SYNC_NONE,
1137 0, DI_SYNC_NONE,
1138 DI_SYNC_NONE, 0, 0);
1139
1140
1141 ipu_di_sync_config(disp, DI_SYNC_HSYNC, h_total - 1,
1142 DI_SYNC_CLK, div * v_to_h_sync, DI_SYNC_CLK,
1143 0, DI_SYNC_NONE, 1, DI_SYNC_NONE,
1144 DI_SYNC_CLK, 0, h_sync_width * 2);
1145
1146 vsync_cnt = DI_SYNC_VSYNC;
1147 ipu_di_sync_config(disp, DI_SYNC_VSYNC, v_total - 1,
1148 DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE, 0,
1149 DI_SYNC_NONE, 1, DI_SYNC_NONE,
1150 DI_SYNC_INT_HSYNC, 0, v_sync_width * 2);
1151 __raw_writel(v_total - 1, DI_SCR_CONF(disp));
1152
1153
1154 ipu_di_sync_config(disp, 4, 0, DI_SYNC_HSYNC,
1155 v_sync_width + v_start_width, DI_SYNC_HSYNC,
1156 height,
1157 DI_SYNC_VSYNC, 0, DI_SYNC_NONE,
1158 DI_SYNC_NONE, 0, 0);
1159 ipu_di_sync_config(disp, 5, 0, DI_SYNC_CLK,
1160 h_sync_width + h_start_width, DI_SYNC_CLK,
1161 width, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0,
1162 0);
1163
1164
1165 __raw_writel(0, DI_SW_GEN0(disp, 6));
1166 __raw_writel(0, DI_SW_GEN1(disp, 6));
1167 __raw_writel(0, DI_SW_GEN0(disp, 7));
1168 __raw_writel(0, DI_SW_GEN1(disp, 7));
1169 __raw_writel(0, DI_SW_GEN0(disp, 8));
1170 __raw_writel(0, DI_SW_GEN1(disp, 8));
1171 __raw_writel(0, DI_SW_GEN0(disp, 9));
1172 __raw_writel(0, DI_SW_GEN1(disp, 9));
1173
1174 reg = __raw_readl(DI_STP_REP(disp, 6));
1175 reg &= 0x0000FFFF;
1176 __raw_writel(reg, DI_STP_REP(disp, 6));
1177 __raw_writel(0, DI_STP_REP(disp, 7));
1178 __raw_writel(0, DI_STP_REP(disp, 9));
1179
1180
1181 if (disp) {
1182 ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5);
1183 ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5);
1184 ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5);
1185 } else {
1186 ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5);
1187 ipu_dc_write_tmpl(6, WROD(0), 0, map, SYNC_WAVE, 4, 5);
1188 ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5);
1189 }
1190
1191 if (sig.Hsync_pol)
1192 di_gen |= DI_GEN_POLARITY_2;
1193 if (sig.Vsync_pol)
1194 di_gen |= DI_GEN_POLARITY_3;
1195
1196 if (sig.clk_pol)
1197 di_gen |= DI_GEN_POL_CLK;
1198
1199 }
1200
1201 __raw_writel(di_gen, DI_GENERAL(disp));
1202
1203 __raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET) |
1204 0x00000002, DI_SYNC_AS_GEN(disp));
1205
1206 reg = __raw_readl(DI_POL(disp));
1207 reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15);
1208 if (sig.enable_pol)
1209 reg |= DI_POL_DRDY_POLARITY_15;
1210 if (sig.data_pol)
1211 reg |= DI_POL_DRDY_DATA_POLARITY;
1212 __raw_writel(reg, DI_POL(disp));
1213
1214 __raw_writel(width, DC_DISP_CONF2(DC_DISP_ID_SYNC(disp)));
1215
1216 return 0;
1217}
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable,
1234 uint8_t alpha)
1235{
1236 uint32_t reg;
1237 uint32_t flow;
1238
1239 unsigned char bg_chan;
1240
1241 if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
1242 flow = DP_SYNC;
1243 else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
1244 flow = DP_ASYNC0;
1245 else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
1246 flow = DP_ASYNC1;
1247 else
1248 return -EINVAL;
1249
1250 if (channel == MEM_BG_SYNC || channel == MEM_BG_ASYNC0 ||
1251 channel == MEM_BG_ASYNC1)
1252 bg_chan = 1;
1253 else
1254 bg_chan = 0;
1255
1256 if (!g_ipu_clk_enabled)
1257 clk_enable(g_ipu_clk);
1258
1259 if (bg_chan) {
1260 reg = __raw_readl(DP_COM_CONF(flow));
1261 __raw_writel(reg & ~DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
1262 } else {
1263 reg = __raw_readl(DP_COM_CONF(flow));
1264 __raw_writel(reg | DP_COM_CONF_GWSEL, DP_COM_CONF(flow));
1265 }
1266
1267 if (enable) {
1268 reg = __raw_readl(DP_GRAPH_WIND_CTRL(flow)) & 0x00FFFFFFL;
1269 __raw_writel(reg | ((uint32_t) alpha << 24),
1270 DP_GRAPH_WIND_CTRL(flow));
1271
1272 reg = __raw_readl(DP_COM_CONF(flow));
1273 __raw_writel(reg | DP_COM_CONF_GWAM, DP_COM_CONF(flow));
1274 } else {
1275 reg = __raw_readl(DP_COM_CONF(flow));
1276 __raw_writel(reg & ~DP_COM_CONF_GWAM, DP_COM_CONF(flow));
1277 }
1278
1279 reg = __raw_readl(IPU_SRM_PRI2) | 0x8;
1280 __raw_writel(reg, IPU_SRM_PRI2);
1281
1282 if (!g_ipu_clk_enabled)
1283 clk_disable(g_ipu_clk);
1284
1285 return 0;
1286}
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
1300 uint32_t color_key)
1301{
1302 uint32_t reg, flow;
1303 int y, u, v;
1304 int red, green, blue;
1305
1306 if (channel == MEM_BG_SYNC || channel == MEM_FG_SYNC)
1307 flow = DP_SYNC;
1308 else if (channel == MEM_BG_ASYNC0 || channel == MEM_FG_ASYNC0)
1309 flow = DP_ASYNC0;
1310 else if (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)
1311 flow = DP_ASYNC1;
1312 else
1313 return -EINVAL;
1314
1315 if (!g_ipu_clk_enabled)
1316 clk_enable(g_ipu_clk);
1317
1318 color_key_4rgb = 1;
1319
1320 if (((fg_csc_type == RGB2YUV) && (bg_csc_type == YUV2YUV)) ||
1321 ((fg_csc_type == YUV2YUV) && (bg_csc_type == RGB2YUV)) ||
1322 ((fg_csc_type == YUV2YUV) && (bg_csc_type == YUV2YUV)) ||
1323 ((fg_csc_type == YUV2RGB) && (bg_csc_type == YUV2RGB))) {
1324
1325 debug("color key 0x%x need change to yuv fmt\n", color_key);
1326
1327 red = (color_key >> 16) & 0xFF;
1328 green = (color_key >> 8) & 0xFF;
1329 blue = color_key & 0xFF;
1330
1331 y = rgb_to_yuv(0, red, green, blue);
1332 u = rgb_to_yuv(1, red, green, blue);
1333 v = rgb_to_yuv(2, red, green, blue);
1334 color_key = (y << 16) | (u << 8) | v;
1335
1336 color_key_4rgb = 0;
1337
1338 debug("color key change to yuv fmt 0x%x\n", color_key);
1339 }
1340
1341 if (enable) {
1342 reg = __raw_readl(DP_GRAPH_WIND_CTRL(flow)) & 0xFF000000L;
1343 __raw_writel(reg | color_key, DP_GRAPH_WIND_CTRL(flow));
1344
1345 reg = __raw_readl(DP_COM_CONF(flow));
1346 __raw_writel(reg | DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
1347 } else {
1348 reg = __raw_readl(DP_COM_CONF(flow));
1349 __raw_writel(reg & ~DP_COM_CONF_GWCKE, DP_COM_CONF(flow));
1350 }
1351
1352 reg = __raw_readl(IPU_SRM_PRI2) | 0x8;
1353 __raw_writel(reg, IPU_SRM_PRI2);
1354
1355 if (!g_ipu_clk_enabled)
1356 clk_disable(g_ipu_clk);
1357
1358 return 0;
1359}
1360