aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Semwal <sumit.semwal@ti.com>2010-12-02 06:27:12 -0500
committerTomi Valkeinen <tomi.valkeinen@nokia.com>2011-01-10 04:36:49 -0500
commit2a205f34b8fb2b86887b177befa7b42efd7a60b9 (patch)
tree2fdc5ca7c8156fafe21d5406a5b7de375e84c97d
parentff1b2cde3f551c9b56887b41e0ebbf2907566a7d (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.h4
-rw-r--r--drivers/video/omap2/dss/dispc.c281
-rw-r--r--drivers/video/omap2/dss/dpi.c2
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
46struct omap_dss_device; 50struct omap_dss_device;
47struct omap_overlay_manager; 51struct 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
532void dispc_go(enum omap_channel channel) 576void 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);
560end: 621end:
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
1691static void _enable_lcd_out(bool enable) 1775static 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
1696static void dispc_enable_lcd_out(bool enable) 1783static 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
1817void dispc_enable_channel(enum omap_channel channel, bool enable) 1912void 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)
1848void dispc_enable_fifohandcheck(enum omap_channel channel, bool enable) 1944void 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}
1951void dispc_enable_alpha_blending(enum omap_channel ch, bool enable) 2060void 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}
1963bool dispc_alpha_blending_enabled(enum omap_channel ch) 2074bool 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
2172static void dispc_get_lcd_divisor(int *lck_div, int *pck_div) 2293static 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}
244EXPORT_SYMBOL(dpi_set_timings); 244EXPORT_SYMBOL(dpi_set_timings);