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

Commit a17538f9 authored by Dave Airlie's avatar Dave Airlie
Browse files

drm/radeon/kms: rs400/480 MC setup is different than r300.



Boot testing on my rs480 laptop found the MC idle never happened
on startup, a quick check with AMD found the idle bit is in a different
place on the rs4xx than r300.

Implement a new rs400 mc idle function to fix this.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 624ab4f8
Loading
Loading
Loading
Loading
+21 −5
Original line number Original line Diff line number Diff line
@@ -223,15 +223,31 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
	return 0;
	return 0;
}
}


int rs400_mc_wait_for_idle(struct radeon_device *rdev)
{
	unsigned i;
	uint32_t tmp;

	for (i = 0; i < rdev->usec_timeout; i++) {
		/* read MC_STATUS */
		tmp = RREG32(0x0150);
		if (tmp & (1 << 2)) {
			return 0;
		}
		DRM_UDELAY(1);
	}
	return -1;
}

void rs400_gpu_init(struct radeon_device *rdev)
void rs400_gpu_init(struct radeon_device *rdev)
{
{
	/* FIXME: HDP same place on rs400 ? */
	/* FIXME: HDP same place on rs400 ? */
	r100_hdp_reset(rdev);
	r100_hdp_reset(rdev);
	/* FIXME: is this correct ? */
	/* FIXME: is this correct ? */
	r420_pipes_init(rdev);
	r420_pipes_init(rdev);
	if (r300_mc_wait_for_idle(rdev)) {
	if (rs400_mc_wait_for_idle(rdev)) {
		printk(KERN_WARNING "Failed to wait MC idle while "
		printk(KERN_WARNING "rs400: Failed to wait MC idle while "
		       "programming pipes. Bad things might happen.\n");
		       "programming pipes. Bad things might happen. %08x\n", RREG32(0x150));
	}
	}
}
}


@@ -370,8 +386,8 @@ void rs400_mc_program(struct radeon_device *rdev)
	r100_mc_stop(rdev, &save);
	r100_mc_stop(rdev, &save);


	/* Wait for mc idle */
	/* Wait for mc idle */
	if (r300_mc_wait_for_idle(rdev))
	if (rs400_mc_wait_for_idle(rdev))
		dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
		dev_warn(rdev->dev, "rs400: Wait MC idle timeout before updating MC.\n");
	WREG32(R_000148_MC_FB_LOCATION,
	WREG32(R_000148_MC_FB_LOCATION,
		S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
		S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
		S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
		S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));