Commit 8d369bb1 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms: fix gtt MC base alignment on rs4xx/rs690/rs740 asics

The asics in question have the following requirements with regard to
their gart setups:

1. The GART aperture size has to be in the form of 2^X bytes, where X is from 25 to 31
2. The GART aperture MC base has to be aligned to a boundary equal to the size of the
aperture.
3. The GART page table has to be aligned to the boundary equal to the size of the table.
4. The GART page table size is: table_entry_size * (aperture_size / page_size)
5. The GART page table has to be allocated in non-paged, non-cached, contiguous system
memory.

This patch takes care 2.  The rest should already be handled properly.

This fixes a regression noticed by: Torsten Kaiser <just.for.lkml@googlemail.com>
Tested-by: default avatarTorsten Kaiser <just.for.lkml@googlemail.com>
Signed-off-by: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 5099fa7f
...@@ -2354,6 +2354,7 @@ void r100_mc_init(struct radeon_device *rdev) ...@@ -2354,6 +2354,7 @@ void r100_mc_init(struct radeon_device *rdev)
if (rdev->flags & RADEON_IS_IGP) if (rdev->flags & RADEON_IS_IGP)
base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
radeon_vram_location(rdev, &rdev->mc, base); radeon_vram_location(rdev, &rdev->mc, base);
rdev->mc.gtt_base_align = 0;
if (!(rdev->flags & RADEON_IS_AGP)) if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev); radeon_update_bandwidth_info(rdev);
......
...@@ -481,6 +481,7 @@ void r300_mc_init(struct radeon_device *rdev) ...@@ -481,6 +481,7 @@ void r300_mc_init(struct radeon_device *rdev)
if (rdev->flags & RADEON_IS_IGP) if (rdev->flags & RADEON_IS_IGP)
base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
radeon_vram_location(rdev, &rdev->mc, base); radeon_vram_location(rdev, &rdev->mc, base);
rdev->mc.gtt_base_align = 0;
if (!(rdev->flags & RADEON_IS_AGP)) if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev); radeon_update_bandwidth_info(rdev);
......
...@@ -125,6 +125,7 @@ void r520_mc_init(struct radeon_device *rdev) ...@@ -125,6 +125,7 @@ void r520_mc_init(struct radeon_device *rdev)
r520_vram_get_type(rdev); r520_vram_get_type(rdev);
r100_vram_init_sizes(rdev); r100_vram_init_sizes(rdev);
radeon_vram_location(rdev, &rdev->mc, 0); radeon_vram_location(rdev, &rdev->mc, 0);
rdev->mc.gtt_base_align = 0;
if (!(rdev->flags & RADEON_IS_AGP)) if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev); radeon_update_bandwidth_info(rdev);
......
...@@ -1179,6 +1179,7 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) ...@@ -1179,6 +1179,7 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
if (rdev->flags & RADEON_IS_IGP) if (rdev->flags & RADEON_IS_IGP)
base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
radeon_vram_location(rdev, &rdev->mc, base); radeon_vram_location(rdev, &rdev->mc, base);
rdev->mc.gtt_base_align = 0;
radeon_gtt_location(rdev, mc); radeon_gtt_location(rdev, mc);
} }
} }
......
...@@ -351,6 +351,7 @@ struct radeon_mc { ...@@ -351,6 +351,7 @@ struct radeon_mc {
int vram_mtrr; int vram_mtrr;
bool vram_is_ddr; bool vram_is_ddr;
bool igp_sideport_enabled; bool igp_sideport_enabled;
u64 gtt_base_align;
}; };
bool radeon_combios_sideport_present(struct radeon_device *rdev); bool radeon_combios_sideport_present(struct radeon_device *rdev);
......
...@@ -226,20 +226,20 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) ...@@ -226,20 +226,20 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
{ {
u64 size_af, size_bf; u64 size_af, size_bf;
size_af = 0xFFFFFFFF - mc->vram_end; size_af = ((0xFFFFFFFF - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align;
size_bf = mc->vram_start; size_bf = mc->vram_start & ~mc->gtt_base_align;
if (size_bf > size_af) { if (size_bf > size_af) {
if (mc->gtt_size > size_bf) { if (mc->gtt_size > size_bf) {
dev_warn(rdev->dev, "limiting GTT\n"); dev_warn(rdev->dev, "limiting GTT\n");
mc->gtt_size = size_bf; mc->gtt_size = size_bf;
} }
mc->gtt_start = mc->vram_start - mc->gtt_size; mc->gtt_start = (mc->vram_start & ~mc->gtt_base_align) - mc->gtt_size;
} else { } else {
if (mc->gtt_size > size_af) { if (mc->gtt_size > size_af) {
dev_warn(rdev->dev, "limiting GTT\n"); dev_warn(rdev->dev, "limiting GTT\n");
mc->gtt_size = size_af; mc->gtt_size = size_af;
} }
mc->gtt_start = mc->vram_end + 1; mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align;
} }
mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n", dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n",
......
...@@ -57,7 +57,9 @@ void rs400_gart_adjust_size(struct radeon_device *rdev) ...@@ -57,7 +57,9 @@ void rs400_gart_adjust_size(struct radeon_device *rdev)
} }
if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) { if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
/* FIXME: RS400 & RS480 seems to have issue with GART size /* FIXME: RS400 & RS480 seems to have issue with GART size
* if 4G of system memory (needs more testing) */ * if 4G of system memory (needs more testing)
*/
/* XXX is this still an issue with proper alignment? */
rdev->mc.gtt_size = 32 * 1024 * 1024; rdev->mc.gtt_size = 32 * 1024 * 1024;
DRM_ERROR("Forcing to 32M GART size (because of ASIC bug ?)\n"); DRM_ERROR("Forcing to 32M GART size (because of ASIC bug ?)\n");
} }
...@@ -263,6 +265,7 @@ void rs400_mc_init(struct radeon_device *rdev) ...@@ -263,6 +265,7 @@ void rs400_mc_init(struct radeon_device *rdev)
r100_vram_init_sizes(rdev); r100_vram_init_sizes(rdev);
base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
radeon_vram_location(rdev, &rdev->mc, base); radeon_vram_location(rdev, &rdev->mc, base);
rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1;
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev); radeon_update_bandwidth_info(rdev);
} }
......
...@@ -698,6 +698,7 @@ void rs600_mc_init(struct radeon_device *rdev) ...@@ -698,6 +698,7 @@ void rs600_mc_init(struct radeon_device *rdev)
base = G_000004_MC_FB_START(base) << 16; base = G_000004_MC_FB_START(base) << 16;
rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
radeon_vram_location(rdev, &rdev->mc, base); radeon_vram_location(rdev, &rdev->mc, base);
rdev->mc.gtt_base_align = 0;
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev); radeon_update_bandwidth_info(rdev);
} }
......
...@@ -162,6 +162,7 @@ void rs690_mc_init(struct radeon_device *rdev) ...@@ -162,6 +162,7 @@ void rs690_mc_init(struct radeon_device *rdev)
rs690_pm_info(rdev); rs690_pm_info(rdev);
rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
radeon_vram_location(rdev, &rdev->mc, base); radeon_vram_location(rdev, &rdev->mc, base);
rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1;
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev); radeon_update_bandwidth_info(rdev);
} }
......
...@@ -195,6 +195,7 @@ void rv515_mc_init(struct radeon_device *rdev) ...@@ -195,6 +195,7 @@ void rv515_mc_init(struct radeon_device *rdev)
rv515_vram_get_type(rdev); rv515_vram_get_type(rdev);
r100_vram_init_sizes(rdev); r100_vram_init_sizes(rdev);
radeon_vram_location(rdev, &rdev->mc, 0); radeon_vram_location(rdev, &rdev->mc, 0);
rdev->mc.gtt_base_align = 0;
if (!(rdev->flags & RADEON_IS_AGP)) if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev); radeon_update_bandwidth_info(rdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment