Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87cbf8f2 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms: fix a regression on r7xx AGP due to the HDP flush fix

commit: 812d0469
drm/radeon/kms/r7xx: add workaround for hw issue with HDP flush
breaks on AGP boards since there is no VRAM gart table.

This patch fixes the issue by creating a VRAM scratch page so that
can be used on both AGP and PCIE.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=29834



Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 8807286e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3541,7 +3541,7 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
	 * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
	 */
	if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
		void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
		void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
		u32 tmp;

		WREG32(HDP_DEBUG1, 0);
+6 −0
Original line number Diff line number Diff line
@@ -1013,6 +1013,11 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
				struct drm_file *filp);

/* VRAM scratch page for HDP bug */
struct r700_vram_scratch {
	struct radeon_bo		*robj;
	volatile uint32_t		*ptr;
};

/*
 * Core structure, functions and helpers.
@@ -1079,6 +1084,7 @@ struct radeon_device {
	const struct firmware *pfp_fw;	/* r6/700 PFP firmware */
	const struct firmware *rlc_fw;	/* r6/700 RLC firmware */
	struct r600_blit r600_blit;
	struct r700_vram_scratch vram_scratch;
	int msi_enabled; /* msi enabled */
	struct r600_ih ih; /* r6/700 interrupt ring */
	struct workqueue_struct *wq;
+52 −0
Original line number Diff line number Diff line
@@ -905,6 +905,54 @@ static void rv770_gpu_init(struct radeon_device *rdev)

}

static int rv770_vram_scratch_init(struct radeon_device *rdev)
{
	int r;
	u64 gpu_addr;

	if (rdev->vram_scratch.robj == NULL) {
		r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
					true, RADEON_GEM_DOMAIN_VRAM,
					&rdev->vram_scratch.robj);
		if (r) {
			return r;
		}
	}

	r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
	if (unlikely(r != 0))
		return r;
	r = radeon_bo_pin(rdev->vram_scratch.robj,
			  RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
	if (r) {
		radeon_bo_unreserve(rdev->vram_scratch.robj);
		return r;
	}
	r = radeon_bo_kmap(rdev->vram_scratch.robj,
				(void **)&rdev->vram_scratch.ptr);
	if (r)
		radeon_bo_unpin(rdev->vram_scratch.robj);
	radeon_bo_unreserve(rdev->vram_scratch.robj);

	return r;
}

static void rv770_vram_scratch_fini(struct radeon_device *rdev)
{
	int r;

	if (rdev->vram_scratch.robj == NULL) {
		return;
	}
	r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
	if (likely(r == 0)) {
		radeon_bo_kunmap(rdev->vram_scratch.robj);
		radeon_bo_unpin(rdev->vram_scratch.robj);
		radeon_bo_unreserve(rdev->vram_scratch.robj);
	}
	radeon_bo_unref(&rdev->vram_scratch.robj);
}

int rv770_mc_init(struct radeon_device *rdev)
{
	u32 tmp;
@@ -970,6 +1018,9 @@ static int rv770_startup(struct radeon_device *rdev)
		if (r)
			return r;
	}
	r = rv770_vram_scratch_init(rdev);
	if (r)
		return r;
	rv770_gpu_init(rdev);
	r = r600_blit_init(rdev);
	if (r) {
@@ -1195,6 +1246,7 @@ void rv770_fini(struct radeon_device *rdev)
	r600_irq_fini(rdev);
	radeon_irq_kms_fini(rdev);
	rv770_pcie_gart_fini(rdev);
	rv770_vram_scratch_fini(rdev);
	radeon_gem_fini(rdev);
	radeon_fence_driver_fini(rdev);
	radeon_clocks_fini(rdev);