diff options
author | Dave Airlie <airlied@redhat.com> | 2010-02-05 06:41:54 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-02-05 06:40:16 +0300 |
commit | a17538f93c16f0e15e35dc31eedad87e2d9c5c26 (patch) | |
tree | b31c33bf5e9d20875ed6ca971734e4a408333b40 | |
parent | 624ab4f87e99f10ea3b45e76039c477fd4d7a7e6 (diff) | |
download | linux-a17538f93c16f0e15e35dc31eedad87e2d9c5c26.tar.xz |
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: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/radeon/rs400.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index eeeb0d6d7a44..287fcebfb4e6 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -223,15 +223,31 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) 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) { /* FIXME: HDP same place on rs400 ? */ r100_hdp_reset(rdev); /* FIXME: is this correct ? */ r420_pipes_init(rdev); - if (r300_mc_wait_for_idle(rdev)) { - printk(KERN_WARNING "Failed to wait MC idle while " - "programming pipes. Bad things might happen.\n"); + if (rs400_mc_wait_for_idle(rdev)) { + printk(KERN_WARNING "rs400: Failed to wait MC idle while " + "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); /* Wait for mc idle */ - if (r300_mc_wait_for_idle(rdev)) - dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); + if (rs400_mc_wait_for_idle(rdev)) + dev_warn(rdev->dev, "rs400: Wait MC idle timeout before updating MC.\n"); WREG32(R_000148_MC_FB_LOCATION, S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); |