aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_device.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 49b06590001e..edfc54e41842 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -897,6 +897,25 @@ static void radeon_check_arguments(struct radeon_device *rdev)
897} 897}
898 898
899/** 899/**
900 * radeon_switcheroo_quirk_long_wakeup - return true if longer d3 delay is
901 * needed for waking up.
902 *
903 * @pdev: pci dev pointer
904 */
905static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev)
906{
907
908 /* 6600m in a macbook pro */
909 if (pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
910 pdev->subsystem_device == 0x00e2) {
911 printk(KERN_INFO "radeon: quirking longer d3 wakeup delay\n");
912 return true;
913 }
914
915 return false;
916}
917
918/**
900 * radeon_switcheroo_set_state - set switcheroo state 919 * radeon_switcheroo_set_state - set switcheroo state
901 * 920 *
902 * @pdev: pci dev pointer 921 * @pdev: pci dev pointer
@@ -910,10 +929,19 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
910 struct drm_device *dev = pci_get_drvdata(pdev); 929 struct drm_device *dev = pci_get_drvdata(pdev);
911 pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; 930 pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
912 if (state == VGA_SWITCHEROO_ON) { 931 if (state == VGA_SWITCHEROO_ON) {
932 unsigned d3_delay = dev->pdev->d3_delay;
933
913 printk(KERN_INFO "radeon: switched on\n"); 934 printk(KERN_INFO "radeon: switched on\n");
914 /* don't suspend or resume card normally */ 935 /* don't suspend or resume card normally */
915 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; 936 dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
937
938 if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev))
939 dev->pdev->d3_delay = 20;
940
916 radeon_resume_kms(dev); 941 radeon_resume_kms(dev);
942
943 dev->pdev->d3_delay = d3_delay;
944
917 dev->switch_power_state = DRM_SWITCH_POWER_ON; 945 dev->switch_power_state = DRM_SWITCH_POWER_ON;
918 drm_kms_helper_poll_enable(dev); 946 drm_kms_helper_poll_enable(dev);
919 } else { 947 } else {
@@ -1164,6 +1192,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
1164 struct drm_crtc *crtc; 1192 struct drm_crtc *crtc;
1165 struct drm_connector *connector; 1193 struct drm_connector *connector;
1166 int i, r; 1194 int i, r;
1195 bool force_completion = false;
1167 1196
1168 if (dev == NULL || dev->dev_private == NULL) { 1197 if (dev == NULL || dev->dev_private == NULL) {
1169 return -ENODEV; 1198 return -ENODEV;
@@ -1206,8 +1235,16 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
1206 1235
1207 mutex_lock(&rdev->ring_lock); 1236 mutex_lock(&rdev->ring_lock);
1208 /* wait for gpu to finish processing current batch */ 1237 /* wait for gpu to finish processing current batch */
1209 for (i = 0; i < RADEON_NUM_RINGS; i++) 1238 for (i = 0; i < RADEON_NUM_RINGS; i++) {
1210 radeon_fence_wait_empty_locked(rdev, i); 1239 r = radeon_fence_wait_empty_locked(rdev, i);
1240 if (r) {
1241 /* delay GPU reset to resume */
1242 force_completion = true;
1243 }
1244 }
1245 if (force_completion) {
1246 radeon_fence_driver_force_completion(rdev);
1247 }
1211 mutex_unlock(&rdev->ring_lock); 1248 mutex_unlock(&rdev->ring_lock);
1212 1249
1213 radeon_save_bios_scratch_regs(rdev); 1250 radeon_save_bios_scratch_regs(rdev);
@@ -1338,7 +1375,6 @@ retry:
1338 } 1375 }
1339 1376
1340 radeon_restore_bios_scratch_regs(rdev); 1377 radeon_restore_bios_scratch_regs(rdev);
1341 drm_helper_resume_force_mode(rdev->ddev);
1342 1378
1343 if (!r) { 1379 if (!r) {
1344 for (i = 0; i < RADEON_NUM_RINGS; ++i) { 1380 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
@@ -1358,11 +1394,14 @@ retry:
1358 } 1394 }
1359 } 1395 }
1360 } else { 1396 } else {
1397 radeon_fence_driver_force_completion(rdev);
1361 for (i = 0; i < RADEON_NUM_RINGS; ++i) { 1398 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1362 kfree(ring_data[i]); 1399 kfree(ring_data[i]);
1363 } 1400 }
1364 } 1401 }
1365 1402
1403 drm_helper_resume_force_mode(rdev->ddev);
1404
1366 ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); 1405 ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
1367 if (r) { 1406 if (r) {
1368 /* bad news, how to tell it to userspace ? */ 1407 /* bad news, how to tell it to userspace ? */