diff options
Diffstat (limited to 'drivers/video/omap2/dss/manager.c')
-rw-r--r-- | drivers/video/omap2/dss/manager.c | 77 |
1 files changed, 48 insertions, 29 deletions
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) | |||
595 | int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) | 599 | int 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 | ||
1199 | end: | 1209 | end: |
@@ -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; |