diff options
author | Sumit Semwal <sumit.semwal@ti.com> | 2010-12-02 06:27:12 -0500 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@nokia.com> | 2011-01-10 04:36:49 -0500 |
commit | 2a205f34b8fb2b86887b177befa7b42efd7a60b9 (patch) | |
tree | 2fdc5ca7c8156fafe21d5406a5b7de375e84c97d | |
parent | ff1b2cde3f551c9b56887b41e0ebbf2907566a7d (diff) |
OMAP: DSS2: LCD2 Channel Changes for DISPC
DISPC functions are modified in order to work when the manager is LCD2.
This includes:
Adding new IRQs specific to LCD2 and their handling.
Provide dumps of the new manager's registers.
Provide dumps of the new manager's clocks.
Checks for channel for registers DISPC_CONTROL2 and DISPC_CONFIG2
which can't be parametrized.
Signed-off-by: Sumit Semwal <sumit.semwal@ti.com>
Signed-off-by: Mukund Mittal <mmittal@ti.com>
Signed-off-by: Samreen <samreen@ti.com>
Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
-rw-r--r-- | arch/arm/plat-omap/include/plat/display.h | 4 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 281 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dpi.c | 2 |
3 files changed, 247 insertions, 40 deletions
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h index 586944d8e9e8..0180f25d1c8b 100644 --- a/arch/arm/plat-omap/include/plat/display.h +++ b/arch/arm/plat-omap/include/plat/display.h | |||
@@ -42,6 +42,10 @@ | |||
42 | #define DISPC_IRQ_SYNC_LOST (1 << 14) | 42 | #define DISPC_IRQ_SYNC_LOST (1 << 14) |
43 | #define DISPC_IRQ_SYNC_LOST_DIGIT (1 << 15) | 43 | #define DISPC_IRQ_SYNC_LOST_DIGIT (1 << 15) |
44 | #define DISPC_IRQ_WAKEUP (1 << 16) | 44 | #define DISPC_IRQ_WAKEUP (1 << 16) |
45 | #define DISPC_IRQ_SYNC_LOST2 (1 << 17) | ||
46 | #define DISPC_IRQ_VSYNC2 (1 << 18) | ||
47 | #define DISPC_IRQ_ACBIAS_COUNT_STAT2 (1 << 21) | ||
48 | #define DISPC_IRQ_FRAMEDONE2 (1 << 22) | ||
45 | 49 | ||
46 | struct omap_dss_device; | 50 | struct omap_dss_device; |
47 | struct omap_overlay_manager; | 51 | struct omap_overlay_manager; |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5dfdf0ba409d..fe41d891fd42 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -234,6 +234,17 @@ void dispc_save_context(void) | |||
234 | SR(GLOBAL_ALPHA); | 234 | SR(GLOBAL_ALPHA); |
235 | SR(SIZE_DIG); | 235 | SR(SIZE_DIG); |
236 | SR(SIZE_LCD(0)); | 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 | } | ||
237 | 248 | ||
238 | SR(GFX_BA0); | 249 | SR(GFX_BA0); |
239 | SR(GFX_BA1); | 250 | SR(GFX_BA1); |
@@ -253,6 +264,15 @@ void dispc_save_context(void) | |||
253 | SR(CPR_COEF_R(0)); | 264 | SR(CPR_COEF_R(0)); |
254 | SR(CPR_COEF_G(0)); | 265 | SR(CPR_COEF_G(0)); |
255 | SR(CPR_COEF_B(0)); | 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 | } | ||
256 | 276 | ||
257 | SR(GFX_PRELOAD); | 277 | SR(GFX_PRELOAD); |
258 | 278 | ||
@@ -373,6 +393,16 @@ void dispc_restore_context(void) | |||
373 | RR(GLOBAL_ALPHA); | 393 | RR(GLOBAL_ALPHA); |
374 | RR(SIZE_DIG); | 394 | RR(SIZE_DIG); |
375 | RR(SIZE_LCD(0)); | 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 | } | ||
376 | 406 | ||
377 | RR(GFX_BA0); | 407 | RR(GFX_BA0); |
378 | RR(GFX_BA1); | 408 | RR(GFX_BA1); |
@@ -392,6 +422,15 @@ void dispc_restore_context(void) | |||
392 | RR(CPR_COEF_R(0)); | 422 | RR(CPR_COEF_R(0)); |
393 | RR(CPR_COEF_G(0)); | 423 | RR(CPR_COEF_G(0)); |
394 | RR(CPR_COEF_B(0)); | 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 | } | ||
395 | 434 | ||
396 | RR(GFX_PRELOAD); | 435 | RR(GFX_PRELOAD); |
397 | 436 | ||
@@ -495,7 +534,8 @@ void dispc_restore_context(void) | |||
495 | 534 | ||
496 | /* enable last, because LCD & DIGIT enable are here */ | 535 | /* enable last, because LCD & DIGIT enable are here */ |
497 | RR(CONTROL); | 536 | RR(CONTROL); |
498 | 537 | if (dss_has_feature(FEAT_MGR_LCD2)) | |
538 | RR(CONTROL2); | ||
499 | /* clear spurious SYNC_LOST_DIGIT interrupts */ | 539 | /* clear spurious SYNC_LOST_DIGIT interrupts */ |
500 | dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); | 540 | dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); |
501 | 541 | ||
@@ -521,42 +561,63 @@ bool dispc_go_busy(enum omap_channel channel) | |||
521 | { | 561 | { |
522 | int bit; | 562 | int bit; |
523 | 563 | ||
524 | if (channel == OMAP_DSS_CHANNEL_LCD) | 564 | if (channel == OMAP_DSS_CHANNEL_LCD || |
565 | channel == OMAP_DSS_CHANNEL_LCD2) | ||
525 | bit = 5; /* GOLCD */ | 566 | bit = 5; /* GOLCD */ |
526 | else | 567 | else |
527 | bit = 6; /* GODIGIT */ | 568 | bit = 6; /* GODIGIT */ |
528 | 569 | ||
529 | 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; | ||
530 | } | 574 | } |
531 | 575 | ||
532 | void dispc_go(enum omap_channel channel) | 576 | void dispc_go(enum omap_channel channel) |
533 | { | 577 | { |
534 | int bit; | 578 | int bit; |
579 | bool enable_bit, go_bit; | ||
535 | 580 | ||
536 | enable_clocks(1); | 581 | enable_clocks(1); |
537 | 582 | ||
538 | if (channel == OMAP_DSS_CHANNEL_LCD) | 583 | if (channel == OMAP_DSS_CHANNEL_LCD || |
584 | channel == OMAP_DSS_CHANNEL_LCD2) | ||
539 | bit = 0; /* LCDENABLE */ | 585 | bit = 0; /* LCDENABLE */ |
540 | else | 586 | else |
541 | bit = 1; /* DIGITALENABLE */ | 587 | bit = 1; /* DIGITALENABLE */ |
542 | 588 | ||
543 | /* if the channel is not enabled, we don't need GO */ | 589 | /* if the channel is not enabled, we don't need GO */ |
544 | 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) | ||
545 | goto end; | 596 | goto end; |
546 | 597 | ||
547 | if (channel == OMAP_DSS_CHANNEL_LCD) | 598 | if (channel == OMAP_DSS_CHANNEL_LCD || |
599 | channel == OMAP_DSS_CHANNEL_LCD2) | ||
548 | bit = 5; /* GOLCD */ | 600 | bit = 5; /* GOLCD */ |
549 | else | 601 | else |
550 | bit = 6; /* GODIGIT */ | 602 | bit = 6; /* GODIGIT */ |
551 | 603 | ||
552 | 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) { | ||
553 | DSSERR("GO bit not down for channel %d\n", channel); | 610 | DSSERR("GO bit not down for channel %d\n", channel); |
554 | goto end; | 611 | goto end; |
555 | } | 612 | } |
556 | 613 | ||
557 | 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")); | ||
558 | 616 | ||
559 | 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); | ||
560 | end: | 621 | end: |
561 | enable_clocks(0); | 622 | enable_clocks(0); |
562 | } | 623 | } |
@@ -869,6 +930,7 @@ static void _dispc_set_channel_out(enum omap_plane plane, | |||
869 | { | 930 | { |
870 | int shift; | 931 | int shift; |
871 | u32 val; | 932 | u32 val; |
933 | int chan = 0, chan2 = 0; | ||
872 | 934 | ||
873 | switch (plane) { | 935 | switch (plane) { |
874 | case OMAP_DSS_GFX: | 936 | case OMAP_DSS_GFX: |
@@ -884,7 +946,29 @@ static void _dispc_set_channel_out(enum omap_plane plane, | |||
884 | } | 946 | } |
885 | 947 | ||
886 | val = dispc_read_reg(dispc_reg_att[plane]); | 948 | val = dispc_read_reg(dispc_reg_att[plane]); |
887 | 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 | } | ||
888 | dispc_write_reg(dispc_reg_att[plane], val); | 972 | dispc_write_reg(dispc_reg_att[plane], val); |
889 | } | 973 | } |
890 | 974 | ||
@@ -1688,36 +1772,44 @@ static void dispc_disable_isr(void *data, u32 mask) | |||
1688 | complete(compl); | 1772 | complete(compl); |
1689 | } | 1773 | } |
1690 | 1774 | ||
1691 | static void _enable_lcd_out(bool enable) | 1775 | static void _enable_lcd_out(enum omap_channel channel, bool enable) |
1692 | { | 1776 | { |
1693 | REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); | 1777 | if (channel == OMAP_DSS_CHANNEL_LCD2) |
1778 | REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0); | ||
1779 | else | ||
1780 | REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0); | ||
1694 | } | 1781 | } |
1695 | 1782 | ||
1696 | static void dispc_enable_lcd_out(bool enable) | 1783 | static void dispc_enable_lcd_out(enum omap_channel channel, bool enable) |
1697 | { | 1784 | { |
1698 | struct completion frame_done_completion; | 1785 | struct completion frame_done_completion; |
1699 | bool is_on; | 1786 | bool is_on; |
1700 | int r; | 1787 | int r; |
1788 | u32 irq; | ||
1701 | 1789 | ||
1702 | enable_clocks(1); | 1790 | enable_clocks(1); |
1703 | 1791 | ||
1704 | /* When we disable LCD output, we need to wait until frame is done. | 1792 | /* When we disable LCD output, we need to wait until frame is done. |
1705 | * Otherwise the DSS is still working, and turning off the clocks | 1793 | * Otherwise the DSS is still working, and turning off the clocks |
1706 | * prevents DSS from going to OFF mode */ | 1794 | * prevents DSS from going to OFF mode */ |
1707 | is_on = REG_GET(DISPC_CONTROL, 0, 0); | 1795 | is_on = channel == OMAP_DSS_CHANNEL_LCD2 ? |
1796 | REG_GET(DISPC_CONTROL2, 0, 0) : | ||
1797 | REG_GET(DISPC_CONTROL, 0, 0); | ||
1798 | |||
1799 | irq = channel == OMAP_DSS_CHANNEL_LCD2 ? DISPC_IRQ_FRAMEDONE2 : | ||
1800 | DISPC_IRQ_FRAMEDONE; | ||
1708 | 1801 | ||
1709 | if (!enable && is_on) { | 1802 | if (!enable && is_on) { |
1710 | init_completion(&frame_done_completion); | 1803 | init_completion(&frame_done_completion); |
1711 | 1804 | ||
1712 | r = omap_dispc_register_isr(dispc_disable_isr, | 1805 | r = omap_dispc_register_isr(dispc_disable_isr, |
1713 | &frame_done_completion, | 1806 | &frame_done_completion, irq); |
1714 | DISPC_IRQ_FRAMEDONE); | ||
1715 | 1807 | ||
1716 | if (r) | 1808 | if (r) |
1717 | DSSERR("failed to register FRAMEDONE isr\n"); | 1809 | DSSERR("failed to register FRAMEDONE isr\n"); |
1718 | } | 1810 | } |
1719 | 1811 | ||
1720 | _enable_lcd_out(enable); | 1812 | _enable_lcd_out(channel, enable); |
1721 | 1813 | ||
1722 | if (!enable && is_on) { | 1814 | if (!enable && is_on) { |
1723 | if (!wait_for_completion_timeout(&frame_done_completion, | 1815 | if (!wait_for_completion_timeout(&frame_done_completion, |
@@ -1725,8 +1817,7 @@ static void dispc_enable_lcd_out(bool enable) | |||
1725 | DSSERR("timeout waiting for FRAME DONE\n"); | 1817 | DSSERR("timeout waiting for FRAME DONE\n"); |
1726 | 1818 | ||
1727 | r = omap_dispc_unregister_isr(dispc_disable_isr, | 1819 | r = omap_dispc_unregister_isr(dispc_disable_isr, |
1728 | &frame_done_completion, | 1820 | &frame_done_completion, irq); |
1729 | DISPC_IRQ_FRAMEDONE); | ||
1730 | 1821 | ||
1731 | if (r) | 1822 | if (r) |
1732 | DSSERR("failed to unregister FRAMEDONE isr\n"); | 1823 | DSSERR("failed to unregister FRAMEDONE isr\n"); |
@@ -1796,6 +1887,8 @@ static void dispc_enable_digit_out(bool enable) | |||
1796 | unsigned long flags; | 1887 | unsigned long flags; |
1797 | spin_lock_irqsave(&dispc.irq_lock, flags); | 1888 | spin_lock_irqsave(&dispc.irq_lock, flags); |
1798 | dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; | 1889 | dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; |
1890 | if (dss_has_feature(FEAT_MGR_LCD2)) | ||
1891 | dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2; | ||
1799 | dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); | 1892 | dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); |
1800 | _omap_dispc_set_irqs(); | 1893 | _omap_dispc_set_irqs(); |
1801 | spin_unlock_irqrestore(&dispc.irq_lock, flags); | 1894 | spin_unlock_irqrestore(&dispc.irq_lock, flags); |
@@ -1810,14 +1903,17 @@ bool dispc_is_channel_enabled(enum omap_channel channel) | |||
1810 | return !!REG_GET(DISPC_CONTROL, 0, 0); | 1903 | return !!REG_GET(DISPC_CONTROL, 0, 0); |
1811 | else if (channel == OMAP_DSS_CHANNEL_DIGIT) | 1904 | else if (channel == OMAP_DSS_CHANNEL_DIGIT) |
1812 | return !!REG_GET(DISPC_CONTROL, 1, 1); | 1905 | return !!REG_GET(DISPC_CONTROL, 1, 1); |
1906 | else if (channel == OMAP_DSS_CHANNEL_LCD2) | ||
1907 | return !!REG_GET(DISPC_CONTROL2, 0, 0); | ||
1813 | else | 1908 | else |
1814 | BUG(); | 1909 | BUG(); |
1815 | } | 1910 | } |
1816 | 1911 | ||
1817 | void dispc_enable_channel(enum omap_channel channel, bool enable) | 1912 | void dispc_enable_channel(enum omap_channel channel, bool enable) |
1818 | { | 1913 | { |
1819 | if (channel == OMAP_DSS_CHANNEL_LCD) | 1914 | if (channel == OMAP_DSS_CHANNEL_LCD || |
1820 | dispc_enable_lcd_out(enable); | 1915 | channel == OMAP_DSS_CHANNEL_LCD2) |
1916 | dispc_enable_lcd_out(channel, enable); | ||
1821 | else if (channel == OMAP_DSS_CHANNEL_DIGIT) | 1917 | else if (channel == OMAP_DSS_CHANNEL_DIGIT) |
1822 | dispc_enable_digit_out(enable); | 1918 | dispc_enable_digit_out(enable); |
1823 | else | 1919 | else |
@@ -1848,7 +1944,10 @@ void dispc_pck_free_enable(bool enable) | |||
1848 | void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable) | 1944 | void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable) |
1849 | { | 1945 | { |
1850 | enable_clocks(1); | 1946 | enable_clocks(1); |
1851 | REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16); | 1947 | if (channel == OMAP_DSS_CHANNEL_LCD2) |
1948 | REG_FLD_MOD(DISPC_CONFIG2, enable ? 1 : 0, 16, 16); | ||
1949 | else | ||
1950 | REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16); | ||
1852 | enable_clocks(0); | 1951 | enable_clocks(0); |
1853 | } | 1952 | } |
1854 | 1953 | ||
@@ -1873,7 +1972,10 @@ void dispc_set_lcd_display_type(enum omap_channel channel, | |||
1873 | } | 1972 | } |
1874 | 1973 | ||
1875 | enable_clocks(1); | 1974 | enable_clocks(1); |
1876 | REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3); | 1975 | if (channel == OMAP_DSS_CHANNEL_LCD2) |
1976 | REG_FLD_MOD(DISPC_CONTROL2, mode, 3, 3); | ||
1977 | else | ||
1978 | REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3); | ||
1877 | enable_clocks(0); | 1979 | enable_clocks(0); |
1878 | } | 1980 | } |
1879 | 1981 | ||
@@ -1897,7 +1999,8 @@ u32 dispc_get_default_color(enum omap_channel channel) | |||
1897 | u32 l; | 1999 | u32 l; |
1898 | 2000 | ||
1899 | BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT && | 2001 | BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT && |
1900 | channel != OMAP_DSS_CHANNEL_LCD); | 2002 | channel != OMAP_DSS_CHANNEL_LCD && |
2003 | channel != OMAP_DSS_CHANNEL_LCD2); | ||
1901 | 2004 | ||
1902 | enable_clocks(1); | 2005 | enable_clocks(1); |
1903 | l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel)); | 2006 | l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel)); |
@@ -1913,8 +2016,10 @@ void dispc_set_trans_key(enum omap_channel ch, | |||
1913 | enable_clocks(1); | 2016 | enable_clocks(1); |
1914 | if (ch == OMAP_DSS_CHANNEL_LCD) | 2017 | if (ch == OMAP_DSS_CHANNEL_LCD) |
1915 | REG_FLD_MOD(DISPC_CONFIG, type, 11, 11); | 2018 | REG_FLD_MOD(DISPC_CONFIG, type, 11, 11); |
1916 | else /* OMAP_DSS_CHANNEL_DIGIT */ | 2019 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) |
1917 | REG_FLD_MOD(DISPC_CONFIG, type, 13, 13); | 2020 | REG_FLD_MOD(DISPC_CONFIG, type, 13, 13); |
2021 | else /* OMAP_DSS_CHANNEL_LCD2 */ | ||
2022 | REG_FLD_MOD(DISPC_CONFIG2, type, 11, 11); | ||
1918 | 2023 | ||
1919 | dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); | 2024 | dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key); |
1920 | enable_clocks(0); | 2025 | enable_clocks(0); |
@@ -1930,6 +2035,8 @@ void dispc_get_trans_key(enum omap_channel ch, | |||
1930 | *type = REG_GET(DISPC_CONFIG, 11, 11); | 2035 | *type = REG_GET(DISPC_CONFIG, 11, 11); |
1931 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) | 2036 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) |
1932 | *type = REG_GET(DISPC_CONFIG, 13, 13); | 2037 | *type = REG_GET(DISPC_CONFIG, 13, 13); |
2038 | else if (ch == OMAP_DSS_CHANNEL_LCD2) | ||
2039 | *type = REG_GET(DISPC_CONFIG2, 11, 11); | ||
1933 | else | 2040 | else |
1934 | BUG(); | 2041 | BUG(); |
1935 | } | 2042 | } |
@@ -1944,8 +2051,10 @@ void dispc_enable_trans_key(enum omap_channel ch, bool enable) | |||
1944 | enable_clocks(1); | 2051 | enable_clocks(1); |
1945 | if (ch == OMAP_DSS_CHANNEL_LCD) | 2052 | if (ch == OMAP_DSS_CHANNEL_LCD) |
1946 | REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); | 2053 | REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10); |
1947 | else /* OMAP_DSS_CHANNEL_DIGIT */ | 2054 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) |
1948 | REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12); | 2055 | REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12); |
2056 | else /* OMAP_DSS_CHANNEL_LCD2 */ | ||
2057 | REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10); | ||
1949 | enable_clocks(0); | 2058 | enable_clocks(0); |
1950 | } | 2059 | } |
1951 | void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) | 2060 | void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) |
@@ -1956,8 +2065,10 @@ void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) | |||
1956 | enable_clocks(1); | 2065 | enable_clocks(1); |
1957 | if (ch == OMAP_DSS_CHANNEL_LCD) | 2066 | if (ch == OMAP_DSS_CHANNEL_LCD) |
1958 | REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18); | 2067 | REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18); |
1959 | else /* OMAP_DSS_CHANNEL_DIGIT */ | 2068 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) |
1960 | REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); | 2069 | REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); |
2070 | else /* OMAP_DSS_CHANNEL_LCD2 */ | ||
2071 | REG_FLD_MOD(DISPC_CONFIG2, enable, 18, 18); | ||
1961 | enable_clocks(0); | 2072 | enable_clocks(0); |
1962 | } | 2073 | } |
1963 | bool dispc_alpha_blending_enabled(enum omap_channel ch) | 2074 | bool dispc_alpha_blending_enabled(enum omap_channel ch) |
@@ -1972,6 +2083,8 @@ bool dispc_alpha_blending_enabled(enum omap_channel ch) | |||
1972 | enabled = REG_GET(DISPC_CONFIG, 18, 18); | 2083 | enabled = REG_GET(DISPC_CONFIG, 18, 18); |
1973 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) | 2084 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) |
1974 | enabled = REG_GET(DISPC_CONFIG, 19, 19); | 2085 | enabled = REG_GET(DISPC_CONFIG, 19, 19); |
2086 | else if (ch == OMAP_DSS_CHANNEL_LCD2) | ||
2087 | enabled = REG_GET(DISPC_CONFIG2, 18, 18); | ||
1975 | else | 2088 | else |
1976 | BUG(); | 2089 | BUG(); |
1977 | enable_clocks(0); | 2090 | enable_clocks(0); |
@@ -1989,6 +2102,8 @@ bool dispc_trans_key_enabled(enum omap_channel ch) | |||
1989 | enabled = REG_GET(DISPC_CONFIG, 10, 10); | 2102 | enabled = REG_GET(DISPC_CONFIG, 10, 10); |
1990 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) | 2103 | else if (ch == OMAP_DSS_CHANNEL_DIGIT) |
1991 | enabled = REG_GET(DISPC_CONFIG, 12, 12); | 2104 | enabled = REG_GET(DISPC_CONFIG, 12, 12); |
2105 | else if (ch == OMAP_DSS_CHANNEL_LCD2) | ||
2106 | enabled = REG_GET(DISPC_CONFIG2, 10, 10); | ||
1992 | else | 2107 | else |
1993 | BUG(); | 2108 | BUG(); |
1994 | enable_clocks(0); | 2109 | enable_clocks(0); |
@@ -2020,7 +2135,10 @@ void dispc_set_tft_data_lines(enum omap_channel channel, u8 data_lines) | |||
2020 | } | 2135 | } |
2021 | 2136 | ||
2022 | enable_clocks(1); | 2137 | enable_clocks(1); |
2023 | REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); | 2138 | if (channel == OMAP_DSS_CHANNEL_LCD2) |
2139 | REG_FLD_MOD(DISPC_CONTROL2, code, 9, 8); | ||
2140 | else | ||
2141 | REG_FLD_MOD(DISPC_CONTROL, code, 9, 8); | ||
2024 | enable_clocks(0); | 2142 | enable_clocks(0); |
2025 | } | 2143 | } |
2026 | 2144 | ||
@@ -2055,15 +2173,17 @@ void dispc_set_parallel_interface_mode(enum omap_channel channel, | |||
2055 | 2173 | ||
2056 | enable_clocks(1); | 2174 | enable_clocks(1); |
2057 | 2175 | ||
2058 | l = dispc_read_reg(DISPC_CONTROL); | 2176 | if (channel == OMAP_DSS_CHANNEL_LCD2) { |
2059 | 2177 | l = dispc_read_reg(DISPC_CONTROL2); | |
2060 | l = FLD_MOD(l, stallmode, 11, 11); | 2178 | l = FLD_MOD(l, stallmode, 11, 11); |
2061 | 2179 | dispc_write_reg(DISPC_CONTROL2, l); | |
2062 | if (channel == OMAP_DSS_CHANNEL_LCD) { | 2180 | } else { |
2181 | l = dispc_read_reg(DISPC_CONTROL); | ||
2182 | l = FLD_MOD(l, stallmode, 11, 11); | ||
2063 | l = FLD_MOD(l, gpout0, 15, 15); | 2183 | l = FLD_MOD(l, gpout0, 15, 15); |
2064 | l = FLD_MOD(l, gpout1, 16, 16); | 2184 | l = FLD_MOD(l, gpout1, 16, 16); |
2185 | dispc_write_reg(DISPC_CONTROL, l); | ||
2065 | } | 2186 | } |
2066 | dispc_write_reg(DISPC_CONTROL, l); | ||
2067 | 2187 | ||
2068 | enable_clocks(0); | 2188 | enable_clocks(0); |
2069 | } | 2189 | } |
@@ -2148,7 +2268,8 @@ void dispc_set_lcd_timings(enum omap_channel channel, | |||
2148 | ht = (timings->pixel_clock * 1000) / xtot; | 2268 | ht = (timings->pixel_clock * 1000) / xtot; |
2149 | vt = (timings->pixel_clock * 1000) / xtot / ytot; | 2269 | vt = (timings->pixel_clock * 1000) / xtot / ytot; |
2150 | 2270 | ||
2151 | DSSDBG("xres %u yres %u\n", timings->x_res, timings->y_res); | 2271 | DSSDBG("channel %d xres %u yres %u\n", channel, timings->x_res, |
2272 | timings->y_res); | ||
2152 | DSSDBG("pck %u\n", timings->pixel_clock); | 2273 | DSSDBG("pck %u\n", timings->pixel_clock); |
2153 | DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", | 2274 | DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n", |
2154 | timings->hsw, timings->hfp, timings->hbp, | 2275 | timings->hsw, timings->hfp, timings->hbp, |
@@ -2169,10 +2290,11 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div, | |||
2169 | enable_clocks(0); | 2290 | enable_clocks(0); |
2170 | } | 2291 | } |
2171 | 2292 | ||
2172 | static void dispc_get_lcd_divisor(int *lck_div, int *pck_div) | 2293 | static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div, |
2294 | int *pck_div) | ||
2173 | { | 2295 | { |
2174 | u32 l; | 2296 | u32 l; |
2175 | l = dispc_read_reg(DISPC_DIVISOR(OMAP_DSS_CHANNEL_LCD)); | 2297 | l = dispc_read_reg(DISPC_DIVISOR(channel)); |
2176 | *lck_div = FLD_GET(l, 23, 16); | 2298 | *lck_div = FLD_GET(l, 23, 16); |
2177 | *pck_div = FLD_GET(l, 7, 0); | 2299 | *pck_div = FLD_GET(l, 7, 0); |
2178 | } | 2300 | } |
@@ -2229,8 +2351,6 @@ void dispc_dump_clocks(struct seq_file *s) | |||
2229 | 2351 | ||
2230 | enable_clocks(1); | 2352 | enable_clocks(1); |
2231 | 2353 | ||
2232 | dispc_get_lcd_divisor(&lcd, &pcd); | ||
2233 | |||
2234 | seq_printf(s, "- DISPC -\n"); | 2354 | seq_printf(s, "- DISPC -\n"); |
2235 | 2355 | ||
2236 | seq_printf(s, "dispc fclk source = %s\n", | 2356 | seq_printf(s, "dispc fclk source = %s\n", |
@@ -2238,11 +2358,25 @@ void dispc_dump_clocks(struct seq_file *s) | |||
2238 | "dss1_alwon_fclk" : "dsi1_pll_fclk"); | 2358 | "dss1_alwon_fclk" : "dsi1_pll_fclk"); |
2239 | 2359 | ||
2240 | seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); | 2360 | seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); |
2361 | |||
2362 | seq_printf(s, "- LCD1 -\n"); | ||
2363 | |||
2364 | dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); | ||
2365 | |||
2241 | seq_printf(s, "lck\t\t%-16lulck div\t%u\n", | 2366 | seq_printf(s, "lck\t\t%-16lulck div\t%u\n", |
2242 | dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd); | 2367 | dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD), lcd); |
2243 | seq_printf(s, "pck\t\t%-16lupck div\t%u\n", | 2368 | seq_printf(s, "pck\t\t%-16lupck div\t%u\n", |
2244 | dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd); | 2369 | dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD), pcd); |
2370 | if (dss_has_feature(FEAT_MGR_LCD2)) { | ||
2371 | seq_printf(s, "- LCD2 -\n"); | ||
2372 | |||
2373 | dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); | ||
2245 | 2374 | ||
2375 | seq_printf(s, "lck\t\t%-16lulck div\t%u\n", | ||
2376 | dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD2), lcd); | ||
2377 | seq_printf(s, "pck\t\t%-16lupck div\t%u\n", | ||
2378 | dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD2), pcd); | ||
2379 | } | ||
2246 | enable_clocks(0); | 2380 | enable_clocks(0); |
2247 | } | 2381 | } |
2248 | 2382 | ||
@@ -2284,6 +2418,12 @@ void dispc_dump_irqs(struct seq_file *s) | |||
2284 | PIS(SYNC_LOST); | 2418 | PIS(SYNC_LOST); |
2285 | PIS(SYNC_LOST_DIGIT); | 2419 | PIS(SYNC_LOST_DIGIT); |
2286 | PIS(WAKEUP); | 2420 | PIS(WAKEUP); |
2421 | if (dss_has_feature(FEAT_MGR_LCD2)) { | ||
2422 | PIS(FRAMEDONE2); | ||
2423 | PIS(VSYNC2); | ||
2424 | PIS(ACBIAS_COUNT_STAT2); | ||
2425 | PIS(SYNC_LOST2); | ||
2426 | } | ||
2287 | #undef PIS | 2427 | #undef PIS |
2288 | } | 2428 | } |
2289 | #endif | 2429 | #endif |
@@ -2315,6 +2455,17 @@ void dispc_dump_regs(struct seq_file *s) | |||
2315 | DUMPREG(DISPC_GLOBAL_ALPHA); | 2455 | DUMPREG(DISPC_GLOBAL_ALPHA); |
2316 | DUMPREG(DISPC_SIZE_DIG); | 2456 | DUMPREG(DISPC_SIZE_DIG); |
2317 | DUMPREG(DISPC_SIZE_LCD(0)); | 2457 | DUMPREG(DISPC_SIZE_LCD(0)); |
2458 | if (dss_has_feature(FEAT_MGR_LCD2)) { | ||
2459 | DUMPREG(DISPC_CONTROL2); | ||
2460 | DUMPREG(DISPC_CONFIG2); | ||
2461 | DUMPREG(DISPC_DEFAULT_COLOR(2)); | ||
2462 | DUMPREG(DISPC_TRANS_COLOR(2)); | ||
2463 | DUMPREG(DISPC_TIMING_H(2)); | ||
2464 | DUMPREG(DISPC_TIMING_V(2)); | ||
2465 | DUMPREG(DISPC_POL_FREQ(2)); | ||
2466 | DUMPREG(DISPC_DIVISOR(2)); | ||
2467 | DUMPREG(DISPC_SIZE_LCD(2)); | ||
2468 | } | ||
2318 | 2469 | ||
2319 | DUMPREG(DISPC_GFX_BA0); | 2470 | DUMPREG(DISPC_GFX_BA0); |
2320 | DUMPREG(DISPC_GFX_BA1); | 2471 | DUMPREG(DISPC_GFX_BA1); |
@@ -2335,6 +2486,15 @@ void dispc_dump_regs(struct seq_file *s) | |||
2335 | DUMPREG(DISPC_CPR_COEF_R(0)); | 2486 | DUMPREG(DISPC_CPR_COEF_R(0)); |
2336 | DUMPREG(DISPC_CPR_COEF_G(0)); | 2487 | DUMPREG(DISPC_CPR_COEF_G(0)); |
2337 | DUMPREG(DISPC_CPR_COEF_B(0)); | 2488 | DUMPREG(DISPC_CPR_COEF_B(0)); |
2489 | if (dss_has_feature(FEAT_MGR_LCD2)) { | ||
2490 | DUMPREG(DISPC_DATA_CYCLE1(2)); | ||
2491 | DUMPREG(DISPC_DATA_CYCLE2(2)); | ||
2492 | DUMPREG(DISPC_DATA_CYCLE3(2)); | ||
2493 | |||
2494 | DUMPREG(DISPC_CPR_COEF_R(2)); | ||
2495 | DUMPREG(DISPC_CPR_COEF_G(2)); | ||
2496 | DUMPREG(DISPC_CPR_COEF_B(2)); | ||
2497 | } | ||
2338 | 2498 | ||
2339 | DUMPREG(DISPC_GFX_PRELOAD); | 2499 | DUMPREG(DISPC_GFX_PRELOAD); |
2340 | 2500 | ||
@@ -2686,6 +2846,8 @@ static void print_irq_status(u32 status) | |||
2686 | PIS(VID2_FIFO_UNDERFLOW); | 2846 | PIS(VID2_FIFO_UNDERFLOW); |
2687 | PIS(SYNC_LOST); | 2847 | PIS(SYNC_LOST); |
2688 | PIS(SYNC_LOST_DIGIT); | 2848 | PIS(SYNC_LOST_DIGIT); |
2849 | if (dss_has_feature(FEAT_MGR_LCD2)) | ||
2850 | PIS(SYNC_LOST2); | ||
2689 | #undef PIS | 2851 | #undef PIS |
2690 | 2852 | ||
2691 | printk("\n"); | 2853 | printk("\n"); |
@@ -2904,6 +3066,45 @@ static void dispc_error_worker(struct work_struct *work) | |||
2904 | } | 3066 | } |
2905 | } | 3067 | } |
2906 | 3068 | ||
3069 | if (errors & DISPC_IRQ_SYNC_LOST2) { | ||
3070 | struct omap_overlay_manager *manager = NULL; | ||
3071 | bool enable = false; | ||
3072 | |||
3073 | DSSERR("SYNC_LOST for LCD2, disabling LCD2\n"); | ||
3074 | |||
3075 | for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { | ||
3076 | struct omap_overlay_manager *mgr; | ||
3077 | mgr = omap_dss_get_overlay_manager(i); | ||
3078 | |||
3079 | if (mgr->id == OMAP_DSS_CHANNEL_LCD2) { | ||
3080 | manager = mgr; | ||
3081 | enable = mgr->device->state == | ||
3082 | OMAP_DSS_DISPLAY_ACTIVE; | ||
3083 | mgr->device->driver->disable(mgr->device); | ||
3084 | break; | ||
3085 | } | ||
3086 | } | ||
3087 | |||
3088 | if (manager) { | ||
3089 | struct omap_dss_device *dssdev = manager->device; | ||
3090 | for (i = 0; i < omap_dss_get_num_overlays(); ++i) { | ||
3091 | struct omap_overlay *ovl; | ||
3092 | ovl = omap_dss_get_overlay(i); | ||
3093 | |||
3094 | if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC)) | ||
3095 | continue; | ||
3096 | |||
3097 | if (ovl->id != 0 && ovl->manager == manager) | ||
3098 | dispc_enable_plane(ovl->id, 0); | ||
3099 | } | ||
3100 | |||
3101 | dispc_go(manager->id); | ||
3102 | mdelay(50); | ||
3103 | if (enable) | ||
3104 | dssdev->driver->enable(dssdev); | ||
3105 | } | ||
3106 | } | ||
3107 | |||
2907 | if (errors & DISPC_IRQ_OCP_ERR) { | 3108 | if (errors & DISPC_IRQ_OCP_ERR) { |
2908 | DSSERR("OCP_ERR\n"); | 3109 | DSSERR("OCP_ERR\n"); |
2909 | for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { | 3110 | for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { |
@@ -3011,6 +3212,8 @@ static void _omap_dispc_initialize_irq(void) | |||
3011 | memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr)); | 3212 | memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr)); |
3012 | 3213 | ||
3013 | dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; | 3214 | dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; |
3215 | if (dss_has_feature(FEAT_MGR_LCD2)) | ||
3216 | dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2; | ||
3014 | 3217 | ||
3015 | /* there's SYNC_LOST_DIGIT waiting after enabling the DSS, | 3218 | /* there's SYNC_LOST_DIGIT waiting after enabling the DSS, |
3016 | * so clear it */ | 3219 | * so clear it */ |
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 8c61e87629b3..75fb0a515430 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c | |||
@@ -238,7 +238,7 @@ void dpi_set_timings(struct omap_dss_device *dssdev, | |||
238 | dssdev->panel.timings = *timings; | 238 | dssdev->panel.timings = *timings; |
239 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { | 239 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { |
240 | dpi_set_mode(dssdev); | 240 | dpi_set_mode(dssdev); |
241 | dispc_go(OMAP_DSS_CHANNEL_LCD); | 241 | dispc_go(dssdev->manager->id); |
242 | } | 242 | } |
243 | } | 243 | } |
244 | EXPORT_SYMBOL(dpi_set_timings); | 244 | EXPORT_SYMBOL(dpi_set_timings); |