aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dispc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r--drivers/video/omap2/dss/dispc.c636
1 files changed, 414 insertions, 222 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index fa40fa59a9ac..9f8c69f16e61 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -44,34 +44,40 @@
44/* DISPC */ 44/* DISPC */
45#define DISPC_BASE 0x48050400 45#define DISPC_BASE 0x48050400
46 46
47#define DISPC_SZ_REGS SZ_1K 47#define DISPC_SZ_REGS SZ_4K
48 48
49struct dispc_reg { u16 idx; }; 49struct dispc_reg { u16 idx; };
50 50
51#define DISPC_REG(idx) ((const struct dispc_reg) { idx }) 51#define DISPC_REG(idx) ((const struct dispc_reg) { idx })
52 52
53/* DISPC common */ 53/*
54 * DISPC common registers and
55 * DISPC channel registers , ch = 0 for LCD, ch = 1 for
56 * DIGIT, and ch = 2 for LCD2
57 */
54#define DISPC_REVISION DISPC_REG(0x0000) 58#define DISPC_REVISION DISPC_REG(0x0000)
55#define DISPC_SYSCONFIG DISPC_REG(0x0010) 59#define DISPC_SYSCONFIG DISPC_REG(0x0010)
56#define DISPC_SYSSTATUS DISPC_REG(0x0014) 60#define DISPC_SYSSTATUS DISPC_REG(0x0014)
57#define DISPC_IRQSTATUS DISPC_REG(0x0018) 61#define DISPC_IRQSTATUS DISPC_REG(0x0018)
58#define DISPC_IRQENABLE DISPC_REG(0x001C) 62#define DISPC_IRQENABLE DISPC_REG(0x001C)
59#define DISPC_CONTROL DISPC_REG(0x0040) 63#define DISPC_CONTROL DISPC_REG(0x0040)
64#define DISPC_CONTROL2 DISPC_REG(0x0238)
60#define DISPC_CONFIG DISPC_REG(0x0044) 65#define DISPC_CONFIG DISPC_REG(0x0044)
66#define DISPC_CONFIG2 DISPC_REG(0x0620)
61#define DISPC_CAPABLE DISPC_REG(0x0048) 67#define DISPC_CAPABLE DISPC_REG(0x0048)
62#define DISPC_DEFAULT_COLOR0 DISPC_REG(0x004C) 68#define DISPC_DEFAULT_COLOR(ch) DISPC_REG(ch == 0 ? 0x004C : \
63#define DISPC_DEFAULT_COLOR1 DISPC_REG(0x0050) 69 (ch == 1 ? 0x0050 : 0x03AC))
64#define DISPC_TRANS_COLOR0 DISPC_REG(0x0054) 70#define DISPC_TRANS_COLOR(ch) DISPC_REG(ch == 0 ? 0x0054 : \
65#define DISPC_TRANS_COLOR1 DISPC_REG(0x0058) 71 (ch == 1 ? 0x0058 : 0x03B0))
66#define DISPC_LINE_STATUS DISPC_REG(0x005C) 72#define DISPC_LINE_STATUS DISPC_REG(0x005C)
67#define DISPC_LINE_NUMBER DISPC_REG(0x0060) 73#define DISPC_LINE_NUMBER DISPC_REG(0x0060)
68#define DISPC_TIMING_H DISPC_REG(0x0064) 74#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
69#define DISPC_TIMING_V DISPC_REG(0x0068) 75#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
70#define DISPC_POL_FREQ DISPC_REG(0x006C) 76#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408)
71#define DISPC_DIVISOR DISPC_REG(0x0070) 77#define DISPC_DIVISOR(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
72#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074) 78#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
73#define DISPC_SIZE_DIG DISPC_REG(0x0078) 79#define DISPC_SIZE_DIG DISPC_REG(0x0078)
74#define DISPC_SIZE_LCD DISPC_REG(0x007C) 80#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
75 81
76/* DISPC GFX plane */ 82/* DISPC GFX plane */
77#define DISPC_GFX_BA0 DISPC_REG(0x0080) 83#define DISPC_GFX_BA0 DISPC_REG(0x0080)
@@ -86,13 +92,12 @@ struct dispc_reg { u16 idx; };
86#define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4) 92#define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4)
87#define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8) 93#define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8)
88 94
89#define DISPC_DATA_CYCLE1 DISPC_REG(0x01D4) 95#define DISPC_DATA_CYCLE1(ch) DISPC_REG(ch != 2 ? 0x01D4 : 0x03C0)
90#define DISPC_DATA_CYCLE2 DISPC_REG(0x01D8) 96#define DISPC_DATA_CYCLE2(ch) DISPC_REG(ch != 2 ? 0x01D8 : 0x03C4)
91#define DISPC_DATA_CYCLE3 DISPC_REG(0x01DC) 97#define DISPC_DATA_CYCLE3(ch) DISPC_REG(ch != 2 ? 0x01DC : 0x03C8)
92 98#define DISPC_CPR_COEF_R(ch) DISPC_REG(ch != 2 ? 0x0220 : 0x03BC)
93#define DISPC_CPR_COEF_R DISPC_REG(0x0220) 99#define DISPC_CPR_COEF_G(ch) DISPC_REG(ch != 2 ? 0x0224 : 0x03B8)
94#define DISPC_CPR_COEF_G DISPC_REG(0x0224) 100#define DISPC_CPR_COEF_B(ch) DISPC_REG(ch != 2 ? 0x0228 : 0x03B4)
95#define DISPC_CPR_COEF_B DISPC_REG(0x0228)
96 101
97#define DISPC_GFX_PRELOAD DISPC_REG(0x022C) 102#define DISPC_GFX_PRELOAD DISPC_REG(0x022C)
98 103
@@ -217,18 +222,29 @@ void dispc_save_context(void)
217 SR(IRQENABLE); 222 SR(IRQENABLE);
218 SR(CONTROL); 223 SR(CONTROL);
219 SR(CONFIG); 224 SR(CONFIG);
220 SR(DEFAULT_COLOR0); 225 SR(DEFAULT_COLOR(0));
221 SR(DEFAULT_COLOR1); 226 SR(DEFAULT_COLOR(1));
222 SR(TRANS_COLOR0); 227 SR(TRANS_COLOR(0));
223 SR(TRANS_COLOR1); 228 SR(TRANS_COLOR(1));
224 SR(LINE_NUMBER); 229 SR(LINE_NUMBER);
225 SR(TIMING_H); 230 SR(TIMING_H(0));
226 SR(TIMING_V); 231 SR(TIMING_V(0));
227 SR(POL_FREQ); 232 SR(POL_FREQ(0));
228 SR(DIVISOR); 233 SR(DIVISOR(0));
229 SR(GLOBAL_ALPHA); 234 SR(GLOBAL_ALPHA);
230 SR(SIZE_DIG); 235 SR(SIZE_DIG);
231 SR(SIZE_LCD); 236 SR(SIZE_LCD(0));
237 if (dss_has_feature(FEAT_MGR_LCD2)) {
238 SR(CONTROL2);
239 SR(DEFAULT_COLOR(2));
240 SR(TRANS_COLOR(2));
241 SR(SIZE_LCD(2));
242 SR(TIMING_H(2));
243 SR(TIMING_V(2));
244 SR(POL_FREQ(2));
245 SR(DIVISOR(2));
246 SR(CONFIG2);
247 }
232 248
233 SR(GFX_BA0); 249 SR(GFX_BA0);
234 SR(GFX_BA1); 250 SR(GFX_BA1);
@@ -241,13 +257,22 @@ void dispc_save_context(void)
241 SR(GFX_WINDOW_SKIP); 257 SR(GFX_WINDOW_SKIP);
242 SR(GFX_TABLE_BA); 258 SR(GFX_TABLE_BA);
243 259
244 SR(DATA_CYCLE1); 260 SR(DATA_CYCLE1(0));
245 SR(DATA_CYCLE2); 261 SR(DATA_CYCLE2(0));
246 SR(DATA_CYCLE3); 262 SR(DATA_CYCLE3(0));
247 263
248 SR(CPR_COEF_R); 264 SR(CPR_COEF_R(0));
249 SR(CPR_COEF_G); 265 SR(CPR_COEF_G(0));
250 SR(CPR_COEF_B); 266 SR(CPR_COEF_B(0));
267 if (dss_has_feature(FEAT_MGR_LCD2)) {
268 SR(CPR_COEF_B(2));
269 SR(CPR_COEF_G(2));
270 SR(CPR_COEF_R(2));
271
272 SR(DATA_CYCLE1(2));
273 SR(DATA_CYCLE2(2));
274 SR(DATA_CYCLE3(2));
275 }
251 276
252 SR(GFX_PRELOAD); 277 SR(GFX_PRELOAD);
253 278
@@ -356,18 +381,28 @@ void dispc_restore_context(void)
356 /*RR(IRQENABLE);*/ 381 /*RR(IRQENABLE);*/
357 /*RR(CONTROL);*/ 382 /*RR(CONTROL);*/
358 RR(CONFIG); 383 RR(CONFIG);
359 RR(DEFAULT_COLOR0); 384 RR(DEFAULT_COLOR(0));
360 RR(DEFAULT_COLOR1); 385 RR(DEFAULT_COLOR(1));
361 RR(TRANS_COLOR0); 386 RR(TRANS_COLOR(0));
362 RR(TRANS_COLOR1); 387 RR(TRANS_COLOR(1));
363 RR(LINE_NUMBER); 388 RR(LINE_NUMBER);
364 RR(TIMING_H); 389 RR(TIMING_H(0));
365 RR(TIMING_V); 390 RR(TIMING_V(0));
366 RR(POL_FREQ); 391 RR(POL_FREQ(0));
367 RR(DIVISOR); 392 RR(DIVISOR(0));
368 RR(GLOBAL_ALPHA); 393 RR(GLOBAL_ALPHA);
369 RR(SIZE_DIG); 394 RR(SIZE_DIG);
370 RR(SIZE_LCD); 395 RR(SIZE_LCD(0));
396 if (dss_has_feature(FEAT_MGR_LCD2)) {
397 RR(DEFAULT_COLOR(2));
398 RR(TRANS_COLOR(2));
399 RR(SIZE_LCD(2));
400 RR(TIMING_H(2));
401 RR(TIMING_V(2));
402 RR(POL_FREQ(2));
403 RR(DIVISOR(2));
404 RR(CONFIG2);
405 }
371 406
372 RR(GFX_BA0); 407 RR(GFX_BA0);
373 RR(GFX_BA1); 408 RR(GFX_BA1);
@@ -380,13 +415,22 @@ void dispc_restore_context(void)
380 RR(GFX_WINDOW_SKIP); 415 RR(GFX_WINDOW_SKIP);
381 RR(GFX_TABLE_BA); 416 RR(GFX_TABLE_BA);
382 417
383 RR(DATA_CYCLE1); 418 RR(DATA_CYCLE1(0));
384 RR(DATA_CYCLE2); 419 RR(DATA_CYCLE2(0));
385 RR(DATA_CYCLE3); 420 RR(DATA_CYCLE3(0));
386 421
387 RR(CPR_COEF_R); 422 RR(CPR_COEF_R(0));
388 RR(CPR_COEF_G); 423 RR(CPR_COEF_G(0));
389 RR(CPR_COEF_B); 424 RR(CPR_COEF_B(0));
425 if (dss_has_feature(FEAT_MGR_LCD2)) {
426 RR(DATA_CYCLE1(2));
427 RR(DATA_CYCLE2(2));
428 RR(DATA_CYCLE3(2));
429
430 RR(CPR_COEF_B(2));
431 RR(CPR_COEF_G(2));
432 RR(CPR_COEF_R(2));
433 }
390 434
391 RR(GFX_PRELOAD); 435 RR(GFX_PRELOAD);
392 436
@@ -490,7 +534,8 @@ void dispc_restore_context(void)
490 534
491 /* enable last, because LCD & DIGIT enable are here */ 535 /* enable last, because LCD & DIGIT enable are here */
492 RR(CONTROL); 536 RR(CONTROL);
493 537 if (dss_has_feature(FEAT_MGR_LCD2))
538 RR(CONTROL2);
494 /* clear spurious SYNC_LOST_DIGIT interrupts */ 539 /* clear spurious SYNC_LOST_DIGIT interrupts */
495 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 540 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
496 541
@@ -516,42 +561,63 @@ bool dispc_go_busy(enum omap_channel channel)
516{ 561{
517 int bit; 562 int bit;
518 563
519 if (channel == OMAP_DSS_CHANNEL_LCD) 564 if (channel == OMAP_DSS_CHANNEL_LCD ||
565 channel == OMAP_DSS_CHANNEL_LCD2)
520 bit = 5; /* GOLCD */ 566 bit = 5; /* GOLCD */
521 else 567 else
522 bit = 6; /* GODIGIT */ 568 bit = 6; /* GODIGIT */
523 569
524 return REG_GET(DISPC_CONTROL, bit, bit) == 1; 570 if (channel == OMAP_DSS_CHANNEL_LCD2)
571 return REG_GET(DISPC_CONTROL2, bit, bit) == 1;
572 else
573 return REG_GET(DISPC_CONTROL, bit, bit) == 1;
525} 574}
526 575
527void dispc_go(enum omap_channel channel) 576void dispc_go(enum omap_channel channel)
528{ 577{
529 int bit; 578 int bit;
579 bool enable_bit, go_bit;
530 580
531 enable_clocks(1); 581 enable_clocks(1);
532 582
533 if (channel == OMAP_DSS_CHANNEL_LCD) 583 if (channel == OMAP_DSS_CHANNEL_LCD ||
584 channel == OMAP_DSS_CHANNEL_LCD2)
534 bit = 0; /* LCDENABLE */ 585 bit = 0; /* LCDENABLE */
535 else 586 else
536 bit = 1; /* DIGITALENABLE */ 587 bit = 1; /* DIGITALENABLE */
537 588
538 /* if the channel is not enabled, we don't need GO */ 589 /* if the channel is not enabled, we don't need GO */
539 if (REG_GET(DISPC_CONTROL, bit, bit) == 0) 590 if (channel == OMAP_DSS_CHANNEL_LCD2)
591 enable_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
592 else
593 enable_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
594
595 if (!enable_bit)
540 goto end; 596 goto end;
541 597
542 if (channel == OMAP_DSS_CHANNEL_LCD) 598 if (channel == OMAP_DSS_CHANNEL_LCD ||
599 channel == OMAP_DSS_CHANNEL_LCD2)
543 bit = 5; /* GOLCD */ 600 bit = 5; /* GOLCD */
544 else 601 else
545 bit = 6; /* GODIGIT */ 602 bit = 6; /* GODIGIT */
546 603
547 if (REG_GET(DISPC_CONTROL, bit, bit) == 1) { 604 if (channel == OMAP_DSS_CHANNEL_LCD2)
605 go_bit = REG_GET(DISPC_CONTROL2, bit, bit) == 1;
606 else
607 go_bit = REG_GET(DISPC_CONTROL, bit, bit) == 1;
608
609 if (go_bit) {
548 DSSERR("GO bit not down for channel %d\n", channel); 610 DSSERR("GO bit not down for channel %d\n", channel);
549 goto end; 611 goto end;
550 } 612 }
551 613
552 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : "DIGIT"); 614 DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" :
615 (channel == OMAP_DSS_CHANNEL_LCD2 ? "LCD2" : "DIGIT"));
553 616
554 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit); 617 if (channel == OMAP_DSS_CHANNEL_LCD2)
618 REG_FLD_MOD(DISPC_CONTROL2, 1, bit, bit);
619 else
620 REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
555end: 621end:
556 enable_clocks(0); 622 enable_clocks(0);
557} 623}
@@ -773,13 +839,26 @@ static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
773 dispc_write_reg(vsi_reg[plane-1], val); 839 dispc_write_reg(vsi_reg[plane-1], val);
774} 840}
775 841
842static void _dispc_set_pre_mult_alpha(enum omap_plane plane, bool enable)
843{
844 if (!dss_has_feature(FEAT_PRE_MULT_ALPHA))
845 return;
846
847 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
848 plane == OMAP_DSS_VIDEO1)
849 return;
850
851 REG_FLD_MOD(dispc_reg_att[plane], enable ? 1 : 0, 28, 28);
852}
853
776static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha) 854static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
777{ 855{
778 if (!dss_has_feature(FEAT_GLOBAL_ALPHA)) 856 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
779 return; 857 return;
780 858
781 BUG_ON(!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) && 859 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
782 plane == OMAP_DSS_VIDEO1); 860 plane == OMAP_DSS_VIDEO1)
861 return;
783 862
784 if (plane == OMAP_DSS_GFX) 863 if (plane == OMAP_DSS_GFX)
785 REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 7, 0); 864 REG_FLD_MOD(DISPC_GLOBAL_ALPHA, global_alpha, 7, 0);
@@ -851,6 +930,7 @@ static void _dispc_set_channel_out(enum omap_plane plane,
851{ 930{
852 int shift; 931 int shift;
853 u32 val; 932 u32 val;
933 int chan = 0, chan2 = 0;
854 934
855 switch (plane) { 935 switch (plane) {
856 case OMAP_DSS_GFX: 936 case OMAP_DSS_GFX:
@@ -866,7 +946,29 @@ static void _dispc_set_channel_out(enum omap_plane plane,
866 } 946 }
867 947
868 val = dispc_read_reg(dispc_reg_att[plane]); 948 val = dispc_read_reg(dispc_reg_att[plane]);
869 val = FLD_MOD(val, channel, shift, shift); 949 if (dss_has_feature(FEAT_MGR_LCD2)) {
950 switch (channel) {
951 case OMAP_DSS_CHANNEL_LCD:
952 chan = 0;
953 chan2 = 0;
954 break;
955 case OMAP_DSS_CHANNEL_DIGIT:
956 chan = 1;
957 chan2 = 0;
958 break;
959 case OMAP_DSS_CHANNEL_LCD2:
960 chan = 0;
961 chan2 = 1;
962 break;
963 default:
964 BUG();
965 }
966
967 val = FLD_MOD(val, chan, shift, shift);
968 val = FLD_MOD(val, chan2, 31, 30);
969 } else {
970 val = FLD_MOD(val, channel, shift, shift);
971 }
870 dispc_write_reg(dispc_reg_att[plane], val); 972 dispc_write_reg(dispc_reg_att[plane], val);
871} 973}
872 974
@@ -923,13 +1025,13 @@ void dispc_enable_replication(enum omap_plane plane, bool enable)
923 enable_clocks(0); 1025 enable_clocks(0);
924} 1026}
925 1027
926void dispc_set_lcd_size(u16 width, u16 height) 1028void dispc_set_lcd_size(enum omap_channel channel, u16 width, u16 height)
927{ 1029{
928 u32 val; 1030 u32 val;
929 BUG_ON((width > (1 << 11)) || (height > (1 << 11))); 1031 BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
930 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0); 1032 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
931 enable_clocks(1); 1033 enable_clocks(1);
932 dispc_write_reg(DISPC_SIZE_LCD, val); 1034 dispc_write_reg(DISPC_SIZE_LCD(channel), val);
933 enable_clocks(0); 1035 enable_clocks(0);
934} 1036}
935 1037
@@ -1426,12 +1528,13 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
1426 } 1528 }
1427} 1529}
1428 1530
1429static unsigned long calc_fclk_five_taps(u16 width, u16 height, 1531static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
1430 u16 out_width, u16 out_height, enum omap_color_mode color_mode) 1532 u16 height, u16 out_width, u16 out_height,
1533 enum omap_color_mode color_mode)
1431{ 1534{
1432 u32 fclk = 0; 1535 u32 fclk = 0;
1433 /* FIXME venc pclk? */ 1536 /* FIXME venc pclk? */
1434 u64 tmp, pclk = dispc_pclk_rate(); 1537 u64 tmp, pclk = dispc_pclk_rate(channel);
1435 1538
1436 if (height > out_height) { 1539 if (height > out_height) {
1437 /* FIXME get real display PPL */ 1540 /* FIXME get real display PPL */
@@ -1463,8 +1566,8 @@ static unsigned long calc_fclk_five_taps(u16 width, u16 height,
1463 return fclk; 1566 return fclk;
1464} 1567}
1465 1568
1466static unsigned long calc_fclk(u16 width, u16 height, 1569static unsigned long calc_fclk(enum omap_channel channel, u16 width,
1467 u16 out_width, u16 out_height) 1570 u16 height, u16 out_width, u16 out_height)
1468{ 1571{
1469 unsigned int hf, vf; 1572 unsigned int hf, vf;
1470 1573
@@ -1488,7 +1591,7 @@ static unsigned long calc_fclk(u16 width, u16 height,
1488 vf = 1; 1591 vf = 1;
1489 1592
1490 /* FIXME venc pclk? */ 1593 /* FIXME venc pclk? */
1491 return dispc_pclk_rate() * vf * hf; 1594 return dispc_pclk_rate(channel) * vf * hf;
1492} 1595}
1493 1596
1494void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out) 1597void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out)
@@ -1507,7 +1610,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1507 bool ilace, 1610 bool ilace,
1508 enum omap_dss_rotation_type rotation_type, 1611 enum omap_dss_rotation_type rotation_type,
1509 u8 rotation, int mirror, 1612 u8 rotation, int mirror,
1510 u8 global_alpha) 1613 u8 global_alpha, u8 pre_mult_alpha,
1614 enum omap_channel channel)
1511{ 1615{
1512 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2; 1616 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
1513 bool five_taps = 0; 1617 bool five_taps = 0;
@@ -1536,29 +1640,12 @@ static int _dispc_setup_plane(enum omap_plane plane,
1536 height, pos_y, out_height); 1640 height, pos_y, out_height);
1537 } 1641 }
1538 1642
1643 if (!dss_feat_color_mode_supported(plane, color_mode))
1644 return -EINVAL;
1645
1539 if (plane == OMAP_DSS_GFX) { 1646 if (plane == OMAP_DSS_GFX) {
1540 if (width != out_width || height != out_height) 1647 if (width != out_width || height != out_height)
1541 return -EINVAL; 1648 return -EINVAL;
1542
1543 switch (color_mode) {
1544 case OMAP_DSS_COLOR_ARGB16:
1545 case OMAP_DSS_COLOR_ARGB32:
1546 case OMAP_DSS_COLOR_RGBA32:
1547 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
1548 return -EINVAL;
1549 case OMAP_DSS_COLOR_RGBX32:
1550 if (cpu_is_omap24xx())
1551 return -EINVAL;
1552 /* fall through */
1553 case OMAP_DSS_COLOR_RGB12U:
1554 case OMAP_DSS_COLOR_RGB16:
1555 case OMAP_DSS_COLOR_RGB24P:
1556 case OMAP_DSS_COLOR_RGB24U:
1557 break;
1558
1559 default:
1560 return -EINVAL;
1561 }
1562 } else { 1649 } else {
1563 /* video plane */ 1650 /* video plane */
1564 1651
@@ -1572,42 +1659,16 @@ static int _dispc_setup_plane(enum omap_plane plane,
1572 out_height > height * 8) 1659 out_height > height * 8)
1573 return -EINVAL; 1660 return -EINVAL;
1574 1661
1575 switch (color_mode) { 1662 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
1576 case OMAP_DSS_COLOR_RGBX32: 1663 color_mode == OMAP_DSS_COLOR_UYVY)
1577 case OMAP_DSS_COLOR_RGB12U:
1578 if (cpu_is_omap24xx())
1579 return -EINVAL;
1580 /* fall through */
1581 case OMAP_DSS_COLOR_RGB16:
1582 case OMAP_DSS_COLOR_RGB24P:
1583 case OMAP_DSS_COLOR_RGB24U:
1584 break;
1585
1586 case OMAP_DSS_COLOR_ARGB16:
1587 case OMAP_DSS_COLOR_ARGB32:
1588 case OMAP_DSS_COLOR_RGBA32:
1589 if (!dss_has_feature(FEAT_GLOBAL_ALPHA))
1590 return -EINVAL;
1591 if (!dss_has_feature(FEAT_GLOBAL_ALPHA_VID1) &&
1592 plane == OMAP_DSS_VIDEO1)
1593 return -EINVAL;
1594 break;
1595
1596 case OMAP_DSS_COLOR_YUV2:
1597 case OMAP_DSS_COLOR_UYVY:
1598 cconv = 1; 1664 cconv = 1;
1599 break;
1600
1601 default:
1602 return -EINVAL;
1603 }
1604 1665
1605 /* Must use 5-tap filter? */ 1666 /* Must use 5-tap filter? */
1606 five_taps = height > out_height * 2; 1667 five_taps = height > out_height * 2;
1607 1668
1608 if (!five_taps) { 1669 if (!five_taps) {
1609 fclk = calc_fclk(width, height, 1670 fclk = calc_fclk(channel, width, height, out_width,
1610 out_width, out_height); 1671 out_height);
1611 1672
1612 /* Try 5-tap filter if 3-tap fclk is too high */ 1673 /* Try 5-tap filter if 3-tap fclk is too high */
1613 if (cpu_is_omap34xx() && height > out_height && 1674 if (cpu_is_omap34xx() && height > out_height &&
@@ -1621,7 +1682,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
1621 } 1682 }
1622 1683
1623 if (five_taps) 1684 if (five_taps)
1624 fclk = calc_fclk_five_taps(width, height, 1685 fclk = calc_fclk_five_taps(channel, width, height,
1625 out_width, out_height, color_mode); 1686 out_width, out_height, color_mode);
1626 1687
1627 DSSDBG("required fclk rate = %lu Hz\n", fclk); 1688 DSSDBG("required fclk rate = %lu Hz\n", fclk);
@@ -1693,8 +1754,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1693 1754
1694 _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode); 1755 _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode);
1695 1756
1696 if (plane != OMAP_DSS_VIDEO1) 1757 _dispc_set_pre_mult_alpha(plane, pre_mult_alpha);
1697 _dispc_setup_global_alpha(plane, global_alpha); 1758 _dispc_setup_global_alpha(plane, global_alpha);
1698 1759
1699 return 0; 1760 return 0;
1700} 1761}
@@ -1710,36 +1771,44 @@ static void dispc_disable_isr(void *data, u32 mask)
1710 complete(compl); 1771 complete(compl);
1711} 1772}
1712 1773
1713static void _enable_lcd_out(bool enable) 1774static void _enable_lcd_out(enum omap_channel channel, bool enable)
1714{ 1775{
1715 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); 1776 if (channel == OMAP_DSS_CHANNEL_LCD2)
1777 REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0);
1778 else
1779 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
1716} 1780}
1717 1781
1718static void dispc_enable_lcd_out(bool enable) 1782static void dispc_enable_lcd_out(enum omap_channel channel, bool enable)
1719{ 1783{
1720 struct completion frame_done_completion; 1784 struct completion frame_done_completion;
1721 bool is_on; 1785 bool is_on;
1722 int r; 1786 int r;
1787 u32 irq;
1723 1788
1724 enable_clocks(1); 1789 enable_clocks(1);
1725 1790
1726 /* When we disable LCD output, we need to wait until frame is done. 1791 /* When we disable LCD output, we need to wait until frame is done.
1727 * Otherwise the DSS is still working, and turning off the clocks 1792 * Otherwise the DSS is still working, and turning off the clocks
1728 * prevents DSS from going to OFF mode */ 1793 * prevents DSS from going to OFF mode */
1729 is_on = REG_GET(DISPC_CONTROL, 0, 0); 1794 is_on = channel == OMAP_DSS_CHANNEL_LCD2 ?
1795 REG_GET(DISPC_CONTROL2, 0, 0) :
1796 REG_GET(DISPC_CONTROL, 0, 0);
1797
1798 irq = channel == OMAP_DSS_CHANNEL_LCD2 ? DISPC_IRQ_FRAMEDONE2 :
1799 DISPC_IRQ_FRAMEDONE;
1730 1800
1731 if (!enable && is_on) { 1801 if (!enable && is_on) {
1732 init_completion(&frame_done_completion); 1802 init_completion(&frame_done_completion);
1733 1803
1734 r = omap_dispc_register_isr(dispc_disable_isr, 1804 r = omap_dispc_register_isr(dispc_disable_isr,
1735 &frame_done_completion, 1805 &frame_done_completion, irq);
1736 DISPC_IRQ_FRAMEDONE);
1737 1806
1738 if (r) 1807 if (r)
1739 DSSERR("failed to register FRAMEDONE isr\n"); 1808 DSSERR("failed to register FRAMEDONE isr\n");
1740 } 1809 }
1741 1810
1742 _enable_lcd_out(enable); 1811 _enable_lcd_out(channel, enable);
1743 1812
1744 if (!enable && is_on) { 1813 if (!enable && is_on) {
1745 if (!wait_for_completion_timeout(&frame_done_completion, 1814 if (!wait_for_completion_timeout(&frame_done_completion,
@@ -1747,8 +1816,7 @@ static void dispc_enable_lcd_out(bool enable)
1747 DSSERR("timeout waiting for FRAME DONE\n"); 1816 DSSERR("timeout waiting for FRAME DONE\n");
1748 1817
1749 r = omap_dispc_unregister_isr(dispc_disable_isr, 1818 r = omap_dispc_unregister_isr(dispc_disable_isr,
1750 &frame_done_completion, 1819 &frame_done_completion, irq);
1751 DISPC_IRQ_FRAMEDONE);
1752 1820
1753 if (r) 1821 if (r)
1754 DSSERR("failed to unregister FRAMEDONE isr\n"); 1822 DSSERR("failed to unregister FRAMEDONE isr\n");
@@ -1818,6 +1886,8 @@ static void dispc_enable_digit_out(bool enable)
1818 unsigned long flags; 1886 unsigned long flags;
1819 spin_lock_irqsave(&dispc.irq_lock, flags); 1887 spin_lock_irqsave(&dispc.irq_lock, flags);
1820 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 1888 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
1889 if (dss_has_feature(FEAT_MGR_LCD2))
1890 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
1821 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 1891 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
1822 _omap_dispc_set_irqs(); 1892 _omap_dispc_set_irqs();
1823 spin_unlock_irqrestore(&dispc.irq_lock, flags); 1893 spin_unlock_irqrestore(&dispc.irq_lock, flags);
@@ -1832,14 +1902,17 @@ bool dispc_is_channel_enabled(enum omap_channel channel)
1832 return !!REG_GET(DISPC_CONTROL, 0, 0); 1902 return !!REG_GET(DISPC_CONTROL, 0, 0);
1833 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 1903 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1834 return !!REG_GET(DISPC_CONTROL, 1, 1); 1904 return !!REG_GET(DISPC_CONTROL, 1, 1);
1905 else if (channel == OMAP_DSS_CHANNEL_LCD2)
1906 return !!REG_GET(DISPC_CONTROL2, 0, 0);
1835 else 1907 else
1836 BUG(); 1908 BUG();
1837} 1909}
1838 1910
1839void dispc_enable_channel(enum omap_channel channel, bool enable) 1911void dispc_enable_channel(enum omap_channel channel, bool enable)
1840{ 1912{
1841 if (channel == OMAP_DSS_CHANNEL_LCD) 1913 if (channel == OMAP_DSS_CHANNEL_LCD ||
1842 dispc_enable_lcd_out(enable); 1914 channel == OMAP_DSS_CHANNEL_LCD2)
1915 dispc_enable_lcd_out(channel, enable);
1843 else if (channel == OMAP_DSS_CHANNEL_DIGIT) 1916 else if (channel == OMAP_DSS_CHANNEL_DIGIT)
1844 dispc_enable_digit_out(enable); 1917 dispc_enable_digit_out(enable);
1845 else 1918 else
@@ -1848,6 +1921,9 @@ void dispc_enable_channel(enum omap_channel channel, bool enable)
1848 1921
1849void dispc_lcd_enable_signal_polarity(bool act_high) 1922void dispc_lcd_enable_signal_polarity(bool act_high)
1850{ 1923{
1924 if (!dss_has_feature(FEAT_LCDENABLEPOL))
1925 return;
1926
1851 enable_clocks(1); 1927 enable_clocks(1);
1852 REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29); 1928 REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
1853 enable_clocks(0); 1929 enable_clocks(0);
@@ -1855,6 +1931,9 @@ void dispc_lcd_enable_signal_polarity(bool act_high)
1855 1931
1856void dispc_lcd_enable_signal(bool enable) 1932void dispc_lcd_enable_signal(bool enable)
1857{ 1933{
1934 if (!dss_has_feature(FEAT_LCDENABLESIGNAL))
1935 return;
1936
1858 enable_clocks(1); 1937 enable_clocks(1);
1859 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28); 1938 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
1860 enable_clocks(0); 1939 enable_clocks(0);
@@ -1862,20 +1941,27 @@ void dispc_lcd_enable_signal(bool enable)
1862 1941
1863void dispc_pck_free_enable(bool enable) 1942void dispc_pck_free_enable(bool enable)
1864{ 1943{
1944 if (!dss_has_feature(FEAT_PCKFREEENABLE))
1945 return;
1946
1865 enable_clocks(1); 1947 enable_clocks(1);
1866 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27); 1948 REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
1867 enable_clocks(0); 1949 enable_clocks(0);
1868} 1950}
1869 1951
1870void dispc_enable_fifohandcheck(bool enable) 1952void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable)
1871{ 1953{
1872 enable_clocks(1); 1954 enable_clocks(1);
1873 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16); 1955 if (channel == OMAP_DSS_CHANNEL_LCD2)
1956 REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16);
1957 else
1958 REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
1874 enable_clocks(0); 1959 enable_clocks(0);
1875} 1960}
1876 1961
1877 1962
1878void dispc_set_lcd_display_type(enum omap_lcd_display_type type) 1963void dispc_set_lcd_display_type(enum omap_channel channel,
1964 enum omap_lcd_display_type type)
1879{ 1965{
1880 int mode; 1966 int mode;
1881 1967
@@ -1894,7 +1980,10 @@ void dispc_set_lcd_display_type(enum omap_lcd_display_type type)
1894 } 1980 }
1895 1981
1896 enable_clocks(1); 1982 enable_clocks(1);
1897 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3); 1983 if (channel == OMAP_DSS_CHANNEL_LCD2)
1984 REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3);
1985 else
1986 REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
1898 enable_clocks(0); 1987 enable_clocks(0);
1899} 1988}
1900 1989
@@ -1908,25 +1997,21 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode)
1908 1997
1909void dispc_set_default_color(enum omap_channel channel, u32 color) 1998void dispc_set_default_color(enum omap_channel channel, u32 color)
1910{ 1999{
1911 const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0,
1912 DISPC_DEFAULT_COLOR1 };
1913
1914 enable_clocks(1); 2000 enable_clocks(1);
1915 dispc_write_reg(def_reg[channel], color); 2001 dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
1916 enable_clocks(0); 2002 enable_clocks(0);
1917} 2003}
1918 2004
1919u32 dispc_get_default_color(enum omap_channel channel) 2005u32 dispc_get_default_color(enum omap_channel channel)
1920{ 2006{
1921 const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0,
1922 DISPC_DEFAULT_COLOR1 };
1923 u32 l; 2007 u32 l;
1924 2008
1925 BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT && 2009 BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT &&
1926 channel != OMAP_DSS_CHANNEL_LCD); 2010 channel != OMAP_DSS_CHANNEL_LCD &&
2011 channel != OMAP_DSS_CHANNEL_LCD2);
1927 2012
1928 enable_clocks(1); 2013 enable_clocks(1);
1929 l = dispc_read_reg(def_reg[channel]); 2014 l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel));
1930 enable_clocks(0); 2015 enable_clocks(0);
1931 2016
1932 return l; 2017 return l;
@@ -1936,16 +2021,15 @@ void dispc_set_trans_key(enum omap_channel ch,
1936 enum omap_dss_trans_key_type type, 2021 enum omap_dss_trans_key_type type,
1937 u32 trans_key) 2022 u32 trans_key)
1938{ 2023{
1939 const struct dispc_reg tr_reg[] = {
1940 DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 };
1941
1942 enable_clocks(1); 2024 enable_clocks(1);
1943 if (ch == OMAP_DSS_CHANNEL_LCD) 2025 if (ch == OMAP_DSS_CHANNEL_LCD)
1944 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11); 2026 REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
1945 else /* OMAP_DSS_CHANNEL_DIGIT */ 2027 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1946 REG_FLD_MOD(DISPC_CONFIG, type, 13, 13); 2028 REG_FLD_MOD(DISPC_CONFIG, type, 13, 13);
2029 else /* OMAP_DSS_CHANNEL_LCD2 */
2030 REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11);
1947 2031
1948 dispc_write_reg(tr_reg[ch], trans_key); 2032 dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
1949 enable_clocks(0); 2033 enable_clocks(0);
1950} 2034}
1951 2035
@@ -1953,21 +2037,20 @@ void dispc_get_trans_key(enum omap_channel ch,
1953 enum omap_dss_trans_key_type *type, 2037 enum omap_dss_trans_key_type *type,
1954 u32 *trans_key) 2038 u32 *trans_key)
1955{ 2039{
1956 const struct dispc_reg tr_reg[] = {
1957 DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 };
1958
1959 enable_clocks(1); 2040 enable_clocks(1);
1960 if (type) { 2041 if (type) {
1961 if (ch == OMAP_DSS_CHANNEL_LCD) 2042 if (ch == OMAP_DSS_CHANNEL_LCD)
1962 *type = REG_GET(DISPC_CONFIG, 11, 11); 2043 *type = REG_GET(DISPC_CONFIG, 11, 11);
1963 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2044 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1964 *type = REG_GET(DISPC_CONFIG, 13, 13); 2045 *type = REG_GET(DISPC_CONFIG, 13, 13);
2046 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2047 *type = REG_GET(DISPC_CONFIG2, 11, 11);
1965 else 2048 else
1966 BUG(); 2049 BUG();
1967 } 2050 }
1968 2051
1969 if (trans_key) 2052 if (trans_key)
1970 *trans_key = dispc_read_reg(tr_reg[ch]); 2053 *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
1971 enable_clocks(0); 2054 enable_clocks(0);
1972} 2055}
1973 2056
@@ -1976,8 +2059,10 @@ void dispc_enable_trans_key(enum omap_channel ch, bool enable)
1976 enable_clocks(1); 2059 enable_clocks(1);
1977 if (ch == OMAP_DSS_CHANNEL_LCD) 2060 if (ch == OMAP_DSS_CHANNEL_LCD)
1978 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); 2061 REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
1979 else /* OMAP_DSS_CHANNEL_DIGIT */ 2062 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1980 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12); 2063 REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
2064 else /* OMAP_DSS_CHANNEL_LCD2 */
2065 REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
1981 enable_clocks(0); 2066 enable_clocks(0);
1982} 2067}
1983void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) 2068void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
@@ -1988,8 +2073,10 @@ void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
1988 enable_clocks(1); 2073 enable_clocks(1);
1989 if (ch == OMAP_DSS_CHANNEL_LCD) 2074 if (ch == OMAP_DSS_CHANNEL_LCD)
1990 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18); 2075 REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
1991 else /* OMAP_DSS_CHANNEL_DIGIT */ 2076 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
1992 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); 2077 REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
2078 else /* OMAP_DSS_CHANNEL_LCD2 */
2079 REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18);
1993 enable_clocks(0); 2080 enable_clocks(0);
1994} 2081}
1995bool dispc_alpha_blending_enabled(enum omap_channel ch) 2082bool dispc_alpha_blending_enabled(enum omap_channel ch)
@@ -2003,13 +2090,14 @@ bool dispc_alpha_blending_enabled(enum omap_channel ch)
2003 if (ch == OMAP_DSS_CHANNEL_LCD) 2090 if (ch == OMAP_DSS_CHANNEL_LCD)
2004 enabled = REG_GET(DISPC_CONFIG, 18, 18); 2091 enabled = REG_GET(DISPC_CONFIG, 18, 18);
2005 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2092 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2006 enabled = REG_GET(DISPC_CONFIG, 18, 18); 2093 enabled = REG_GET(DISPC_CONFIG, 19, 19);
2094 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2095 enabled = REG_GET(DISPC_CONFIG2, 18, 18);
2007 else 2096 else
2008 BUG(); 2097 BUG();
2009 enable_clocks(0); 2098 enable_clocks(0);
2010 2099
2011 return enabled; 2100 return enabled;
2012
2013} 2101}
2014 2102
2015 2103
@@ -2022,6 +2110,8 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
2022 enabled = REG_GET(DISPC_CONFIG, 10, 10); 2110 enabled = REG_GET(DISPC_CONFIG, 10, 10);
2023 else if (ch == OMAP_DSS_CHANNEL_DIGIT) 2111 else if (ch == OMAP_DSS_CHANNEL_DIGIT)
2024 enabled = REG_GET(DISPC_CONFIG, 12, 12); 2112 enabled = REG_GET(DISPC_CONFIG, 12, 12);
2113 else if (ch == OMAP_DSS_CHANNEL_LCD2)
2114 enabled = REG_GET(DISPC_CONFIG2, 10, 10);
2025 else 2115 else
2026 BUG(); 2116 BUG();
2027 enable_clocks(0); 2117 enable_clocks(0);
@@ -2030,7 +2120,7 @@ bool dispc_trans_key_enabled(enum omap_channel ch)
2030} 2120}
2031 2121
2032 2122
2033void dispc_set_tft_data_lines(u8 data_lines) 2123void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
2034{ 2124{
2035 int code; 2125 int code;
2036 2126
@@ -2053,11 +2143,15 @@ void dispc_set_tft_data_lines(u8 data_lines)
2053 } 2143 }
2054 2144
2055 enable_clocks(1); 2145 enable_clocks(1);
2056 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); 2146 if (channel == OMAP_DSS_CHANNEL_LCD2)
2147 REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8);
2148 else
2149 REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
2057 enable_clocks(0); 2150 enable_clocks(0);
2058} 2151}
2059 2152
2060void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode) 2153void dispc_set_parallel_interface_mode(enum omap_channel channel,
2154 enum omap_parallel_interface_mode mode)
2061{ 2155{
2062 u32 l; 2156 u32 l;
2063 int stallmode; 2157 int stallmode;
@@ -2087,13 +2181,17 @@ void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode)
2087 2181
2088 enable_clocks(1); 2182 enable_clocks(1);
2089 2183
2090 l = dispc_read_reg(DISPC_CONTROL); 2184 if (channel == OMAP_DSS_CHANNEL_LCD2) {
2091 2185 l = dispc_read_reg(DISPC_CONTROL2);
2092 l = FLD_MOD(l, stallmode, 11, 11); 2186 l = FLD_MOD(l, stallmode, 11, 11);
2093 l = FLD_MOD(l, gpout0, 15, 15); 2187 dispc_write_reg(DISPC_CONTROL2, l);
2094 l = FLD_MOD(l, gpout1, 16, 16); 2188 } else {
2095 2189 l = dispc_read_reg(DISPC_CONTROL);
2096 dispc_write_reg(DISPC_CONTROL, l); 2190 l = FLD_MOD(l, stallmode, 11, 11);
2191 l = FLD_MOD(l, gpout0, 15, 15);
2192 l = FLD_MOD(l, gpout1, 16, 16);
2193 dispc_write_reg(DISPC_CONTROL, l);
2194 }
2097 2195
2098 enable_clocks(0); 2196 enable_clocks(0);
2099} 2197}
@@ -2129,8 +2227,8 @@ bool dispc_lcd_timings_ok(struct omap_video_timings *timings)
2129 timings->vfp, timings->vbp); 2227 timings->vfp, timings->vbp);
2130} 2228}
2131 2229
2132static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp, 2230static void _dispc_set_lcd_timings(enum omap_channel channel, int hsw,
2133 int vsw, int vfp, int vbp) 2231 int hfp, int hbp, int vsw, int vfp, int vbp)
2134{ 2232{
2135 u32 timing_h, timing_v; 2233 u32 timing_h, timing_v;
2136 2234
@@ -2149,13 +2247,14 @@ static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp,
2149 } 2247 }
2150 2248
2151 enable_clocks(1); 2249 enable_clocks(1);
2152 dispc_write_reg(DISPC_TIMING_H, timing_h); 2250 dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
2153 dispc_write_reg(DISPC_TIMING_V, timing_v); 2251 dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
2154 enable_clocks(0); 2252 enable_clocks(0);
2155} 2253}
2156 2254
2157/* change name to mode? */ 2255/* change name to mode? */
2158void dispc_set_lcd_timings(struct omap_video_timings *timings) 2256void dispc_set_lcd_timings(enum omap_channel channel,
2257 struct omap_video_timings *timings)
2159{ 2258{
2160 unsigned xtot, ytot; 2259 unsigned xtot, ytot;
2161 unsigned long ht, vt; 2260 unsigned long ht, vt;
@@ -2165,10 +2264,11 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings)
2165 timings->vfp, timings->vbp)) 2264 timings->vfp, timings->vbp))
2166 BUG(); 2265 BUG();
2167 2266
2168 _dispc_set_lcd_timings(timings->hsw, timings->hfp, timings->hbp, 2267 _dispc_set_lcd_timings(channel, timings->hsw, timings->hfp,
2169 timings->vsw, timings->vfp, timings->vbp); 2268 timings->hbp, timings->vsw, timings->vfp,
2269 timings->vbp);
2170 2270
2171 dispc_set_lcd_size(timings->x_res, timings->y_res); 2271 dispc_set_lcd_size(channel, timings->x_res, timings->y_res);
2172 2272
2173 xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp; 2273 xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp;
2174 ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp; 2274 ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp;
@@ -2176,7 +2276,8 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings)
2176 ht = (timings->pixel_clock * 1000) / xtot; 2276 ht = (timings->pixel_clock * 1000) / xtot;
2177 vt = (timings->pixel_clock * 1000) / xtot / ytot; 2277 vt = (timings->pixel_clock * 1000) / xtot / ytot;
2178 2278
2179 DSSDBG("xres %u yres %u\n", timings->x_res, timings->y_res); 2279 DSSDBG("channel %d xres %u yres %u\n", channel, timings->x_res,
2280 timings->y_res);
2180 DSSDBG("pck %u\n", timings->pixel_clock); 2281 DSSDBG("pck %u\n", timings->pixel_clock);
2181 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", 2282 DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
2182 timings->hsw, timings->hfp, timings->hbp, 2283 timings->hsw, timings->hfp, timings->hbp,
@@ -2185,21 +2286,23 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings)
2185 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt); 2286 DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
2186} 2287}
2187 2288
2188static void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div) 2289static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2290 u16 pck_div)
2189{ 2291{
2190 BUG_ON(lck_div < 1); 2292 BUG_ON(lck_div < 1);
2191 BUG_ON(pck_div < 2); 2293 BUG_ON(pck_div < 2);
2192 2294
2193 enable_clocks(1); 2295 enable_clocks(1);
2194 dispc_write_reg(DISPC_DIVISOR, 2296 dispc_write_reg(DISPC_DIVISOR(channel),
2195 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2297 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2196 enable_clocks(0); 2298 enable_clocks(0);
2197} 2299}
2198 2300
2199static void dispc_get_lcd_divisor(int *lck_div, int *pck_div) 2301static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
2302 int *pck_div)
2200{ 2303{
2201 u32 l; 2304 u32 l;
2202 l = dispc_read_reg(DISPC_DIVISOR); 2305 l = dispc_read_reg(DISPC_DIVISOR(channel));
2203 *lck_div = FLD_GET(l, 23, 16); 2306 *lck_div = FLD_GET(l, 23, 16);
2204 *pck_div = FLD_GET(l, 7, 0); 2307 *pck_div = FLD_GET(l, 7, 0);
2205} 2308}
@@ -2219,13 +2322,13 @@ unsigned long dispc_fclk_rate(void)
2219 return r; 2322 return r;
2220} 2323}
2221 2324
2222unsigned long dispc_lclk_rate(void) 2325unsigned long dispc_lclk_rate(enum omap_channel channel)
2223{ 2326{
2224 int lcd; 2327 int lcd;
2225 unsigned long r; 2328 unsigned long r;
2226 u32 l; 2329 u32 l;
2227 2330
2228 l = dispc_read_reg(DISPC_DIVISOR); 2331 l = dispc_read_reg(DISPC_DIVISOR(channel));
2229 2332
2230 lcd = FLD_GET(l, 23, 16); 2333 lcd = FLD_GET(l, 23, 16);
2231 2334
@@ -2234,13 +2337,13 @@ unsigned long dispc_lclk_rate(void)
2234 return r / lcd; 2337 return r / lcd;
2235} 2338}
2236 2339
2237unsigned long dispc_pclk_rate(void) 2340unsigned long dispc_pclk_rate(enum omap_channel channel)
2238{ 2341{
2239 int lcd, pcd; 2342 int lcd, pcd;
2240 unsigned long r; 2343 unsigned long r;
2241 u32 l; 2344 u32 l;
2242 2345
2243 l = dispc_read_reg(DISPC_DIVISOR); 2346 l = dispc_read_reg(DISPC_DIVISOR(channel));
2244 2347
2245 lcd = FLD_GET(l, 23, 16); 2348 lcd = FLD_GET(l, 23, 16);
2246 pcd = FLD_GET(l, 7, 0); 2349 pcd = FLD_GET(l, 7, 0);
@@ -2256,8 +2359,6 @@ void dispc_dump_clocks(struct seq_file *s)
2256 2359
2257 enable_clocks(1); 2360 enable_clocks(1);
2258 2361
2259 dispc_get_lcd_divisor(&lcd, &pcd);
2260
2261 seq_printf(s, "- DISPC -\n"); 2362 seq_printf(s, "- DISPC -\n");
2262 2363
2263 seq_printf(s, "dispc fclk source = %s\n", 2364 seq_printf(s, "dispc fclk source = %s\n",
@@ -2265,9 +2366,25 @@ void dispc_dump_clocks(struct seq_file *s)
2265 "dss1_alwon_fclk" : "dsi1_pll_fclk"); 2366 "dss1_alwon_fclk" : "dsi1_pll_fclk");
2266 2367
2267 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); 2368 seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate());
2268 seq_printf(s, "lck\t\t%-16lulck div\t%u\n", dispc_lclk_rate(), lcd);
2269 seq_printf(s, "pck\t\t%-16lupck div\t%u\n", dispc_pclk_rate(), pcd);
2270 2369
2370 seq_printf(s, "- LCD1 -\n");
2371
2372 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd);
2373
2374 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2375 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd);
2376 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2377 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd);
2378 if (dss_has_feature(FEAT_MGR_LCD2)) {
2379 seq_printf(s, "- LCD2 -\n");
2380
2381 dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd);
2382
2383 seq_printf(s, "lck\t\t%-16lulck div\t%u\n",
2384 dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd);
2385 seq_printf(s, "pck\t\t%-16lupck div\t%u\n",
2386 dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd);
2387 }
2271 enable_clocks(0); 2388 enable_clocks(0);
2272} 2389}
2273 2390
@@ -2309,6 +2426,12 @@ void dispc_dump_irqs(struct seq_file *s)
2309 PIS(SYNC_LOST); 2426 PIS(SYNC_LOST);
2310 PIS(SYNC_LOST_DIGIT); 2427 PIS(SYNC_LOST_DIGIT);
2311 PIS(WAKEUP); 2428 PIS(WAKEUP);
2429 if (dss_has_feature(FEAT_MGR_LCD2)) {
2430 PIS(FRAMEDONE2);
2431 PIS(VSYNC2);
2432 PIS(ACBIAS_COUNT_STAT2);
2433 PIS(SYNC_LOST2);
2434 }
2312#undef PIS 2435#undef PIS
2313} 2436}
2314#endif 2437#endif
@@ -2327,19 +2450,30 @@ void dispc_dump_regs(struct seq_file *s)
2327 DUMPREG(DISPC_CONTROL); 2450 DUMPREG(DISPC_CONTROL);
2328 DUMPREG(DISPC_CONFIG); 2451 DUMPREG(DISPC_CONFIG);
2329 DUMPREG(DISPC_CAPABLE); 2452 DUMPREG(DISPC_CAPABLE);
2330 DUMPREG(DISPC_DEFAULT_COLOR0); 2453 DUMPREG(DISPC_DEFAULT_COLOR(0));
2331 DUMPREG(DISPC_DEFAULT_COLOR1); 2454 DUMPREG(DISPC_DEFAULT_COLOR(1));
2332 DUMPREG(DISPC_TRANS_COLOR0); 2455 DUMPREG(DISPC_TRANS_COLOR(0));
2333 DUMPREG(DISPC_TRANS_COLOR1); 2456 DUMPREG(DISPC_TRANS_COLOR(1));
2334 DUMPREG(DISPC_LINE_STATUS); 2457 DUMPREG(DISPC_LINE_STATUS);
2335 DUMPREG(DISPC_LINE_NUMBER); 2458 DUMPREG(DISPC_LINE_NUMBER);
2336 DUMPREG(DISPC_TIMING_H); 2459 DUMPREG(DISPC_TIMING_H(0));
2337 DUMPREG(DISPC_TIMING_V); 2460 DUMPREG(DISPC_TIMING_V(0));
2338 DUMPREG(DISPC_POL_FREQ); 2461 DUMPREG(DISPC_POL_FREQ(0));
2339 DUMPREG(DISPC_DIVISOR); 2462 DUMPREG(DISPC_DIVISOR(0));
2340 DUMPREG(DISPC_GLOBAL_ALPHA); 2463 DUMPREG(DISPC_GLOBAL_ALPHA);
2341 DUMPREG(DISPC_SIZE_DIG); 2464 DUMPREG(DISPC_SIZE_DIG);
2342 DUMPREG(DISPC_SIZE_LCD); 2465 DUMPREG(DISPC_SIZE_LCD(0));
2466 if (dss_has_feature(FEAT_MGR_LCD2)) {
2467 DUMPREG(DISPC_CONTROL2);
2468 DUMPREG(DISPC_CONFIG2);
2469 DUMPREG(DISPC_DEFAULT_COLOR(2));
2470 DUMPREG(DISPC_TRANS_COLOR(2));
2471 DUMPREG(DISPC_TIMING_H(2));
2472 DUMPREG(DISPC_TIMING_V(2));
2473 DUMPREG(DISPC_POL_FREQ(2));
2474 DUMPREG(DISPC_DIVISOR(2));
2475 DUMPREG(DISPC_SIZE_LCD(2));
2476 }
2343 2477
2344 DUMPREG(DISPC_GFX_BA0); 2478 DUMPREG(DISPC_GFX_BA0);
2345 DUMPREG(DISPC_GFX_BA1); 2479 DUMPREG(DISPC_GFX_BA1);
@@ -2353,13 +2487,22 @@ void dispc_dump_regs(struct seq_file *s)
2353 DUMPREG(DISPC_GFX_WINDOW_SKIP); 2487 DUMPREG(DISPC_GFX_WINDOW_SKIP);
2354 DUMPREG(DISPC_GFX_TABLE_BA); 2488 DUMPREG(DISPC_GFX_TABLE_BA);
2355 2489
2356 DUMPREG(DISPC_DATA_CYCLE1); 2490 DUMPREG(DISPC_DATA_CYCLE1(0));
2357 DUMPREG(DISPC_DATA_CYCLE2); 2491 DUMPREG(DISPC_DATA_CYCLE2(0));
2358 DUMPREG(DISPC_DATA_CYCLE3); 2492 DUMPREG(DISPC_DATA_CYCLE3(0));
2359 2493
2360 DUMPREG(DISPC_CPR_COEF_R); 2494 DUMPREG(DISPC_CPR_COEF_R(0));
2361 DUMPREG(DISPC_CPR_COEF_G); 2495 DUMPREG(DISPC_CPR_COEF_G(0));
2362 DUMPREG(DISPC_CPR_COEF_B); 2496 DUMPREG(DISPC_CPR_COEF_B(0));
2497 if (dss_has_feature(FEAT_MGR_LCD2)) {
2498 DUMPREG(DISPC_DATA_CYCLE1(2));
2499 DUMPREG(DISPC_DATA_CYCLE2(2));
2500 DUMPREG(DISPC_DATA_CYCLE3(2));
2501
2502 DUMPREG(DISPC_CPR_COEF_R(2));
2503 DUMPREG(DISPC_CPR_COEF_G(2));
2504 DUMPREG(DISPC_CPR_COEF_B(2));
2505 }
2363 2506
2364 DUMPREG(DISPC_GFX_PRELOAD); 2507 DUMPREG(DISPC_GFX_PRELOAD);
2365 2508
@@ -2458,8 +2601,8 @@ void dispc_dump_regs(struct seq_file *s)
2458#undef DUMPREG 2601#undef DUMPREG
2459} 2602}
2460 2603
2461static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc, 2604static void _dispc_set_pol_freq(enum omap_channel channel, bool onoff, bool rf,
2462 bool ihs, bool ivs, u8 acbi, u8 acb) 2605 bool ieo, bool ipc, bool ihs, bool ivs, u8 acbi, u8 acb)
2463{ 2606{
2464 u32 l = 0; 2607 u32 l = 0;
2465 2608
@@ -2476,13 +2619,14 @@ static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc,
2476 l |= FLD_VAL(acb, 7, 0); 2619 l |= FLD_VAL(acb, 7, 0);
2477 2620
2478 enable_clocks(1); 2621 enable_clocks(1);
2479 dispc_write_reg(DISPC_POL_FREQ, l); 2622 dispc_write_reg(DISPC_POL_FREQ(channel), l);
2480 enable_clocks(0); 2623 enable_clocks(0);
2481} 2624}
2482 2625
2483void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb) 2626void dispc_set_pol_freq(enum omap_channel channel,
2627 enum omap_panel_config config, u8 acbi, u8 acb)
2484{ 2628{
2485 _dispc_set_pol_freq((config & OMAP_DSS_LCD_ONOFF) != 0, 2629 _dispc_set_pol_freq(channel, (config & OMAP_DSS_LCD_ONOFF) != 0,
2486 (config & OMAP_DSS_LCD_RF) != 0, 2630 (config & OMAP_DSS_LCD_RF) != 0,
2487 (config & OMAP_DSS_LCD_IEO) != 0, 2631 (config & OMAP_DSS_LCD_IEO) != 0,
2488 (config & OMAP_DSS_LCD_IPC) != 0, 2632 (config & OMAP_DSS_LCD_IPC) != 0,
@@ -2551,24 +2695,26 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
2551 return 0; 2695 return 0;
2552} 2696}
2553 2697
2554int dispc_set_clock_div(struct dispc_clock_info *cinfo) 2698int dispc_set_clock_div(enum omap_channel channel,
2699 struct dispc_clock_info *cinfo)
2555{ 2700{
2556 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div); 2701 DSSDBG("lck = %lu (%u)\n", cinfo->lck, cinfo->lck_div);
2557 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div); 2702 DSSDBG("pck = %lu (%u)\n", cinfo->pck, cinfo->pck_div);
2558 2703
2559 dispc_set_lcd_divisor(cinfo->lck_div, cinfo->pck_div); 2704 dispc_set_lcd_divisor(channel, cinfo->lck_div, cinfo->pck_div);
2560 2705
2561 return 0; 2706 return 0;
2562} 2707}
2563 2708
2564int dispc_get_clock_div(struct dispc_clock_info *cinfo) 2709int dispc_get_clock_div(enum omap_channel channel,
2710 struct dispc_clock_info *cinfo)
2565{ 2711{
2566 unsigned long fck; 2712 unsigned long fck;
2567 2713
2568 fck = dispc_fclk_rate(); 2714 fck = dispc_fclk_rate();
2569 2715
2570 cinfo->lck_div = REG_GET(DISPC_DIVISOR, 23, 16); 2716 cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16);
2571 cinfo->pck_div = REG_GET(DISPC_DIVISOR, 7, 0); 2717 cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0);
2572 2718
2573 cinfo->lck = fck / cinfo->lck_div; 2719 cinfo->lck = fck / cinfo->lck_div;
2574 cinfo->pck = cinfo->lck / cinfo->pck_div; 2720 cinfo->pck = cinfo->lck / cinfo->pck_div;
@@ -2708,6 +2854,8 @@ static void print_irq_status(u32 status)
2708 PIS(VID2_FIFO_UNDERFLOW); 2854 PIS(VID2_FIFO_UNDERFLOW);
2709 PIS(SYNC_LOST); 2855 PIS(SYNC_LOST);
2710 PIS(SYNC_LOST_DIGIT); 2856 PIS(SYNC_LOST_DIGIT);
2857 if (dss_has_feature(FEAT_MGR_LCD2))
2858 PIS(SYNC_LOST2);
2711#undef PIS 2859#undef PIS
2712 2860
2713 printk("\n"); 2861 printk("\n");
@@ -2926,6 +3074,45 @@ static void dispc_error_worker(struct work_struct *work)
2926 } 3074 }
2927 } 3075 }
2928 3076
3077 if (errors & DISPC_IRQ_SYNC_LOST2) {
3078 struct omap_overlay_manager *manager = NULL;
3079 bool enable = false;
3080
3081 DSSERR("SYNC_LOST for LCD2, disabling LCD2\n");
3082
3083 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
3084 struct omap_overlay_manager *mgr;
3085 mgr = omap_dss_get_overlay_manager(i);
3086
3087 if (mgr->id == OMAP_DSS_CHANNEL_LCD2) {
3088 manager = mgr;
3089 enable = mgr->device->state ==
3090 OMAP_DSS_DISPLAY_ACTIVE;
3091 mgr->device->driver->disable(mgr->device);
3092 break;
3093 }
3094 }
3095
3096 if (manager) {
3097 struct omap_dss_device *dssdev = manager->device;
3098 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
3099 struct omap_overlay *ovl;
3100 ovl = omap_dss_get_overlay(i);
3101
3102 if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
3103 continue;
3104
3105 if (ovl->id != 0 && ovl->manager == manager)
3106 dispc_enable_plane(ovl->id, 0);
3107 }
3108
3109 dispc_go(manager->id);
3110 mdelay(50);
3111 if (enable)
3112 dssdev->driver->enable(dssdev);
3113 }
3114 }
3115
2929 if (errors & DISPC_IRQ_OCP_ERR) { 3116 if (errors & DISPC_IRQ_OCP_ERR) {
2930 DSSERR("OCP_ERR\n"); 3117 DSSERR("OCP_ERR\n");
2931 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { 3118 for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
@@ -3033,6 +3220,8 @@ static void _omap_dispc_initialize_irq(void)
3033 memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr)); 3220 memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr));
3034 3221
3035 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 3222 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
3223 if (dss_has_feature(FEAT_MGR_LCD2))
3224 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
3036 3225
3037 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS, 3226 /* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
3038 * so clear it */ 3227 * so clear it */
@@ -3065,7 +3254,8 @@ static void _omap_dispc_initial_config(void)
3065 dispc_write_reg(DISPC_SYSCONFIG, l); 3254 dispc_write_reg(DISPC_SYSCONFIG, l);
3066 3255
3067 /* FUNCGATED */ 3256 /* FUNCGATED */
3068 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); 3257 if (dss_has_feature(FEAT_FUNCGATED))
3258 REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
3069 3259
3070 /* L3 firewall setting: enable access to OCM RAM */ 3260 /* L3 firewall setting: enable access to OCM RAM */
3071 /* XXX this should be somewhere in plat-omap */ 3261 /* XXX this should be somewhere in plat-omap */
@@ -3139,17 +3329,18 @@ int dispc_setup_plane(enum omap_plane plane,
3139 enum omap_color_mode color_mode, 3329 enum omap_color_mode color_mode,
3140 bool ilace, 3330 bool ilace,
3141 enum omap_dss_rotation_type rotation_type, 3331 enum omap_dss_rotation_type rotation_type,
3142 u8 rotation, bool mirror, u8 global_alpha) 3332 u8 rotation, bool mirror, u8 global_alpha,
3333 u8 pre_mult_alpha, enum omap_channel channel)
3143{ 3334{
3144 int r = 0; 3335 int r = 0;
3145 3336
3146 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> " 3337 DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> "
3147 "%dx%d, ilace %d, cmode %x, rot %d, mir %d\n", 3338 "%dx%d, ilace %d, cmode %x, rot %d, mir %d chan %d\n",
3148 plane, paddr, screen_width, pos_x, pos_y, 3339 plane, paddr, screen_width, pos_x, pos_y,
3149 width, height, 3340 width, height,
3150 out_width, out_height, 3341 out_width, out_height,
3151 ilace, color_mode, 3342 ilace, color_mode,
3152 rotation, mirror); 3343 rotation, mirror, channel);
3153 3344
3154 enable_clocks(1); 3345 enable_clocks(1);
3155 3346
@@ -3161,7 +3352,8 @@ int dispc_setup_plane(enum omap_plane plane,
3161 color_mode, ilace, 3352 color_mode, ilace,
3162 rotation_type, 3353 rotation_type,
3163 rotation, mirror, 3354 rotation, mirror,
3164 global_alpha); 3355 global_alpha,
3356 pre_mult_alpha, channel);
3165 3357
3166 enable_clocks(0); 3358 enable_clocks(0);
3167 3359