drm/radeon/kms: fix some GART table entry bugs.
Dave Airlie [Mon, 29 Jun 2009 08:29:11 +0000 (18:29 +1000)]
1. rv370 can accept 40-bit addresses - also at 24-bit shift not 4 bits
2. rs480 table can be in 40-bit space. - 4 bit shift for top 8 bits
3. rs480 table entries can be in 40-bit space.

Signed-off-by: Dave Airlie <airlied@redhat.com>

drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/radeon_gart.c
drivers/gpu/drm/radeon/rs400.c

index c550932..1b23106 100644 (file)
@@ -110,7 +110,7 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
        if (i < 0 || i > rdev->gart.num_gpu_pages) {
                return -EINVAL;
        }
-       rdev->gart.table.ram.ptr[i] = cpu_to_le32((uint32_t)addr);
+       rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr));
        return 0;
 }
 
index e2ed5bc..cd9ea98 100644 (file)
@@ -150,7 +150,9 @@ int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
        if (i < 0 || i > rdev->gart.num_gpu_pages) {
                return -EINVAL;
        }
-       addr = (((u32)addr) >> 8) | ((upper_32_bits(addr) & 0xff) << 4) | 0xC;
+       addr = (lower_32_bits(addr) >> 8) |
+              ((upper_32_bits(addr) & 0xff) << 24) |
+              0xc;
        writel(cpu_to_le32(addr), ((void __iomem *)ptr) + (i * 4));
        return 0;
 }
index d343a15..2977539 100644 (file)
@@ -177,7 +177,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
                        return -ENOMEM;
                }
                rdev->gart.pages[p] = pagelist[i];
-               page_base = (uint32_t)rdev->gart.pages_addr[p];
+               page_base = rdev->gart.pages_addr[p];
                for (j = 0; j < (PAGE_SIZE / 4096); j++, t++) {
                        radeon_gart_set_page(rdev, t, page_base);
                        page_base += 4096;
index cc074b5..3275de4 100644 (file)
@@ -164,7 +164,9 @@ int rs400_gart_enable(struct radeon_device *rdev)
                WREG32(RADEON_BUS_CNTL, tmp);
        }
        /* Table should be in 32bits address space so ignore bits above. */
-       tmp = rdev->gart.table_addr & 0xfffff000;
+       tmp = (u32)rdev->gart.table_addr & 0xfffff000;
+       tmp |= (upper_32_bits(rdev->gart.table_addr) & 0xff) << 4;
+
        WREG32_MC(RS480_GART_BASE, tmp);
        /* TODO: more tweaking here */
        WREG32_MC(RS480_GART_FEATURE_ID,
@@ -201,10 +203,17 @@ void rs400_gart_disable(struct radeon_device *rdev)
 
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 {
+       uint32_t entry;
+
        if (i < 0 || i > rdev->gart.num_gpu_pages) {
                return -EINVAL;
        }
-       rdev->gart.table.ram.ptr[i] = cpu_to_le32(((uint32_t)addr) | 0xC);
+
+       entry = (lower_32_bits(addr) & PAGE_MASK) |
+               ((upper_32_bits(addr) & 0xff) << 4) |
+               0xc;
+       entry = cpu_to_le32(entry);
+       rdev->gart.table.ram.ptr[i] = entry;
        return 0;
 }