Commit f6bec6ea6816ece9d229c4d37c44e3222de14044
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'drm-intel-fixes-2015-03-05' of git://anongit.freedesktop.org/drm-intel into drm-fixes
two fixes, both cc'd stable. * tag 'drm-intel-fixes-2015-03-05' of git://anongit.freedesktop.org/drm-intel: drm/i915: gen4: work around hang during hibernation drm/i915: Check for driver readyness before handling an underrun interrupt
Showing 2 changed files Side-by-side Diff
drivers/gpu/drm/i915/i915_drv.c
... | ... | @@ -622,7 +622,7 @@ |
622 | 622 | return 0; |
623 | 623 | } |
624 | 624 | |
625 | -static int i915_drm_suspend_late(struct drm_device *drm_dev) | |
625 | +static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation) | |
626 | 626 | { |
627 | 627 | struct drm_i915_private *dev_priv = drm_dev->dev_private; |
628 | 628 | int ret; |
... | ... | @@ -636,7 +636,17 @@ |
636 | 636 | } |
637 | 637 | |
638 | 638 | pci_disable_device(drm_dev->pdev); |
639 | - pci_set_power_state(drm_dev->pdev, PCI_D3hot); | |
639 | + /* | |
640 | + * During hibernation on some GEN4 platforms the BIOS may try to access | |
641 | + * the device even though it's already in D3 and hang the machine. So | |
642 | + * leave the device in D0 on those platforms and hope the BIOS will | |
643 | + * power down the device properly. Platforms where this was seen: | |
644 | + * Lenovo Thinkpad X301, X61s | |
645 | + */ | |
646 | + if (!(hibernation && | |
647 | + drm_dev->pdev->subsystem_vendor == PCI_VENDOR_ID_LENOVO && | |
648 | + INTEL_INFO(dev_priv)->gen == 4)) | |
649 | + pci_set_power_state(drm_dev->pdev, PCI_D3hot); | |
640 | 650 | |
641 | 651 | return 0; |
642 | 652 | } |
... | ... | @@ -662,7 +672,7 @@ |
662 | 672 | if (error) |
663 | 673 | return error; |
664 | 674 | |
665 | - return i915_drm_suspend_late(dev); | |
675 | + return i915_drm_suspend_late(dev, false); | |
666 | 676 | } |
667 | 677 | |
668 | 678 | static int i915_drm_resume(struct drm_device *dev) |
669 | 679 | |
... | ... | @@ -950,9 +960,19 @@ |
950 | 960 | if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
951 | 961 | return 0; |
952 | 962 | |
953 | - return i915_drm_suspend_late(drm_dev); | |
963 | + return i915_drm_suspend_late(drm_dev, false); | |
954 | 964 | } |
955 | 965 | |
966 | +static int i915_pm_poweroff_late(struct device *dev) | |
967 | +{ | |
968 | + struct drm_device *drm_dev = dev_to_i915(dev)->dev; | |
969 | + | |
970 | + if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) | |
971 | + return 0; | |
972 | + | |
973 | + return i915_drm_suspend_late(drm_dev, true); | |
974 | +} | |
975 | + | |
956 | 976 | static int i915_pm_resume_early(struct device *dev) |
957 | 977 | { |
958 | 978 | struct drm_device *drm_dev = dev_to_i915(dev)->dev; |
... | ... | @@ -1520,7 +1540,7 @@ |
1520 | 1540 | .thaw_early = i915_pm_resume_early, |
1521 | 1541 | .thaw = i915_pm_resume, |
1522 | 1542 | .poweroff = i915_pm_suspend, |
1523 | - .poweroff_late = i915_pm_suspend_late, | |
1543 | + .poweroff_late = i915_pm_poweroff_late, | |
1524 | 1544 | .restore_early = i915_pm_resume_early, |
1525 | 1545 | .restore = i915_pm_resume, |
1526 | 1546 |
drivers/gpu/drm/i915/intel_fifo_underrun.c
... | ... | @@ -282,16 +282,6 @@ |
282 | 282 | return ret; |
283 | 283 | } |
284 | 284 | |
285 | -static bool | |
286 | -__cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv, | |
287 | - enum pipe pipe) | |
288 | -{ | |
289 | - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | |
290 | - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | |
291 | - | |
292 | - return !intel_crtc->cpu_fifo_underrun_disabled; | |
293 | -} | |
294 | - | |
295 | 285 | /** |
296 | 286 | * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state |
297 | 287 | * @dev_priv: i915 device instance |
298 | 288 | |
... | ... | @@ -352,9 +342,15 @@ |
352 | 342 | void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, |
353 | 343 | enum pipe pipe) |
354 | 344 | { |
345 | + struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | |
346 | + | |
347 | + /* We may be called too early in init, thanks BIOS! */ | |
348 | + if (crtc == NULL) | |
349 | + return; | |
350 | + | |
355 | 351 | /* GMCH can't disable fifo underruns, filter them. */ |
356 | 352 | if (HAS_GMCH_DISPLAY(dev_priv->dev) && |
357 | - !__cpu_fifo_underrun_reporting_enabled(dev_priv, pipe)) | |
353 | + to_intel_crtc(crtc)->cpu_fifo_underrun_disabled) | |
358 | 354 | return; |
359 | 355 | |
360 | 356 | if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) |