diff options
author | Jerome Glisse <jglisse@redhat.com> | 2009-09-14 12:29:49 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-09-14 18:53:14 -0400 |
commit | 4aac047323e3082d0866b8ad3784236632105af4 (patch) | |
tree | af4c118e42b9ea55c961c4f5bbb02998dc2cc4fe /drivers/gpu/drm/radeon/r600.c | |
parent | 21f9a437222e92adb3abc68584a5f04801b92739 (diff) |
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: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 1bc25678986b..65699e9f2025 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -113,21 +113,34 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | int r600_pcie_gart_enable(struct radeon_device *rdev) | 116 | int r600_pcie_gart_init(struct radeon_device *rdev) |
117 | { | 117 | { |
118 | u32 tmp; | 118 | int r; |
119 | int r, i; | ||
120 | 119 | ||
120 | if (rdev->gart.table.vram.robj) { | ||
121 | WARN(1, "R600 PCIE GART already initialized.\n"); | ||
122 | return 0; | ||
123 | } | ||
121 | /* Initialize common gart structure */ | 124 | /* Initialize common gart structure */ |
122 | r = radeon_gart_init(rdev); | 125 | r = radeon_gart_init(rdev); |
123 | if (r) { | 126 | if (r) |
124 | return r; | 127 | return r; |
125 | } | ||
126 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; | 128 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; |
127 | r = radeon_gart_table_vram_alloc(rdev); | 129 | return radeon_gart_table_vram_alloc(rdev); |
128 | if (r) { | 130 | } |
129 | return r; | 131 | |
132 | int r600_pcie_gart_enable(struct radeon_device *rdev) | ||
133 | { | ||
134 | u32 tmp; | ||
135 | int r, i; | ||
136 | |||
137 | if (rdev->gart.table.vram.robj == NULL) { | ||
138 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | ||
139 | return -EINVAL; | ||
130 | } | 140 | } |
141 | r = radeon_gart_table_vram_pin(rdev); | ||
142 | if (r) | ||
143 | return r; | ||
131 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) | 144 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) |
132 | r600_gart_clear_page(rdev, i); | 145 | r600_gart_clear_page(rdev, i); |
133 | /* Setup L2 cache */ | 146 | /* Setup L2 cache */ |
@@ -175,10 +188,6 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) | |||
175 | u32 tmp; | 188 | u32 tmp; |
176 | int i; | 189 | int i; |
177 | 190 | ||
178 | /* Clear ptes*/ | ||
179 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) | ||
180 | r600_gart_clear_page(rdev, i); | ||
181 | r600_pcie_gart_tlb_flush(rdev); | ||
182 | /* Disable all tables */ | 191 | /* Disable all tables */ |
183 | for (i = 0; i < 7; i++) | 192 | for (i = 0; i < 7; i++) |
184 | WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); | 193 | WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); |
@@ -204,6 +213,17 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) | |||
204 | WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); | 213 | WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); |
205 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); | 214 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); |
206 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); | 215 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); |
216 | if (rdev->gart.table.vram.robj) { | ||
217 | radeon_object_kunmap(rdev->gart.table.vram.robj); | ||
218 | radeon_object_unpin(rdev->gart.table.vram.robj); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | void r600_pcie_gart_fini(struct radeon_device *rdev) | ||
223 | { | ||
224 | r600_pcie_gart_disable(rdev); | ||
225 | radeon_gart_table_vram_free(rdev); | ||
226 | radeon_gart_fini(rdev); | ||
207 | } | 227 | } |
208 | 228 | ||
209 | int r600_mc_wait_for_idle(struct radeon_device *rdev) | 229 | int r600_mc_wait_for_idle(struct radeon_device *rdev) |
@@ -1472,6 +1492,7 @@ int r600_suspend(struct radeon_device *rdev) | |||
1472 | { | 1492 | { |
1473 | /* FIXME: we should wait for ring to be empty */ | 1493 | /* FIXME: we should wait for ring to be empty */ |
1474 | r600_cp_stop(rdev); | 1494 | r600_cp_stop(rdev); |
1495 | r600_pcie_gart_disable(rdev); | ||
1475 | return 0; | 1496 | return 0; |
1476 | } | 1497 | } |
1477 | 1498 | ||
@@ -1548,6 +1569,10 @@ int r600_init(struct radeon_device *rdev) | |||
1548 | } | 1569 | } |
1549 | } | 1570 | } |
1550 | 1571 | ||
1572 | r = r600_pcie_gart_init(rdev); | ||
1573 | if (r) | ||
1574 | return r; | ||
1575 | |||
1551 | r = r600_resume(rdev); | 1576 | r = r600_resume(rdev); |
1552 | if (r) { | 1577 | if (r) { |
1553 | if (rdev->flags & RADEON_IS_AGP) { | 1578 | if (rdev->flags & RADEON_IS_AGP) { |
@@ -1583,9 +1608,7 @@ void r600_fini(struct radeon_device *rdev) | |||
1583 | 1608 | ||
1584 | r600_blit_fini(rdev); | 1609 | r600_blit_fini(rdev); |
1585 | radeon_ring_fini(rdev); | 1610 | radeon_ring_fini(rdev); |
1586 | r600_pcie_gart_disable(rdev); | 1611 | r600_pcie_gart_fini(rdev); |
1587 | radeon_gart_table_vram_free(rdev); | ||
1588 | radeon_gart_fini(rdev); | ||
1589 | radeon_gem_fini(rdev); | 1612 | radeon_gem_fini(rdev); |
1590 | radeon_fence_driver_fini(rdev); | 1613 | radeon_fence_driver_fini(rdev); |
1591 | radeon_clocks_fini(rdev); | 1614 | radeon_clocks_fini(rdev); |