aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandrabhanu Mahapatra <cmahapatra@ti.com>2012-06-29 01:13:13 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-06-29 02:41:24 -0400
commite86d456a23f3ecbb97704e63899ecfd6ec54b8d8 (patch)
tree6984403531a2af514031916a20ff6d37c15c4f22
parentff6331e25e3e02de17deef9a1e96334dad29e097 (diff)
OMAPDSS: Add LCD3 overlay manager and Clock and IRQ support
The support for LCD3 manager has been added into the manager module. LCD3 panel has registers as DISPC_CONTROL3 and DISPC_CONFIG3 just like those in LCD and LCD2 panels. These registers control the Display Controller (DISPC) module for LCD3 output. The three LCDs support Display Serial Interface (DSI), Remote Frame Buffer Interface (RFBI) and Parallel CMOS Output Interface (DPI). These LCDs can be connected through parallel output interface using DISPC and RFBI or DPI. For serial interface DSS uses DSI. The LCD3 panel, just like LCD and LCD2 panels, has a clock switch in DSS_CTRL register which has been enabled. The clock switch chooses between DSS_CLK and DPLL_DSI1_C_CLK1 as source for LCD3_CLK. New IRQs as DISPC_IRQ_VSYNC3, DISPC_IRQ_FRAMEDONE3, DISPC_IRQ_ACBIAS_COUNT_STAT3 and DISPC_IRQ_SYNC_LOST3 have been added specific to the new manager. Signed-off-by: Chandrabhanu Mahapatra <cmahapatra@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/video/omap2/dss/dispc.c48
-rw-r--r--drivers/video/omap2/dss/dispc.h2
-rw-r--r--drivers/video/omap2/dss/dss.c12
-rw-r--r--drivers/video/omap2/dss/dss_features.h5
-rw-r--r--drivers/video/omap2/dss/manager.c4
-rw-r--r--drivers/video/omap2/dss/overlay.c12
-rw-r--r--include/video/omapdss.h4
7 files changed, 78 insertions, 9 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index eb1c9be20d0a..d19665e74e72 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -191,6 +191,23 @@ static const struct {
191 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG2, 16, 16 }, 191 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG2, 16, 16 },
192 }, 192 },
193 }, 193 },
194 [OMAP_DSS_CHANNEL_LCD3] = {
195 .name = "LCD3",
196 .vsync_irq = DISPC_IRQ_VSYNC3,
197 .framedone_irq = DISPC_IRQ_FRAMEDONE3,
198 .sync_lost_irq = DISPC_IRQ_SYNC_LOST3,
199 .reg_desc = {
200 [DISPC_MGR_FLD_ENABLE] = { DISPC_CONTROL3, 0, 0 },
201 [DISPC_MGR_FLD_STNTFT] = { DISPC_CONTROL3, 3, 3 },
202 [DISPC_MGR_FLD_GO] = { DISPC_CONTROL3, 5, 5 },
203 [DISPC_MGR_FLD_TFTDATALINES] = { DISPC_CONTROL3, 9, 8 },
204 [DISPC_MGR_FLD_STALLMODE] = { DISPC_CONTROL3, 11, 11 },
205 [DISPC_MGR_FLD_TCKENABLE] = { DISPC_CONFIG3, 10, 10 },
206 [DISPC_MGR_FLD_TCKSELECTION] = { DISPC_CONFIG3, 11, 11 },
207 [DISPC_MGR_FLD_CPR] = { DISPC_CONFIG3, 15, 15 },
208 [DISPC_MGR_FLD_FIFOHANDCHECK] = { DISPC_CONFIG3, 16, 16 },
209 },
210 },
194}; 211};
195 212
196static void _omap_dispc_set_irqs(void); 213static void _omap_dispc_set_irqs(void);
@@ -239,6 +256,10 @@ static void dispc_save_context(void)
239 SR(CONTROL2); 256 SR(CONTROL2);
240 SR(CONFIG2); 257 SR(CONFIG2);
241 } 258 }
259 if (dss_has_feature(FEAT_MGR_LCD3)) {
260 SR(CONTROL3);
261 SR(CONFIG3);
262 }
242 263
243 for (i = 0; i < dss_feat_get_num_mgrs(); i++) { 264 for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
244 SR(DEFAULT_COLOR(i)); 265 SR(DEFAULT_COLOR(i));
@@ -352,6 +373,8 @@ static void dispc_restore_context(void)
352 RR(GLOBAL_ALPHA); 373 RR(GLOBAL_ALPHA);
353 if (dss_has_feature(FEAT_MGR_LCD2)) 374 if (dss_has_feature(FEAT_MGR_LCD2))
354 RR(CONFIG2); 375 RR(CONFIG2);
376 if (dss_has_feature(FEAT_MGR_LCD3))
377 RR(CONFIG3);
355 378
356 for (i = 0; i < dss_feat_get_num_mgrs(); i++) { 379 for (i = 0; i < dss_feat_get_num_mgrs(); i++) {
357 RR(DEFAULT_COLOR(i)); 380 RR(DEFAULT_COLOR(i));
@@ -437,6 +460,8 @@ static void dispc_restore_context(void)
437 RR(CONTROL); 460 RR(CONTROL);
438 if (dss_has_feature(FEAT_MGR_LCD2)) 461 if (dss_has_feature(FEAT_MGR_LCD2))
439 RR(CONTROL2); 462 RR(CONTROL2);
463 if (dss_has_feature(FEAT_MGR_LCD3))
464 RR(CONTROL3);
440 /* clear spurious SYNC_LOST_DIGIT interrupts */ 465 /* clear spurious SYNC_LOST_DIGIT interrupts */
441 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); 466 dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
442 467
@@ -476,7 +501,8 @@ void dispc_runtime_put(void)
476static inline bool dispc_mgr_is_lcd(enum omap_channel channel) 501static inline bool dispc_mgr_is_lcd(enum omap_channel channel)
477{ 502{
478 if (channel == OMAP_DSS_CHANNEL_LCD || 503 if (channel == OMAP_DSS_CHANNEL_LCD ||
479 channel == OMAP_DSS_CHANNEL_LCD2) 504 channel == OMAP_DSS_CHANNEL_LCD2 ||
505 channel == OMAP_DSS_CHANNEL_LCD3)
480 return true; 506 return true;
481 else 507 else
482 return false; 508 return false;
@@ -867,6 +893,15 @@ void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
867 chan = 0; 893 chan = 0;
868 chan2 = 1; 894 chan2 = 1;
869 break; 895 break;
896 case OMAP_DSS_CHANNEL_LCD3:
897 if (dss_has_feature(FEAT_MGR_LCD3)) {
898 chan = 0;
899 chan2 = 2;
900 } else {
901 BUG();
902 return;
903 }
904 break;
870 default: 905 default:
871 BUG(); 906 BUG();
872 return; 907 return;
@@ -902,7 +937,14 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
902 937
903 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane)); 938 val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
904 939
905 if (dss_has_feature(FEAT_MGR_LCD2)) { 940 if (dss_has_feature(FEAT_MGR_LCD3)) {
941 if (FLD_GET(val, 31, 30) == 0)
942 channel = FLD_GET(val, shift, shift);
943 else if (FLD_GET(val, 31, 30) == 1)
944 channel = OMAP_DSS_CHANNEL_LCD2;
945 else
946 channel = OMAP_DSS_CHANNEL_LCD3;
947 } else if (dss_has_feature(FEAT_MGR_LCD2)) {
906 if (FLD_GET(val, 31, 30) == 0) 948 if (FLD_GET(val, 31, 30) == 0)
907 channel = FLD_GET(val, shift, shift); 949 channel = FLD_GET(val, shift, shift);
908 else 950 else
@@ -3587,6 +3629,8 @@ static void _omap_dispc_initialize_irq(void)
3587 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR; 3629 dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
3588 if (dss_has_feature(FEAT_MGR_LCD2)) 3630 if (dss_has_feature(FEAT_MGR_LCD2))
3589 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2; 3631 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
3632 if (dss_has_feature(FEAT_MGR_LCD3))
3633 dispc.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
3590 if (dss_feat_get_num_ovls() > 3) 3634 if (dss_feat_get_num_ovls() > 3)
3591 dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW; 3635 dispc.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
3592 3636
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 420c980dcbdd..92d8a9be86fc 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -36,6 +36,8 @@
36#define DISPC_CONTROL2 0x0238 36#define DISPC_CONTROL2 0x0238
37#define DISPC_CONFIG2 0x0620 37#define DISPC_CONFIG2 0x0620
38#define DISPC_DIVISOR 0x0804 38#define DISPC_DIVISOR 0x0804
39#define DISPC_CONTROL3 0x0848
40#define DISPC_CONFIG3 0x084C
39 41
40/* DISPC overlay registers */ 42/* DISPC overlay registers */
41#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \ 43#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index d2b57197b292..fc0c3ce802e1 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -388,7 +388,8 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
388 dsi_wait_pll_hsdiv_dispc_active(dsidev); 388 dsi_wait_pll_hsdiv_dispc_active(dsidev);
389 break; 389 break;
390 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 390 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
391 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2); 391 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
392 channel != OMAP_DSS_CHANNEL_LCD3);
392 b = 1; 393 b = 1;
393 dsidev = dsi_get_dsidev_from_id(1); 394 dsidev = dsi_get_dsidev_from_id(1);
394 dsi_wait_pll_hsdiv_dispc_active(dsidev); 395 dsi_wait_pll_hsdiv_dispc_active(dsidev);
@@ -398,10 +399,12 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
398 return; 399 return;
399 } 400 }
400 401
401 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12; 402 pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
403 (channel == OMAP_DSS_CHANNEL_LCD2 ? 12 : 19);
402 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */ 404 REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */
403 405
404 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; 406 ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
407 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
405 dss.lcd_clk_source[ix] = clk_src; 408 dss.lcd_clk_source[ix] = clk_src;
406} 409}
407 410
@@ -418,7 +421,8 @@ enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
418enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) 421enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
419{ 422{
420 if (dss_has_feature(FEAT_LCD_CLK_SRC)) { 423 if (dss_has_feature(FEAT_LCD_CLK_SRC)) {
421 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; 424 int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 :
425 (channel == OMAP_DSS_CHANNEL_LCD2 ? 1 : 2);
422 return dss.lcd_clk_source[ix]; 426 return dss.lcd_clk_source[ix];
423 } else { 427 } else {
424 /* LCD_CLK source is the same as DISPC_FCLK source for 428 /* LCD_CLK source is the same as DISPC_FCLK source for
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index bdf469f080e7..996ffcbfed58 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -24,9 +24,9 @@
24#include "ti_hdmi.h" 24#include "ti_hdmi.h"
25#endif 25#endif
26 26
27#define MAX_DSS_MANAGERS 3 27#define MAX_DSS_MANAGERS 4
28#define MAX_DSS_OVERLAYS 4 28#define MAX_DSS_OVERLAYS 4
29#define MAX_DSS_LCD_MANAGERS 2 29#define MAX_DSS_LCD_MANAGERS 3
30#define MAX_NUM_DSI 2 30#define MAX_NUM_DSI 2
31 31
32/* DSS has feature id */ 32/* DSS has feature id */
@@ -36,6 +36,7 @@ enum dss_feat_id {
36 FEAT_PCKFREEENABLE, 36 FEAT_PCKFREEENABLE,
37 FEAT_FUNCGATED, 37 FEAT_FUNCGATED,
38 FEAT_MGR_LCD2, 38 FEAT_MGR_LCD2,
39 FEAT_MGR_LCD3,
39 FEAT_LINEBUFFERSPLIT, 40 FEAT_LINEBUFFERSPLIT,
40 FEAT_ROWREPEATENABLE, 41 FEAT_ROWREPEATENABLE,
41 FEAT_RESIZECONF, 42 FEAT_RESIZECONF,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index bb602a2d57c1..a51eb060c142 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -541,6 +541,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
541 mgr->name = "lcd2"; 541 mgr->name = "lcd2";
542 mgr->id = OMAP_DSS_CHANNEL_LCD2; 542 mgr->id = OMAP_DSS_CHANNEL_LCD2;
543 break; 543 break;
544 case 3:
545 mgr->name = "lcd3";
546 mgr->id = OMAP_DSS_CHANNEL_LCD3;
547 break;
544 } 548 }
545 549
546 mgr->set_device = &dss_mgr_set_device; 550 mgr->set_device = &dss_mgr_set_device;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index c492bb074d0f..ec69325a118a 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -528,14 +528,24 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
528 struct omap_overlay_manager *lcd_mgr; 528 struct omap_overlay_manager *lcd_mgr;
529 struct omap_overlay_manager *tv_mgr; 529 struct omap_overlay_manager *tv_mgr;
530 struct omap_overlay_manager *lcd2_mgr = NULL; 530 struct omap_overlay_manager *lcd2_mgr = NULL;
531 struct omap_overlay_manager *lcd3_mgr = NULL;
531 struct omap_overlay_manager *mgr = NULL; 532 struct omap_overlay_manager *mgr = NULL;
532 533
533 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD); 534 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
534 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT); 535 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
536 if (dss_has_feature(FEAT_MGR_LCD3))
537 lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
535 if (dss_has_feature(FEAT_MGR_LCD2)) 538 if (dss_has_feature(FEAT_MGR_LCD2))
536 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2); 539 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
537 540
538 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { 541 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
542 if (!lcd3_mgr->device || force) {
543 if (lcd3_mgr->device)
544 lcd3_mgr->unset_device(lcd3_mgr);
545 lcd3_mgr->set_device(lcd3_mgr, dssdev);
546 mgr = lcd3_mgr;
547 }
548 } else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
539 if (!lcd2_mgr->device || force) { 549 if (!lcd2_mgr->device || force) {
540 if (lcd2_mgr->device) 550 if (lcd2_mgr->device)
541 lcd2_mgr->unset_device(lcd2_mgr); 551 lcd2_mgr->unset_device(lcd2_mgr);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 23887b358a49..117de0e695f4 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -48,6 +48,10 @@
48#define DISPC_IRQ_FRAMEDONEWB (1 << 23) 48#define DISPC_IRQ_FRAMEDONEWB (1 << 23)
49#define DISPC_IRQ_FRAMEDONETV (1 << 24) 49#define DISPC_IRQ_FRAMEDONETV (1 << 24)
50#define DISPC_IRQ_WBBUFFEROVERFLOW (1 << 25) 50#define DISPC_IRQ_WBBUFFEROVERFLOW (1 << 25)
51#define DISPC_IRQ_FRAMEDONE3 (1 << 26)
52#define DISPC_IRQ_VSYNC3 (1 << 27)
53#define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 28)
54#define DISPC_IRQ_SYNC_LOST3 (1 << 29)
51 55
52struct omap_dss_device; 56struct omap_dss_device;
53struct omap_overlay_manager; 57struct omap_overlay_manager;