aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-omap/include/plat/display.h2
-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
5 files changed, 74 insertions, 44 deletions
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 0180f25d1c8..537f4e449f5 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -358,6 +358,8 @@ struct omap_dss_device {
358 358
359 enum omap_display_type type; 359 enum omap_display_type type;
360 360
361 enum omap_channel channel;
362
361 union { 363 union {
362 struct { 364 struct {
363 u8 data_lines; 365 u8 data_lines;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 6171bcc589f..9f8c69f16e6 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 3fcb8ab781a..b394951120a 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 873b3346906..172d4e69730 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 41a29024a8d..456efef03c2 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);