aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2015-12-18 12:24:39 -0500
committerJani Nikula <jani.nikula@intel.com>2015-12-22 05:57:56 -0500
commitef8dd37af85a8f37ca3a29074647511e52c56181 (patch)
tree96e9e3c8c1e4fb18a23f75621a9a856232a603b7 /drivers/gpu
parent0f0cd472062eca6f9fac8be0cd5585f9a2df1ab2 (diff)
drm/i915: Workaround CHV pipe C cursor fail
Turns out CHV pipe C was glued on somewhat poorly, and there's something wrong with the cursor. If the cursor straddles the left screen edge, and is then moved away from the edge or disabled, the pipe will often underrun. If enough underruns are triggered quickly enough the pipe will fall over and die (it just scans out a solid color and reports a constant underrun). We need to turn the disp2d power well off and on again to recover the pipe. None of that is very nice for the user, so let's just refuse to place the cursor in the compromised position. The ddx appears to fall back to swcursor when the ioctl returns an error, so theoretically there's no loss of functionality for the user (discounting swcursor bugs). I suppose most cursors images actually have the hotspot not exactly at 0,0 so under typical conditions the fallback will in fact kick in as soon as the cursor touches the left edge of the screen. Any atomic compositor should anyway be prepared to fall back to GPU composition when things don't work out, so there should be no problem with those. Other things that I tried to solve this include flipping all display related clock gating knobs I could find, increasing the minimum gtt alignment all the way up to 512k. I also tried to see if there are more specific screen coordinates that hit the bug, but the findings were somewhat inconclusive. Sometimes the failures happen almost across the whole left edge, sometimes more at the very top and around the bottom half. I wasn't able to find any real pattern to these variations, so it seems our only choice is to just refuse to straddle the left screen edge at all. Cc: stable@vger.kernel.org Cc: Jason Plum <max@warheads.net> Testcase: igt/kms_chv_cursor_fail Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92826 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1450459479-16286-1-git-send-email-ville.syrjala@linux.intel.com Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> (cherry picked from commit b29ec92c4f5e6d45d8bae8194e664427a01c6687) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 13bc6d44293a..69e158789365 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13728,6 +13728,7 @@ intel_check_cursor_plane(struct drm_plane *plane,
13728 struct drm_crtc *crtc = crtc_state->base.crtc; 13728 struct drm_crtc *crtc = crtc_state->base.crtc;
13729 struct drm_framebuffer *fb = state->base.fb; 13729 struct drm_framebuffer *fb = state->base.fb;
13730 struct drm_i915_gem_object *obj = intel_fb_obj(fb); 13730 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
13731 enum pipe pipe = to_intel_plane(plane)->pipe;
13731 unsigned stride; 13732 unsigned stride;
13732 int ret; 13733 int ret;
13733 13734
@@ -13761,6 +13762,22 @@ intel_check_cursor_plane(struct drm_plane *plane,
13761 return -EINVAL; 13762 return -EINVAL;
13762 } 13763 }
13763 13764
13765 /*
13766 * There's something wrong with the cursor on CHV pipe C.
13767 * If it straddles the left edge of the screen then
13768 * moving it away from the edge or disabling it often
13769 * results in a pipe underrun, and often that can lead to
13770 * dead pipe (constant underrun reported, and it scans
13771 * out just a solid color). To recover from that, the
13772 * display power well must be turned off and on again.
13773 * Refuse the put the cursor into that compromised position.
13774 */
13775 if (IS_CHERRYVIEW(plane->dev) && pipe == PIPE_C &&
13776 state->visible && state->base.crtc_x < 0) {
13777 DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
13778 return -EINVAL;
13779 }
13780
13764 return 0; 13781 return 0;
13765} 13782}
13766 13783