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>

FWIW, I think we may need a similar fix for the crtc base addresses.
They are also limited to 27 bit offsets from the mc address specified
in DISPLAY[2]_BASE_ADDR.

> ---
> ?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..388be34 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) {
> + ? ? ? ? ? ? ? ? ? ? ? if (lpfn < bo->placement.lpfn)
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bo->placement.lpfn = lpfn;
> + ? ? ? ? ? ? ? } else
> + ? ? ? ? ? ? ? ? ? ? ? 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

Reply via email to