diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_drv.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 80 |
1 files changed, 54 insertions, 26 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 184340d486c3..61a03ac90f8c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -301,6 +301,8 @@ static void vmw_print_capabilities(uint32_t capabilities) | |||
301 | DRM_INFO(" Guest Backed Resources.\n"); | 301 | DRM_INFO(" Guest Backed Resources.\n"); |
302 | if (capabilities & SVGA_CAP_DX) | 302 | if (capabilities & SVGA_CAP_DX) |
303 | DRM_INFO(" DX Features.\n"); | 303 | DRM_INFO(" DX Features.\n"); |
304 | if (capabilities & SVGA_CAP_HP_CMD_QUEUE) | ||
305 | DRM_INFO(" HP Command Queue.\n"); | ||
304 | } | 306 | } |
305 | 307 | ||
306 | /** | 308 | /** |
@@ -1277,8 +1279,7 @@ static void vmw_master_drop(struct drm_device *dev, | |||
1277 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); | 1279 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); |
1278 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); | 1280 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); |
1279 | 1281 | ||
1280 | if (dev_priv->enable_fb) | 1282 | vmw_fb_refresh(dev_priv); |
1281 | vmw_fb_on(dev_priv); | ||
1282 | } | 1283 | } |
1283 | 1284 | ||
1284 | /** | 1285 | /** |
@@ -1368,28 +1369,23 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, | |||
1368 | 1369 | ||
1369 | switch (val) { | 1370 | switch (val) { |
1370 | case PM_HIBERNATION_PREPARE: | 1371 | case PM_HIBERNATION_PREPARE: |
1371 | if (dev_priv->enable_fb) | ||
1372 | vmw_fb_off(dev_priv); | ||
1373 | ttm_suspend_lock(&dev_priv->reservation_sem); | ||
1374 | |||
1375 | /* | 1372 | /* |
1376 | * This empties VRAM and unbinds all GMR bindings. | 1373 | * Take the reservation sem in write mode, which will make sure |
1377 | * Buffer contents is moved to swappable memory. | 1374 | * there are no other processes holding a buffer object |
1375 | * reservation, meaning we should be able to evict all buffer | ||
1376 | * objects if needed. | ||
1377 | * Once user-space processes have been frozen, we can release | ||
1378 | * the lock again. | ||
1378 | */ | 1379 | */ |
1379 | vmw_execbuf_release_pinned_bo(dev_priv); | 1380 | ttm_suspend_lock(&dev_priv->reservation_sem); |
1380 | vmw_resource_evict_all(dev_priv); | 1381 | dev_priv->suspend_locked = true; |
1381 | vmw_release_device_early(dev_priv); | ||
1382 | ttm_bo_swapout_all(&dev_priv->bdev); | ||
1383 | vmw_fence_fifo_down(dev_priv->fman); | ||
1384 | break; | 1382 | break; |
1385 | case PM_POST_HIBERNATION: | 1383 | case PM_POST_HIBERNATION: |
1386 | case PM_POST_RESTORE: | 1384 | case PM_POST_RESTORE: |
1387 | vmw_fence_fifo_up(dev_priv->fman); | 1385 | if (READ_ONCE(dev_priv->suspend_locked)) { |
1388 | ttm_suspend_unlock(&dev_priv->reservation_sem); | 1386 | dev_priv->suspend_locked = false; |
1389 | if (dev_priv->enable_fb) | 1387 | ttm_suspend_unlock(&dev_priv->reservation_sem); |
1390 | vmw_fb_on(dev_priv); | 1388 | } |
1391 | break; | ||
1392 | case PM_RESTORE_PREPARE: | ||
1393 | break; | 1389 | break; |
1394 | default: | 1390 | default: |
1395 | break; | 1391 | break; |
@@ -1440,25 +1436,48 @@ static int vmw_pm_freeze(struct device *kdev) | |||
1440 | struct pci_dev *pdev = to_pci_dev(kdev); | 1436 | struct pci_dev *pdev = to_pci_dev(kdev); |
1441 | struct drm_device *dev = pci_get_drvdata(pdev); | 1437 | struct drm_device *dev = pci_get_drvdata(pdev); |
1442 | struct vmw_private *dev_priv = vmw_priv(dev); | 1438 | struct vmw_private *dev_priv = vmw_priv(dev); |
1439 | int ret; | ||
1443 | 1440 | ||
1444 | dev_priv->suspended = true; | 1441 | /* |
1442 | * Unlock for vmw_kms_suspend. | ||
1443 | * No user-space processes should be running now. | ||
1444 | */ | ||
1445 | ttm_suspend_unlock(&dev_priv->reservation_sem); | ||
1446 | ret = vmw_kms_suspend(dev_priv->dev); | ||
1447 | if (ret) { | ||
1448 | ttm_suspend_lock(&dev_priv->reservation_sem); | ||
1449 | DRM_ERROR("Failed to freeze modesetting.\n"); | ||
1450 | return ret; | ||
1451 | } | ||
1445 | if (dev_priv->enable_fb) | 1452 | if (dev_priv->enable_fb) |
1446 | vmw_fifo_resource_dec(dev_priv); | 1453 | vmw_fb_off(dev_priv); |
1447 | 1454 | ||
1455 | ttm_suspend_lock(&dev_priv->reservation_sem); | ||
1456 | vmw_execbuf_release_pinned_bo(dev_priv); | ||
1457 | vmw_resource_evict_all(dev_priv); | ||
1458 | vmw_release_device_early(dev_priv); | ||
1459 | ttm_bo_swapout_all(&dev_priv->bdev); | ||
1460 | if (dev_priv->enable_fb) | ||
1461 | vmw_fifo_resource_dec(dev_priv); | ||
1448 | if (atomic_read(&dev_priv->num_fifo_resources) != 0) { | 1462 | if (atomic_read(&dev_priv->num_fifo_resources) != 0) { |
1449 | DRM_ERROR("Can't hibernate while 3D resources are active.\n"); | 1463 | DRM_ERROR("Can't hibernate while 3D resources are active.\n"); |
1450 | if (dev_priv->enable_fb) | 1464 | if (dev_priv->enable_fb) |
1451 | vmw_fifo_resource_inc(dev_priv); | 1465 | vmw_fifo_resource_inc(dev_priv); |
1452 | WARN_ON(vmw_request_device_late(dev_priv)); | 1466 | WARN_ON(vmw_request_device_late(dev_priv)); |
1453 | dev_priv->suspended = false; | 1467 | dev_priv->suspend_locked = false; |
1468 | ttm_suspend_unlock(&dev_priv->reservation_sem); | ||
1469 | if (dev_priv->suspend_state) | ||
1470 | vmw_kms_resume(dev); | ||
1471 | if (dev_priv->enable_fb) | ||
1472 | vmw_fb_on(dev_priv); | ||
1473 | vmw_fb_refresh(dev_priv); | ||
1454 | return -EBUSY; | 1474 | return -EBUSY; |
1455 | } | 1475 | } |
1456 | 1476 | ||
1457 | if (dev_priv->enable_fb) | 1477 | vmw_fence_fifo_down(dev_priv->fman); |
1458 | __vmw_svga_disable(dev_priv); | 1478 | __vmw_svga_disable(dev_priv); |
1459 | 1479 | ||
1460 | vmw_release_device_late(dev_priv); | 1480 | vmw_release_device_late(dev_priv); |
1461 | |||
1462 | return 0; | 1481 | return 0; |
1463 | } | 1482 | } |
1464 | 1483 | ||
@@ -1482,7 +1501,16 @@ static int vmw_pm_restore(struct device *kdev) | |||
1482 | if (dev_priv->enable_fb) | 1501 | if (dev_priv->enable_fb) |
1483 | __vmw_svga_enable(dev_priv); | 1502 | __vmw_svga_enable(dev_priv); |
1484 | 1503 | ||
1485 | dev_priv->suspended = false; | 1504 | vmw_fence_fifo_up(dev_priv->fman); |
1505 | dev_priv->suspend_locked = false; | ||
1506 | ttm_suspend_unlock(&dev_priv->reservation_sem); | ||
1507 | if (dev_priv->suspend_state) | ||
1508 | vmw_kms_resume(dev_priv->dev); | ||
1509 | |||
1510 | if (dev_priv->enable_fb) | ||
1511 | vmw_fb_on(dev_priv); | ||
1512 | |||
1513 | vmw_fb_refresh(dev_priv); | ||
1486 | 1514 | ||
1487 | return 0; | 1515 | return 0; |
1488 | } | 1516 | } |