aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorSumit Semwal <sumit.semwal@ti.com>2010-12-02 06:27:14 -0500
committerTomi Valkeinen <tomi.valkeinen@nokia.com>2011-01-10 04:36:51 -0500
commit18faa1b68a54ff976dd03bfd9ace2c4ef4f7315c (patch)
treeda28dceaa98d68870f832f31916590137db8bebb /drivers/video
parent6ced40bfc01f016de89b65d9c733c1fb5eeb06d0 (diff)
OMAP: DSS2: Introduce omap_channel as an omap_dss_device parameter, add new overlay manager.
A panel connects to one of the overlay managers of DSS through some interface block. On OMAP4, specifying the type of the display is not sufficient to conclude which manager the panel should be connected to. Hence, a new member 'channel' is introduced in omap_dss_device structure to determine which manager the panel uses. The dss_recheck_connections() called in dss_driver_probe() uses this channel parameter to set the correct manager to the corresponding omap_dss_device. The channel parameter is used only once to ensure the correct managers are set for each panel. The parameter dssdev->manager->id will take care of ensuring that the panel and then the interface driver configures the correct DISPC channel. Also, add a new Overlay Manager in manager.c, make other changes needed for LCD2 channel. 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: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/dispc.c21
-rw-r--r--drivers/video/omap2/dss/dss.h4
-rw-r--r--drivers/video/omap2/dss/manager.c77
-rw-r--r--drivers/video/omap2/dss/overlay.c14
4 files changed, 72 insertions, 44 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 6171bcc589f8..9f8c69f16e61 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1610,8 +1610,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1610 bool ilace, 1610 bool ilace,
1611 enum omap_dss_rotation_type rotation_type, 1611 enum omap_dss_rotation_type rotation_type,
1612 u8 rotation, int mirror, 1612 u8 rotation, int mirror,
1613 u8 global_alpha, 1613 u8 global_alpha, u8 pre_mult_alpha,
1614 u8 pre_mult_alpha) 1614 enum omap_channel channel)
1615{ 1615{
1616 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2; 1616 const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
1617 bool five_taps = 0; 1617 bool five_taps = 0;
@@ -1667,8 +1667,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1667 five_taps = height > out_height * 2; 1667 five_taps = height > out_height * 2;
1668 1668
1669 if (!five_taps) { 1669 if (!five_taps) {
1670 fclk = calc_fclk(OMAP_DSS_CHANNEL_LCD, width, height, 1670 fclk = calc_fclk(channel, width, height, out_width,
1671 out_width, out_height); 1671 out_height);
1672 1672
1673 /* Try 5-tap filter if 3-tap fclk is too high */ 1673 /* Try 5-tap filter if 3-tap fclk is too high */
1674 if (cpu_is_omap34xx() && height > out_height && 1674 if (cpu_is_omap34xx() && height > out_height &&
@@ -1682,9 +1682,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
1682 } 1682 }
1683 1683
1684 if (five_taps) 1684 if (five_taps)
1685 fclk = calc_fclk_five_taps(OMAP_DSS_CHANNEL_LCD, width, 1685 fclk = calc_fclk_five_taps(channel, width, height,
1686 height, out_width, out_height, 1686 out_width, out_height, color_mode);
1687 color_mode);
1688 1687
1689 DSSDBG("required fclk rate = %lu Hz\n", fclk); 1688 DSSDBG("required fclk rate = %lu Hz\n", fclk);
1690 DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate()); 1689 DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
@@ -3331,17 +3330,17 @@ int dispc_setup_plane(enum omap_plane plane,
3331 bool ilace, 3330 bool ilace,
3332 enum omap_dss_rotation_type rotation_type, 3331 enum omap_dss_rotation_type rotation_type,
3333 u8 rotation, bool mirror, u8 global_alpha, 3332 u8 rotation, bool mirror, u8 global_alpha,
3334 u8 pre_mult_alpha) 3333 u8 pre_mult_alpha, enum omap_channel channel)
3335{ 3334{
3336 int r = 0; 3335 int r = 0;
3337 3336
3338 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 -> "
3339 "%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",
3340 plane, paddr, screen_width, pos_x, pos_y, 3339 plane, paddr, screen_width, pos_x, pos_y,
3341 width, height, 3340 width, height,
3342 out_width, out_height, 3341 out_width, out_height,
3343 ilace, color_mode, 3342 ilace, color_mode,
3344 rotation, mirror); 3343 rotation, mirror, channel);
3345 3344
3346 enable_clocks(1); 3345 enable_clocks(1);
3347 3346
@@ -3354,7 +3353,7 @@ int dispc_setup_plane(enum omap_plane plane,
3354 rotation_type, 3353 rotation_type,
3355 rotation, mirror, 3354 rotation, mirror,
3356 global_alpha, 3355 global_alpha,
3357 pre_mult_alpha); 3356 pre_mult_alpha, channel);
3358 3357
3359 enable_clocks(0); 3358 enable_clocks(0);
3360 3359
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 3fcb8ab781af..b394951120ac 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -359,8 +359,8 @@ int dispc_setup_plane(enum omap_plane plane,
359 bool ilace, 359 bool ilace,
360 enum omap_dss_rotation_type rotation_type, 360 enum omap_dss_rotation_type rotation_type,
361 u8 rotation, bool mirror, 361 u8 rotation, bool mirror,
362 u8 global_alpha, 362 u8 global_alpha, u8 pre_mult_alpha,
363 u8 pre_mult_alpha); 363 enum omap_channel channel);
364 364
365bool dispc_go_busy(enum omap_channel channel); 365bool dispc_go_busy(enum omap_channel channel);
366void dispc_go(enum omap_channel channel); 366void dispc_go(enum omap_channel channel);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 873b33469060..172d4e697309 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -513,11 +513,14 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
513 unsigned long timeout = msecs_to_jiffies(500); 513 unsigned long timeout = msecs_to_jiffies(500);
514 u32 irq; 514 u32 irq;
515 515
516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) 516 if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
517 irq = DISPC_IRQ_EVSYNC_ODD; 517 irq = DISPC_IRQ_EVSYNC_ODD;
518 else 518 } else {
519 irq = DISPC_IRQ_VSYNC; 519 if (mgr->id == OMAP_DSS_CHANNEL_LCD)
520 520 irq = DISPC_IRQ_VSYNC;
521 else
522 irq = DISPC_IRQ_VSYNC2;
523 }
521 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 524 return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
522} 525}
523 526
@@ -525,7 +528,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
525{ 528{
526 unsigned long timeout = msecs_to_jiffies(500); 529 unsigned long timeout = msecs_to_jiffies(500);
527 struct manager_cache_data *mc; 530 struct manager_cache_data *mc;
528 enum omap_channel channel;
529 u32 irq; 531 u32 irq;
530 int r; 532 int r;
531 int i; 533 int i;
@@ -536,7 +538,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
536 538
537 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 539 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
538 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 540 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
539 channel = OMAP_DSS_CHANNEL_DIGIT;
540 } else { 541 } else {
541 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 542 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
542 enum omap_dss_update_mode mode; 543 enum omap_dss_update_mode mode;
@@ -544,11 +545,14 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
544 if (mode != OMAP_DSS_UPDATE_AUTO) 545 if (mode != OMAP_DSS_UPDATE_AUTO)
545 return 0; 546 return 0;
546 547
547 irq = DISPC_IRQ_FRAMEDONE; 548 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
549 DISPC_IRQ_FRAMEDONE
550 : DISPC_IRQ_FRAMEDONE2;
548 } else { 551 } else {
549 irq = DISPC_IRQ_VSYNC; 552 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
553 DISPC_IRQ_VSYNC
554 : DISPC_IRQ_VSYNC2;
550 } 555 }
551 channel = OMAP_DSS_CHANNEL_LCD;
552 } 556 }
553 557
554 mc = &dss_cache.manager_cache[mgr->id]; 558 mc = &dss_cache.manager_cache[mgr->id];
@@ -595,7 +599,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
595int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) 599int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
596{ 600{
597 unsigned long timeout = msecs_to_jiffies(500); 601 unsigned long timeout = msecs_to_jiffies(500);
598 enum omap_channel channel;
599 struct overlay_cache_data *oc; 602 struct overlay_cache_data *oc;
600 struct omap_dss_device *dssdev; 603 struct omap_dss_device *dssdev;
601 u32 irq; 604 u32 irq;
@@ -612,7 +615,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
612 615
613 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { 616 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
614 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; 617 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
615 channel = OMAP_DSS_CHANNEL_DIGIT;
616 } else { 618 } else {
617 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 619 if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
618 enum omap_dss_update_mode mode; 620 enum omap_dss_update_mode mode;
@@ -620,11 +622,14 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
620 if (mode != OMAP_DSS_UPDATE_AUTO) 622 if (mode != OMAP_DSS_UPDATE_AUTO)
621 return 0; 623 return 0;
622 624
623 irq = DISPC_IRQ_FRAMEDONE; 625 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
626 DISPC_IRQ_FRAMEDONE
627 : DISPC_IRQ_FRAMEDONE2;
624 } else { 628 } else {
625 irq = DISPC_IRQ_VSYNC; 629 irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
630 DISPC_IRQ_VSYNC
631 : DISPC_IRQ_VSYNC2;
626 } 632 }
627 channel = OMAP_DSS_CHANNEL_LCD;
628 } 633 }
629 634
630 oc = &dss_cache.overlay_cache[ovl->id]; 635 oc = &dss_cache.overlay_cache[ovl->id];
@@ -844,7 +849,8 @@ static int configure_overlay(enum omap_plane plane)
844 c->rotation, 849 c->rotation,
845 c->mirror, 850 c->mirror,
846 c->global_alpha, 851 c->global_alpha,
847 c->pre_mult_alpha); 852 c->pre_mult_alpha,
853 c->channel);
848 854
849 if (r) { 855 if (r) {
850 /* this shouldn't happen */ 856 /* this shouldn't happen */
@@ -896,10 +902,10 @@ static int configure_dispc(void)
896 r = 0; 902 r = 0;
897 busy = false; 903 busy = false;
898 904
899 mgr_busy[0] = dispc_go_busy(0); 905 for (i = 0; i < num_mgrs; i++) {
900 mgr_busy[1] = dispc_go_busy(1); 906 mgr_busy[i] = dispc_go_busy(i);
901 mgr_go[0] = false; 907 mgr_go[i] = false;
902 mgr_go[1] = false; 908 }
903 909
904 /* Commit overlay settings */ 910 /* Commit overlay settings */
905 for (i = 0; i < num_ovls; ++i) { 911 for (i = 0; i < num_ovls; ++i) {
@@ -1158,9 +1164,10 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1158 const int num_mgrs = dss_feat_get_num_mgrs(); 1164 const int num_mgrs = dss_feat_get_num_mgrs();
1159 int i, r; 1165 int i, r;
1160 bool mgr_busy[MAX_DSS_MANAGERS]; 1166 bool mgr_busy[MAX_DSS_MANAGERS];
1167 u32 irq_mask;
1161 1168
1162 mgr_busy[0] = dispc_go_busy(0); 1169 for (i = 0; i < num_mgrs; i++)
1163 mgr_busy[1] = dispc_go_busy(1); 1170 mgr_busy[i] = dispc_go_busy(i);
1164 1171
1165 spin_lock(&dss_cache.lock); 1172 spin_lock(&dss_cache.lock);
1166 1173
@@ -1181,8 +1188,8 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1181 goto end; 1188 goto end;
1182 1189
1183 /* re-read busy flags */ 1190 /* re-read busy flags */
1184 mgr_busy[0] = dispc_go_busy(0); 1191 for (i = 0; i < num_mgrs; i++)
1185 mgr_busy[1] = dispc_go_busy(1); 1192 mgr_busy[i] = dispc_go_busy(i);
1186 1193
1187 /* keep running as long as there are busy managers, so that 1194 /* keep running as long as there are busy managers, so that
1188 * we can collect overlay-applied information */ 1195 * we can collect overlay-applied information */
@@ -1191,9 +1198,12 @@ static void dss_apply_irq_handler(void *data, u32 mask)
1191 goto end; 1198 goto end;
1192 } 1199 }
1193 1200
1194 omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, 1201 irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
1195 DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | 1202 DISPC_IRQ_EVSYNC_EVEN;
1196 DISPC_IRQ_EVSYNC_EVEN); 1203 if (dss_has_feature(FEAT_MGR_LCD2))
1204 irq_mask |= DISPC_IRQ_VSYNC2;
1205
1206 omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask);
1197 dss_cache.irq_enabled = false; 1207 dss_cache.irq_enabled = false;
1198 1208
1199end: 1209end:
@@ -1386,9 +1396,14 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
1386 r = 0; 1396 r = 0;
1387 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); 1397 dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
1388 if (!dss_cache.irq_enabled) { 1398 if (!dss_cache.irq_enabled) {
1389 r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, 1399 u32 mask;
1390 DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | 1400
1391 DISPC_IRQ_EVSYNC_EVEN); 1401 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
1402 DISPC_IRQ_EVSYNC_EVEN;
1403 if (dss_has_feature(FEAT_MGR_LCD2))
1404 mask |= DISPC_IRQ_VSYNC2;
1405
1406 r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
1392 dss_cache.irq_enabled = true; 1407 dss_cache.irq_enabled = true;
1393 } 1408 }
1394 configure_dispc(); 1409 configure_dispc();
@@ -1480,6 +1495,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
1480 mgr->name = "tv"; 1495 mgr->name = "tv";
1481 mgr->id = OMAP_DSS_CHANNEL_DIGIT; 1496 mgr->id = OMAP_DSS_CHANNEL_DIGIT;
1482 break; 1497 break;
1498 case 2:
1499 mgr->name = "lcd2";
1500 mgr->id = OMAP_DSS_CHANNEL_LCD2;
1501 break;
1483 } 1502 }
1484 1503
1485 mgr->set_device = &omap_dss_set_device; 1504 mgr->set_device = &omap_dss_set_device;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 41a29024a8d0..456efef03c20 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -664,12 +664,22 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
664 int i; 664 int i;
665 struct omap_overlay_manager *lcd_mgr; 665 struct omap_overlay_manager *lcd_mgr;
666 struct omap_overlay_manager *tv_mgr; 666 struct omap_overlay_manager *tv_mgr;
667 struct omap_overlay_manager *lcd2_mgr = NULL;
667 struct omap_overlay_manager *mgr = NULL; 668 struct omap_overlay_manager *mgr = NULL;
668 669
669 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD); 670 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
670 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV); 671 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
671 672 if (dss_has_feature(FEAT_MGR_LCD2))
672 if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { 673 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);
674
675 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
676 if (!lcd2_mgr->device || force) {
677 if (lcd2_mgr->device)
678 lcd2_mgr->unset_device(lcd2_mgr);
679 lcd2_mgr->set_device(lcd2_mgr, dssdev);
680 mgr = lcd2_mgr;
681 }
682 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
673 if (!lcd_mgr->device || force) { 683 if (!lcd_mgr->device || force) {
674 if (lcd_mgr->device) 684 if (lcd_mgr->device)
675 lcd_mgr->unset_device(lcd_mgr); 685 lcd_mgr->unset_device(lcd_mgr);