diff options
Diffstat (limited to 'drivers/video/omap2/dss/manager.c')
-rw-r--r-- | drivers/video/omap2/dss/manager.c | 80 |
1 files changed, 51 insertions, 29 deletions
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 545e9b9a4d92..172d4e697309 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c | |||
@@ -406,6 +406,7 @@ struct overlay_cache_data { | |||
406 | u16 out_width; /* if 0, out_width == width */ | 406 | u16 out_width; /* if 0, out_width == width */ |
407 | u16 out_height; /* if 0, out_height == height */ | 407 | u16 out_height; /* if 0, out_height == height */ |
408 | u8 global_alpha; | 408 | u8 global_alpha; |
409 | u8 pre_mult_alpha; | ||
409 | 410 | ||
410 | enum omap_channel channel; | 411 | enum omap_channel channel; |
411 | bool replication; | 412 | bool replication; |
@@ -512,11 +513,14 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) | |||
512 | unsigned long timeout = msecs_to_jiffies(500); | 513 | unsigned long timeout = msecs_to_jiffies(500); |
513 | u32 irq; | 514 | u32 irq; |
514 | 515 | ||
515 | if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) | 516 | if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { |
516 | irq = DISPC_IRQ_EVSYNC_ODD; | 517 | irq = DISPC_IRQ_EVSYNC_ODD; |
517 | else | 518 | } else { |
518 | irq = DISPC_IRQ_VSYNC; | 519 | if (mgr->id == OMAP_DSS_CHANNEL_LCD) |
519 | 520 | irq = DISPC_IRQ_VSYNC; | |
521 | else | ||
522 | irq = DISPC_IRQ_VSYNC2; | ||
523 | } | ||
520 | return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); | 524 | return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); |
521 | } | 525 | } |
522 | 526 | ||
@@ -524,7 +528,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) | |||
524 | { | 528 | { |
525 | unsigned long timeout = msecs_to_jiffies(500); | 529 | unsigned long timeout = msecs_to_jiffies(500); |
526 | struct manager_cache_data *mc; | 530 | struct manager_cache_data *mc; |
527 | enum omap_channel channel; | ||
528 | u32 irq; | 531 | u32 irq; |
529 | int r; | 532 | int r; |
530 | int i; | 533 | int i; |
@@ -535,7 +538,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) | |||
535 | 538 | ||
536 | if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { | 539 | if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { |
537 | irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; | 540 | irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; |
538 | channel = OMAP_DSS_CHANNEL_DIGIT; | ||
539 | } else { | 541 | } else { |
540 | if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { | 542 | if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { |
541 | enum omap_dss_update_mode mode; | 543 | enum omap_dss_update_mode mode; |
@@ -543,11 +545,14 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) | |||
543 | if (mode != OMAP_DSS_UPDATE_AUTO) | 545 | if (mode != OMAP_DSS_UPDATE_AUTO) |
544 | return 0; | 546 | return 0; |
545 | 547 | ||
546 | irq = DISPC_IRQ_FRAMEDONE; | 548 | irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? |
549 | DISPC_IRQ_FRAMEDONE | ||
550 | : DISPC_IRQ_FRAMEDONE2; | ||
547 | } else { | 551 | } else { |
548 | irq = DISPC_IRQ_VSYNC; | 552 | irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? |
553 | DISPC_IRQ_VSYNC | ||
554 | : DISPC_IRQ_VSYNC2; | ||
549 | } | 555 | } |
550 | channel = OMAP_DSS_CHANNEL_LCD; | ||
551 | } | 556 | } |
552 | 557 | ||
553 | mc = &dss_cache.manager_cache[mgr->id]; | 558 | mc = &dss_cache.manager_cache[mgr->id]; |
@@ -594,7 +599,6 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) | |||
594 | int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) | 599 | int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) |
595 | { | 600 | { |
596 | unsigned long timeout = msecs_to_jiffies(500); | 601 | unsigned long timeout = msecs_to_jiffies(500); |
597 | enum omap_channel channel; | ||
598 | struct overlay_cache_data *oc; | 602 | struct overlay_cache_data *oc; |
599 | struct omap_dss_device *dssdev; | 603 | struct omap_dss_device *dssdev; |
600 | u32 irq; | 604 | u32 irq; |
@@ -611,7 +615,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) | |||
611 | 615 | ||
612 | if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { | 616 | if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { |
613 | irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; | 617 | irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; |
614 | channel = OMAP_DSS_CHANNEL_DIGIT; | ||
615 | } else { | 618 | } else { |
616 | if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { | 619 | if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { |
617 | enum omap_dss_update_mode mode; | 620 | enum omap_dss_update_mode mode; |
@@ -619,11 +622,14 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) | |||
619 | if (mode != OMAP_DSS_UPDATE_AUTO) | 622 | if (mode != OMAP_DSS_UPDATE_AUTO) |
620 | return 0; | 623 | return 0; |
621 | 624 | ||
622 | irq = DISPC_IRQ_FRAMEDONE; | 625 | irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? |
626 | DISPC_IRQ_FRAMEDONE | ||
627 | : DISPC_IRQ_FRAMEDONE2; | ||
623 | } else { | 628 | } else { |
624 | irq = DISPC_IRQ_VSYNC; | 629 | irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ? |
630 | DISPC_IRQ_VSYNC | ||
631 | : DISPC_IRQ_VSYNC2; | ||
625 | } | 632 | } |
626 | channel = OMAP_DSS_CHANNEL_LCD; | ||
627 | } | 633 | } |
628 | 634 | ||
629 | oc = &dss_cache.overlay_cache[ovl->id]; | 635 | oc = &dss_cache.overlay_cache[ovl->id]; |
@@ -842,7 +848,9 @@ static int configure_overlay(enum omap_plane plane) | |||
842 | c->rotation_type, | 848 | c->rotation_type, |
843 | c->rotation, | 849 | c->rotation, |
844 | c->mirror, | 850 | c->mirror, |
845 | c->global_alpha); | 851 | c->global_alpha, |
852 | c->pre_mult_alpha, | ||
853 | c->channel); | ||
846 | 854 | ||
847 | if (r) { | 855 | if (r) { |
848 | /* this shouldn't happen */ | 856 | /* this shouldn't happen */ |
@@ -894,10 +902,10 @@ static int configure_dispc(void) | |||
894 | r = 0; | 902 | r = 0; |
895 | busy = false; | 903 | busy = false; |
896 | 904 | ||
897 | mgr_busy[0] = dispc_go_busy(0); | 905 | for (i = 0; i < num_mgrs; i++) { |
898 | mgr_busy[1] = dispc_go_busy(1); | 906 | mgr_busy[i] = dispc_go_busy(i); |
899 | mgr_go[0] = false; | 907 | mgr_go[i] = false; |
900 | mgr_go[1] = false; | 908 | } |
901 | 909 | ||
902 | /* Commit overlay settings */ | 910 | /* Commit overlay settings */ |
903 | for (i = 0; i < num_ovls; ++i) { | 911 | for (i = 0; i < num_ovls; ++i) { |
@@ -1156,9 +1164,10 @@ static void dss_apply_irq_handler(void *data, u32 mask) | |||
1156 | const int num_mgrs = dss_feat_get_num_mgrs(); | 1164 | const int num_mgrs = dss_feat_get_num_mgrs(); |
1157 | int i, r; | 1165 | int i, r; |
1158 | bool mgr_busy[MAX_DSS_MANAGERS]; | 1166 | bool mgr_busy[MAX_DSS_MANAGERS]; |
1167 | u32 irq_mask; | ||
1159 | 1168 | ||
1160 | mgr_busy[0] = dispc_go_busy(0); | 1169 | for (i = 0; i < num_mgrs; i++) |
1161 | mgr_busy[1] = dispc_go_busy(1); | 1170 | mgr_busy[i] = dispc_go_busy(i); |
1162 | 1171 | ||
1163 | spin_lock(&dss_cache.lock); | 1172 | spin_lock(&dss_cache.lock); |
1164 | 1173 | ||
@@ -1179,8 +1188,8 @@ static void dss_apply_irq_handler(void *data, u32 mask) | |||
1179 | goto end; | 1188 | goto end; |
1180 | 1189 | ||
1181 | /* re-read busy flags */ | 1190 | /* re-read busy flags */ |
1182 | mgr_busy[0] = dispc_go_busy(0); | 1191 | for (i = 0; i < num_mgrs; i++) |
1183 | mgr_busy[1] = dispc_go_busy(1); | 1192 | mgr_busy[i] = dispc_go_busy(i); |
1184 | 1193 | ||
1185 | /* keep running as long as there are busy managers, so that | 1194 | /* keep running as long as there are busy managers, so that |
1186 | * we can collect overlay-applied information */ | 1195 | * we can collect overlay-applied information */ |
@@ -1189,9 +1198,12 @@ static void dss_apply_irq_handler(void *data, u32 mask) | |||
1189 | goto end; | 1198 | goto end; |
1190 | } | 1199 | } |
1191 | 1200 | ||
1192 | omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, | 1201 | irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | |
1193 | DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | | 1202 | DISPC_IRQ_EVSYNC_EVEN; |
1194 | 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); | ||
1195 | dss_cache.irq_enabled = false; | 1207 | dss_cache.irq_enabled = false; |
1196 | 1208 | ||
1197 | end: | 1209 | end: |
@@ -1265,6 +1277,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) | |||
1265 | oc->out_width = ovl->info.out_width; | 1277 | oc->out_width = ovl->info.out_width; |
1266 | oc->out_height = ovl->info.out_height; | 1278 | oc->out_height = ovl->info.out_height; |
1267 | oc->global_alpha = ovl->info.global_alpha; | 1279 | oc->global_alpha = ovl->info.global_alpha; |
1280 | oc->pre_mult_alpha = ovl->info.pre_mult_alpha; | ||
1268 | 1281 | ||
1269 | oc->replication = | 1282 | oc->replication = |
1270 | dss_use_replication(dssdev, ovl->info.color_mode); | 1283 | dss_use_replication(dssdev, ovl->info.color_mode); |
@@ -1383,9 +1396,14 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) | |||
1383 | r = 0; | 1396 | r = 0; |
1384 | dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); | 1397 | dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); |
1385 | if (!dss_cache.irq_enabled) { | 1398 | if (!dss_cache.irq_enabled) { |
1386 | r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, | 1399 | u32 mask; |
1387 | DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD | | 1400 | |
1388 | 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); | ||
1389 | dss_cache.irq_enabled = true; | 1407 | dss_cache.irq_enabled = true; |
1390 | } | 1408 | } |
1391 | configure_dispc(); | 1409 | configure_dispc(); |
@@ -1477,6 +1495,10 @@ int dss_init_overlay_managers(struct platform_device *pdev) | |||
1477 | mgr->name = "tv"; | 1495 | mgr->name = "tv"; |
1478 | mgr->id = OMAP_DSS_CHANNEL_DIGIT; | 1496 | mgr->id = OMAP_DSS_CHANNEL_DIGIT; |
1479 | break; | 1497 | break; |
1498 | case 2: | ||
1499 | mgr->name = "lcd2"; | ||
1500 | mgr->id = OMAP_DSS_CHANNEL_LCD2; | ||
1501 | break; | ||
1480 | } | 1502 | } |
1481 | 1503 | ||
1482 | mgr->set_device = &omap_dss_set_device; | 1504 | mgr->set_device = &omap_dss_set_device; |