diff options
Diffstat (limited to 'drivers/gpu/drm/omapdrm/dss/dispc.c')
-rw-r--r-- | drivers/gpu/drm/omapdrm/dss/dispc.c | 223 |
1 files changed, 121 insertions, 102 deletions
diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index aae6037f499f..6d8228f976f9 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c | |||
@@ -162,7 +162,7 @@ struct dispc_features { | |||
162 | #define DISPC_MAX_NR_FIFOS 5 | 162 | #define DISPC_MAX_NR_FIFOS 5 |
163 | #define DISPC_MAX_CHANNEL_GAMMA 4 | 163 | #define DISPC_MAX_CHANNEL_GAMMA 4 |
164 | 164 | ||
165 | static struct { | 165 | struct dispc_device { |
166 | struct platform_device *pdev; | 166 | struct platform_device *pdev; |
167 | void __iomem *base; | 167 | void __iomem *base; |
168 | struct dss_device *dss; | 168 | struct dss_device *dss; |
@@ -194,7 +194,9 @@ static struct { | |||
194 | 194 | ||
195 | /* DISPC_CONTROL & DISPC_CONFIG lock*/ | 195 | /* DISPC_CONTROL & DISPC_CONFIG lock*/ |
196 | spinlock_t control_lock; | 196 | spinlock_t control_lock; |
197 | } dispc; | 197 | }; |
198 | |||
199 | static struct dispc_device dispc; | ||
198 | 200 | ||
199 | enum omap_color_component { | 201 | enum omap_color_component { |
200 | /* used for all color formats for OMAP3 and earlier | 202 | /* used for all color formats for OMAP3 and earlier |
@@ -361,9 +363,7 @@ static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); | |||
361 | static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane); | 363 | static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane); |
362 | static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane); | 364 | static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane); |
363 | 365 | ||
364 | static void dispc_clear_irqstatus(u32 mask); | 366 | static void dispc_clear_irqstatus(struct dispc_device *dispc, u32 mask); |
365 | static bool dispc_mgr_is_enabled(enum omap_channel channel); | ||
366 | static void dispc_clear_irqstatus(u32 mask); | ||
367 | 367 | ||
368 | static inline void dispc_write_reg(const u16 idx, u32 val) | 368 | static inline void dispc_write_reg(const u16 idx, u32 val) |
369 | { | 369 | { |
@@ -396,14 +396,14 @@ static void mgr_fld_write(enum omap_channel channel, | |||
396 | spin_unlock_irqrestore(&dispc.control_lock, flags); | 396 | spin_unlock_irqrestore(&dispc.control_lock, flags); |
397 | } | 397 | } |
398 | 398 | ||
399 | static int dispc_get_num_ovls(void) | 399 | static int dispc_get_num_ovls(struct dispc_device *dispc) |
400 | { | 400 | { |
401 | return dispc.feat->num_ovls; | 401 | return dispc->feat->num_ovls; |
402 | } | 402 | } |
403 | 403 | ||
404 | static int dispc_get_num_mgrs(void) | 404 | static int dispc_get_num_mgrs(struct dispc_device *dispc) |
405 | { | 405 | { |
406 | return dispc.feat->num_mgrs; | 406 | return dispc->feat->num_mgrs; |
407 | } | 407 | } |
408 | 408 | ||
409 | static void dispc_get_reg_field(enum dispc_feat_reg_field id, | 409 | static void dispc_get_reg_field(enum dispc_feat_reg_field id, |
@@ -455,7 +455,7 @@ static void dispc_save_context(void) | |||
455 | SR(CONFIG3); | 455 | SR(CONFIG3); |
456 | } | 456 | } |
457 | 457 | ||
458 | for (i = 0; i < dispc_get_num_mgrs(); i++) { | 458 | for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) { |
459 | SR(DEFAULT_COLOR(i)); | 459 | SR(DEFAULT_COLOR(i)); |
460 | SR(TRANS_COLOR(i)); | 460 | SR(TRANS_COLOR(i)); |
461 | SR(SIZE_MGR(i)); | 461 | SR(SIZE_MGR(i)); |
@@ -477,7 +477,7 @@ static void dispc_save_context(void) | |||
477 | } | 477 | } |
478 | } | 478 | } |
479 | 479 | ||
480 | for (i = 0; i < dispc_get_num_ovls(); i++) { | 480 | for (i = 0; i < dispc_get_num_ovls(&dispc); i++) { |
481 | SR(OVL_BA0(i)); | 481 | SR(OVL_BA0(i)); |
482 | SR(OVL_BA1(i)); | 482 | SR(OVL_BA1(i)); |
483 | SR(OVL_POSITION(i)); | 483 | SR(OVL_POSITION(i)); |
@@ -561,7 +561,7 @@ static void dispc_restore_context(void) | |||
561 | if (dispc_has_feature(FEAT_MGR_LCD3)) | 561 | if (dispc_has_feature(FEAT_MGR_LCD3)) |
562 | RR(CONFIG3); | 562 | RR(CONFIG3); |
563 | 563 | ||
564 | for (i = 0; i < dispc_get_num_mgrs(); i++) { | 564 | for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) { |
565 | RR(DEFAULT_COLOR(i)); | 565 | RR(DEFAULT_COLOR(i)); |
566 | RR(TRANS_COLOR(i)); | 566 | RR(TRANS_COLOR(i)); |
567 | RR(SIZE_MGR(i)); | 567 | RR(SIZE_MGR(i)); |
@@ -583,7 +583,7 @@ static void dispc_restore_context(void) | |||
583 | } | 583 | } |
584 | } | 584 | } |
585 | 585 | ||
586 | for (i = 0; i < dispc_get_num_ovls(); i++) { | 586 | for (i = 0; i < dispc_get_num_ovls(&dispc); i++) { |
587 | RR(OVL_BA0(i)); | 587 | RR(OVL_BA0(i)); |
588 | RR(OVL_BA1(i)); | 588 | RR(OVL_BA1(i)); |
589 | RR(OVL_POSITION(i)); | 589 | RR(OVL_POSITION(i)); |
@@ -648,7 +648,7 @@ static void dispc_restore_context(void) | |||
648 | if (dispc_has_feature(FEAT_MGR_LCD3)) | 648 | if (dispc_has_feature(FEAT_MGR_LCD3)) |
649 | RR(CONTROL3); | 649 | RR(CONTROL3); |
650 | /* clear spurious SYNC_LOST_DIGIT interrupts */ | 650 | /* clear spurious SYNC_LOST_DIGIT interrupts */ |
651 | dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT); | 651 | dispc_clear_irqstatus(&dispc, DISPC_IRQ_SYNC_LOST_DIGIT); |
652 | 652 | ||
653 | /* | 653 | /* |
654 | * enable last so IRQs won't trigger before | 654 | * enable last so IRQs won't trigger before |
@@ -662,41 +662,44 @@ static void dispc_restore_context(void) | |||
662 | #undef SR | 662 | #undef SR |
663 | #undef RR | 663 | #undef RR |
664 | 664 | ||
665 | int dispc_runtime_get(void) | 665 | int dispc_runtime_get(struct dispc_device *dispc) |
666 | { | 666 | { |
667 | int r; | 667 | int r; |
668 | 668 | ||
669 | DSSDBG("dispc_runtime_get\n"); | 669 | DSSDBG("dispc_runtime_get\n"); |
670 | 670 | ||
671 | r = pm_runtime_get_sync(&dispc.pdev->dev); | 671 | r = pm_runtime_get_sync(&dispc->pdev->dev); |
672 | WARN_ON(r < 0); | 672 | WARN_ON(r < 0); |
673 | return r < 0 ? r : 0; | 673 | return r < 0 ? r : 0; |
674 | } | 674 | } |
675 | 675 | ||
676 | void dispc_runtime_put(void) | 676 | void dispc_runtime_put(struct dispc_device *dispc) |
677 | { | 677 | { |
678 | int r; | 678 | int r; |
679 | 679 | ||
680 | DSSDBG("dispc_runtime_put\n"); | 680 | DSSDBG("dispc_runtime_put\n"); |
681 | 681 | ||
682 | r = pm_runtime_put_sync(&dispc.pdev->dev); | 682 | r = pm_runtime_put_sync(&dispc->pdev->dev); |
683 | WARN_ON(r < 0 && r != -ENOSYS); | 683 | WARN_ON(r < 0 && r != -ENOSYS); |
684 | } | 684 | } |
685 | 685 | ||
686 | static u32 dispc_mgr_get_vsync_irq(enum omap_channel channel) | 686 | static u32 dispc_mgr_get_vsync_irq(struct dispc_device *dispc, |
687 | enum omap_channel channel) | ||
687 | { | 688 | { |
688 | return mgr_desc[channel].vsync_irq; | 689 | return mgr_desc[channel].vsync_irq; |
689 | } | 690 | } |
690 | 691 | ||
691 | static u32 dispc_mgr_get_framedone_irq(enum omap_channel channel) | 692 | static u32 dispc_mgr_get_framedone_irq(struct dispc_device *dispc, |
693 | enum omap_channel channel) | ||
692 | { | 694 | { |
693 | if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc.feat->no_framedone_tv) | 695 | if (channel == OMAP_DSS_CHANNEL_DIGIT && dispc->feat->no_framedone_tv) |
694 | return 0; | 696 | return 0; |
695 | 697 | ||
696 | return mgr_desc[channel].framedone_irq; | 698 | return mgr_desc[channel].framedone_irq; |
697 | } | 699 | } |
698 | 700 | ||
699 | static u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel) | 701 | static u32 dispc_mgr_get_sync_lost_irq(struct dispc_device *dispc, |
702 | enum omap_channel channel) | ||
700 | { | 703 | { |
701 | return mgr_desc[channel].sync_lost_irq; | 704 | return mgr_desc[channel].sync_lost_irq; |
702 | } | 705 | } |
@@ -706,27 +709,30 @@ u32 dispc_wb_get_framedone_irq(void) | |||
706 | return DISPC_IRQ_FRAMEDONEWB; | 709 | return DISPC_IRQ_FRAMEDONEWB; |
707 | } | 710 | } |
708 | 711 | ||
709 | static void dispc_mgr_enable(enum omap_channel channel, bool enable) | 712 | static void dispc_mgr_enable(struct dispc_device *dispc, |
713 | enum omap_channel channel, bool enable) | ||
710 | { | 714 | { |
711 | mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable); | 715 | mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable); |
712 | /* flush posted write */ | 716 | /* flush posted write */ |
713 | mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); | 717 | mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); |
714 | } | 718 | } |
715 | 719 | ||
716 | static bool dispc_mgr_is_enabled(enum omap_channel channel) | 720 | static bool dispc_mgr_is_enabled(struct dispc_device *dispc, |
721 | enum omap_channel channel) | ||
717 | { | 722 | { |
718 | return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); | 723 | return !!mgr_fld_read(channel, DISPC_MGR_FLD_ENABLE); |
719 | } | 724 | } |
720 | 725 | ||
721 | static bool dispc_mgr_go_busy(enum omap_channel channel) | 726 | static bool dispc_mgr_go_busy(struct dispc_device *dispc, |
727 | enum omap_channel channel) | ||
722 | { | 728 | { |
723 | return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; | 729 | return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1; |
724 | } | 730 | } |
725 | 731 | ||
726 | static void dispc_mgr_go(enum omap_channel channel) | 732 | static void dispc_mgr_go(struct dispc_device *dispc, enum omap_channel channel) |
727 | { | 733 | { |
728 | WARN_ON(!dispc_mgr_is_enabled(channel)); | 734 | WARN_ON(!dispc_mgr_is_enabled(dispc, channel)); |
729 | WARN_ON(dispc_mgr_go_busy(channel)); | 735 | WARN_ON(dispc_mgr_go_busy(dispc, channel)); |
730 | 736 | ||
731 | DSSDBG("GO %s\n", mgr_desc[channel].name); | 737 | DSSDBG("GO %s\n", mgr_desc[channel].name); |
732 | 738 | ||
@@ -864,7 +870,7 @@ static void dispc_ovl_write_color_conv_coef(enum omap_plane_id plane, | |||
864 | static void dispc_setup_color_conv_coef(void) | 870 | static void dispc_setup_color_conv_coef(void) |
865 | { | 871 | { |
866 | int i; | 872 | int i; |
867 | int num_ovl = dispc_get_num_ovls(); | 873 | int num_ovl = dispc_get_num_ovls(&dispc); |
868 | const struct color_conv_coef ctbl_bt601_5_ovl = { | 874 | const struct color_conv_coef ctbl_bt601_5_ovl = { |
869 | /* YUV -> RGB */ | 875 | /* YUV -> RGB */ |
870 | 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, | 876 | 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, |
@@ -956,7 +962,7 @@ static void dispc_ovl_enable_zorder_planes(void) | |||
956 | if (!dispc_has_feature(FEAT_ALPHA_FREE_ZORDER)) | 962 | if (!dispc_has_feature(FEAT_ALPHA_FREE_ZORDER)) |
957 | return; | 963 | return; |
958 | 964 | ||
959 | for (i = 0; i < dispc_get_num_ovls(); i++) | 965 | for (i = 0; i < dispc_get_num_ovls(&dispc); i++) |
960 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); | 966 | REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25); |
961 | } | 967 | } |
962 | 968 | ||
@@ -1213,7 +1219,7 @@ static void dispc_configure_burst_sizes(void) | |||
1213 | const int burst_size = BURST_SIZE_X8; | 1219 | const int burst_size = BURST_SIZE_X8; |
1214 | 1220 | ||
1215 | /* Configure burst size always to maximum size */ | 1221 | /* Configure burst size always to maximum size */ |
1216 | for (i = 0; i < dispc_get_num_ovls(); ++i) | 1222 | for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) |
1217 | dispc_ovl_set_burst_size(i, burst_size); | 1223 | dispc_ovl_set_burst_size(i, burst_size); |
1218 | if (dispc.feat->has_writeback) | 1224 | if (dispc.feat->has_writeback) |
1219 | dispc_ovl_set_burst_size(OMAP_DSS_WB, burst_size); | 1225 | dispc_ovl_set_burst_size(OMAP_DSS_WB, burst_size); |
@@ -1240,9 +1246,10 @@ static bool dispc_ovl_color_mode_supported(enum omap_plane_id plane, u32 fourcc) | |||
1240 | return false; | 1246 | return false; |
1241 | } | 1247 | } |
1242 | 1248 | ||
1243 | static const u32 *dispc_ovl_get_color_modes(enum omap_plane_id plane) | 1249 | static const u32 *dispc_ovl_get_color_modes(struct dispc_device *dispc, |
1250 | enum omap_plane_id plane) | ||
1244 | { | 1251 | { |
1245 | return dispc.feat->supported_color_modes[plane]; | 1252 | return dispc->feat->supported_color_modes[plane]; |
1246 | } | 1253 | } |
1247 | 1254 | ||
1248 | static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) | 1255 | static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable) |
@@ -1359,7 +1366,7 @@ static void dispc_init_fifos(void) | |||
1359 | /* | 1366 | /* |
1360 | * Setup default fifo thresholds. | 1367 | * Setup default fifo thresholds. |
1361 | */ | 1368 | */ |
1362 | for (i = 0; i < dispc_get_num_ovls(); ++i) { | 1369 | for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) { |
1363 | u32 low, high; | 1370 | u32 low, high; |
1364 | const bool use_fifomerge = false; | 1371 | const bool use_fifomerge = false; |
1365 | const bool manual_update = false; | 1372 | const bool manual_update = false; |
@@ -1462,7 +1469,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane, | |||
1462 | 1469 | ||
1463 | if (use_fifomerge) { | 1470 | if (use_fifomerge) { |
1464 | total_fifo_size = 0; | 1471 | total_fifo_size = 0; |
1465 | for (i = 0; i < dispc_get_num_ovls(); ++i) | 1472 | for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) |
1466 | total_fifo_size += dispc_ovl_get_fifo_size(i); | 1473 | total_fifo_size += dispc_ovl_get_fifo_size(i); |
1467 | } else { | 1474 | } else { |
1468 | total_fifo_size = ovl_fifo_size; | 1475 | total_fifo_size = ovl_fifo_size; |
@@ -1528,7 +1535,7 @@ static void dispc_init_mflag(void) | |||
1528 | (1 << 0) | /* MFLAG_CTRL = force always on */ | 1535 | (1 << 0) | /* MFLAG_CTRL = force always on */ |
1529 | (0 << 2)); /* MFLAG_START = disable */ | 1536 | (0 << 2)); /* MFLAG_START = disable */ |
1530 | 1537 | ||
1531 | for (i = 0; i < dispc_get_num_ovls(); ++i) { | 1538 | for (i = 0; i < dispc_get_num_ovls(&dispc); ++i) { |
1532 | u32 size = dispc_ovl_get_fifo_size(i); | 1539 | u32 size = dispc_ovl_get_fifo_size(i); |
1533 | u32 unit = dispc.feat->buffer_size_unit; | 1540 | u32 unit = dispc.feat->buffer_size_unit; |
1534 | u32 low, high; | 1541 | u32 low, high; |
@@ -2631,13 +2638,14 @@ static int dispc_ovl_setup_common(enum omap_plane_id plane, | |||
2631 | return 0; | 2638 | return 0; |
2632 | } | 2639 | } |
2633 | 2640 | ||
2634 | static int dispc_ovl_setup(enum omap_plane_id plane, | 2641 | static int dispc_ovl_setup(struct dispc_device *dispc, |
2635 | const struct omap_overlay_info *oi, | 2642 | enum omap_plane_id plane, |
2636 | const struct videomode *vm, bool mem_to_mem, | 2643 | const struct omap_overlay_info *oi, |
2637 | enum omap_channel channel) | 2644 | const struct videomode *vm, bool mem_to_mem, |
2645 | enum omap_channel channel) | ||
2638 | { | 2646 | { |
2639 | int r; | 2647 | int r; |
2640 | enum omap_overlay_caps caps = dispc.feat->overlay_caps[plane]; | 2648 | enum omap_overlay_caps caps = dispc->feat->overlay_caps[plane]; |
2641 | const bool replication = true; | 2649 | const bool replication = true; |
2642 | 2650 | ||
2643 | DSSDBG("dispc_ovl_setup %d, pa %pad, pa_uv %pad, sw %d, %d,%d, %dx%d ->" | 2651 | DSSDBG("dispc_ovl_setup %d, pa %pad, pa_uv %pad, sw %d, %d,%d, %dx%d ->" |
@@ -2724,7 +2732,8 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi, | |||
2724 | return r; | 2732 | return r; |
2725 | } | 2733 | } |
2726 | 2734 | ||
2727 | static int dispc_ovl_enable(enum omap_plane_id plane, bool enable) | 2735 | static int dispc_ovl_enable(struct dispc_device *dispc, |
2736 | enum omap_plane_id plane, bool enable) | ||
2728 | { | 2737 | { |
2729 | DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); | 2738 | DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); |
2730 | 2739 | ||
@@ -2733,9 +2742,11 @@ static int dispc_ovl_enable(enum omap_plane_id plane, bool enable) | |||
2733 | return 0; | 2742 | return 0; |
2734 | } | 2743 | } |
2735 | 2744 | ||
2736 | static enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel) | 2745 | static enum omap_dss_output_id |
2746 | dispc_mgr_get_supported_outputs(struct dispc_device *dispc, | ||
2747 | enum omap_channel channel) | ||
2737 | { | 2748 | { |
2738 | return dss_get_supported_outputs(dispc.dss, channel); | 2749 | return dss_get_supported_outputs(dispc->dss, channel); |
2739 | } | 2750 | } |
2740 | 2751 | ||
2741 | static void dispc_lcd_enable_signal_polarity(bool act_high) | 2752 | static void dispc_lcd_enable_signal_polarity(bool act_high) |
@@ -2810,8 +2821,9 @@ static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, | |||
2810 | REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); | 2821 | REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19); |
2811 | } | 2822 | } |
2812 | 2823 | ||
2813 | static void dispc_mgr_setup(enum omap_channel channel, | 2824 | static void dispc_mgr_setup(struct dispc_device *dispc, |
2814 | const struct omap_overlay_manager_info *info) | 2825 | enum omap_channel channel, |
2826 | const struct omap_overlay_manager_info *info) | ||
2815 | { | 2827 | { |
2816 | dispc_mgr_set_default_color(channel, info->default_color); | 2828 | dispc_mgr_set_default_color(channel, info->default_color); |
2817 | dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key); | 2829 | dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key); |
@@ -2883,8 +2895,9 @@ static void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable) | |||
2883 | mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable); | 2895 | mgr_fld_write(channel, DISPC_MGR_FLD_STALLMODE, enable); |
2884 | } | 2896 | } |
2885 | 2897 | ||
2886 | static void dispc_mgr_set_lcd_config(enum omap_channel channel, | 2898 | static void dispc_mgr_set_lcd_config(struct dispc_device *dispc, |
2887 | const struct dss_lcd_mgr_config *config) | 2899 | enum omap_channel channel, |
2900 | const struct dss_lcd_mgr_config *config) | ||
2888 | { | 2901 | { |
2889 | dispc_mgr_set_io_pad_mode(config->io_pad_mode); | 2902 | dispc_mgr_set_io_pad_mode(config->io_pad_mode); |
2890 | 2903 | ||
@@ -3039,8 +3052,9 @@ static int vm_flag_to_int(enum display_flags flags, enum display_flags high, | |||
3039 | } | 3052 | } |
3040 | 3053 | ||
3041 | /* change name to mode? */ | 3054 | /* change name to mode? */ |
3042 | static void dispc_mgr_set_timings(enum omap_channel channel, | 3055 | static void dispc_mgr_set_timings(struct dispc_device *dispc, |
3043 | const struct videomode *vm) | 3056 | enum omap_channel channel, |
3057 | const struct videomode *vm) | ||
3044 | { | 3058 | { |
3045 | unsigned int xtot, ytot; | 3059 | unsigned int xtot, ytot; |
3046 | unsigned long ht, vt; | 3060 | unsigned long ht, vt; |
@@ -3078,7 +3092,7 @@ static void dispc_mgr_set_timings(enum omap_channel channel, | |||
3078 | if (t.flags & DISPLAY_FLAGS_INTERLACED) | 3092 | if (t.flags & DISPLAY_FLAGS_INTERLACED) |
3079 | t.vactive /= 2; | 3093 | t.vactive /= 2; |
3080 | 3094 | ||
3081 | if (dispc.feat->supports_double_pixel) | 3095 | if (dispc->feat->supports_double_pixel) |
3082 | REG_FLD_MOD(DISPC_CONTROL, | 3096 | REG_FLD_MOD(DISPC_CONTROL, |
3083 | !!(t.flags & DISPLAY_FLAGS_DOUBLECLK), | 3097 | !!(t.flags & DISPLAY_FLAGS_DOUBLECLK), |
3084 | 19, 17); | 3098 | 19, 17); |
@@ -3241,7 +3255,7 @@ void dispc_dump_clocks(struct seq_file *s) | |||
3241 | u32 l; | 3255 | u32 l; |
3242 | enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(dispc.dss); | 3256 | enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(dispc.dss); |
3243 | 3257 | ||
3244 | if (dispc_runtime_get()) | 3258 | if (dispc_runtime_get(&dispc)) |
3245 | return; | 3259 | return; |
3246 | 3260 | ||
3247 | seq_printf(s, "- DISPC -\n"); | 3261 | seq_printf(s, "- DISPC -\n"); |
@@ -3267,7 +3281,7 @@ void dispc_dump_clocks(struct seq_file *s) | |||
3267 | if (dispc_has_feature(FEAT_MGR_LCD3)) | 3281 | if (dispc_has_feature(FEAT_MGR_LCD3)) |
3268 | dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD3); | 3282 | dispc_dump_clocks_channel(s, OMAP_DSS_CHANNEL_LCD3); |
3269 | 3283 | ||
3270 | dispc_runtime_put(); | 3284 | dispc_runtime_put(&dispc); |
3271 | } | 3285 | } |
3272 | 3286 | ||
3273 | static int dispc_dump_regs(struct seq_file *s, void *p) | 3287 | static int dispc_dump_regs(struct seq_file *s, void *p) |
@@ -3290,7 +3304,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) | |||
3290 | 3304 | ||
3291 | #define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r)) | 3305 | #define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r)) |
3292 | 3306 | ||
3293 | if (dispc_runtime_get()) | 3307 | if (dispc_runtime_get(&dispc)) |
3294 | return 0; | 3308 | return 0; |
3295 | 3309 | ||
3296 | /* DISPC common registers */ | 3310 | /* DISPC common registers */ |
@@ -3328,7 +3342,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) | |||
3328 | p_names = mgr_names; | 3342 | p_names = mgr_names; |
3329 | 3343 | ||
3330 | /* DISPC channel specific registers */ | 3344 | /* DISPC channel specific registers */ |
3331 | for (i = 0; i < dispc_get_num_mgrs(); i++) { | 3345 | for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) { |
3332 | DUMPREG(i, DISPC_DEFAULT_COLOR); | 3346 | DUMPREG(i, DISPC_DEFAULT_COLOR); |
3333 | DUMPREG(i, DISPC_TRANS_COLOR); | 3347 | DUMPREG(i, DISPC_TRANS_COLOR); |
3334 | DUMPREG(i, DISPC_SIZE_MGR); | 3348 | DUMPREG(i, DISPC_SIZE_MGR); |
@@ -3354,7 +3368,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) | |||
3354 | 3368 | ||
3355 | p_names = ovl_names; | 3369 | p_names = ovl_names; |
3356 | 3370 | ||
3357 | for (i = 0; i < dispc_get_num_ovls(); i++) { | 3371 | for (i = 0; i < dispc_get_num_ovls(&dispc); i++) { |
3358 | DUMPREG(i, DISPC_OVL_BA0); | 3372 | DUMPREG(i, DISPC_OVL_BA0); |
3359 | DUMPREG(i, DISPC_OVL_BA1); | 3373 | DUMPREG(i, DISPC_OVL_BA1); |
3360 | DUMPREG(i, DISPC_OVL_POSITION); | 3374 | DUMPREG(i, DISPC_OVL_POSITION); |
@@ -3432,7 +3446,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) | |||
3432 | /* Video pipeline coefficient registers */ | 3446 | /* Video pipeline coefficient registers */ |
3433 | 3447 | ||
3434 | /* start from OMAP_DSS_VIDEO1 */ | 3448 | /* start from OMAP_DSS_VIDEO1 */ |
3435 | for (i = 1; i < dispc_get_num_ovls(); i++) { | 3449 | for (i = 1; i < dispc_get_num_ovls(&dispc); i++) { |
3436 | for (j = 0; j < 8; j++) | 3450 | for (j = 0; j < 8; j++) |
3437 | DUMPREG(i, DISPC_OVL_FIR_COEF_H, j); | 3451 | DUMPREG(i, DISPC_OVL_FIR_COEF_H, j); |
3438 | 3452 | ||
@@ -3459,7 +3473,7 @@ static int dispc_dump_regs(struct seq_file *s, void *p) | |||
3459 | } | 3473 | } |
3460 | } | 3474 | } |
3461 | 3475 | ||
3462 | dispc_runtime_put(); | 3476 | dispc_runtime_put(&dispc); |
3463 | 3477 | ||
3464 | #undef DISPC_REG | 3478 | #undef DISPC_REG |
3465 | #undef DUMPREG | 3479 | #undef DUMPREG |
@@ -3567,22 +3581,22 @@ int dispc_mgr_get_clock_div(enum omap_channel channel, | |||
3567 | return 0; | 3581 | return 0; |
3568 | } | 3582 | } |
3569 | 3583 | ||
3570 | static u32 dispc_read_irqstatus(void) | 3584 | static u32 dispc_read_irqstatus(struct dispc_device *dispc) |
3571 | { | 3585 | { |
3572 | return dispc_read_reg(DISPC_IRQSTATUS); | 3586 | return dispc_read_reg(DISPC_IRQSTATUS); |
3573 | } | 3587 | } |
3574 | 3588 | ||
3575 | static void dispc_clear_irqstatus(u32 mask) | 3589 | static void dispc_clear_irqstatus(struct dispc_device *dispc, u32 mask) |
3576 | { | 3590 | { |
3577 | dispc_write_reg(DISPC_IRQSTATUS, mask); | 3591 | dispc_write_reg(DISPC_IRQSTATUS, mask); |
3578 | } | 3592 | } |
3579 | 3593 | ||
3580 | static void dispc_write_irqenable(u32 mask) | 3594 | static void dispc_write_irqenable(struct dispc_device *dispc, u32 mask) |
3581 | { | 3595 | { |
3582 | u32 old_mask = dispc_read_reg(DISPC_IRQENABLE); | 3596 | u32 old_mask = dispc_read_reg(DISPC_IRQENABLE); |
3583 | 3597 | ||
3584 | /* clear the irqstatus for newly enabled irqs */ | 3598 | /* clear the irqstatus for newly enabled irqs */ |
3585 | dispc_clear_irqstatus((mask ^ old_mask) & mask); | 3599 | dispc_clear_irqstatus(dispc, (mask ^ old_mask) & mask); |
3586 | 3600 | ||
3587 | dispc_write_reg(DISPC_IRQENABLE, mask); | 3601 | dispc_write_reg(DISPC_IRQENABLE, mask); |
3588 | 3602 | ||
@@ -3600,11 +3614,12 @@ void dispc_disable_sidle(void) | |||
3600 | REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */ | 3614 | REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */ |
3601 | } | 3615 | } |
3602 | 3616 | ||
3603 | static u32 dispc_mgr_gamma_size(enum omap_channel channel) | 3617 | static u32 dispc_mgr_gamma_size(struct dispc_device *dispc, |
3618 | enum omap_channel channel) | ||
3604 | { | 3619 | { |
3605 | const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma; | 3620 | const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma; |
3606 | 3621 | ||
3607 | if (!dispc.feat->has_gamma_table) | 3622 | if (!dispc->feat->has_gamma_table) |
3608 | return 0; | 3623 | return 0; |
3609 | 3624 | ||
3610 | return gdesc->len; | 3625 | return gdesc->len; |
@@ -3653,18 +3668,19 @@ static const struct drm_color_lut dispc_mgr_gamma_default_lut[] = { | |||
3653 | { .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, }, | 3668 | { .red = U16_MAX, .green = U16_MAX, .blue = U16_MAX, }, |
3654 | }; | 3669 | }; |
3655 | 3670 | ||
3656 | static void dispc_mgr_set_gamma(enum omap_channel channel, | 3671 | static void dispc_mgr_set_gamma(struct dispc_device *dispc, |
3657 | const struct drm_color_lut *lut, | 3672 | enum omap_channel channel, |
3658 | unsigned int length) | 3673 | const struct drm_color_lut *lut, |
3674 | unsigned int length) | ||
3659 | { | 3675 | { |
3660 | const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma; | 3676 | const struct dispc_gamma_desc *gdesc = &mgr_desc[channel].gamma; |
3661 | u32 *table = dispc.gamma_table[channel]; | 3677 | u32 *table = dispc->gamma_table[channel]; |
3662 | uint i; | 3678 | uint i; |
3663 | 3679 | ||
3664 | DSSDBG("%s: channel %d, lut len %u, hw len %u\n", __func__, | 3680 | DSSDBG("%s: channel %d, lut len %u, hw len %u\n", __func__, |
3665 | channel, length, gdesc->len); | 3681 | channel, length, gdesc->len); |
3666 | 3682 | ||
3667 | if (!dispc.feat->has_gamma_table) | 3683 | if (!dispc->feat->has_gamma_table) |
3668 | return; | 3684 | return; |
3669 | 3685 | ||
3670 | if (lut == NULL || length < 2) { | 3686 | if (lut == NULL || length < 2) { |
@@ -3696,7 +3712,7 @@ static void dispc_mgr_set_gamma(enum omap_channel channel, | |||
3696 | } | 3712 | } |
3697 | } | 3713 | } |
3698 | 3714 | ||
3699 | if (dispc.is_enabled) | 3715 | if (dispc->is_enabled) |
3700 | dispc_mgr_write_gamma_table(channel); | 3716 | dispc_mgr_write_gamma_table(channel); |
3701 | } | 3717 | } |
3702 | 3718 | ||
@@ -3726,7 +3742,7 @@ static int dispc_init_gamma_tables(void) | |||
3726 | 3742 | ||
3727 | dispc.gamma_table[channel] = gt; | 3743 | dispc.gamma_table[channel] = gt; |
3728 | 3744 | ||
3729 | dispc_mgr_set_gamma(channel, NULL, 0); | 3745 | dispc_mgr_set_gamma(&dispc, channel, NULL, 0); |
3730 | } | 3746 | } |
3731 | return 0; | 3747 | return 0; |
3732 | } | 3748 | } |
@@ -4296,43 +4312,44 @@ static irqreturn_t dispc_irq_handler(int irq, void *arg) | |||
4296 | return dispc.user_handler(irq, dispc.user_data); | 4312 | return dispc.user_handler(irq, dispc.user_data); |
4297 | } | 4313 | } |
4298 | 4314 | ||
4299 | static int dispc_request_irq(irq_handler_t handler, void *dev_id) | 4315 | static int dispc_request_irq(struct dispc_device *dispc, irq_handler_t handler, |
4316 | void *dev_id) | ||
4300 | { | 4317 | { |
4301 | int r; | 4318 | int r; |
4302 | 4319 | ||
4303 | if (dispc.user_handler != NULL) | 4320 | if (dispc->user_handler != NULL) |
4304 | return -EBUSY; | 4321 | return -EBUSY; |
4305 | 4322 | ||
4306 | dispc.user_handler = handler; | 4323 | dispc->user_handler = handler; |
4307 | dispc.user_data = dev_id; | 4324 | dispc->user_data = dev_id; |
4308 | 4325 | ||
4309 | /* ensure the dispc_irq_handler sees the values above */ | 4326 | /* ensure the dispc_irq_handler sees the values above */ |
4310 | smp_wmb(); | 4327 | smp_wmb(); |
4311 | 4328 | ||
4312 | r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler, | 4329 | r = devm_request_irq(&dispc->pdev->dev, dispc->irq, dispc_irq_handler, |
4313 | IRQF_SHARED, "OMAP DISPC", &dispc); | 4330 | IRQF_SHARED, "OMAP DISPC", dispc); |
4314 | if (r) { | 4331 | if (r) { |
4315 | dispc.user_handler = NULL; | 4332 | dispc->user_handler = NULL; |
4316 | dispc.user_data = NULL; | 4333 | dispc->user_data = NULL; |
4317 | } | 4334 | } |
4318 | 4335 | ||
4319 | return r; | 4336 | return r; |
4320 | } | 4337 | } |
4321 | 4338 | ||
4322 | static void dispc_free_irq(void *dev_id) | 4339 | static void dispc_free_irq(struct dispc_device *dispc, void *dev_id) |
4323 | { | 4340 | { |
4324 | devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc); | 4341 | devm_free_irq(&dispc->pdev->dev, dispc->irq, dispc); |
4325 | 4342 | ||
4326 | dispc.user_handler = NULL; | 4343 | dispc->user_handler = NULL; |
4327 | dispc.user_data = NULL; | 4344 | dispc->user_data = NULL; |
4328 | } | 4345 | } |
4329 | 4346 | ||
4330 | static u32 dispc_get_memory_bandwidth_limit(void) | 4347 | static u32 dispc_get_memory_bandwidth_limit(struct dispc_device *dispc) |
4331 | { | 4348 | { |
4332 | u32 limit = 0; | 4349 | u32 limit = 0; |
4333 | 4350 | ||
4334 | /* Optional maximum memory bandwidth */ | 4351 | /* Optional maximum memory bandwidth */ |
4335 | of_property_read_u32(dispc.pdev->dev.of_node, "max-memory-bandwidth", | 4352 | of_property_read_u32(dispc->pdev->dev.of_node, "max-memory-bandwidth", |
4336 | &limit); | 4353 | &limit); |
4337 | 4354 | ||
4338 | return limit; | 4355 | return limit; |
@@ -4439,7 +4456,8 @@ static void dispc_errata_i734_wa_fini(void) | |||
4439 | 4456 | ||
4440 | static void dispc_errata_i734_wa(void) | 4457 | static void dispc_errata_i734_wa(void) |
4441 | { | 4458 | { |
4442 | u32 framedone_irq = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_LCD); | 4459 | u32 framedone_irq = dispc_mgr_get_framedone_irq(&dispc, |
4460 | OMAP_DSS_CHANNEL_LCD); | ||
4443 | struct omap_overlay_info ovli; | 4461 | struct omap_overlay_info ovli; |
4444 | struct dss_lcd_mgr_config lcd_conf; | 4462 | struct dss_lcd_mgr_config lcd_conf; |
4445 | u32 gatestate; | 4463 | u32 gatestate; |
@@ -4458,39 +4476,39 @@ static void dispc_errata_i734_wa(void) | |||
4458 | REG_FLD_MOD(DISPC_CONFIG, 0x1f, 8, 4); | 4476 | REG_FLD_MOD(DISPC_CONFIG, 0x1f, 8, 4); |
4459 | 4477 | ||
4460 | /* Setup and enable GFX plane */ | 4478 | /* Setup and enable GFX plane */ |
4461 | dispc_ovl_setup(OMAP_DSS_GFX, &ovli, &i734.vm, false, | 4479 | dispc_ovl_setup(&dispc, OMAP_DSS_GFX, &ovli, &i734.vm, false, |
4462 | OMAP_DSS_CHANNEL_LCD); | 4480 | OMAP_DSS_CHANNEL_LCD); |
4463 | dispc_ovl_enable(OMAP_DSS_GFX, true); | 4481 | dispc_ovl_enable(&dispc, OMAP_DSS_GFX, true); |
4464 | 4482 | ||
4465 | /* Set up and enable display manager for LCD1 */ | 4483 | /* Set up and enable display manager for LCD1 */ |
4466 | dispc_mgr_setup(OMAP_DSS_CHANNEL_LCD, &i734.mgri); | 4484 | dispc_mgr_setup(&dispc, OMAP_DSS_CHANNEL_LCD, &i734.mgri); |
4467 | dispc_calc_clock_rates(dss_get_dispc_clk_rate(dispc.dss), | 4485 | dispc_calc_clock_rates(dss_get_dispc_clk_rate(dispc.dss), |
4468 | &lcd_conf.clock_info); | 4486 | &lcd_conf.clock_info); |
4469 | dispc_mgr_set_lcd_config(OMAP_DSS_CHANNEL_LCD, &lcd_conf); | 4487 | dispc_mgr_set_lcd_config(&dispc, OMAP_DSS_CHANNEL_LCD, &lcd_conf); |
4470 | dispc_mgr_set_timings(OMAP_DSS_CHANNEL_LCD, &i734.vm); | 4488 | dispc_mgr_set_timings(&dispc, OMAP_DSS_CHANNEL_LCD, &i734.vm); |
4471 | 4489 | ||
4472 | dispc_clear_irqstatus(framedone_irq); | 4490 | dispc_clear_irqstatus(&dispc, framedone_irq); |
4473 | 4491 | ||
4474 | /* Enable and shut the channel to produce just one frame */ | 4492 | /* Enable and shut the channel to produce just one frame */ |
4475 | dispc_mgr_enable(OMAP_DSS_CHANNEL_LCD, true); | 4493 | dispc_mgr_enable(&dispc, OMAP_DSS_CHANNEL_LCD, true); |
4476 | dispc_mgr_enable(OMAP_DSS_CHANNEL_LCD, false); | 4494 | dispc_mgr_enable(&dispc, OMAP_DSS_CHANNEL_LCD, false); |
4477 | 4495 | ||
4478 | /* Busy wait for framedone. We can't fiddle with irq handlers | 4496 | /* Busy wait for framedone. We can't fiddle with irq handlers |
4479 | * in PM resume. Typically the loop runs less than 5 times and | 4497 | * in PM resume. Typically the loop runs less than 5 times and |
4480 | * waits less than a micro second. | 4498 | * waits less than a micro second. |
4481 | */ | 4499 | */ |
4482 | count = 0; | 4500 | count = 0; |
4483 | while (!(dispc_read_irqstatus() & framedone_irq)) { | 4501 | while (!(dispc_read_irqstatus(&dispc) & framedone_irq)) { |
4484 | if (count++ > 10000) { | 4502 | if (count++ > 10000) { |
4485 | dev_err(&dispc.pdev->dev, "%s: framedone timeout\n", | 4503 | dev_err(&dispc.pdev->dev, "%s: framedone timeout\n", |
4486 | __func__); | 4504 | __func__); |
4487 | break; | 4505 | break; |
4488 | } | 4506 | } |
4489 | } | 4507 | } |
4490 | dispc_ovl_enable(OMAP_DSS_GFX, false); | 4508 | dispc_ovl_enable(&dispc, OMAP_DSS_GFX, false); |
4491 | 4509 | ||
4492 | /* Clear all irq bits before continuing */ | 4510 | /* Clear all irq bits before continuing */ |
4493 | dispc_clear_irqstatus(0xffffffff); | 4511 | dispc_clear_irqstatus(&dispc, 0xffffffff); |
4494 | 4512 | ||
4495 | /* Restore the original state to LCD1 output gates */ | 4513 | /* Restore the original state to LCD1 output gates */ |
4496 | REG_FLD_MOD(DISPC_CONFIG, gatestate, 8, 4); | 4514 | REG_FLD_MOD(DISPC_CONFIG, gatestate, 8, 4); |
@@ -4610,7 +4628,7 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) | |||
4610 | 4628 | ||
4611 | pm_runtime_enable(&pdev->dev); | 4629 | pm_runtime_enable(&pdev->dev); |
4612 | 4630 | ||
4613 | r = dispc_runtime_get(); | 4631 | r = dispc_runtime_get(&dispc); |
4614 | if (r) | 4632 | if (r) |
4615 | goto err_runtime_get; | 4633 | goto err_runtime_get; |
4616 | 4634 | ||
@@ -4620,8 +4638,9 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) | |||
4620 | dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n", | 4638 | dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n", |
4621 | FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); | 4639 | FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); |
4622 | 4640 | ||
4623 | dispc_runtime_put(); | 4641 | dispc_runtime_put(&dispc); |
4624 | 4642 | ||
4643 | dss->dispc = &dispc; | ||
4625 | dss->dispc_ops = &dispc_ops; | 4644 | dss->dispc_ops = &dispc_ops; |
4626 | 4645 | ||
4627 | dispc.debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs, | 4646 | dispc.debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs, |
@@ -4634,13 +4653,13 @@ err_runtime_get: | |||
4634 | return r; | 4653 | return r; |
4635 | } | 4654 | } |
4636 | 4655 | ||
4637 | static void dispc_unbind(struct device *dev, struct device *master, | 4656 | static void dispc_unbind(struct device *dev, struct device *master, void *data) |
4638 | void *data) | ||
4639 | { | 4657 | { |
4640 | struct dss_device *dss = dispc.dss; | 4658 | struct dss_device *dss = dispc.dss; |
4641 | 4659 | ||
4642 | dss_debugfs_remove_file(dispc.debugfs); | 4660 | dss_debugfs_remove_file(dispc.debugfs); |
4643 | 4661 | ||
4662 | dss->dispc = NULL; | ||
4644 | dss->dispc_ops = NULL; | 4663 | dss->dispc_ops = NULL; |
4645 | 4664 | ||
4646 | pm_runtime_disable(dev); | 4665 | pm_runtime_disable(dev); |