On Thu, Nov 20, 2014 at 9:48 PM, Michel Dänzer <michel@xxxxxxxxxxx> wrote: > From: Michel Dänzer <michel.daenzer@xxxxxxx> > > Setting a mode seems to clear the cursor registers, so we need to > re-program them to make sure the cursor is visible. > > Signed-off-by: Michel Dänzer <michel.daenzer@xxxxxxx> > Reviewed-by: Alex Deucher <alexander.deucher@xxxxxxx> Applied the series to my -next tree. Thanks! Alex > --- > drivers/gpu/drm/radeon/atombios_crtc.c | 1 + > drivers/gpu/drm/radeon/radeon_cursor.c | 89 +++++++++++++++++++++-------- > drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 1 + > drivers/gpu/drm/radeon/radeon_mode.h | 1 + > 4 files changed, 68 insertions(+), 24 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c > index 30d242b..d59ec49 100644 > --- a/drivers/gpu/drm/radeon/atombios_crtc.c > +++ b/drivers/gpu/drm/radeon/atombios_crtc.c > @@ -2039,6 +2039,7 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, > atombios_crtc_set_base(crtc, x, y, old_fb); > atombios_overscan_setup(crtc, mode, adjusted_mode); > atombios_scaler_setup(crtc); > + radeon_cursor_reset(crtc); > /* update the hw version fpr dpm */ > radeon_crtc->hw_mode = *adjusted_mode; > > diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c > index 85f38ee..44dcbde6 100644 > --- a/drivers/gpu/drm/radeon/radeon_cursor.c > +++ b/drivers/gpu/drm/radeon/radeon_cursor.c > @@ -227,11 +227,25 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, > return ret; > } > > -static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, > - uint64_t gpu_addr, int hot_x, int hot_y) > +static int radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, > + int hot_x, int hot_y) > { > struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); > struct radeon_device *rdev = crtc->dev->dev_private; > + struct radeon_bo *robj = gem_to_radeon_bo(obj); > + uint64_t gpu_addr; > + int ret; > + > + ret = radeon_bo_reserve(robj, false); > + if (unlikely(ret != 0)) > + goto fail; > + /* Only 27 bit offset for legacy cursor */ > + ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, > + ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, > + &gpu_addr); > + radeon_bo_unreserve(robj); > + if (ret) > + goto fail; > > if (ASIC_IS_DCE4(rdev)) { > WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, > @@ -265,6 +279,13 @@ static void radeon_set_cursor(struct drm_crtc *crtc, struct drm_gem_object *obj, > radeon_crtc->cursor_hot_x = hot_x; > radeon_crtc->cursor_hot_y = hot_y; > } > + > + return 0; > + > +fail: > + drm_gem_object_unreference_unlocked(obj); > + > + return ret; > } > > int radeon_crtc_cursor_set2(struct drm_crtc *crtc, > @@ -276,10 +297,7 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, > int32_t hot_y) > { > struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); > - struct radeon_device *rdev = crtc->dev->dev_private; > struct drm_gem_object *obj; > - struct radeon_bo *robj; > - uint64_t gpu_addr; > int ret; > > if (!handle) { > @@ -301,41 +319,64 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc, > return -ENOENT; > } > > - robj = gem_to_radeon_bo(obj); > - ret = radeon_bo_reserve(robj, false); > - if (unlikely(ret != 0)) > - goto fail; > - /* Only 27 bit offset for legacy cursor */ > - ret = radeon_bo_pin_restricted(robj, RADEON_GEM_DOMAIN_VRAM, > - ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, > - &gpu_addr); > - radeon_bo_unreserve(robj); > - if (ret) > - goto fail; > - > radeon_crtc->cursor_width = width; > radeon_crtc->cursor_height = height; > > radeon_lock_cursor(crtc, true); > - radeon_set_cursor(crtc, obj, gpu_addr, hot_x, hot_y); > - radeon_show_cursor(crtc); > + ret = radeon_set_cursor(crtc, obj, hot_x, hot_y); > + > + if (ret) > + DRM_ERROR("radeon_set_cursor returned %d, not changing cursor\n", > + ret); > + else > + radeon_show_cursor(crtc); > + > radeon_lock_cursor(crtc, false); > > unpin: > if (radeon_crtc->cursor_bo) { > - robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); > + struct radeon_bo *robj = gem_to_radeon_bo(radeon_crtc->cursor_bo); > ret = radeon_bo_reserve(robj, false); > if (likely(ret == 0)) { > radeon_bo_unpin(robj); > radeon_bo_unreserve(robj); > } > - drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); > + if (radeon_crtc->cursor_bo != obj) > + drm_gem_object_unreference_unlocked(radeon_crtc->cursor_bo); > } > > radeon_crtc->cursor_bo = obj; > return 0; > -fail: > - drm_gem_object_unreference_unlocked(obj); > +} > > - return ret; > +/** > + * radeon_cursor_reset - Re-set the current cursor, if any. > + * > + * @crtc: drm crtc > + * > + * If the CRTC passed in currently has a cursor assigned, this function > + * makes sure it's visible. > + */ > +void radeon_cursor_reset(struct drm_crtc *crtc) > +{ > + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); > + int ret; > + > + if (radeon_crtc->cursor_bo) { > + radeon_lock_cursor(crtc, true); > + > + radeon_cursor_move_locked(crtc, radeon_crtc->cursor_x, > + radeon_crtc->cursor_y); > + > + ret = radeon_set_cursor(crtc, radeon_crtc->cursor_bo, > + radeon_crtc->cursor_hot_x, > + radeon_crtc->cursor_hot_y); > + if (ret) > + DRM_ERROR("radeon_set_cursor returned %d, not showing " > + "cursor\n", ret); > + else > + radeon_show_cursor(crtc); > + > + radeon_lock_cursor(crtc, false); > + } > } > diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c > index cafb1cc..678b438 100644 > --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c > +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c > @@ -1054,6 +1054,7 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, > DRM_ERROR("Mode need scaling but only first crtc can do that.\n"); > } > } > + radeon_cursor_reset(crtc); > return 0; > } > > diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h > index de1b0d6..c793274 100644 > --- a/drivers/gpu/drm/radeon/radeon_mode.h > +++ b/drivers/gpu/drm/radeon/radeon_mode.h > @@ -815,6 +815,7 @@ extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc, > int32_t hot_y); > extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, > int x, int y); > +extern void radeon_cursor_reset(struct drm_crtc *crtc); > > extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, > unsigned int flags, > -- > 2.1.3 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel