diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2017-07-08 05:16:40 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2017-12-08 07:18:35 -0500 |
commit | 28b304339900027988ace06bcbda8cd4c6a67883 (patch) | |
tree | e5991769e3c1aa8d968b8e52d42cd3db91d38018 /drivers/gpu | |
parent | 65724a19438ce50a7cf85bc2d3172ea237ab05de (diff) |
drm/armada: allow the primary plane to be disabled
Add our own hook to allow the primary plane to be disabled.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/armada/armada_crtc.c | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 328f030ffbdc..7f7f21166488 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c | |||
@@ -341,7 +341,7 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc, | |||
341 | if (work) { | 341 | if (work) { |
342 | work->old_fb = fb; | 342 | work->old_fb = fb; |
343 | 343 | ||
344 | if (armada_drm_plane_work_queue(dcrtc, work) == 0) | 344 | if (armada_drm_plane_work_queue(dcrtc, &work->work) == 0) |
345 | return; | 345 | return; |
346 | 346 | ||
347 | kfree(work); | 347 | kfree(work); |
@@ -760,51 +760,13 @@ static int armada_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | |||
760 | return 0; | 760 | return 0; |
761 | } | 761 | } |
762 | 762 | ||
763 | void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc, | ||
764 | struct drm_plane *plane) | ||
765 | { | ||
766 | struct armada_plane *dplane = drm_to_armada_plane(plane); | ||
767 | u32 sram_para1, dma_ctrl0_mask; | ||
768 | |||
769 | /* | ||
770 | * Drop our reference on any framebuffer attached to this plane. | ||
771 | * We don't need to NULL this out as drm_plane_force_disable(), | ||
772 | * and __setplane_internal() will do so for an overlay plane, and | ||
773 | * __drm_helper_disable_unused_functions() will do so for the | ||
774 | * primary plane. | ||
775 | */ | ||
776 | if (plane->fb) | ||
777 | drm_framebuffer_put(plane->fb); | ||
778 | |||
779 | /* Power down most RAMs and FIFOs if this is the primary plane */ | ||
780 | if (plane->type == DRM_PLANE_TYPE_PRIMARY) { | ||
781 | sram_para1 = CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 | | ||
782 | CFG_PDWN32x32 | CFG_PDWN64x66; | ||
783 | dma_ctrl0_mask = CFG_GRA_ENA; | ||
784 | } else { | ||
785 | /* Power down the Y/U/V FIFOs */ | ||
786 | sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66; | ||
787 | dma_ctrl0_mask = CFG_DMA_ENA; | ||
788 | } | ||
789 | |||
790 | /* Wait for any preceding work to complete, but don't wedge */ | ||
791 | if (WARN_ON(!armada_drm_plane_work_wait(dplane, HZ))) | ||
792 | armada_drm_plane_work_cancel(dcrtc, dplane); | ||
793 | |||
794 | spin_lock_irq(&dcrtc->irq_lock); | ||
795 | armada_updatel(0, dma_ctrl0_mask, dcrtc->base + LCD_SPU_DMA_CTRL0); | ||
796 | spin_unlock_irq(&dcrtc->irq_lock); | ||
797 | |||
798 | armada_updatel(sram_para1, 0, dcrtc->base + LCD_SPU_SRAM_PARA1); | ||
799 | } | ||
800 | |||
801 | /* The mode_config.mutex will be held for this call */ | 763 | /* The mode_config.mutex will be held for this call */ |
802 | static void armada_drm_crtc_disable(struct drm_crtc *crtc) | 764 | static void armada_drm_crtc_disable(struct drm_crtc *crtc) |
803 | { | 765 | { |
804 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | ||
805 | |||
806 | armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 766 | armada_drm_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
807 | armada_drm_crtc_plane_disable(dcrtc, crtc->primary); | 767 | |
768 | /* Disable our primary plane when we disable the CRTC. */ | ||
769 | crtc->primary->funcs->disable_plane(crtc->primary, NULL); | ||
808 | } | 770 | } |
809 | 771 | ||
810 | static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = { | 772 | static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = { |
@@ -1081,7 +1043,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, | |||
1081 | */ | 1043 | */ |
1082 | drm_framebuffer_get(fb); | 1044 | drm_framebuffer_get(fb); |
1083 | 1045 | ||
1084 | ret = armada_drm_plane_work_queue(dcrtc, work); | 1046 | ret = armada_drm_plane_work_queue(dcrtc, &work->work); |
1085 | if (ret) { | 1047 | if (ret) { |
1086 | /* Undo our reference above */ | 1048 | /* Undo our reference above */ |
1087 | drm_framebuffer_put(fb); | 1049 | drm_framebuffer_put(fb); |
@@ -1161,9 +1123,58 @@ static const struct drm_crtc_funcs armada_crtc_funcs = { | |||
1161 | .disable_vblank = armada_drm_crtc_disable_vblank, | 1123 | .disable_vblank = armada_drm_crtc_disable_vblank, |
1162 | }; | 1124 | }; |
1163 | 1125 | ||
1126 | void armada_drm_crtc_plane_disable(struct armada_crtc *dcrtc, | ||
1127 | struct drm_plane *plane) | ||
1128 | { | ||
1129 | struct armada_plane *dplane = drm_to_armada_plane(plane); | ||
1130 | u32 sram_para1, dma_ctrl0_mask; | ||
1131 | |||
1132 | /* | ||
1133 | * Drop our reference on any framebuffer attached to this plane. | ||
1134 | * We don't need to NULL this out as drm_plane_force_disable(), | ||
1135 | * and __setplane_internal() will do so for an overlay plane, and | ||
1136 | * __drm_helper_disable_unused_functions() will do so for the | ||
1137 | * primary plane. | ||
1138 | */ | ||
1139 | if (plane->fb) | ||
1140 | drm_framebuffer_put(plane->fb); | ||
1141 | |||
1142 | /* Power down most RAMs and FIFOs if this is the primary plane */ | ||
1143 | if (plane->type == DRM_PLANE_TYPE_PRIMARY) { | ||
1144 | sram_para1 = CFG_PDWN256x32 | CFG_PDWN256x24 | CFG_PDWN256x8 | | ||
1145 | CFG_PDWN32x32 | CFG_PDWN64x66; | ||
1146 | dma_ctrl0_mask = CFG_GRA_ENA; | ||
1147 | } else { | ||
1148 | /* Power down the Y/U/V FIFOs */ | ||
1149 | sram_para1 = CFG_PDWN16x66 | CFG_PDWN32x66; | ||
1150 | dma_ctrl0_mask = CFG_DMA_ENA; | ||
1151 | } | ||
1152 | |||
1153 | /* Wait for any preceding work to complete, but don't wedge */ | ||
1154 | if (WARN_ON(!armada_drm_plane_work_wait(dplane, HZ))) | ||
1155 | armada_drm_plane_work_cancel(dcrtc, dplane); | ||
1156 | |||
1157 | spin_lock_irq(&dcrtc->irq_lock); | ||
1158 | armada_updatel(0, dma_ctrl0_mask, dcrtc->base + LCD_SPU_DMA_CTRL0); | ||
1159 | spin_unlock_irq(&dcrtc->irq_lock); | ||
1160 | |||
1161 | armada_updatel(sram_para1, 0, dcrtc->base + LCD_SPU_SRAM_PARA1); | ||
1162 | } | ||
1163 | |||
1164 | static int armada_drm_primary_disable(struct drm_plane *plane, | ||
1165 | struct drm_modeset_acquire_ctx *ctx) | ||
1166 | { | ||
1167 | if (plane->crtc) { | ||
1168 | struct armada_crtc *dcrtc = drm_to_armada_crtc(plane->crtc); | ||
1169 | |||
1170 | armada_drm_crtc_plane_disable(dcrtc, plane); | ||
1171 | } | ||
1172 | return 0; | ||
1173 | } | ||
1174 | |||
1164 | static const struct drm_plane_funcs armada_primary_plane_funcs = { | 1175 | static const struct drm_plane_funcs armada_primary_plane_funcs = { |
1165 | .update_plane = drm_primary_helper_update, | 1176 | .update_plane = drm_primary_helper_update, |
1166 | .disable_plane = drm_primary_helper_disable, | 1177 | .disable_plane = armada_drm_primary_disable, |
1167 | .destroy = drm_primary_helper_destroy, | 1178 | .destroy = drm_primary_helper_destroy, |
1168 | }; | 1179 | }; |
1169 | 1180 | ||