aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss/manager.c')
-rw-r--r--drivers/video/omap2/dss/manager.c80
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)
594int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) 599int 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
1197end: 1209end:
@@ -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;