提交 4aac0473 编写于 作者: J Jerome Glisse 提交者: Dave Airlie

drm/radeon/kms: clear confusion in GART init/deinit path

GART static one time initialization was mixed up with GART
enabling/disabling which could happen several time for instance
during suspend/resume cycles. This patch splits all GART
handling into 4 differents function. gart_init is for one
time initialization, gart_deinit is called upon module unload
to free resources allocated by gart_init, gart_enable enable
the GART and is intented to be call after first initialization
and at each resume cycle or reset cycle. Finaly gart_disable
stop the GART and is intended to be call at suspend time or
when unloading the module.
Signed-off-by: NJerome Glisse <jglisse@redhat.com>
Signed-off-by: NDave Airlie <airlied@redhat.com>
上级 21f9a437
...@@ -84,23 +84,28 @@ void r100_pci_gart_tlb_flush(struct radeon_device *rdev) ...@@ -84,23 +84,28 @@ void r100_pci_gart_tlb_flush(struct radeon_device *rdev)
* could end up in wrong address. */ * could end up in wrong address. */
} }
int r100_pci_gart_enable(struct radeon_device *rdev) int r100_pci_gart_init(struct radeon_device *rdev)
{ {
uint32_t tmp;
int r; int r;
if (rdev->gart.table.ram.ptr) {
WARN(1, "R100 PCI GART already initialized.\n");
return 0;
}
/* Initialize common gart structure */ /* Initialize common gart structure */
r = radeon_gart_init(rdev); r = radeon_gart_init(rdev);
if (r) { if (r)
return r; return r;
} rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
if (rdev->gart.table.ram.ptr == NULL) { rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; rdev->asic->gart_set_page = &r100_pci_gart_set_page;
r = radeon_gart_table_ram_alloc(rdev); return radeon_gart_table_ram_alloc(rdev);
if (r) { }
return r;
} int r100_pci_gart_enable(struct radeon_device *rdev)
} {
uint32_t tmp;
/* discard memory request outside of configured range */ /* discard memory request outside of configured range */
tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS; tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
WREG32(RADEON_AIC_CNTL, tmp); WREG32(RADEON_AIC_CNTL, tmp);
...@@ -140,13 +145,11 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) ...@@ -140,13 +145,11 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
return 0; return 0;
} }
int r100_gart_enable(struct radeon_device *rdev) void r100_pci_gart_fini(struct radeon_device *rdev)
{ {
if (rdev->flags & RADEON_IS_AGP) { r100_pci_gart_disable(rdev);
r100_pci_gart_disable(rdev); radeon_gart_table_ram_free(rdev);
return 0; radeon_gart_fini(rdev);
}
return r100_pci_gart_enable(rdev);
} }
...@@ -273,9 +276,6 @@ int r100_mc_init(struct radeon_device *rdev) ...@@ -273,9 +276,6 @@ int r100_mc_init(struct radeon_device *rdev)
void r100_mc_fini(struct radeon_device *rdev) void r100_mc_fini(struct radeon_device *rdev)
{ {
r100_pci_gart_disable(rdev);
radeon_gart_table_ram_free(rdev);
radeon_gart_fini(rdev);
} }
......
...@@ -42,7 +42,6 @@ int r100_cp_reset(struct radeon_device *rdev); ...@@ -42,7 +42,6 @@ int r100_cp_reset(struct radeon_device *rdev);
int r100_rb2d_reset(struct radeon_device *rdev); int r100_rb2d_reset(struct radeon_device *rdev);
int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
int r100_pci_gart_enable(struct radeon_device *rdev); int r100_pci_gart_enable(struct radeon_device *rdev);
void r100_pci_gart_disable(struct radeon_device *rdev);
void r100_mc_setup(struct radeon_device *rdev); void r100_mc_setup(struct radeon_device *rdev);
void r100_mc_disable_clients(struct radeon_device *rdev); void r100_mc_disable_clients(struct radeon_device *rdev);
int r100_gui_wait_for_idle(struct radeon_device *rdev); int r100_gui_wait_for_idle(struct radeon_device *rdev);
...@@ -86,26 +85,57 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) ...@@ -86,26 +85,57 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
mb(); mb();
} }
int rv370_pcie_gart_enable(struct radeon_device *rdev) int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
{
void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
if (i < 0 || i > rdev->gart.num_gpu_pages) {
return -EINVAL;
}
addr = (lower_32_bits(addr) >> 8) |
((upper_32_bits(addr) & 0xff) << 24) |
0xc;
/* 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));
return 0;
}
int rv370_pcie_gart_init(struct radeon_device *rdev)
{ {
uint32_t table_addr;
uint32_t tmp;
int r; int r;
if (rdev->gart.table.vram.robj) {
WARN(1, "RV370 PCIE GART already initialized.\n");
return 0;
}
/* Initialize common gart structure */ /* Initialize common gart structure */
r = radeon_gart_init(rdev); r = radeon_gart_init(rdev);
if (r) { if (r)
return r; return r;
}
r = rv370_debugfs_pcie_gart_info_init(rdev); r = rv370_debugfs_pcie_gart_info_init(rdev);
if (r) { if (r)
DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); DRM_ERROR("Failed to register debugfs file for PCIE gart !\n");
}
rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
r = radeon_gart_table_vram_alloc(rdev); rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
if (r) { rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
return r; return radeon_gart_table_vram_alloc(rdev);
}
int rv370_pcie_gart_enable(struct radeon_device *rdev)
{
uint32_t table_addr;
uint32_t tmp;
int r;
if (rdev->gart.table.vram.robj == NULL) {
dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
return -EINVAL;
} }
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
/* discard memory request outside of configured range */ /* discard memory request outside of configured range */
tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
...@@ -145,51 +175,13 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev) ...@@ -145,51 +175,13 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
} }
} }
int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) void rv370_pcie_gart_fini(struct radeon_device *rdev)
{
void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
if (i < 0 || i > rdev->gart.num_gpu_pages) {
return -EINVAL;
}
addr = (lower_32_bits(addr) >> 8) |
((upper_32_bits(addr) & 0xff) << 24) |
0xc;
/* 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));
return 0;
}
int r300_gart_enable(struct radeon_device *rdev)
{ {
#if __OS_HAS_AGP rv370_pcie_gart_disable(rdev);
if (rdev->flags & RADEON_IS_AGP) { radeon_gart_table_vram_free(rdev);
if (rdev->family > CHIP_RV350) { radeon_gart_fini(rdev);
rv370_pcie_gart_disable(rdev);
} else {
r100_pci_gart_disable(rdev);
}
return 0;
}
#endif
if (rdev->flags & RADEON_IS_PCIE) {
rdev->asic->gart_disable = &rv370_pcie_gart_disable;
rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
return rv370_pcie_gart_enable(rdev);
}
if (rdev->flags & RADEON_IS_PCI) {
rdev->asic->gart_disable = &r100_pci_gart_disable;
rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
rdev->asic->gart_set_page = &r100_pci_gart_set_page;
return r100_pci_gart_enable(rdev);
}
return r100_pci_gart_enable(rdev);
} }
/* /*
* MC * MC
*/ */
...@@ -237,14 +229,6 @@ int r300_mc_init(struct radeon_device *rdev) ...@@ -237,14 +229,6 @@ int r300_mc_init(struct radeon_device *rdev)
void r300_mc_fini(struct radeon_device *rdev) void r300_mc_fini(struct radeon_device *rdev)
{ {
if (rdev->flags & RADEON_IS_PCIE) {
rv370_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
} else {
r100_pci_gart_disable(rdev);
radeon_gart_table_ram_free(rdev);
}
radeon_gart_fini(rdev);
} }
...@@ -1299,8 +1283,6 @@ void r300_mc_program(struct radeon_device *rdev) ...@@ -1299,8 +1283,6 @@ void r300_mc_program(struct radeon_device *rdev)
/* Stops all mc clients */ /* Stops all mc clients */
r100_mc_stop(rdev, &save); r100_mc_stop(rdev, &save);
/* Shutdown PCI/PCIE GART */
radeon_gart_disable(rdev);
if (rdev->flags & RADEON_IS_AGP) { if (rdev->flags & RADEON_IS_AGP) {
WREG32(R_00014C_MC_AGP_LOCATION, WREG32(R_00014C_MC_AGP_LOCATION,
S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) | S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) |
......
...@@ -161,6 +161,11 @@ int r420_resume(struct radeon_device *rdev) ...@@ -161,6 +161,11 @@ int r420_resume(struct radeon_device *rdev)
{ {
int r; int r;
/* Make sur GART are not working */
if (rdev->flags & RADEON_IS_PCIE)
rv370_pcie_gart_disable(rdev);
if (rdev->flags & RADEON_IS_PCI)
r100_pci_gart_disable(rdev);
/* Resume clock before doing reset */ /* Resume clock before doing reset */
r420_clock_resume(rdev); r420_clock_resume(rdev);
/* Reset gpu before posting otherwise ATOM will enter infinite loop */ /* Reset gpu before posting otherwise ATOM will enter infinite loop */
...@@ -180,10 +185,15 @@ int r420_resume(struct radeon_device *rdev) ...@@ -180,10 +185,15 @@ int r420_resume(struct radeon_device *rdev)
r300_mc_program(rdev); r300_mc_program(rdev);
/* Initialize GART (initialize after TTM so we can allocate /* Initialize GART (initialize after TTM so we can allocate
* memory through TTM but finalize after TTM) */ * memory through TTM but finalize after TTM) */
r = radeon_gart_enable(rdev); if (rdev->flags & RADEON_IS_PCIE) {
if (r) { r = rv370_pcie_gart_enable(rdev);
dev_err(rdev->dev, "failled initializing GART (%d).\n", r); if (r)
return r; return r;
}
if (rdev->flags & RADEON_IS_PCI) {
r = r100_pci_gart_enable(rdev);
if (r)
return r;
} }
r420_pipes_init(rdev); r420_pipes_init(rdev);
/* Enable IRQ */ /* Enable IRQ */
...@@ -212,7 +222,10 @@ int r420_suspend(struct radeon_device *rdev) ...@@ -212,7 +222,10 @@ int r420_suspend(struct radeon_device *rdev)
r100_cp_disable(rdev); r100_cp_disable(rdev);
r100_wb_disable(rdev); r100_wb_disable(rdev);
r100_irq_disable(rdev); r100_irq_disable(rdev);
radeon_gart_disable(rdev); if (rdev->flags & RADEON_IS_PCIE)
rv370_pcie_gart_disable(rdev);
if (rdev->flags & RADEON_IS_PCI)
r100_pci_gart_disable(rdev);
return 0; return 0;
} }
...@@ -222,14 +235,10 @@ void r420_fini(struct radeon_device *rdev) ...@@ -222,14 +235,10 @@ void r420_fini(struct radeon_device *rdev)
r100_wb_fini(rdev); r100_wb_fini(rdev);
r100_ib_fini(rdev); r100_ib_fini(rdev);
radeon_gem_fini(rdev); radeon_gem_fini(rdev);
if (rdev->flags & RADEON_IS_PCIE) { if (rdev->flags & RADEON_IS_PCIE)
rv370_pcie_gart_disable(rdev); rv370_pcie_gart_fini(rdev);
radeon_gart_table_vram_free(rdev); if (rdev->flags & RADEON_IS_PCI)
} else { r100_pci_gart_fini(rdev);
r100_pci_gart_disable(rdev);
radeon_gart_table_ram_free(rdev);
}
radeon_gart_fini(rdev);
radeon_agp_fini(rdev); radeon_agp_fini(rdev);
radeon_irq_kms_fini(rdev); radeon_irq_kms_fini(rdev);
radeon_fence_driver_fini(rdev); radeon_fence_driver_fini(rdev);
...@@ -309,6 +318,16 @@ int r420_init(struct radeon_device *rdev) ...@@ -309,6 +318,16 @@ int r420_init(struct radeon_device *rdev)
if (r) { if (r) {
return r; return r;
} }
if (rdev->flags & RADEON_IS_PCIE) {
r = rv370_pcie_gart_init(rdev);
if (r)
return r;
}
if (rdev->flags & RADEON_IS_PCI) {
r = r100_pci_gart_init(rdev);
if (r)
return r;
}
r300_set_reg_safe(rdev); r300_set_reg_safe(rdev);
r = r420_resume(rdev); r = r420_resume(rdev);
if (r) { if (r) {
...@@ -318,14 +337,10 @@ int r420_init(struct radeon_device *rdev) ...@@ -318,14 +337,10 @@ int r420_init(struct radeon_device *rdev)
r100_cp_fini(rdev); r100_cp_fini(rdev);
r100_wb_fini(rdev); r100_wb_fini(rdev);
r100_ib_fini(rdev); r100_ib_fini(rdev);
if (rdev->flags & RADEON_IS_PCIE) { if (rdev->flags & RADEON_IS_PCIE)
rv370_pcie_gart_disable(rdev); rv370_pcie_gart_fini(rdev);
radeon_gart_table_vram_free(rdev); if (rdev->flags & RADEON_IS_PCI)
} else { r100_pci_gart_fini(rdev);
r100_pci_gart_disable(rdev);
radeon_gart_table_ram_free(rdev);
}
radeon_gart_fini(rdev);
radeon_agp_fini(rdev); radeon_agp_fini(rdev);
radeon_irq_kms_fini(rdev); radeon_irq_kms_fini(rdev);
} }
......
...@@ -31,8 +31,6 @@ ...@@ -31,8 +31,6 @@
/* r520,rv530,rv560,rv570,r580 depends on : */ /* r520,rv530,rv560,rv570,r580 depends on : */
void r100_hdp_reset(struct radeon_device *rdev); void r100_hdp_reset(struct radeon_device *rdev);
int rv370_pcie_gart_enable(struct radeon_device *rdev);
void rv370_pcie_gart_disable(struct radeon_device *rdev);
void r420_pipes_init(struct radeon_device *rdev); void r420_pipes_init(struct radeon_device *rdev);
void rs600_mc_disable_clients(struct radeon_device *rdev); void rs600_mc_disable_clients(struct radeon_device *rdev);
void rs600_disable_vga(struct radeon_device *rdev); void rs600_disable_vga(struct radeon_device *rdev);
...@@ -118,9 +116,6 @@ int r520_mc_init(struct radeon_device *rdev) ...@@ -118,9 +116,6 @@ int r520_mc_init(struct radeon_device *rdev)
void r520_mc_fini(struct radeon_device *rdev) void r520_mc_fini(struct radeon_device *rdev)
{ {
rv370_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
} }
......
...@@ -113,21 +113,34 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) ...@@ -113,21 +113,34 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
} }
} }
int r600_pcie_gart_enable(struct radeon_device *rdev) int r600_pcie_gart_init(struct radeon_device *rdev)
{ {
u32 tmp; int r;
int r, i;
if (rdev->gart.table.vram.robj) {
WARN(1, "R600 PCIE GART already initialized.\n");
return 0;
}
/* Initialize common gart structure */ /* Initialize common gart structure */
r = radeon_gart_init(rdev); r = radeon_gart_init(rdev);
if (r) { if (r)
return r; return r;
}
rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
r = radeon_gart_table_vram_alloc(rdev); return radeon_gart_table_vram_alloc(rdev);
if (r) { }
return r;
int r600_pcie_gart_enable(struct radeon_device *rdev)
{
u32 tmp;
int r, i;
if (rdev->gart.table.vram.robj == NULL) {
dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
return -EINVAL;
} }
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
for (i = 0; i < rdev->gart.num_gpu_pages; i++) for (i = 0; i < rdev->gart.num_gpu_pages; i++)
r600_gart_clear_page(rdev, i); r600_gart_clear_page(rdev, i);
/* Setup L2 cache */ /* Setup L2 cache */
...@@ -175,10 +188,6 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) ...@@ -175,10 +188,6 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
u32 tmp; u32 tmp;
int i; int i;
/* Clear ptes*/
for (i = 0; i < rdev->gart.num_gpu_pages; i++)
r600_gart_clear_page(rdev, i);
r600_pcie_gart_tlb_flush(rdev);
/* Disable all tables */ /* Disable all tables */
for (i = 0; i < 7; i++) for (i = 0; i < 7; i++)
WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
...@@ -204,6 +213,17 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) ...@@ -204,6 +213,17 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
if (rdev->gart.table.vram.robj) {
radeon_object_kunmap(rdev->gart.table.vram.robj);
radeon_object_unpin(rdev->gart.table.vram.robj);
}
}
void r600_pcie_gart_fini(struct radeon_device *rdev)
{
r600_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
} }
int r600_mc_wait_for_idle(struct radeon_device *rdev) int r600_mc_wait_for_idle(struct radeon_device *rdev)
...@@ -1472,6 +1492,7 @@ int r600_suspend(struct radeon_device *rdev) ...@@ -1472,6 +1492,7 @@ int r600_suspend(struct radeon_device *rdev)
{ {
/* FIXME: we should wait for ring to be empty */ /* FIXME: we should wait for ring to be empty */
r600_cp_stop(rdev); r600_cp_stop(rdev);
r600_pcie_gart_disable(rdev);
return 0; return 0;
} }
...@@ -1548,6 +1569,10 @@ int r600_init(struct radeon_device *rdev) ...@@ -1548,6 +1569,10 @@ int r600_init(struct radeon_device *rdev)
} }
} }
r = r600_pcie_gart_init(rdev);
if (r)
return r;
r = r600_resume(rdev); r = r600_resume(rdev);
if (r) { if (r) {
if (rdev->flags & RADEON_IS_AGP) { if (rdev->flags & RADEON_IS_AGP) {
...@@ -1583,9 +1608,7 @@ void r600_fini(struct radeon_device *rdev) ...@@ -1583,9 +1608,7 @@ void r600_fini(struct radeon_device *rdev)
r600_blit_fini(rdev); r600_blit_fini(rdev);
radeon_ring_fini(rdev); radeon_ring_fini(rdev);
r600_pcie_gart_disable(rdev); r600_pcie_gart_fini(rdev);
radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
radeon_gem_fini(rdev); radeon_gem_fini(rdev);
radeon_fence_driver_fini(rdev); radeon_fence_driver_fini(rdev);
radeon_clocks_fini(rdev); radeon_clocks_fini(rdev);
......
...@@ -596,6 +596,8 @@ struct radeon_asic { ...@@ -596,6 +596,8 @@ struct radeon_asic {
void (*mc_fini)(struct radeon_device *rdev); void (*mc_fini)(struct radeon_device *rdev);
int (*wb_init)(struct radeon_device *rdev); int (*wb_init)(struct radeon_device *rdev);
void (*wb_fini)(struct radeon_device *rdev); void (*wb_fini)(struct radeon_device *rdev);
int (*gart_init)(struct radeon_device *rdev);
void (*gart_fini)(struct radeon_device *rdev);
int (*gart_enable)(struct radeon_device *rdev); int (*gart_enable)(struct radeon_device *rdev);
void (*gart_disable)(struct radeon_device *rdev); void (*gart_disable)(struct radeon_device *rdev);
void (*gart_tlb_flush)(struct radeon_device *rdev); void (*gart_tlb_flush)(struct radeon_device *rdev);
...@@ -950,6 +952,8 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) ...@@ -950,6 +952,8 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
#define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev)) #define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev))
#define radeon_wb_init(rdev) (rdev)->asic->wb_init((rdev)) #define radeon_wb_init(rdev) (rdev)->asic->wb_init((rdev))
#define radeon_wb_fini(rdev) (rdev)->asic->wb_fini((rdev)) #define radeon_wb_fini(rdev) (rdev)->asic->wb_fini((rdev))
#define radeon_gpu_gart_init(rdev) (rdev)->asic->gart_init((rdev))
#define radeon_gpu_gart_fini(rdev) (rdev)->asic->gart_fini((rdev))
#define radeon_gart_enable(rdev) (rdev)->asic->gart_enable((rdev)) #define radeon_gart_enable(rdev) (rdev)->asic->gart_enable((rdev))
#define radeon_gart_disable(rdev) (rdev)->asic->gart_disable((rdev)) #define radeon_gart_disable(rdev) (rdev)->asic->gart_disable((rdev))
#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev)) #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev))
...@@ -978,6 +982,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) ...@@ -978,6 +982,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
#define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev))
/* Common functions */ /* Common functions */
extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
extern int radeon_modeset_init(struct radeon_device *rdev); extern int radeon_modeset_init(struct radeon_device *rdev);
extern void radeon_modeset_fini(struct radeon_device *rdev); extern void radeon_modeset_fini(struct radeon_device *rdev);
extern bool radeon_card_posted(struct radeon_device *rdev); extern bool radeon_card_posted(struct radeon_device *rdev);
...@@ -1000,6 +1005,8 @@ extern void r100_cp_disable(struct radeon_device *rdev); ...@@ -1000,6 +1005,8 @@ extern void r100_cp_disable(struct radeon_device *rdev);
extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
extern void r100_cp_fini(struct radeon_device *rdev); extern void r100_cp_fini(struct radeon_device *rdev);
extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev); extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
extern int r100_pci_gart_init(struct radeon_device *rdev);
extern void r100_pci_gart_fini(struct radeon_device *rdev);
extern int r100_pci_gart_enable(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 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_set_page(struct radeon_device *rdev, int i, uint64_t addr);
...@@ -1020,6 +1027,9 @@ extern int r100_wb_init(struct radeon_device *rdev); ...@@ -1020,6 +1027,9 @@ extern int r100_wb_init(struct radeon_device *rdev);
extern void r300_set_reg_safe(struct radeon_device *rdev); extern void r300_set_reg_safe(struct radeon_device *rdev);
extern void r300_mc_program(struct radeon_device *rdev); extern void r300_mc_program(struct radeon_device *rdev);
extern void r300_vram_info(struct radeon_device *rdev); extern void r300_vram_info(struct radeon_device *rdev);
extern int rv370_pcie_gart_init(struct radeon_device *rdev);
extern void rv370_pcie_gart_fini(struct radeon_device *rdev);
extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
extern void rv370_pcie_gart_disable(struct radeon_device *rdev); extern void rv370_pcie_gart_disable(struct radeon_device *rdev);
/* r420,r423,rv410 */ /* r420,r423,rv410 */
...@@ -1043,6 +1053,7 @@ extern int r600_cp_resume(struct radeon_device *rdev); ...@@ -1043,6 +1053,7 @@ extern int r600_cp_resume(struct radeon_device *rdev);
extern int r600_count_pipe_bits(uint32_t val); extern int r600_count_pipe_bits(uint32_t val);
extern int r600_gart_clear_page(struct radeon_device *rdev, int i); extern int r600_gart_clear_page(struct radeon_device *rdev, int i);
extern int r600_mc_wait_for_idle(struct radeon_device *rdev); extern int r600_mc_wait_for_idle(struct radeon_device *rdev);
extern int r600_pcie_gart_init(struct radeon_device *rdev);
extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
extern int r600_ib_test(struct radeon_device *rdev); extern int r600_ib_test(struct radeon_device *rdev);
extern int r600_ring_test(struct radeon_device *rdev); extern int r600_ring_test(struct radeon_device *rdev);
......
...@@ -53,7 +53,9 @@ void r100_mc_fini(struct radeon_device *rdev); ...@@ -53,7 +53,9 @@ void r100_mc_fini(struct radeon_device *rdev);
u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
int r100_wb_init(struct radeon_device *rdev); int r100_wb_init(struct radeon_device *rdev);
void r100_wb_fini(struct radeon_device *rdev); void r100_wb_fini(struct radeon_device *rdev);
int r100_gart_enable(struct radeon_device *rdev); int r100_pci_gart_init(struct radeon_device *rdev);
void r100_pci_gart_fini(struct radeon_device *rdev);
int r100_pci_gart_enable(struct radeon_device *rdev);
void r100_pci_gart_disable(struct radeon_device *rdev); void r100_pci_gart_disable(struct radeon_device *rdev);
void r100_pci_gart_tlb_flush(struct radeon_device *rdev); 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_set_page(struct radeon_device *rdev, int i, uint64_t addr);
...@@ -92,7 +94,9 @@ static struct radeon_asic r100_asic = { ...@@ -92,7 +94,9 @@ static struct radeon_asic r100_asic = {
.mc_fini = &r100_mc_fini, .mc_fini = &r100_mc_fini,
.wb_init = &r100_wb_init, .wb_init = &r100_wb_init,
.wb_fini = &r100_wb_fini, .wb_fini = &r100_wb_fini,
.gart_enable = &r100_gart_enable, .gart_init = &r100_pci_gart_init,
.gart_fini = &r100_pci_gart_fini,
.gart_enable = &r100_pci_gart_enable,
.gart_disable = &r100_pci_gart_disable, .gart_disable = &r100_pci_gart_disable,
.gart_tlb_flush = &r100_pci_gart_tlb_flush, .gart_tlb_flush = &r100_pci_gart_tlb_flush,
.gart_set_page = &r100_pci_gart_set_page, .gart_set_page = &r100_pci_gart_set_page,
...@@ -135,7 +139,9 @@ void r300_ring_start(struct radeon_device *rdev); ...@@ -135,7 +139,9 @@ void r300_ring_start(struct radeon_device *rdev);
void r300_fence_ring_emit(struct radeon_device *rdev, void r300_fence_ring_emit(struct radeon_device *rdev,
struct radeon_fence *fence); struct radeon_fence *fence);
int r300_cs_parse(struct radeon_cs_parser *p); int r300_cs_parse(struct radeon_cs_parser *p);
int r300_gart_enable(struct radeon_device *rdev); int rv370_pcie_gart_init(struct radeon_device *rdev);
void rv370_pcie_gart_fini(struct radeon_device *rdev);
int rv370_pcie_gart_enable(struct radeon_device *rdev);
void rv370_pcie_gart_disable(struct radeon_device *rdev); void rv370_pcie_gart_disable(struct radeon_device *rdev);
void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
...@@ -157,7 +163,9 @@ static struct radeon_asic r300_asic = { ...@@ -157,7 +163,9 @@ static struct radeon_asic r300_asic = {
.mc_fini = &r300_mc_fini, .mc_fini = &r300_mc_fini,
.wb_init = &r100_wb_init, .wb_init = &r100_wb_init,
.wb_fini = &r100_wb_fini, .wb_fini = &r100_wb_fini,
.gart_enable = &r300_gart_enable, .gart_init = &r100_pci_gart_init,
.gart_fini = &r100_pci_gart_fini,
.gart_enable = &r100_pci_gart_enable,
.gart_disable = &r100_pci_gart_disable, .gart_disable = &r100_pci_gart_disable,
.gart_tlb_flush = &r100_pci_gart_tlb_flush, .gart_tlb_flush = &r100_pci_gart_tlb_flush,
.gart_set_page = &r100_pci_gart_set_page, .gart_set_page = &r100_pci_gart_set_page,
...@@ -205,8 +213,8 @@ static struct radeon_asic r420_asic = { ...@@ -205,8 +213,8 @@ static struct radeon_asic r420_asic = {
.mc_fini = NULL, .mc_fini = NULL,
.wb_init = NULL, .wb_init = NULL,
.wb_fini = NULL, .wb_fini = NULL,
.gart_enable = &r300_gart_enable, .gart_enable = NULL,
.gart_disable = &rv370_pcie_gart_disable, .gart_disable = NULL,
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
.gart_set_page = &rv370_pcie_gart_set_page, .gart_set_page = &rv370_pcie_gart_set_page,
.cp_init = NULL, .cp_init = NULL,
...@@ -242,6 +250,8 @@ void rs400_errata(struct radeon_device *rdev); ...@@ -242,6 +250,8 @@ void rs400_errata(struct radeon_device *rdev);
void rs400_vram_info(struct radeon_device *rdev); void rs400_vram_info(struct radeon_device *rdev);
int rs400_mc_init(struct radeon_device *rdev); int rs400_mc_init(struct radeon_device *rdev);
void rs400_mc_fini(struct radeon_device *rdev); void rs400_mc_fini(struct radeon_device *rdev);
int rs400_gart_init(struct radeon_device *rdev);
void rs400_gart_fini(struct radeon_device *rdev);
int rs400_gart_enable(struct radeon_device *rdev); int rs400_gart_enable(struct radeon_device *rdev);
void rs400_gart_disable(struct radeon_device *rdev); void rs400_gart_disable(struct radeon_device *rdev);
void rs400_gart_tlb_flush(struct radeon_device *rdev); void rs400_gart_tlb_flush(struct radeon_device *rdev);
...@@ -257,6 +267,8 @@ static struct radeon_asic rs400_asic = { ...@@ -257,6 +267,8 @@ static struct radeon_asic rs400_asic = {
.mc_fini = &rs400_mc_fini, .mc_fini = &rs400_mc_fini,
.wb_init = &r100_wb_init, .wb_init = &r100_wb_init,
.wb_fini = &r100_wb_fini, .wb_fini = &r100_wb_fini,
.gart_init = &rs400_gart_init,
.gart_fini = &rs400_gart_fini,
.gart_enable = &rs400_gart_enable, .gart_enable = &rs400_gart_enable,
.gart_disable = &rs400_gart_disable, .gart_disable = &rs400_gart_disable,
.gart_tlb_flush = &rs400_gart_tlb_flush, .gart_tlb_flush = &rs400_gart_tlb_flush,
...@@ -298,6 +310,8 @@ void rs600_mc_fini(struct radeon_device *rdev); ...@@ -298,6 +310,8 @@ void rs600_mc_fini(struct radeon_device *rdev);
int rs600_irq_set(struct radeon_device *rdev); int rs600_irq_set(struct radeon_device *rdev);
int rs600_irq_process(struct radeon_device *rdev); int rs600_irq_process(struct radeon_device *rdev);
u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
int rs600_gart_init(struct radeon_device *rdev);
void rs600_gart_fini(struct radeon_device *rdev);
int rs600_gart_enable(struct radeon_device *rdev); int rs600_gart_enable(struct radeon_device *rdev);
void rs600_gart_disable(struct radeon_device *rdev); void rs600_gart_disable(struct radeon_device *rdev);
void rs600_gart_tlb_flush(struct radeon_device *rdev); void rs600_gart_tlb_flush(struct radeon_device *rdev);
...@@ -314,6 +328,8 @@ static struct radeon_asic rs600_asic = { ...@@ -314,6 +328,8 @@ static struct radeon_asic rs600_asic = {
.mc_fini = &rs600_mc_fini, .mc_fini = &rs600_mc_fini,
.wb_init = &r100_wb_init, .wb_init = &r100_wb_init,
.wb_fini = &r100_wb_fini, .wb_fini = &r100_wb_fini,
.gart_init = &rs600_gart_init,
.gart_fini = &rs600_gart_fini,
.gart_enable = &rs600_gart_enable, .gart_enable = &rs600_gart_enable,
.gart_disable = &rs600_gart_disable, .gart_disable = &rs600_gart_disable,
.gart_tlb_flush = &rs600_gart_tlb_flush, .gart_tlb_flush = &rs600_gart_tlb_flush,
...@@ -361,6 +377,8 @@ static struct radeon_asic rs690_asic = { ...@@ -361,6 +377,8 @@ static struct radeon_asic rs690_asic = {
.mc_fini = &rs690_mc_fini, .mc_fini = &rs690_mc_fini,
.wb_init = &r100_wb_init, .wb_init = &r100_wb_init,
.wb_fini = &r100_wb_fini, .wb_fini = &r100_wb_fini,
.gart_init = &rs400_gart_init,
.gart_fini = &rs400_gart_fini,
.gart_enable = &rs400_gart_enable, .gart_enable = &rs400_gart_enable,
.gart_disable = &rs400_gart_disable, .gart_disable = &rs400_gart_disable,
.gart_tlb_flush = &rs400_gart_tlb_flush, .gart_tlb_flush = &rs400_gart_tlb_flush,
...@@ -415,7 +433,9 @@ static struct radeon_asic rv515_asic = { ...@@ -415,7 +433,9 @@ static struct radeon_asic rv515_asic = {
.mc_fini = &rv515_mc_fini, .mc_fini = &rv515_mc_fini,
.wb_init = &r100_wb_init, .wb_init = &r100_wb_init,
.wb_fini = &r100_wb_fini, .wb_fini = &r100_wb_fini,
.gart_enable = &r300_gart_enable, .gart_init = &rv370_pcie_gart_init,
.gart_fini = &rv370_pcie_gart_fini,
.gart_enable = &rv370_pcie_gart_enable,
.gart_disable = &rv370_pcie_gart_disable, .gart_disable = &rv370_pcie_gart_disable,
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
.gart_set_page = &rv370_pcie_gart_set_page, .gart_set_page = &rv370_pcie_gart_set_page,
...@@ -462,7 +482,9 @@ static struct radeon_asic r520_asic = { ...@@ -462,7 +482,9 @@ static struct radeon_asic r520_asic = {
.mc_fini = &r520_mc_fini, .mc_fini = &r520_mc_fini,
.wb_init = &r100_wb_init, .wb_init = &r100_wb_init,
.wb_fini = &r100_wb_fini, .wb_fini = &r100_wb_fini,
.gart_enable = &r300_gart_enable, .gart_init = &rv370_pcie_gart_init,
.gart_fini = &rv370_pcie_gart_fini,
.gart_enable = &rv370_pcie_gart_enable,
.gart_disable = &rv370_pcie_gart_disable, .gart_disable = &rv370_pcie_gart_disable,
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
.gart_set_page = &rv370_pcie_gart_set_page, .gart_set_page = &rv370_pcie_gart_set_page,
......
...@@ -320,6 +320,14 @@ int radeon_asic_init(struct radeon_device *rdev) ...@@ -320,6 +320,14 @@ int radeon_asic_init(struct radeon_device *rdev)
case CHIP_RV350: case CHIP_RV350:
case CHIP_RV380: case CHIP_RV380:
rdev->asic = &r300_asic; rdev->asic = &r300_asic;
if (rdev->flags & RADEON_IS_PCIE) {
rdev->asic->gart_init = &rv370_pcie_gart_init;
rdev->asic->gart_fini = &rv370_pcie_gart_fini;
rdev->asic->gart_enable = &rv370_pcie_gart_enable;
rdev->asic->gart_disable = &rv370_pcie_gart_disable;
rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
}
break; break;
case CHIP_R420: case CHIP_R420:
case CHIP_R423: case CHIP_R423:
...@@ -504,6 +512,12 @@ int radeon_device_init(struct radeon_device *rdev, ...@@ -504,6 +512,12 @@ int radeon_device_init(struct radeon_device *rdev,
rwlock_init(&rdev->fence_drv.lock); rwlock_init(&rdev->fence_drv.lock);
INIT_LIST_HEAD(&rdev->gem.objects); INIT_LIST_HEAD(&rdev->gem.objects);
/* Set asic functions */
r = radeon_asic_init(rdev);
if (r) {
return r;
}
if (radeon_agpmode == -1) { if (radeon_agpmode == -1) {
rdev->flags &= ~RADEON_IS_AGP; rdev->flags &= ~RADEON_IS_AGP;
if (rdev->family >= CHIP_RV515 || if (rdev->family >= CHIP_RV515 ||
...@@ -512,18 +526,24 @@ int radeon_device_init(struct radeon_device *rdev, ...@@ -512,18 +526,24 @@ int radeon_device_init(struct radeon_device *rdev,
rdev->family == CHIP_R423) { rdev->family == CHIP_R423) {
DRM_INFO("Forcing AGP to PCIE mode\n"); DRM_INFO("Forcing AGP to PCIE mode\n");
rdev->flags |= RADEON_IS_PCIE; rdev->flags |= RADEON_IS_PCIE;
rdev->asic->gart_init = &rv370_pcie_gart_init;
rdev->asic->gart_fini = &rv370_pcie_gart_fini;
rdev->asic->gart_enable = &rv370_pcie_gart_enable;
rdev->asic->gart_disable = &rv370_pcie_gart_disable;
rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
} else { } else {
DRM_INFO("Forcing AGP to PCI mode\n"); DRM_INFO("Forcing AGP to PCI mode\n");
rdev->flags |= RADEON_IS_PCI; rdev->flags |= RADEON_IS_PCI;
rdev->asic->gart_init = &r100_pci_gart_init;
rdev->asic->gart_fini = &r100_pci_gart_fini;
rdev->asic->gart_enable = &r100_pci_gart_enable;
rdev->asic->gart_disable = &r100_pci_gart_disable;
rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
rdev->asic->gart_set_page = &r100_pci_gart_set_page;
} }
} }
/* Set asic functions */
r = radeon_asic_init(rdev);
if (r) {
return r;
}
/* set DMA mask + need_dma32 flags. /* set DMA mask + need_dma32 flags.
* PCIE - can handle 40-bits. * PCIE - can handle 40-bits.
* IGP - can handle 40-bits (in theory) * IGP - can handle 40-bits (in theory)
...@@ -623,6 +643,9 @@ int radeon_device_init(struct radeon_device *rdev, ...@@ -623,6 +643,9 @@ int radeon_device_init(struct radeon_device *rdev,
if (r) { if (r) {
return r; return r;
} }
r = radeon_gpu_gart_init(rdev);
if (r)
return r;
/* Initialize GART (initialize after TTM so we can allocate /* Initialize GART (initialize after TTM so we can allocate
* memory through TTM but finalize after TTM) */ * memory through TTM but finalize after TTM) */
r = radeon_gart_enable(rdev); r = radeon_gart_enable(rdev);
...@@ -675,6 +698,7 @@ void radeon_device_fini(struct radeon_device *rdev) ...@@ -675,6 +698,7 @@ void radeon_device_fini(struct radeon_device *rdev)
radeon_ib_pool_fini(rdev); radeon_ib_pool_fini(rdev);
radeon_cp_fini(rdev); radeon_cp_fini(rdev);
radeon_wb_fini(rdev); radeon_wb_fini(rdev);
radeon_gpu_gart_fini(rdev);
radeon_gem_fini(rdev); radeon_gem_fini(rdev);
radeon_mc_fini(rdev); radeon_mc_fini(rdev);
#if __OS_HAS_AGP #if __OS_HAS_AGP
......
...@@ -75,7 +75,6 @@ void radeon_gart_table_ram_free(struct radeon_device *rdev) ...@@ -75,7 +75,6 @@ void radeon_gart_table_ram_free(struct radeon_device *rdev)
int radeon_gart_table_vram_alloc(struct radeon_device *rdev) int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
{ {
uint64_t gpu_addr;
int r; int r;
if (rdev->gart.table.vram.robj == NULL) { if (rdev->gart.table.vram.robj == NULL) {
...@@ -88,6 +87,14 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) ...@@ -88,6 +87,14 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
return r; return r;
} }
} }
return 0;
}
int radeon_gart_table_vram_pin(struct radeon_device *rdev)
{
uint64_t gpu_addr;
int r;
r = radeon_object_pin(rdev->gart.table.vram.robj, r = radeon_object_pin(rdev->gart.table.vram.robj,
RADEON_GEM_DOMAIN_VRAM, &gpu_addr); RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
if (r) { if (r) {
......
...@@ -92,20 +92,41 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev) ...@@ -92,20 +92,41 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev)
WREG32_MC(RS480_GART_CACHE_CNTRL, 0); WREG32_MC(RS480_GART_CACHE_CNTRL, 0);
} }
int rs400_gart_enable(struct radeon_device *rdev) int rs400_gart_init(struct radeon_device *rdev)
{ {
uint32_t size_reg;
uint32_t tmp;
int r; int r;
if (rdev->gart.table.ram.ptr) {
WARN(1, "RS400 GART already initialized.\n");
return 0;
}
/* Check gart size */
switch(rdev->mc.gtt_size / (1024 * 1024)) {
case 32:
case 64:
case 128:
case 256:
case 512:
case 1024:
case 2048:
break;
default:
return -EINVAL;
}
/* Initialize common gart structure */ /* Initialize common gart structure */
r = radeon_gart_init(rdev); r = radeon_gart_init(rdev);
if (r) { if (r)
return r; return r;
} if (rs400_debugfs_pcie_gart_info_init(rdev))
if (rs400_debugfs_pcie_gart_info_init(rdev)) {
DRM_ERROR("Failed to register debugfs file for RS400 GART !\n"); DRM_ERROR("Failed to register debugfs file for RS400 GART !\n");
} rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
return radeon_gart_table_ram_alloc(rdev);
}
int rs400_gart_enable(struct radeon_device *rdev)
{
uint32_t size_reg;
uint32_t tmp;
tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH); tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);
tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS; tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS;
...@@ -136,13 +157,6 @@ int rs400_gart_enable(struct radeon_device *rdev) ...@@ -136,13 +157,6 @@ int rs400_gart_enable(struct radeon_device *rdev)
default: default:
return -EINVAL; return -EINVAL;
} }
if (rdev->gart.table.ram.ptr == NULL) {
rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
r = radeon_gart_table_ram_alloc(rdev);
if (r) {
return r;
}
}
/* It should be fine to program it to max value */ /* It should be fine to program it to max value */
if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) { if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) {
WREG32_MC(RS690_MCCFG_AGP_BASE, 0xFFFFFFFF); WREG32_MC(RS690_MCCFG_AGP_BASE, 0xFFFFFFFF);
...@@ -201,6 +215,13 @@ void rs400_gart_disable(struct radeon_device *rdev) ...@@ -201,6 +215,13 @@ void rs400_gart_disable(struct radeon_device *rdev)
WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, 0); WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, 0);
} }
void rs400_gart_fini(struct radeon_device *rdev)
{
rs400_gart_disable(rdev);
radeon_gart_table_ram_free(rdev);
radeon_gart_fini(rdev);
}
int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
{ {
uint32_t entry; uint32_t entry;
...@@ -255,14 +276,12 @@ int rs400_mc_init(struct radeon_device *rdev) ...@@ -255,14 +276,12 @@ int rs400_mc_init(struct radeon_device *rdev)
(void)RREG32(RADEON_HOST_PATH_CNTL); (void)RREG32(RADEON_HOST_PATH_CNTL);
WREG32(RADEON_HOST_PATH_CNTL, tmp); WREG32(RADEON_HOST_PATH_CNTL, tmp);
(void)RREG32(RADEON_HOST_PATH_CNTL); (void)RREG32(RADEON_HOST_PATH_CNTL);
return 0; return 0;
} }
void rs400_mc_fini(struct radeon_device *rdev) void rs400_mc_fini(struct radeon_device *rdev)
{ {
rs400_gart_disable(rdev);
radeon_gart_table_ram_free(rdev);
radeon_gart_fini(rdev);
} }
......
...@@ -68,22 +68,35 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev) ...@@ -68,22 +68,35 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
tmp = RREG32_MC(RS600_MC_PT0_CNTL); tmp = RREG32_MC(RS600_MC_PT0_CNTL);
} }
int rs600_gart_enable(struct radeon_device *rdev) int rs600_gart_init(struct radeon_device *rdev)
{ {
uint32_t tmp;
int i;
int r; int r;
if (rdev->gart.table.vram.robj) {
WARN(1, "RS600 GART already initialized.\n");
return 0;
}
/* Initialize common gart structure */ /* Initialize common gart structure */
r = radeon_gart_init(rdev); r = radeon_gart_init(rdev);
if (r) { if (r) {
return r; return r;
} }
rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
r = radeon_gart_table_vram_alloc(rdev); return radeon_gart_table_vram_alloc(rdev);
if (r) { }
return r;
int rs600_gart_enable(struct radeon_device *rdev)
{
uint32_t tmp;
int r, i;
if (rdev->gart.table.vram.robj == NULL) {
dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
return -EINVAL;
} }
r = radeon_gart_table_vram_pin(rdev);
if (r)
return r;
/* FIXME: setup default page */ /* FIXME: setup default page */
WREG32_MC(RS600_MC_PT0_CNTL, WREG32_MC(RS600_MC_PT0_CNTL,
(RS600_EFFECTIVE_L2_CACHE_SIZE(6) | (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
...@@ -138,8 +151,17 @@ void rs600_gart_disable(struct radeon_device *rdev) ...@@ -138,8 +151,17 @@ void rs600_gart_disable(struct radeon_device *rdev)
tmp = RREG32_MC(RS600_MC_CNTL1); tmp = RREG32_MC(RS600_MC_CNTL1);
tmp &= ~RS600_ENABLE_PAGE_TABLES; tmp &= ~RS600_ENABLE_PAGE_TABLES;
WREG32_MC(RS600_MC_CNTL1, tmp); WREG32_MC(RS600_MC_CNTL1, tmp);
radeon_object_kunmap(rdev->gart.table.vram.robj); if (rdev->gart.table.vram.robj) {
radeon_object_unpin(rdev->gart.table.vram.robj); radeon_object_kunmap(rdev->gart.table.vram.robj);
radeon_object_unpin(rdev->gart.table.vram.robj);
}
}
void rs600_gart_fini(struct radeon_device *rdev)
{
rs600_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
} }
#define R600_PTE_VALID (1 << 0) #define R600_PTE_VALID (1 << 0)
...@@ -235,9 +257,6 @@ int rs600_mc_init(struct radeon_device *rdev) ...@@ -235,9 +257,6 @@ int rs600_mc_init(struct radeon_device *rdev)
void rs600_mc_fini(struct radeon_device *rdev) void rs600_mc_fini(struct radeon_device *rdev)
{ {
rs600_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
} }
......
...@@ -94,9 +94,6 @@ int rs690_mc_init(struct radeon_device *rdev) ...@@ -94,9 +94,6 @@ int rs690_mc_init(struct radeon_device *rdev)
void rs690_mc_fini(struct radeon_device *rdev) void rs690_mc_fini(struct radeon_device *rdev)
{ {
rs400_gart_disable(rdev);
radeon_gart_table_ram_free(rdev);
radeon_gart_fini(rdev);
} }
......
...@@ -37,8 +37,6 @@ int r100_cp_reset(struct radeon_device *rdev); ...@@ -37,8 +37,6 @@ int r100_cp_reset(struct radeon_device *rdev);
int r100_rb2d_reset(struct radeon_device *rdev); int r100_rb2d_reset(struct radeon_device *rdev);
int r100_gui_wait_for_idle(struct radeon_device *rdev); int r100_gui_wait_for_idle(struct radeon_device *rdev);
int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
int rv370_pcie_gart_enable(struct radeon_device *rdev);
void rv370_pcie_gart_disable(struct radeon_device *rdev);
void r420_pipes_init(struct radeon_device *rdev); void r420_pipes_init(struct radeon_device *rdev);
void rs600_mc_disable_clients(struct radeon_device *rdev); void rs600_mc_disable_clients(struct radeon_device *rdev);
void rs600_disable_vga(struct radeon_device *rdev); void rs600_disable_vga(struct radeon_device *rdev);
...@@ -126,9 +124,6 @@ int rv515_mc_init(struct radeon_device *rdev) ...@@ -126,9 +124,6 @@ int rv515_mc_init(struct radeon_device *rdev)
void rv515_mc_fini(struct radeon_device *rdev) void rv515_mc_fini(struct radeon_device *rdev)
{ {
rv370_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
} }
......
...@@ -48,16 +48,13 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev) ...@@ -48,16 +48,13 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
u32 tmp; u32 tmp;
int r, i; int r, i;
/* Initialize common gart structure */ if (rdev->gart.table.vram.robj == NULL) {
r = radeon_gart_init(rdev); dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
if (r) { return -EINVAL;
return r;
} }
rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; r = radeon_gart_table_vram_pin(rdev);
r = radeon_gart_table_vram_alloc(rdev); if (r)
if (r) {
return r; return r;
}
for (i = 0; i < rdev->gart.num_gpu_pages; i++) for (i = 0; i < rdev->gart.num_gpu_pages; i++)
r600_gart_clear_page(rdev, i); r600_gart_clear_page(rdev, i);
/* Setup L2 cache */ /* Setup L2 cache */
...@@ -98,10 +95,6 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev) ...@@ -98,10 +95,6 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)
u32 tmp; u32 tmp;
int i; int i;
/* Clear ptes*/
for (i = 0; i < rdev->gart.num_gpu_pages; i++)
r600_gart_clear_page(rdev, i);
r600_pcie_gart_tlb_flush(rdev);
/* Disable all tables */ /* Disable all tables */
for (i = 0; i < 7; i++) for (i = 0; i < 7; i++)
WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
...@@ -120,6 +113,17 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev) ...@@ -120,6 +113,17 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)
WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
if (rdev->gart.table.vram.robj) {
radeon_object_kunmap(rdev->gart.table.vram.robj);
radeon_object_unpin(rdev->gart.table.vram.robj);
}
}
void rv770_pcie_gart_fini(struct radeon_device *rdev)
{
rv770_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
} }
...@@ -871,6 +875,7 @@ int rv770_suspend(struct radeon_device *rdev) ...@@ -871,6 +875,7 @@ int rv770_suspend(struct radeon_device *rdev)
{ {
/* FIXME: we should wait for ring to be empty */ /* FIXME: we should wait for ring to be empty */
r700_cp_stop(rdev); r700_cp_stop(rdev);
rv770_pcie_gart_disable(rdev);
return 0; return 0;
} }
...@@ -944,6 +949,10 @@ int rv770_init(struct radeon_device *rdev) ...@@ -944,6 +949,10 @@ int rv770_init(struct radeon_device *rdev)
} }
} }
r = r600_pcie_gart_init(rdev);
if (r)
return r;
r = rv770_resume(rdev); r = rv770_resume(rdev);
if (r) { if (r) {
if (rdev->flags & RADEON_IS_AGP) { if (rdev->flags & RADEON_IS_AGP) {
...@@ -976,9 +985,7 @@ void rv770_fini(struct radeon_device *rdev) ...@@ -976,9 +985,7 @@ void rv770_fini(struct radeon_device *rdev)
{ {
r600_blit_fini(rdev); r600_blit_fini(rdev);
radeon_ring_fini(rdev); radeon_ring_fini(rdev);
rv770_pcie_gart_disable(rdev); rv770_pcie_gart_fini(rdev);
radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
radeon_gem_fini(rdev); radeon_gem_fini(rdev);
radeon_fence_driver_fini(rdev); radeon_fence_driver_fini(rdev);
radeon_clocks_fini(rdev); radeon_clocks_fini(rdev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册