diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 21 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 4 | ||||
-rw-r--r-- | drivers/video/omap2/dss/manager.c | 77 | ||||
-rw-r--r-- | drivers/video/omap2/dss/overlay.c | 14 |
4 files changed, 72 insertions, 44 deletions
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 | ||
365 | bool dispc_go_busy(enum omap_channel channel); | 365 | bool dispc_go_busy(enum omap_channel channel); |
366 | void dispc_go(enum omap_channel channel); | 366 | void 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) | |||
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; |
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); |