2012/3/14 Michel D?nzer <michel at daenzer.net>: > From: Michel D?nzer <michel.daenzer at amd.com> > > The hardware only takes 27 bits for the offset, so larger offsets are > truncated, and the hardware cursor shows random bits other than the intended > ones. > > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=46796 > > Cc: stable at vger.kernel.org > Signed-off-by: Michel D?nzer <michel.daenzer at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com> > --- > > v2: Make sure bo->placement.lpfn isn't larger than the memory size, even if > ? ?radeon_bo_pin_restricted were to be called for the GTT domain. > > ?drivers/gpu/drm/radeon/radeon_cursor.c | ? 13 +++++++++++-- > ?drivers/gpu/drm/radeon/radeon_object.c | ? 18 +++++++++++++++++- > ?drivers/gpu/drm/radeon/radeon_object.h | ? ?2 ++ > ?3 files changed, 30 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c > b/drivers/gpu/drm/radeon/radeon_cursor.c > index fde25c0..986d608 100644 > --- a/drivers/gpu/drm/radeon/radeon_cursor.c > +++ b/drivers/gpu/drm/radeon/radeon_cursor.c > @@ -151,7 +151,9 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, > ? ? ? ? ? ? ? ? ? ? ? ? ? uint32_t height) > ?{ > ? ? ? ?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; > > @@ -173,7 +175,15 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, > ? ? ? ? ? ? ? ?return -ENOENT; > ? ? ? ?} > > - ? ? ? ret = radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &gpu_addr); > + ? ? ? 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; > > @@ -181,7 +191,6 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, > ? ? ? ?radeon_crtc->cursor_height = height; > > ? ? ? ?radeon_lock_cursor(crtc, true); > - ? ? ? /* XXX only 27 bit offset for legacy cursor */ > ? ? ? ?radeon_set_cursor(crtc, obj, gpu_addr); > ? ? ? ?radeon_show_cursor(crtc); > ? ? ? ?radeon_lock_cursor(crtc, false); > diff --git a/drivers/gpu/drm/radeon/radeon_object.c > b/drivers/gpu/drm/radeon/radeon_object.c > index d45df17..fd2dc0e 100644 > --- a/drivers/gpu/drm/radeon/radeon_object.c > +++ b/drivers/gpu/drm/radeon/radeon_object.c > @@ -224,7 +224,8 @@ void radeon_bo_unref(struct radeon_bo **bo) > ? ? ? ? ? ? ? ?*bo = NULL; > ?} > > -int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) > +int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 > max_offset, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?u64 *gpu_addr) > ?{ > ? ? ? ?int r, i; > > @@ -232,6 +233,7 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 > *gpu_addr) > ? ? ? ? ? ? ? ?bo->pin_count++; > ? ? ? ? ? ? ? ?if (gpu_addr) > ? ? ? ? ? ? ? ? ? ? ? ?*gpu_addr = radeon_bo_gpu_offset(bo); > + ? ? ? ? ? ? ? WARN_ON_ONCE(max_offset != 0); > ? ? ? ? ? ? ? ?return 0; > ? ? ? ?} > ? ? ? ?radeon_ttm_placement_from_domain(bo, domain); > @@ -239,6 +241,15 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 > *gpu_addr) > ? ? ? ? ? ? ? ?/* force to pin into visible video ram */ > ? ? ? ? ? ? ? ?bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> > PAGE_SHIFT; > ? ? ? ?} > + ? ? ? if (max_offset) { > + ? ? ? ? ? ? ? u64 lpfn = max_offset >> PAGE_SHIFT; > + > + ? ? ? ? ? ? ? if (!bo->placement.lpfn) > + ? ? ? ? ? ? ? ? ? ? ? bo->placement.lpfn = bo->rdev->mc.gtt_size >> > PAGE_SHIFT; > + > + ? ? ? ? ? ? ? if (lpfn < bo->placement.lpfn) > + ? ? ? ? ? ? ? ? ? ? ? bo->placement.lpfn = lpfn; > + ? ? ? } > ? ? ? ?for (i = 0; i < bo->placement.num_placement; i++) > ? ? ? ? ? ? ? ?bo->placements[i] |= TTM_PL_FLAG_NO_EVICT; > ? ? ? ?r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false, false); > @@ -252,6 +263,11 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 > *gpu_addr) > ? ? ? ?return r; > ?} > > +int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr) > +{ > + ? ? ? return radeon_bo_pin_restricted(bo, domain, 0, gpu_addr); > +} > + > ?int radeon_bo_unpin(struct radeon_bo *bo) > ?{ > ? ? ? ?int r, i; > diff --git a/drivers/gpu/drm/radeon/radeon_object.h > b/drivers/gpu/drm/radeon/radeon_object.h > index cde4303..f9104be 100644 > --- a/drivers/gpu/drm/radeon/radeon_object.h > +++ b/drivers/gpu/drm/radeon/radeon_object.h > @@ -118,6 +118,8 @@ extern int radeon_bo_kmap(struct radeon_bo *bo, void > **ptr); > ?extern void radeon_bo_kunmap(struct radeon_bo *bo); > ?extern void radeon_bo_unref(struct radeon_bo **bo); > ?extern int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr); > +extern int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? u64 max_offset, u64 *gpu_addr); > ?extern int radeon_bo_unpin(struct radeon_bo *bo); > ?extern int radeon_bo_evict_vram(struct radeon_device *rdev); > ?extern void radeon_bo_force_delete(struct radeon_device *rdev); > -- > 1.7.9.1 > > _______________________________________________ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel