From: Dave Airlie <airl...@redhat.com> this uses a new entrypoint to invalidate gart entries instead of using 0.
I'm not 100% sure this is going to work, we probably need to allocate a dummy page and point all the GTT entries at it similiar to what AGP does. but we can test this first I suppose. Signed-off-by: Dave Airlie <airl...@redhat.com> --- drivers/gpu/drm/radeon/r100.c | 10 ++++++++++ drivers/gpu/drm/radeon/r300.c | 14 ++++++++++++++ drivers/gpu/drm/radeon/radeon.h | 3 +++ drivers/gpu/drm/radeon/radeon_asic.h | 14 ++++++++++++++ drivers/gpu/drm/radeon/radeon_device.c | 3 +++ drivers/gpu/drm/radeon/radeon_gart.c | 2 +- drivers/gpu/drm/radeon/rs400.c | 10 ++++++++++ drivers/gpu/drm/radeon/rs600.c | 11 +++++++++++ 8 files changed, 66 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 9667c3e..302a2ba 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -181,6 +181,7 @@ int r100_pci_gart_init(struct radeon_device *rdev) rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; rdev->asic->gart_set_page = &r100_pci_gart_set_page; + rdev->asic->gart_clear_page = &r100_pci_gart_clear_page; return radeon_gart_table_ram_alloc(rdev); } @@ -233,6 +234,15 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) return 0; } +int r100_pci_gart_clear_page(struct radeon_device *rdev, int i) +{ + if (i < 0 || i > rdev->gart.num_gpu_pages) { + return -EINVAL; + } + rdev->gart.table.ram.ptr[i] = 0; + return 0; +} + void r100_pci_gart_fini(struct radeon_device *rdev) { r100_pci_gart_disable(rdev); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index ffada48..6bd9c5c 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -83,6 +83,19 @@ int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) return 0; } + +int rv370_pcie_gart_clear_page(struct radeon_device *rdev, int i) +{ + void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; + + if (i < 0 || i > rdev->gart.num_gpu_pages) { + return -EINVAL; + } + + writel(0, ((void __iomem *)ptr) + (i * 4)); + return 0; +} + int rv370_pcie_gart_init(struct radeon_device *rdev) { int r; @@ -101,6 +114,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev) rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; + rdev->asic->gart_clear_page = &rv370_pcie_gart_clear_page; return radeon_gart_table_vram_alloc(rdev); } diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index d8b5c61..be111f6 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -723,6 +723,7 @@ struct radeon_asic { int (*gpu_reset)(struct radeon_device *rdev); void (*gart_tlb_flush)(struct radeon_device *rdev); int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr); + int (*gart_clear_page)(struct radeon_device *rdev, int i); int (*cp_init)(struct radeon_device *rdev, unsigned ring_size); void (*cp_fini)(struct radeon_device *rdev); void (*cp_disable)(struct radeon_device *rdev); @@ -1111,6 +1112,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) #define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev)) #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev)) #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart_set_page((rdev), (i), (p)) +#define radeon_gart_clear_page(rdev, i) (rdev)->asic->gart_clear_page((rdev), (i)) #define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev)) #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) #define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev)) @@ -1173,6 +1175,7 @@ extern void r100_pci_gart_fini(struct radeon_device *rdev); extern int r100_pci_gart_enable(struct radeon_device *rdev); extern void r100_pci_gart_disable(struct radeon_device *rdev); extern int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); +extern int r100_pci_gart_clear_page(struct radeon_device *rdev, int i); extern int r100_debugfs_mc_info_init(struct radeon_device *rdev); extern int r100_gui_wait_for_idle(struct radeon_device *rdev); extern void r100_ib_fini(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index d758b1f..6077f0e 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -56,6 +56,7 @@ int r100_gpu_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); int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); +int r100_pci_gart_clear_page(struct radeon_device *rdev, int i); void r100_cp_commit(struct radeon_device *rdev); void r100_ring_start(struct radeon_device *rdev); int r100_irq_set(struct radeon_device *rdev); @@ -92,6 +93,7 @@ static struct radeon_asic r100_asic = { .gpu_reset = &r100_gpu_reset, .gart_tlb_flush = &r100_pci_gart_tlb_flush, .gart_set_page = &r100_pci_gart_set_page, + .gart_clear_page = &r100_pci_gart_clear_page, .cp_commit = &r100_cp_commit, .ring_start = &r100_ring_start, .ring_test = &r100_ring_test, @@ -136,6 +138,7 @@ extern void r300_fence_ring_emit(struct radeon_device *rdev, extern int r300_cs_parse(struct radeon_cs_parser *p); extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); extern int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); +extern int rv370_pcie_gart_clear_page(struct radeon_device *rdev, int i); extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg); extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); @@ -154,6 +157,7 @@ static struct radeon_asic r300_asic = { .gpu_reset = &r300_gpu_reset, .gart_tlb_flush = &r100_pci_gart_tlb_flush, .gart_set_page = &r100_pci_gart_set_page, + .gart_clear_page = &r100_pci_gart_clear_page, .cp_commit = &r100_cp_commit, .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, @@ -199,6 +203,7 @@ static struct radeon_asic r420_asic = { .gpu_reset = &r300_gpu_reset, .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, .gart_set_page = &rv370_pcie_gart_set_page, + .gart_clear_page = &rv370_pcie_gart_clear_page, .cp_commit = &r100_cp_commit, .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, @@ -238,6 +243,7 @@ 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); int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); +int rs400_gart_clear_page(struct radeon_device *rdev, int i); 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); static struct radeon_asic rs400_asic = { @@ -249,6 +255,7 @@ static struct radeon_asic rs400_asic = { .gpu_reset = &r300_gpu_reset, .gart_tlb_flush = &rs400_gart_tlb_flush, .gart_set_page = &rs400_gart_set_page, + .gart_clear_page = &rs400_gart_clear_page, .cp_commit = &r100_cp_commit, .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, @@ -291,6 +298,7 @@ int rs600_irq_process(struct radeon_device *rdev); u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); void rs600_gart_tlb_flush(struct radeon_device *rdev); int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); +int rs600_gart_clear_page(struct radeon_device *rdev, int i); 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); @@ -309,6 +317,7 @@ static struct radeon_asic rs600_asic = { .gpu_reset = &r300_gpu_reset, .gart_tlb_flush = &rs600_gart_tlb_flush, .gart_set_page = &rs600_gart_set_page, + .gart_clear_page = &rs600_gart_clear_page, .cp_commit = &r100_cp_commit, .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, @@ -356,6 +365,7 @@ static struct radeon_asic rs690_asic = { .gpu_reset = &r300_gpu_reset, .gart_tlb_flush = &rs400_gart_tlb_flush, .gart_set_page = &rs400_gart_set_page, + .gart_clear_page = &rs400_gart_clear_page, .cp_commit = &r100_cp_commit, .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, @@ -409,6 +419,7 @@ static struct radeon_asic rv515_asic = { .gpu_reset = &rv515_gpu_reset, .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, .gart_set_page = &rv370_pcie_gart_set_page, + .gart_clear_page = &rv370_pcie_gart_clear_page, .cp_commit = &r100_cp_commit, .ring_start = &rv515_ring_start, .ring_test = &r100_ring_test, @@ -453,6 +464,7 @@ static struct radeon_asic r520_asic = { .gpu_reset = &rv515_gpu_reset, .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, .gart_set_page = &rv370_pcie_gart_set_page, + .gart_clear_page = &rv370_pcie_gart_clear_page, .cp_commit = &r100_cp_commit, .ring_start = &rv515_ring_start, .ring_test = &r100_ring_test, @@ -533,6 +545,7 @@ static struct radeon_asic r600_asic = { .gpu_reset = &r600_gpu_reset, .gart_tlb_flush = &r600_pcie_gart_tlb_flush, .gart_set_page = &rs600_gart_set_page, + .gart_clear_page = &rs600_gart_clear_page, .ring_test = &r600_ring_test, .ring_ib_execute = &r600_ring_ib_execute, .irq_set = &r600_irq_set, @@ -579,6 +592,7 @@ static struct radeon_asic rv770_asic = { .vga_set_state = &r600_vga_set_state, .gart_tlb_flush = &r600_pcie_gart_tlb_flush, .gart_set_page = &rs600_gart_set_page, + .gart_clear_page = &rs600_gart_clear_page, .ring_test = &r600_ring_test, .ring_ib_execute = &r600_ring_ib_execute, .irq_set = &r600_irq_set, diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 3b52a10..42cfadd 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -343,6 +343,7 @@ int radeon_asic_init(struct radeon_device *rdev) if (rdev->flags & RADEON_IS_PCIE) { rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; + rdev->asic->gart_clear_page = &rv370_pcie_gart_clear_page; } break; case CHIP_R420: @@ -538,11 +539,13 @@ void radeon_agp_disable(struct radeon_device *rdev) rdev->flags |= RADEON_IS_PCIE; rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; + rdev->asic->gart_clear_page = &rv370_pcie_gart_clear_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_set_page = &r100_pci_gart_set_page; + rdev->asic->gart_clear_page = &r100_pci_gart_clear_page; } rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; } diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index e73d56e..694d88f 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -153,7 +153,7 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, rdev->gart.pages[p] = NULL; rdev->gart.pages_addr[p] = 0; for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { - radeon_gart_set_page(rdev, t, 0); + radeon_gart_clear_page(rdev, t); } } } diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 287fceb..dcf3a84 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -223,6 +223,16 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) return 0; } +int rs400_gart_clear_page(struct radeon_device *rdev, int i) +{ + if (i < 0 || i > rdev->gart.num_gpu_pages) { + return -EINVAL; + } + + rdev->gart.table.ram.ptr[i] = 0; + return 0; +} + int rs400_mc_wait_for_idle(struct radeon_device *rdev) { unsigned i; diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 979b000..2a10f72 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -308,6 +308,17 @@ int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) return 0; } +int rs600_gart_clear_page(struct radeon_device *rdev, int i) +{ + void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; + + if (i < 0 || i > rdev->gart.num_gpu_pages) { + return -EINVAL; + } + writeq(0, ((void __iomem *)ptr) + (i * 8)); + return 0; +} + int rs600_irq_set(struct radeon_device *rdev) { uint32_t tmp = 0; -- 1.6.5.2 ------------------------------------------------------------------------------ The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel