Patch "drm/radeon: Hide the HW cursor while it's out of bounds" has been added to the 4.8-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
drm/radeon: Hide the HW cursor while it's out of bounds
to the 4.8-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-radeon-hide-the-hw-cursor-while-it-s-out-of-bounds.patch
and it can be found in the queue-4.8 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
6b16cf7785a4200b1bddf4f70c9dda2efc49e278Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <[email protected]>
Date: Thu, 27 Oct 2016 14:54:31 +0900
Subject: drm/radeon: Hide the HW cursor while it's out of bounds
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Michel Dänzer <[email protected]>
commit 6b16cf7785a4200b1bddf4f70c9dda2efc49e278 upstream.
Fixes hangs in that case under some circumstances.
v2:
* Only use non-0 x/yorigin if the cursor is (partially) outside of the top/left edge of the total surface with AVIVO/DCE
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1000433
--- drivers/gpu/drm/radeon/radeon_cursor.c | 60 +++++++++++++++++++++++---------- drivers/gpu/drm/radeon/radeon_mode.h | 1 2 files changed, 43 insertions(+), 18 deletions(-)
drivers/gpu/drm/radeon/radeon_cursor.c +42 -18
@@ -90,6 +90,9 @@ static void radeon_show_cursor(struct drstruct radeon_crtc *radeon_crtc =to_radeon_crtc (crtc);struct radeon_device *rdev = crtc->dev->dev_private; +if (radeon_crtc->cursor_out_of_bounds) +return ; +if (ASIC_IS_DCE4 (rdev)) {WREG32 (EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,upper_32_bits (radeon_crtc->cursor_addr));
@@ -148,16 +151,17 @@ static int radeon_cursor_move_locked(str x += crtc->x; y += crtc->y; } -DRM_DEBUG ("x %d y %d c->x %d c->y %d\n" , x, y, crtc->x, crtc->y); -if (x <0 ) { +if (x <0 ) xorigin =min (-x, radeon_crtc->max_cursor_width -1 ); - x =0 ; - } -if (y <0 ) { +if (y <0 ) yorigin =min (-y, radeon_crtc->max_cursor_height -1 ); - y =0 ; + +if (!ASIC_IS_AVIVO (rdev)) { + x += crtc->x; + y += crtc->y; } +DRM_DEBUG ("x %d y %d c->x %d c->y %d\n" , x, y, crtc->x, crtc->y);/* fixed on DCE6 and newer */ if (ASIC_IS_AVIVO (rdev) && !ASIC_IS_DCE6 (rdev)) {
@@ -180,27 +184,31 @@ static int radeon_cursor_move_locked(strif (i >1 ) {int cursor_end, frame_end; - cursor_end = x - xorigin + w; + cursor_end = x + w; frame_end = crtc->x + crtc->mode.crtc_hdisplay;if (cursor_end >= frame_end) { w = w - (cursor_end - frame_end);if (!(frame_end &0x7f )) w--; - }else { -if (!(cursor_end &0x7f )) - w--; + }else if (cursor_end <=0 ) { + goto out_of_bounds; + }else if (!(cursor_end &0x7f )) { + w--; }if (w <=0 ) { - w =1 ; - cursor_end = x - xorigin + w; -if (!(cursor_end &0x7f )) { - x--; -WARN_ON_ONCE (x <0 ); - } + goto out_of_bounds; } } } +if (x <= (crtc->x - w) || y <= (crtc->y - radeon_crtc->cursor_height) || + x >= (crtc->x + crtc->mode.crtc_hdisplay) || + y >= (crtc->y + crtc->mode.crtc_vdisplay)) + goto out_of_bounds; + + x += xorigin; + y += yorigin; +if (ASIC_IS_DCE4 (rdev)) {WREG32 (EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x <<16 ) | y);WREG32 (EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin <<16 ) | yorigin);
@@ -212,6 +220,9 @@ static int radeon_cursor_move_locked(strWREG32 (AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset, ((w -1 ) <<16 ) | (radeon_crtc->cursor_height -1 )); }else { + x -= crtc->x; + y -= crtc->y; +if (crtc->mode.flags &DRM_MODE_FLAG_DBLSCAN ) y *=2 ;
@@ -232,6 +243,19 @@ static int radeon_cursor_move_locked(str radeon_crtc->cursor_x = x; radeon_crtc->cursor_y = y; +if (radeon_crtc->cursor_out_of_bounds) { + radeon_crtc->cursor_out_of_bounds = false; +if (radeon_crtc->cursor_bo) +radeon_show_cursor (crtc); + } + +return 0 ; + + out_of_bounds: +if (!radeon_crtc->cursor_out_of_bounds) { +radeon_hide_cursor (crtc); + radeon_crtc->cursor_out_of_bounds = true; + }return 0 ; }
@@ -308,12 +332,12 @@ int radeon_crtc_cursor_set2(struct drm_c x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x; y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y; -radeon_cursor_move_locked (crtc, x, y); - radeon_crtc->cursor_width = width; radeon_crtc->cursor_height = height; radeon_crtc->cursor_hot_x = hot_x; radeon_crtc->cursor_hot_y = hot_y; + +radeon_cursor_move_locked (crtc, x, y); }radeon_show_cursor (crtc);
drivers/gpu/drm/radeon/radeon_mode.h +1 -0
@@ -330,6 +330,7 @@ struct radeon_crtc {u16 lut_r[256 ], lut_g[256 ], lut_b[256 ];bool enabled;bool can_tile; +bool cursor_out_of_bounds;uint32_t crtc_offset;struct drm_gem_object *cursor_bo;uint64_t cursor_addr;
Patches currently in stable-queue which might be from [email protected] are
queue-4.8/drm-radeon-also-call-cursor_move_locked-when-the-cursor-size-changes.patch queue-4.8/drm-radeon-hide-the-hw-cursor-while-it-s-out-of-bounds.patch