| From cb65890610dca287718a63bd8a5d9ce3dc80c3d7 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com> |
| Date: Wed, 21 Jan 2015 17:36:35 +0900 |
| Subject: drm/radeon: Split off gart_get_page_entry ASIC hook from set_page_entry |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com> |
| |
| commit cb65890610dca287718a63bd8a5d9ce3dc80c3d7 upstream. |
| |
| get_page_entry calculates the GART page table entry, which is just written |
| to the GART page table by set_page_entry. |
| |
| This is a prerequisite for the following fix. |
| |
| Reviewed-by: Christian König <christian.koenig@amd.com> |
| Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> |
| Signed-off-by: Alex Deucher <alexander.deucher@amd.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/radeon/r100.c | 10 +++++++- |
| drivers/gpu/drm/radeon/r300.c | 16 +++++++++----- |
| drivers/gpu/drm/radeon/radeon.h | 8 +++++-- |
| drivers/gpu/drm/radeon/radeon_asic.c | 24 +++++++++++++++++++++ |
| drivers/gpu/drm/radeon/radeon_asic.h | 12 +++++++--- |
| drivers/gpu/drm/radeon/radeon_device.c | 2 + |
| drivers/gpu/drm/radeon/radeon_gart.c | 37 ++++++++++++++++++++------------- |
| drivers/gpu/drm/radeon/rs400.c | 14 ++++++++---- |
| drivers/gpu/drm/radeon/rs600.c | 14 ++++++++---- |
| 9 files changed, 100 insertions(+), 37 deletions(-) |
| |
| --- a/drivers/gpu/drm/radeon/r100.c |
| +++ b/drivers/gpu/drm/radeon/r100.c |
| @@ -644,6 +644,7 @@ int r100_pci_gart_init(struct radeon_dev |
| return r; |
| rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
| rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; |
| + rdev->asic->gart.get_page_entry = &r100_pci_gart_get_page_entry; |
| rdev->asic->gart.set_page = &r100_pci_gart_set_page; |
| return radeon_gart_table_ram_alloc(rdev); |
| } |
| @@ -681,11 +682,16 @@ void r100_pci_gart_disable(struct radeon |
| WREG32(RADEON_AIC_HI_ADDR, 0); |
| } |
| |
| +uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags) |
| +{ |
| + return addr; |
| +} |
| + |
| void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i, |
| - uint64_t addr, uint32_t flags) |
| + uint64_t entry) |
| { |
| u32 *gtt = rdev->gart.ptr; |
| - gtt[i] = cpu_to_le32(lower_32_bits(addr)); |
| + gtt[i] = cpu_to_le32(lower_32_bits(entry)); |
| } |
| |
| void r100_pci_gart_fini(struct radeon_device *rdev) |
| --- a/drivers/gpu/drm/radeon/r300.c |
| +++ b/drivers/gpu/drm/radeon/r300.c |
| @@ -73,11 +73,8 @@ void rv370_pcie_gart_tlb_flush(struct ra |
| #define R300_PTE_WRITEABLE (1 << 2) |
| #define R300_PTE_READABLE (1 << 3) |
| |
| -void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, |
| - uint64_t addr, uint32_t flags) |
| +uint64_t rv370_pcie_gart_get_page_entry(uint64_t addr, uint32_t flags) |
| { |
| - void __iomem *ptr = rdev->gart.ptr; |
| - |
| addr = (lower_32_bits(addr) >> 8) | |
| ((upper_32_bits(addr) & 0xff) << 24); |
| if (flags & RADEON_GART_PAGE_READ) |
| @@ -86,10 +83,18 @@ void rv370_pcie_gart_set_page(struct rad |
| addr |= R300_PTE_WRITEABLE; |
| if (!(flags & RADEON_GART_PAGE_SNOOP)) |
| addr |= R300_PTE_UNSNOOPED; |
| + return addr; |
| +} |
| + |
| +void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, |
| + uint64_t entry) |
| +{ |
| + void __iomem *ptr = rdev->gart.ptr; |
| + |
| /* on x86 we want this to be CPU endian, on powerpc |
| * on powerpc without HW swappers, it'll get swapped on way |
| * into VRAM - so no need for cpu_to_le32 on VRAM tables */ |
| - writel(addr, ((void __iomem *)ptr) + (i * 4)); |
| + writel(entry, ((void __iomem *)ptr) + (i * 4)); |
| } |
| |
| int rv370_pcie_gart_init(struct radeon_device *rdev) |
| @@ -109,6 +114,7 @@ int rv370_pcie_gart_init(struct radeon_d |
| DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); |
| rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
| rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; |
| + rdev->asic->gart.get_page_entry = &rv370_pcie_gart_get_page_entry; |
| rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; |
| return radeon_gart_table_vram_alloc(rdev); |
| } |
| --- a/drivers/gpu/drm/radeon/radeon.h |
| +++ b/drivers/gpu/drm/radeon/radeon.h |
| @@ -245,6 +245,7 @@ bool radeon_get_bios(struct radeon_devic |
| * Dummy page |
| */ |
| struct radeon_dummy_page { |
| + uint64_t entry; |
| struct page *page; |
| dma_addr_t addr; |
| }; |
| @@ -626,6 +627,7 @@ struct radeon_gart { |
| unsigned table_size; |
| struct page **pages; |
| dma_addr_t *pages_addr; |
| + uint64_t *pages_entry; |
| bool ready; |
| }; |
| |
| @@ -1819,8 +1821,9 @@ struct radeon_asic { |
| /* gart */ |
| struct { |
| void (*tlb_flush)(struct radeon_device *rdev); |
| + uint64_t (*get_page_entry)(uint64_t addr, uint32_t flags); |
| void (*set_page)(struct radeon_device *rdev, unsigned i, |
| - uint64_t addr, uint32_t flags); |
| + uint64_t entry); |
| } gart; |
| struct { |
| int (*init)(struct radeon_device *rdev); |
| @@ -2818,7 +2821,8 @@ static inline void radeon_ring_write(str |
| #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) |
| #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) |
| #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) |
| -#define radeon_gart_set_page(rdev, i, p, f) (rdev)->asic->gart.set_page((rdev), (i), (p), (f)) |
| +#define radeon_gart_get_page_entry(a, f) (rdev)->asic->gart.get_page_entry((a), (f)) |
| +#define radeon_gart_set_page(rdev, i, e) (rdev)->asic->gart.set_page((rdev), (i), (e)) |
| #define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev)) |
| #define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev)) |
| #define radeon_asic_vm_copy_pages(rdev, ib, pe, src, count) ((rdev)->asic->vm.copy_pages((rdev), (ib), (pe), (src), (count))) |
| --- a/drivers/gpu/drm/radeon/radeon_asic.c |
| +++ b/drivers/gpu/drm/radeon/radeon_asic.c |
| @@ -159,11 +159,13 @@ void radeon_agp_disable(struct radeon_de |
| DRM_INFO("Forcing AGP to PCIE mode\n"); |
| rdev->flags |= RADEON_IS_PCIE; |
| rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; |
| + rdev->asic->gart.get_page_entry = &rv370_pcie_gart_get_page_entry; |
| rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; |
| } else { |
| DRM_INFO("Forcing AGP to PCI mode\n"); |
| rdev->flags |= RADEON_IS_PCI; |
| rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; |
| + rdev->asic->gart.get_page_entry = &r100_pci_gart_get_page_entry; |
| rdev->asic->gart.set_page = &r100_pci_gart_set_page; |
| } |
| rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
| @@ -199,6 +201,7 @@ static struct radeon_asic r100_asic = { |
| .mc_wait_for_idle = &r100_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &r100_pci_gart_tlb_flush, |
| + .get_page_entry = &r100_pci_gart_get_page_entry, |
| .set_page = &r100_pci_gart_set_page, |
| }, |
| .ring = { |
| @@ -265,6 +268,7 @@ static struct radeon_asic r200_asic = { |
| .mc_wait_for_idle = &r100_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &r100_pci_gart_tlb_flush, |
| + .get_page_entry = &r100_pci_gart_get_page_entry, |
| .set_page = &r100_pci_gart_set_page, |
| }, |
| .ring = { |
| @@ -359,6 +363,7 @@ static struct radeon_asic r300_asic = { |
| .mc_wait_for_idle = &r300_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &r100_pci_gart_tlb_flush, |
| + .get_page_entry = &r100_pci_gart_get_page_entry, |
| .set_page = &r100_pci_gart_set_page, |
| }, |
| .ring = { |
| @@ -425,6 +430,7 @@ static struct radeon_asic r300_asic_pcie |
| .mc_wait_for_idle = &r300_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &rv370_pcie_gart_tlb_flush, |
| + .get_page_entry = &rv370_pcie_gart_get_page_entry, |
| .set_page = &rv370_pcie_gart_set_page, |
| }, |
| .ring = { |
| @@ -491,6 +497,7 @@ static struct radeon_asic r420_asic = { |
| .mc_wait_for_idle = &r300_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &rv370_pcie_gart_tlb_flush, |
| + .get_page_entry = &rv370_pcie_gart_get_page_entry, |
| .set_page = &rv370_pcie_gart_set_page, |
| }, |
| .ring = { |
| @@ -557,6 +564,7 @@ static struct radeon_asic rs400_asic = { |
| .mc_wait_for_idle = &rs400_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &rs400_gart_tlb_flush, |
| + .get_page_entry = &rs400_gart_get_page_entry, |
| .set_page = &rs400_gart_set_page, |
| }, |
| .ring = { |
| @@ -623,6 +631,7 @@ static struct radeon_asic rs600_asic = { |
| .mc_wait_for_idle = &rs600_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &rs600_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .ring = { |
| @@ -691,6 +700,7 @@ static struct radeon_asic rs690_asic = { |
| .mc_wait_for_idle = &rs690_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &rs400_gart_tlb_flush, |
| + .get_page_entry = &rs400_gart_get_page_entry, |
| .set_page = &rs400_gart_set_page, |
| }, |
| .ring = { |
| @@ -759,6 +769,7 @@ static struct radeon_asic rv515_asic = { |
| .mc_wait_for_idle = &rv515_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &rv370_pcie_gart_tlb_flush, |
| + .get_page_entry = &rv370_pcie_gart_get_page_entry, |
| .set_page = &rv370_pcie_gart_set_page, |
| }, |
| .ring = { |
| @@ -825,6 +836,7 @@ static struct radeon_asic r520_asic = { |
| .mc_wait_for_idle = &r520_mc_wait_for_idle, |
| .gart = { |
| .tlb_flush = &rv370_pcie_gart_tlb_flush, |
| + .get_page_entry = &rv370_pcie_gart_get_page_entry, |
| .set_page = &rv370_pcie_gart_set_page, |
| }, |
| .ring = { |
| @@ -919,6 +931,7 @@ static struct radeon_asic r600_asic = { |
| .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &r600_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .ring = { |
| @@ -1004,6 +1017,7 @@ static struct radeon_asic rv6xx_asic = { |
| .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &r600_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .ring = { |
| @@ -1095,6 +1109,7 @@ static struct radeon_asic rs780_asic = { |
| .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &r600_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .ring = { |
| @@ -1199,6 +1214,7 @@ static struct radeon_asic rv770_asic = { |
| .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &r600_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .ring = { |
| @@ -1317,6 +1333,7 @@ static struct radeon_asic evergreen_asic |
| .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .ring = { |
| @@ -1409,6 +1426,7 @@ static struct radeon_asic sumo_asic = { |
| .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .ring = { |
| @@ -1500,6 +1518,7 @@ static struct radeon_asic btc_asic = { |
| .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .ring = { |
| @@ -1635,6 +1654,7 @@ static struct radeon_asic cayman_asic = |
| .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &cayman_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .vm = { |
| @@ -1738,6 +1758,7 @@ static struct radeon_asic trinity_asic = |
| .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &cayman_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .vm = { |
| @@ -1871,6 +1892,7 @@ static struct radeon_asic si_asic = { |
| .get_gpu_clock_counter = &si_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &si_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .vm = { |
| @@ -2032,6 +2054,7 @@ static struct radeon_asic ci_asic = { |
| .get_gpu_clock_counter = &cik_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &cik_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .vm = { |
| @@ -2139,6 +2162,7 @@ static struct radeon_asic kv_asic = { |
| .get_gpu_clock_counter = &cik_get_gpu_clock_counter, |
| .gart = { |
| .tlb_flush = &cik_pcie_gart_tlb_flush, |
| + .get_page_entry = &rs600_gart_get_page_entry, |
| .set_page = &rs600_gart_set_page, |
| }, |
| .vm = { |
| --- a/drivers/gpu/drm/radeon/radeon_asic.h |
| +++ b/drivers/gpu/drm/radeon/radeon_asic.h |
| @@ -67,8 +67,9 @@ bool r100_gpu_is_lockup(struct radeon_de |
| int r100_asic_reset(struct radeon_device *rdev); |
| u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); |
| void r100_pci_gart_tlb_flush(struct radeon_device *rdev); |
| +uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags); |
| void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i, |
| - uint64_t addr, uint32_t flags); |
| + uint64_t entry); |
| void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); |
| int r100_irq_set(struct radeon_device *rdev); |
| int r100_irq_process(struct radeon_device *rdev); |
| @@ -172,8 +173,9 @@ extern void r300_fence_ring_emit(struct |
| struct radeon_fence *fence); |
| extern int r300_cs_parse(struct radeon_cs_parser *p); |
| extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); |
| +extern uint64_t rv370_pcie_gart_get_page_entry(uint64_t addr, uint32_t flags); |
| extern void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, |
| - uint64_t addr, uint32_t flags); |
| + uint64_t entry); |
| extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); |
| extern int rv370_get_pcie_lanes(struct radeon_device *rdev); |
| extern void r300_set_reg_safe(struct radeon_device *rdev); |
| @@ -208,8 +210,9 @@ extern void rs400_fini(struct radeon_dev |
| extern int rs400_suspend(struct radeon_device *rdev); |
| extern int rs400_resume(struct radeon_device *rdev); |
| void rs400_gart_tlb_flush(struct radeon_device *rdev); |
| +uint64_t rs400_gart_get_page_entry(uint64_t addr, uint32_t flags); |
| void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, |
| - uint64_t addr, uint32_t flags); |
| + uint64_t entry); |
| uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| int rs400_gart_init(struct radeon_device *rdev); |
| @@ -232,8 +235,9 @@ int rs600_irq_process(struct radeon_devi |
| void rs600_irq_disable(struct radeon_device *rdev); |
| u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); |
| void rs600_gart_tlb_flush(struct radeon_device *rdev); |
| +uint64_t rs600_gart_get_page_entry(uint64_t addr, uint32_t flags); |
| void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, |
| - uint64_t addr, uint32_t flags); |
| + uint64_t entry); |
| uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| void rs600_bandwidth_update(struct radeon_device *rdev); |
| --- a/drivers/gpu/drm/radeon/radeon_device.c |
| +++ b/drivers/gpu/drm/radeon/radeon_device.c |
| @@ -743,6 +743,8 @@ int radeon_dummy_page_init(struct radeon |
| rdev->dummy_page.page = NULL; |
| return -ENOMEM; |
| } |
| + rdev->dummy_page.entry = radeon_gart_get_page_entry(rdev->dummy_page.addr, |
| + RADEON_GART_PAGE_DUMMY); |
| return 0; |
| } |
| |
| --- a/drivers/gpu/drm/radeon/radeon_gart.c |
| +++ b/drivers/gpu/drm/radeon/radeon_gart.c |
| @@ -228,7 +228,6 @@ void radeon_gart_unbind(struct radeon_de |
| unsigned t; |
| unsigned p; |
| int i, j; |
| - u64 page_base; |
| |
| if (!rdev->gart.ready) { |
| WARN(1, "trying to unbind memory from uninitialized GART !\n"); |
| @@ -240,13 +239,12 @@ void radeon_gart_unbind(struct radeon_de |
| if (rdev->gart.pages[p]) { |
| rdev->gart.pages[p] = NULL; |
| rdev->gart.pages_addr[p] = rdev->dummy_page.addr; |
| - page_base = rdev->gart.pages_addr[p]; |
| for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
| + rdev->gart.pages_entry[t] = rdev->dummy_page.entry; |
| if (rdev->gart.ptr) { |
| - radeon_gart_set_page(rdev, t, page_base, |
| - RADEON_GART_PAGE_DUMMY); |
| + radeon_gart_set_page(rdev, t, |
| + rdev->dummy_page.entry); |
| } |
| - page_base += RADEON_GPU_PAGE_SIZE; |
| } |
| } |
| } |
| @@ -274,7 +272,7 @@ int radeon_gart_bind(struct radeon_devic |
| { |
| unsigned t; |
| unsigned p; |
| - uint64_t page_base; |
| + uint64_t page_base, page_entry; |
| int i, j; |
| |
| if (!rdev->gart.ready) { |
| @@ -287,12 +285,14 @@ int radeon_gart_bind(struct radeon_devic |
| for (i = 0; i < pages; i++, p++) { |
| rdev->gart.pages_addr[p] = dma_addr[i]; |
| rdev->gart.pages[p] = pagelist[i]; |
| - if (rdev->gart.ptr) { |
| - page_base = rdev->gart.pages_addr[p]; |
| - for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
| - radeon_gart_set_page(rdev, t, page_base, flags); |
| - page_base += RADEON_GPU_PAGE_SIZE; |
| + page_base = dma_addr[i]; |
| + for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
| + page_entry = radeon_gart_get_page_entry(page_base, flags); |
| + rdev->gart.pages_entry[t] = page_entry; |
| + if (rdev->gart.ptr) { |
| + radeon_gart_set_page(rdev, t, page_entry); |
| } |
| + page_base += RADEON_GPU_PAGE_SIZE; |
| } |
| } |
| mb(); |
| @@ -340,10 +340,17 @@ int radeon_gart_init(struct radeon_devic |
| radeon_gart_fini(rdev); |
| return -ENOMEM; |
| } |
| + rdev->gart.pages_entry = vmalloc(sizeof(uint64_t) * |
| + rdev->gart.num_gpu_pages); |
| + if (rdev->gart.pages_entry == NULL) { |
| + radeon_gart_fini(rdev); |
| + return -ENOMEM; |
| + } |
| /* set GART entry to point to the dummy page by default */ |
| - for (i = 0; i < rdev->gart.num_cpu_pages; i++) { |
| + for (i = 0; i < rdev->gart.num_cpu_pages; i++) |
| rdev->gart.pages_addr[i] = rdev->dummy_page.addr; |
| - } |
| + for (i = 0; i < rdev->gart.num_gpu_pages; i++) |
| + rdev->gart.pages_entry[i] = rdev->dummy_page.entry; |
| return 0; |
| } |
| |
| @@ -356,15 +363,17 @@ int radeon_gart_init(struct radeon_devic |
| */ |
| void radeon_gart_fini(struct radeon_device *rdev) |
| { |
| - if (rdev->gart.pages && rdev->gart.pages_addr && rdev->gart.ready) { |
| + if (rdev->gart.ready) { |
| /* unbind pages */ |
| radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); |
| } |
| rdev->gart.ready = false; |
| vfree(rdev->gart.pages); |
| vfree(rdev->gart.pages_addr); |
| + vfree(rdev->gart.pages_entry); |
| rdev->gart.pages = NULL; |
| rdev->gart.pages_addr = NULL; |
| + rdev->gart.pages_entry = NULL; |
| |
| radeon_dummy_page_fini(rdev); |
| } |
| --- a/drivers/gpu/drm/radeon/rs400.c |
| +++ b/drivers/gpu/drm/radeon/rs400.c |
| @@ -212,11 +212,9 @@ void rs400_gart_fini(struct radeon_devic |
| #define RS400_PTE_WRITEABLE (1 << 2) |
| #define RS400_PTE_READABLE (1 << 3) |
| |
| -void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, |
| - uint64_t addr, uint32_t flags) |
| +uint64_t rs400_gart_get_page_entry(uint64_t addr, uint32_t flags) |
| { |
| uint32_t entry; |
| - u32 *gtt = rdev->gart.ptr; |
| |
| entry = (lower_32_bits(addr) & PAGE_MASK) | |
| ((upper_32_bits(addr) & 0xff) << 4); |
| @@ -226,8 +224,14 @@ void rs400_gart_set_page(struct radeon_d |
| entry |= RS400_PTE_WRITEABLE; |
| if (!(flags & RADEON_GART_PAGE_SNOOP)) |
| entry |= RS400_PTE_UNSNOOPED; |
| - entry = cpu_to_le32(entry); |
| - gtt[i] = entry; |
| + return entry; |
| +} |
| + |
| +void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, |
| + uint64_t entry) |
| +{ |
| + u32 *gtt = rdev->gart.ptr; |
| + gtt[i] = cpu_to_le32(lower_32_bits(entry)); |
| } |
| |
| int rs400_mc_wait_for_idle(struct radeon_device *rdev) |
| --- a/drivers/gpu/drm/radeon/rs600.c |
| +++ b/drivers/gpu/drm/radeon/rs600.c |
| @@ -625,11 +625,8 @@ static void rs600_gart_fini(struct radeo |
| radeon_gart_table_vram_free(rdev); |
| } |
| |
| -void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, |
| - uint64_t addr, uint32_t flags) |
| +uint64_t rs600_gart_get_page_entry(uint64_t addr, uint32_t flags) |
| { |
| - void __iomem *ptr = (void *)rdev->gart.ptr; |
| - |
| addr = addr & 0xFFFFFFFFFFFFF000ULL; |
| addr |= R600_PTE_SYSTEM; |
| if (flags & RADEON_GART_PAGE_VALID) |
| @@ -640,7 +637,14 @@ void rs600_gart_set_page(struct radeon_d |
| addr |= R600_PTE_WRITEABLE; |
| if (flags & RADEON_GART_PAGE_SNOOP) |
| addr |= R600_PTE_SNOOPED; |
| - writeq(addr, ptr + (i * 8)); |
| + return addr; |
| +} |
| + |
| +void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, |
| + uint64_t entry) |
| +{ |
| + void __iomem *ptr = (void *)rdev->gart.ptr; |
| + writeq(entry, ptr + (i * 8)); |
| } |
| |
| int rs600_irq_set(struct radeon_device *rdev) |