[PATCH 1/2] drm/radeon: Use cursor_set2 hook for enabling / disabling the HW cursor
Alex Deucher
alexdeucher at gmail.com
Tue Nov 18 11:09:00 PST 2014
On Tue, Nov 18, 2014 at 4:00 AM, Michel Dänzer <michel at daenzer.net> wrote:
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> The cursor_set2 hook provides the cursor hotspot position within the
> cursor image. When the hotspot position changes, we can adjust the cursor
> position such that the hotspot doesn't move on the screen. This prevents
> the cursor from appearing to intermittently jump around on the screen
> when the position of the hotspot within the cursor image changes.
>
> Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
Series applied to my -next tree.
Thanks!
Alex
> ---
> drivers/gpu/drm/radeon/radeon_cursor.c | 51 ++++++++++++++++++++++++++-------
> drivers/gpu/drm/radeon/radeon_display.c | 2 +-
> drivers/gpu/drm/radeon/radeon_mode.h | 16 +++++++----
> 3 files changed, 52 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
> index 9630e8d..fd4bddf 100644
> --- a/drivers/gpu/drm/radeon/radeon_cursor.c
> +++ b/drivers/gpu/drm/radeon/radeon_cursor.c
> @@ -117,8 +117,10 @@ static void radeon_show_cursor(struct drm_crtc *crtc)
> }
> }
>
> +static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y);
> +
> static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj,
> - uint64_t gpu_addr)
> + uint64_t gpu_addr, int hot_x, int hot_y)
> {
> struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
> struct radeon_device *rdev = crtc->dev->dev_private;
> @@ -142,13 +144,28 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj,
> /* offset is from DISP(2)_BASE_ADDRESS */
> WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
> }
> +
> + if (hot_x != radeon_crtc->cursor_hot_x ||
> + hot_y != radeon_crtc->cursor_hot_y) {
> + int x, y;
> +
> + 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_hot_x = hot_x;
> + radeon_crtc->cursor_hot_y = hot_y;
> + }
> }
>
> -int radeon_crtc_cursor_set(struct drm_crtc *crtc,
> - struct drm_file *file_priv,
> - uint32_t handle,
> - uint32_t width,
> - uint32_t height)
> +int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
> + struct drm_file *file_priv,
> + uint32_t handle,
> + uint32_t width,
> + uint32_t height,
> + int32_t hot_x,
> + int32_t hot_y)
> {
> struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
> struct radeon_device *rdev = crtc->dev->dev_private;
> @@ -192,7 +209,7 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,
> radeon_crtc->cursor_height = height;
>
> radeon_lock_cursor(crtc, true);
> - radeon_set_cursor(crtc, obj, gpu_addr);
> + radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y);
> radeon_show_cursor(crtc);
> radeon_lock_cursor(crtc, false);
>
> @@ -215,8 +232,7 @@ fail:
> return ret;
> }
>
> -int radeon_crtc_cursor_move(struct drm_crtc *crtc,
> - int x, int y)
> +static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y)
> {
> struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
> struct radeon_device *rdev = crtc->dev->dev_private;
> @@ -281,7 +297,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,
> }
> }
>
> - radeon_lock_cursor(crtc, true);
> 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);
> @@ -308,7 +323,21 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,
> WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset +
> (yorigin * 256)));
> }
> - radeon_lock_cursor(crtc, false);
> +
> + radeon_crtc->cursor_x = x;
> + radeon_crtc->cursor_y = y;
>
> return 0;
> }
> +
> +int radeon_crtc_cursor_move(struct drm_crtc *crtc,
> + int x, int y)
> +{
> + int ret;
> +
> + radeon_lock_cursor(crtc, true);
> + ret = radeon_cursor_move_locked(crtc, x, y);
> + radeon_lock_cursor(crtc, false);
> +
> + return ret;
> +}
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> index 00ead8c..b233dcd 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -634,7 +634,7 @@ radeon_crtc_set_config(struct drm_mode_set *set)
> return ret;
> }
> static const struct drm_crtc_funcs radeon_crtc_funcs = {
> - .cursor_set = radeon_crtc_cursor_set,
> + .cursor_set2 = radeon_crtc_cursor_set2,
> .cursor_move = radeon_crtc_cursor_move,
> .gamma_set = radeon_crtc_gamma_set,
> .set_config = radeon_crtc_set_config,
> diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
> index 04db2fd..de1b0d6 100644
> --- a/drivers/gpu/drm/radeon/radeon_mode.h
> +++ b/drivers/gpu/drm/radeon/radeon_mode.h
> @@ -321,6 +321,10 @@ struct radeon_crtc {
> uint32_t crtc_offset;
> struct drm_gem_object *cursor_bo;
> uint64_t cursor_addr;
> + int cursor_x;
> + int cursor_y;
> + int cursor_hot_x;
> + int cursor_hot_y;
> int cursor_width;
> int cursor_height;
> int max_cursor_width;
> @@ -802,11 +806,13 @@ extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc,
> extern int radeon_crtc_do_set_base(struct drm_crtc *crtc,
> struct drm_framebuffer *fb,
> int x, int y, int atomic);
> -extern int radeon_crtc_cursor_set(struct drm_crtc *crtc,
> - struct drm_file *file_priv,
> - uint32_t handle,
> - uint32_t width,
> - uint32_t height);
> +extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
> + struct drm_file *file_priv,
> + uint32_t handle,
> + uint32_t width,
> + uint32_t height,
> + int32_t hot_x,
> + int32_t hot_y);
> extern int radeon_crtc_cursor_move(struct drm_crtc *crtc,
> int x, int y);
>
> --
> 2.1.3
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the dri-devel
mailing list