drm/radeon/kms: fix gtt MC base alignment on rs4xx/rs690/rs740 asics
authorAlex Deucher <alexdeucher@gmail.com>
Thu, 15 Jul 2010 14:51:10 +0000 (10:51 -0400)
committerDave Airlie <airlied@redhat.com>
Fri, 16 Jul 2010 01:27:01 +0000 (11:27 +1000)
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: Torsten Kaiser <just.for.lkml@googlemail.com>
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c

index 3970e62eaab8f75582e0838e5770a7346731bff6..aab5ba040bd6a1fbdf92a8dafe1b9078bc1f65fa 100644 (file)
@@ -2354,6 +2354,7 @@ void r100_mc_init(struct radeon_device *rdev)
        if (rdev->flags & RADEON_IS_IGP)
                base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
        radeon_vram_location(rdev, &rdev->mc, base);
+       rdev->mc.gtt_base_align = 0;
        if (!(rdev->flags & RADEON_IS_AGP))
                radeon_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
index 7e81db5eb8041b1c66afe1ade046724abf235805..0a1638c1ba79eed429a35cdbbbb353466f2e799b 100644 (file)
@@ -481,6 +481,7 @@ void r300_mc_init(struct radeon_device *rdev)
        if (rdev->flags & RADEON_IS_IGP)
                base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
        radeon_vram_location(rdev, &rdev->mc, base);
+       rdev->mc.gtt_base_align = 0;
        if (!(rdev->flags & RADEON_IS_AGP))
                radeon_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
index 34330df2848329c178a9f2a659d44b0596b0bbaf..694af7cc23ac1b3ce91b8abb71ca1d3fdbb58ae2 100644 (file)
@@ -125,6 +125,7 @@ void r520_mc_init(struct radeon_device *rdev)
        r520_vram_get_type(rdev);
        r100_vram_init_sizes(rdev);
        radeon_vram_location(rdev, &rdev->mc, 0);
+       rdev->mc.gtt_base_align = 0;
        if (!(rdev->flags & RADEON_IS_AGP))
                radeon_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
index 3d6645ce21518a640dd0981e38a67e223e86a49e..e100f69faeec80a0c447ee186774a14ea95620c4 100644 (file)
@@ -1179,6 +1179,7 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
                if (rdev->flags & RADEON_IS_IGP)
                        base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
                radeon_vram_location(rdev, &rdev->mc, base);
+               rdev->mc.gtt_base_align = 0;
                radeon_gtt_location(rdev, mc);
        }
 }
index ab61aaa887bb449c486b59abccb89772b021f35a..2f94dc66c1836f4bf5d6814bb51b5730a13945ad 100644 (file)
@@ -351,6 +351,7 @@ struct radeon_mc {
        int                     vram_mtrr;
        bool                    vram_is_ddr;
        bool                    igp_sideport_enabled;
+       u64                     gtt_base_align;
 };
 
 bool radeon_combios_sideport_present(struct radeon_device *rdev);
index 5f317317aba29dc972331f32994c0acae66e9840..dd279da90546ee03929b02b8bd7095683ef31caf 100644 (file)
@@ -226,20 +226,20 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
 {
        u64 size_af, size_bf;
 
-       size_af = 0xFFFFFFFF - mc->vram_end;
-       size_bf = mc->vram_start;
+       size_af = ((0xFFFFFFFF - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align;
+       size_bf = mc->vram_start & ~mc->gtt_base_align;
        if (size_bf > size_af) {
                if (mc->gtt_size > size_bf) {
                        dev_warn(rdev->dev, "limiting GTT\n");
                        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 {
                if (mc->gtt_size > size_af) {
                        dev_warn(rdev->dev, "limiting GTT\n");
                        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;
        dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n",
index 9e4240b3bf0bb1ff950b4c74a8e003fc51903e2b..f454c9a5e7f22269a9ffe0618d87f1a74e05f276 100644 (file)
@@ -57,7 +57,9 @@ void rs400_gart_adjust_size(struct radeon_device *rdev)
        }
        if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
                /* 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;
                DRM_ERROR("Forcing to 32M GART size (because of ASIC bug ?)\n");
        }
@@ -263,6 +265,7 @@ void rs400_mc_init(struct radeon_device *rdev)
        r100_vram_init_sizes(rdev);
        base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
        radeon_vram_location(rdev, &rdev->mc, base);
+       rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1;
        radeon_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
 }
index 7bb4c3e52f3b055ceafc27471e516477e4a3fa5b..6dc15ea8ba33ce088f273b17eea0f1fc42e537df 100644 (file)
@@ -698,6 +698,7 @@ void rs600_mc_init(struct radeon_device *rdev)
        base = G_000004_MC_FB_START(base) << 16;
        rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        radeon_vram_location(rdev, &rdev->mc, base);
+       rdev->mc.gtt_base_align = 0;
        radeon_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
 }
index f4f0a61bcdce3d188dd01a5737120c4e9a0d6432..ce4ecbe108163126c74fb14779eaf90dcf15ce41 100644 (file)
@@ -162,6 +162,7 @@ void rs690_mc_init(struct radeon_device *rdev)
        rs690_pm_info(rdev);
        rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
        radeon_vram_location(rdev, &rdev->mc, base);
+       rdev->mc.gtt_base_align = rdev->mc.gtt_size - 1;
        radeon_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);
 }
index 7d9a7b0a180ac7b735702221450e2a9e12be92fe..0c9c169a6852f453c6703901cd64dc2fb84699e9 100644 (file)
@@ -195,6 +195,7 @@ void rv515_mc_init(struct radeon_device *rdev)
        rv515_vram_get_type(rdev);
        r100_vram_init_sizes(rdev);
        radeon_vram_location(rdev, &rdev->mc, 0);
+       rdev->mc.gtt_base_align = 0;
        if (!(rdev->flags & RADEON_IS_AGP))
                radeon_gtt_location(rdev, &rdev->mc);
        radeon_update_bandwidth_info(rdev);