aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2012-07-05 08:32:00 -0400
committerChristian König <deathsimple@vodafone.de>2012-07-17 04:32:55 -0400
commitc6105f249a637e1bb2b04b1cad7feaf507d06e8c (patch)
tree6dfaa699908277f651d60bbea6089bf25ac228ae /drivers
parent6f72a631998d37673828b0e97c63dafc8e923382 (diff)
drm/radeon: remove vm_manager start/suspend
Just restore the page table instead. Addressing three problem with this change: 1. Calling vm_manager_suspend in the suspend path is problematic cause it wants to wait for the VM use to end, which in case of a lockup never happens. 2. In case of a locked up memory controller unbinding the VM seems to make it even more unstable, creating an unrecoverable lockup in the end. 3. If we want to backup/restore the leftover ring content we must not unbind VMs in between. Signed-off-by: Christian König <deathsimple@vodafone.de> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/ni.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c83
-rw-r--r--drivers/gpu/drm/radeon/si.c12
4 files changed, 59 insertions, 50 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 4004376362ee..ec5307c582f4 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1280,9 +1280,11 @@ static int cayman_startup(struct radeon_device *rdev)
1280 if (r) 1280 if (r)
1281 return r; 1281 return r;
1282 1282
1283 r = radeon_vm_manager_start(rdev); 1283 r = radeon_vm_manager_init(rdev);
1284 if (r) 1284 if (r) {
1285 dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
1285 return r; 1286 return r;
1287 }
1286 1288
1287 r = r600_audio_init(rdev); 1289 r = r600_audio_init(rdev);
1288 if (r) 1290 if (r)
@@ -1315,7 +1317,6 @@ int cayman_resume(struct radeon_device *rdev)
1315int cayman_suspend(struct radeon_device *rdev) 1317int cayman_suspend(struct radeon_device *rdev)
1316{ 1318{
1317 r600_audio_fini(rdev); 1319 r600_audio_fini(rdev);
1318 radeon_vm_manager_suspend(rdev);
1319 cayman_cp_enable(rdev, false); 1320 cayman_cp_enable(rdev, false);
1320 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; 1321 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1321 evergreen_irq_suspend(rdev); 1322 evergreen_irq_suspend(rdev);
@@ -1392,11 +1393,6 @@ int cayman_init(struct radeon_device *rdev)
1392 return r; 1393 return r;
1393 1394
1394 rdev->accel_working = true; 1395 rdev->accel_working = true;
1395 r = radeon_vm_manager_init(rdev);
1396 if (r) {
1397 dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
1398 }
1399
1400 r = cayman_startup(rdev); 1396 r = cayman_startup(rdev);
1401 if (r) { 1397 if (r) {
1402 dev_err(rdev->dev, "disabling GPU acceleration\n"); 1398 dev_err(rdev->dev, "disabling GPU acceleration\n");
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 8a8c3f82950e..872270c9a0d0 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1759,8 +1759,6 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size
1759 */ 1759 */
1760int radeon_vm_manager_init(struct radeon_device *rdev); 1760int radeon_vm_manager_init(struct radeon_device *rdev);
1761void radeon_vm_manager_fini(struct radeon_device *rdev); 1761void radeon_vm_manager_fini(struct radeon_device *rdev);
1762int radeon_vm_manager_start(struct radeon_device *rdev);
1763int radeon_vm_manager_suspend(struct radeon_device *rdev);
1764int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); 1762int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm);
1765void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); 1763void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm);
1766int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); 1764int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm);
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index ee11c5073726..56752da4b816 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -282,27 +282,58 @@ void radeon_gart_fini(struct radeon_device *rdev)
282 * 282 *
283 * TODO bind a default page at vm initialization for default address 283 * TODO bind a default page at vm initialization for default address
284 */ 284 */
285
285int radeon_vm_manager_init(struct radeon_device *rdev) 286int radeon_vm_manager_init(struct radeon_device *rdev)
286{ 287{
288 struct radeon_vm *vm;
289 struct radeon_bo_va *bo_va;
287 int r; 290 int r;
288 291
289 rdev->vm_manager.enabled = false; 292 if (!rdev->vm_manager.enabled) {
293 /* mark first vm as always in use, it's the system one */
294 r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
295 rdev->vm_manager.max_pfn * 8,
296 RADEON_GEM_DOMAIN_VRAM);
297 if (r) {
298 dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
299 (rdev->vm_manager.max_pfn * 8) >> 10);
300 return r;
301 }
290 302
291 /* mark first vm as always in use, it's the system one */ 303 r = rdev->vm_manager.funcs->init(rdev);
292 r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, 304 if (r)
293 rdev->vm_manager.max_pfn * 8, 305 return r;
294 RADEON_GEM_DOMAIN_VRAM); 306
295 if (r) { 307 rdev->vm_manager.enabled = true;
296 dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", 308
297 (rdev->vm_manager.max_pfn * 8) >> 10); 309 r = radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager);
298 return r; 310 if (r)
311 return r;
299 } 312 }
300 313
301 r = rdev->vm_manager.funcs->init(rdev); 314 /* restore page table */
302 if (r == 0) 315 list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) {
303 rdev->vm_manager.enabled = true; 316 if (vm->id == -1)
317 continue;
304 318
305 return r; 319 list_for_each_entry(bo_va, &vm->va, vm_list) {
320 struct ttm_mem_reg *mem = NULL;
321 if (bo_va->valid)
322 mem = &bo_va->bo->tbo.mem;
323
324 bo_va->valid = false;
325 r = radeon_vm_bo_update_pte(rdev, vm, bo_va->bo, mem);
326 if (r) {
327 DRM_ERROR("Failed to update pte for vm %d!\n", vm->id);
328 }
329 }
330
331 r = rdev->vm_manager.funcs->bind(rdev, vm, vm->id);
332 if (r) {
333 DRM_ERROR("Failed to bind vm %d!\n", vm->id);
334 }
335 }
336 return 0;
306} 337}
307 338
308/* global mutex must be lock */ 339/* global mutex must be lock */
@@ -347,26 +378,11 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev,
347 378
348void radeon_vm_manager_fini(struct radeon_device *rdev) 379void radeon_vm_manager_fini(struct radeon_device *rdev)
349{ 380{
350 if (rdev->vm_manager.sa_manager.bo == NULL)
351 return;
352 radeon_vm_manager_suspend(rdev);
353 rdev->vm_manager.funcs->fini(rdev);
354 radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager);
355 rdev->vm_manager.enabled = false;
356}
357
358int radeon_vm_manager_start(struct radeon_device *rdev)
359{
360 if (rdev->vm_manager.sa_manager.bo == NULL) {
361 return -EINVAL;
362 }
363 return radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager);
364}
365
366int radeon_vm_manager_suspend(struct radeon_device *rdev)
367{
368 struct radeon_vm *vm, *tmp; 381 struct radeon_vm *vm, *tmp;
369 382
383 if (!rdev->vm_manager.enabled)
384 return;
385
370 mutex_lock(&rdev->vm_manager.lock); 386 mutex_lock(&rdev->vm_manager.lock);
371 /* unbind all active vm */ 387 /* unbind all active vm */
372 list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { 388 list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) {
@@ -374,7 +390,10 @@ int radeon_vm_manager_suspend(struct radeon_device *rdev)
374 } 390 }
375 rdev->vm_manager.funcs->fini(rdev); 391 rdev->vm_manager.funcs->fini(rdev);
376 mutex_unlock(&rdev->vm_manager.lock); 392 mutex_unlock(&rdev->vm_manager.lock);
377 return radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); 393
394 radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager);
395 radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager);
396 rdev->vm_manager.enabled = false;
378} 397}
379 398
380/* global mutex must be locked */ 399/* global mutex must be locked */
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 7c2618b9aa34..2b691abef4f7 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -3777,9 +3777,11 @@ static int si_startup(struct radeon_device *rdev)
3777 return r; 3777 return r;
3778 } 3778 }
3779 3779
3780 r = radeon_vm_manager_start(rdev); 3780 r = radeon_vm_manager_init(rdev);
3781 if (r) 3781 if (r) {
3782 dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
3782 return r; 3783 return r;
3784 }
3783 3785
3784 return 0; 3786 return 0;
3785} 3787}
@@ -3809,7 +3811,6 @@ int si_resume(struct radeon_device *rdev)
3809 3811
3810int si_suspend(struct radeon_device *rdev) 3812int si_suspend(struct radeon_device *rdev)
3811{ 3813{
3812 radeon_vm_manager_suspend(rdev);
3813 si_cp_enable(rdev, false); 3814 si_cp_enable(rdev, false);
3814 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; 3815 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3815 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; 3816 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
@@ -3899,11 +3900,6 @@ int si_init(struct radeon_device *rdev)
3899 return r; 3900 return r;
3900 3901
3901 rdev->accel_working = true; 3902 rdev->accel_working = true;
3902 r = radeon_vm_manager_init(rdev);
3903 if (r) {
3904 dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
3905 }
3906
3907 r = si_startup(rdev); 3903 r = si_startup(rdev);
3908 if (r) { 3904 if (r) {
3909 dev_err(rdev->dev, "disabling GPU acceleration\n"); 3905 dev_err(rdev->dev, "disabling GPU acceleration\n");