diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-16 18:01:13 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-01-17 05:07:06 -0500 |
commit | 931872fceabacf2d4f8b6fbd51611c167e83164c (patch) | |
tree | c90897b37ba97704ee667ced04431eb5e2d095e2 | |
parent | f3953dcb98bad1c3badf451bcf41bf83ae2ce542 (diff) |
drm/i915: Check that plane/pipe is disabled before removing the fb
Staring at an error state such as:
PGTBL_ER: 0x00000400
Display B: Invalid tiling
fence[0] = 05001001
valid, x-tiled, pitch: 512, start: 0x05000000, size: 1048576
Pinned [2]:
00000000 131072 0001 0001 00000000 P uncached
00020000 4096000 0041 0000 00000000 P uncached (name: 1)
Plane [1]:
CNTR: c0000000 # enabled | gamma
STRIDE: 00001400
SIZE: 03ff04ff
POS: 00000000
ADDR: 05000000
Suggests that we did not clear the DSPBCNTR prior to unpinning the
framebuffer and reusing the GTT space. Impossible! Unless our DPMS
bookkeeping ran afoul again...
In the meantime add an assertion that the plane is decoupled from the
framebuffer prior to release.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f3e706c2bd31..5fa1476cbfc6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -944,19 +944,24 @@ void assert_pipe(struct drm_i915_private *dev_priv, | |||
944 | pipe_name(pipe), state_string(state), state_string(cur_state)); | 944 | pipe_name(pipe), state_string(state), state_string(cur_state)); |
945 | } | 945 | } |
946 | 946 | ||
947 | static void assert_plane_enabled(struct drm_i915_private *dev_priv, | 947 | static void assert_plane(struct drm_i915_private *dev_priv, |
948 | enum plane plane) | 948 | enum plane plane, bool state) |
949 | { | 949 | { |
950 | int reg; | 950 | int reg; |
951 | u32 val; | 951 | u32 val; |
952 | bool cur_state; | ||
952 | 953 | ||
953 | reg = DSPCNTR(plane); | 954 | reg = DSPCNTR(plane); |
954 | val = I915_READ(reg); | 955 | val = I915_READ(reg); |
955 | WARN(!(val & DISPLAY_PLANE_ENABLE), | 956 | cur_state = !!(val & DISPLAY_PLANE_ENABLE); |
956 | "plane %c assertion failure, should be active but is disabled\n", | 957 | WARN(cur_state != state, |
957 | plane_name(plane)); | 958 | "plane %c assertion failure (expected %s, current %s)\n", |
959 | plane_name(plane), state_string(state), state_string(cur_state)); | ||
958 | } | 960 | } |
959 | 961 | ||
962 | #define assert_plane_enabled(d, p) assert_plane(d, p, true) | ||
963 | #define assert_plane_disabled(d, p) assert_plane(d, p, false) | ||
964 | |||
960 | static void assert_planes_disabled(struct drm_i915_private *dev_priv, | 965 | static void assert_planes_disabled(struct drm_i915_private *dev_priv, |
961 | enum pipe pipe) | 966 | enum pipe pipe) |
962 | { | 967 | { |
@@ -3335,6 +3340,8 @@ static void intel_crtc_disable(struct drm_crtc *crtc) | |||
3335 | struct drm_device *dev = crtc->dev; | 3340 | struct drm_device *dev = crtc->dev; |
3336 | 3341 | ||
3337 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); | 3342 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); |
3343 | assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); | ||
3344 | assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); | ||
3338 | 3345 | ||
3339 | if (crtc->fb) { | 3346 | if (crtc->fb) { |
3340 | mutex_lock(&dev->struct_mutex); | 3347 | mutex_lock(&dev->struct_mutex); |