aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorMatt Roper <matthew.d.roper@intel.com>2015-03-04 13:49:04 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-03-17 17:29:59 -0400
commit0d703d4e5d7094e77186d09619548de42be9b493 (patch)
treee10f6f149bfb2bc51df4ffd36bce84f2c731875c /drivers/gpu/drm/i915/intel_display.c
parent2934368e41551b641df6654d93e7ffe26e94dc10 (diff)
drm/i915: Don't clobber plane state on internal disables
We need to disable all sprite planes when disabling the CRTC. We had been using the top-level atomic 'disable' entrypoint to accomplish this, which was wrong. Not only can this lead to various locking issues, it also modifies the actual plane state, making it impossible to restore the plane properly later. For example, a DPMS off followed by a DPMS on will result in any sprite planes in use not being restored properly. The proper solution here is to call directly into our 'commit plane' hook with a copy of the plane's current state that has 'visible' set to false. Committing this dummy state will turn off the plane, but will not touch the actual plane->state pointer, allowing us to properly restore the plane state later. Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8e9e18ccfcd8..3404da8e77b4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4204,6 +4204,24 @@ static void intel_enable_sprite_planes(struct drm_crtc *crtc)
4204 } 4204 }
4205} 4205}
4206 4206
4207/*
4208 * Disable a plane internally without actually modifying the plane's state.
4209 * This will allow us to easily restore the plane later by just reprogramming
4210 * its state.
4211 */
4212static void disable_plane_internal(struct drm_plane *plane)
4213{
4214 struct intel_plane *intel_plane = to_intel_plane(plane);
4215 struct drm_plane_state *state =
4216 plane->funcs->atomic_duplicate_state(plane);
4217 struct intel_plane_state *intel_state = to_intel_plane_state(state);
4218
4219 intel_state->visible = false;
4220 intel_plane->commit_plane(plane, intel_state);
4221
4222 intel_plane_destroy_state(plane, state);
4223}
4224
4207static void intel_disable_sprite_planes(struct drm_crtc *crtc) 4225static void intel_disable_sprite_planes(struct drm_crtc *crtc)
4208{ 4226{
4209 struct drm_device *dev = crtc->dev; 4227 struct drm_device *dev = crtc->dev;
@@ -4213,8 +4231,8 @@ static void intel_disable_sprite_planes(struct drm_crtc *crtc)
4213 4231
4214 drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { 4232 drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) {
4215 intel_plane = to_intel_plane(plane); 4233 intel_plane = to_intel_plane(plane);
4216 if (intel_plane->pipe == pipe) 4234 if (plane->fb && intel_plane->pipe == pipe)
4217 plane->funcs->disable_plane(plane); 4235 disable_plane_internal(plane);
4218 } 4236 }
4219} 4237}
4220 4238