diff options
Diffstat (limited to 'drivers/video/omap2/dss/dispc.c')
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 636 |
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 | ||
49 | struct dispc_reg { u16 idx; }; | 49 | struct 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 | ||
527 | void dispc_go(enum omap_channel channel) | 576 | void 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); | ||
555 | end: | 621 | end: |
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 | ||
842 | static 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 | |||
776 | static void _dispc_setup_global_alpha(enum omap_plane plane, u8 global_alpha) | 854 | static 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 | ||
926 | void dispc_set_lcd_size(u16 width, u16 height) | 1028 | void 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 | ||
1429 | static unsigned long calc_fclk_five_taps(u16 width, u16 height, | 1531 | static 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 | ||
1466 | static unsigned long calc_fclk(u16 width, u16 height, | 1569 | static 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 | ||
1494 | void dispc_set_channel_out(enum omap_plane plane, enum omap_channel channel_out) | 1597 | void 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 | ||
1713 | static void _enable_lcd_out(bool enable) | 1774 | static 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 | ||
1718 | static void dispc_enable_lcd_out(bool enable) | 1782 | static 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 | ||
1839 | void dispc_enable_channel(enum omap_channel channel, bool enable) | 1911 | void 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 | ||
1849 | void dispc_lcd_enable_signal_polarity(bool act_high) | 1922 | void 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 | ||
1856 | void dispc_lcd_enable_signal(bool enable) | 1932 | void 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 | ||
1863 | void dispc_pck_free_enable(bool enable) | 1942 | void 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 | ||
1870 | void dispc_enable_fifohandcheck(bool enable) | 1952 | void 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 | ||
1878 | void dispc_set_lcd_display_type(enum omap_lcd_display_type type) | 1963 | void 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 | ||
1909 | void dispc_set_default_color(enum omap_channel channel, u32 color) | 1998 | void 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 | ||
1919 | u32 dispc_get_default_color(enum omap_channel channel) | 2005 | u32 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 | } |
1983 | void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) | 2068 | void 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 | } |
1995 | bool dispc_alpha_blending_enabled(enum omap_channel ch) | 2082 | bool 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 | ||
2033 | void dispc_set_tft_data_lines(u8 data_lines) | 2123 | void 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 | ||
2060 | void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode) | 2153 | void 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 | ||
2132 | static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp, | 2230 | static 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? */ |
2158 | void dispc_set_lcd_timings(struct omap_video_timings *timings) | 2256 | void 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 | ||
2188 | static void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div) | 2289 | static 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 | ||
2199 | static void dispc_get_lcd_divisor(int *lck_div, int *pck_div) | 2301 | static 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 | ||
2222 | unsigned long dispc_lclk_rate(void) | 2325 | unsigned 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 | ||
2237 | unsigned long dispc_pclk_rate(void) | 2340 | unsigned 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 | ||
2461 | static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc, | 2604 | static 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 | ||
2483 | void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb) | 2626 | void 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 | ||
2554 | int dispc_set_clock_div(struct dispc_clock_info *cinfo) | 2698 | int 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 | ||
2564 | int dispc_get_clock_div(struct dispc_clock_info *cinfo) | 2709 | int 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 | ||