From 35cd5b7110b7f0c9bd6f9497cddd68d506cf19f5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 7 Sep 2010 11:29:52 -0400 Subject: [PATCH] drm/radeon/kms: always align mc vram/gtt base to size This is a requirement on at least some asics, so might was well apply to all. May fix lockups reported in bugs like: https://bugs.freedesktop.org/show_bug.cgi?id=28402 Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/r100.c | 3 ++- drivers/gpu/drm/radeon/r300.c | 3 ++- drivers/gpu/drm/radeon/r520.c | 3 ++- drivers/gpu/drm/radeon/r600.c | 11 ++++++++--- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_device.c | 6 ++++-- drivers/gpu/drm/radeon/rs400.c | 1 + drivers/gpu/drm/radeon/rs600.c | 3 ++- drivers/gpu/drm/radeon/rs690.c | 1 + drivers/gpu/drm/radeon/rv515.c | 3 ++- 10 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index ab062f0..782fd6d 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2308,8 +2308,9 @@ void r100_mc_init(struct radeon_device *rdev) base = rdev->mc.aper_base; if (rdev->flags & RADEON_IS_IGP) base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = 0; + rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; if (!(rdev->flags & RADEON_IS_AGP)) radeon_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 34527e6..a5e6fd0 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -480,8 +480,9 @@ void r300_mc_init(struct radeon_device *rdev) base = rdev->mc.aper_base; if (rdev->flags & RADEON_IS_IGP) base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = 0; + rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; if (!(rdev->flags & RADEON_IS_AGP)) radeon_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 3c8677f..fe042fd 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -124,8 +124,9 @@ void r520_mc_init(struct radeon_device *rdev) r520_vram_get_type(rdev); r100_vram_init_sizes(rdev); + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; radeon_vram_location(rdev, &rdev->mc, 0); - rdev->mc.gtt_base_align = 0; + rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; if (!(rdev->flags & RADEON_IS_AGP)) radeon_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 41ca173..30a51c3 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1186,14 +1186,18 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) mc->real_vram_size = size_bf; mc->mc_vram_size = size_bf; } - mc->vram_start = mc->gtt_start - mc->mc_vram_size; + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; + mc->vram_start = (mc->gtt_start - mc->mc_vram_size + rdev->mc.vram_base_align) & + ~rdev->mc.vram_base_align; } else { if (mc->mc_vram_size > size_af) { dev_warn(rdev->dev, "limiting VRAM\n"); mc->real_vram_size = size_af; mc->mc_vram_size = size_af; } - mc->vram_start = mc->gtt_end; + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; + mc->vram_start = (mc->gtt_end + rdev->mc.vram_base_align) & + ~rdev->mc.vram_base_align; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", @@ -1203,8 +1207,9 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) u64 base = 0; if (rdev->flags & RADEON_IS_IGP) base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = 0; + rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; radeon_gtt_location(rdev, mc); } } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 2bfae56..ed2ed12 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -355,6 +355,7 @@ struct radeon_mc { bool vram_is_ddr; bool igp_sideport_enabled; u64 gtt_base_align; + u64 vram_base_align; }; bool radeon_combios_sideport_present(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 8adfedf..f9e3bd6 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -273,8 +273,10 @@ int radeon_wb_init(struct radeon_device *rdev) */ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) { - mc->vram_start = base; - if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { + u64 vram_base = (base + mc->vram_base_align) & ~mc->vram_base_align; + + mc->vram_start = vram_base; + if (mc->mc_vram_size > (0xFFFFFFFF - vram_base + 1)) { dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); mc->real_vram_size = mc->aper_size; mc->mc_vram_size = mc->aper_size; diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index f683e51..a1bf1bd 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -256,6 +256,7 @@ void rs400_mc_init(struct radeon_device *rdev) rdev->mc.vram_width = 128; r100_vram_init_sizes(rdev); base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; radeon_vram_location(rdev, &rdev->mc, base); rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; radeon_gtt_location(rdev, &rdev->mc); diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 8d8359a..b24ed50 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -696,8 +696,9 @@ void rs600_mc_init(struct radeon_device *rdev) rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); base = RREG32_MC(R_000004_MC_FB_LOCATION); base = G_000004_MC_FB_START(base) << 16; + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; radeon_vram_location(rdev, &rdev->mc, base); - rdev->mc.gtt_base_align = 0; + rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; radeon_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); } diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 70ed66e..f020e90 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -161,6 +161,7 @@ void rs690_mc_init(struct radeon_device *rdev) base = G_000100_MC_FB_START(base) << 16; rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); rs690_pm_info(rdev); + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; radeon_vram_location(rdev, &rdev->mc, base); rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; radeon_gtt_location(rdev, &rdev->mc); diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 5d569f4..8631f2b 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -194,8 +194,9 @@ void rv515_mc_init(struct radeon_device *rdev) rv515_vram_get_type(rdev); r100_vram_init_sizes(rdev); + rdev->mc.vram_base_align = rdev->mc.mc_vram_size - 1; radeon_vram_location(rdev, &rdev->mc, 0); - rdev->mc.gtt_base_align = 0; + rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1; if (!(rdev->flags & RADEON_IS_AGP)) radeon_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); -- 1.7.1.1