diff options
| author | Dave Airlie <airlied@redhat.com> | 2015-03-06 16:40:17 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2015-03-06 16:40:17 -0500 |
| commit | f6bec6ea6816ece9d229c4d37c44e3222de14044 (patch) | |
| tree | bf603d1038d06554daf18f242a76cfb8c8ecee6f /drivers/gpu | |
| parent | b0b20ce347b66a705943628ec0cc9e0a30eb785e (diff) | |
| parent | ab3be73fa7b43f4c3648ce29b5fd649ea54d3adb (diff) | |
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
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 30 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_fifo_underrun.c | 18 |
2 files changed, 32 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8039cec71fc2..cc6ea53d2b81 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -622,7 +622,7 @@ static int i915_drm_suspend(struct drm_device *dev) | |||
| 622 | return 0; | 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 | struct drm_i915_private *dev_priv = drm_dev->dev_private; | 627 | struct drm_i915_private *dev_priv = drm_dev->dev_private; |
| 628 | int ret; | 628 | int ret; |
| @@ -636,7 +636,17 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev) | |||
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | pci_disable_device(drm_dev->pdev); | 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 | return 0; | 651 | return 0; |
| 642 | } | 652 | } |
| @@ -662,7 +672,7 @@ int i915_suspend_legacy(struct drm_device *dev, pm_message_t state) | |||
| 662 | if (error) | 672 | if (error) |
| 663 | return error; | 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 | static int i915_drm_resume(struct drm_device *dev) | 678 | static int i915_drm_resume(struct drm_device *dev) |
| @@ -950,7 +960,17 @@ static int i915_pm_suspend_late(struct device *dev) | |||
| 950 | if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 960 | if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
| 951 | return 0; | 961 | return 0; |
| 952 | 962 | ||
| 953 | return i915_drm_suspend_late(drm_dev); | 963 | return i915_drm_suspend_late(drm_dev, false); |
| 964 | } | ||
| 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); | ||
| 954 | } | 974 | } |
| 955 | 975 | ||
| 956 | static int i915_pm_resume_early(struct device *dev) | 976 | static int i915_pm_resume_early(struct device *dev) |
| @@ -1520,7 +1540,7 @@ static const struct dev_pm_ops i915_pm_ops = { | |||
| 1520 | .thaw_early = i915_pm_resume_early, | 1540 | .thaw_early = i915_pm_resume_early, |
| 1521 | .thaw = i915_pm_resume, | 1541 | .thaw = i915_pm_resume, |
| 1522 | .poweroff = i915_pm_suspend, | 1542 | .poweroff = i915_pm_suspend, |
| 1523 | .poweroff_late = i915_pm_suspend_late, | 1543 | .poweroff_late = i915_pm_poweroff_late, |
| 1524 | .restore_early = i915_pm_resume_early, | 1544 | .restore_early = i915_pm_resume_early, |
| 1525 | .restore = i915_pm_resume, | 1545 | .restore = i915_pm_resume, |
| 1526 | 1546 | ||
diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index 04e248dd2259..54daa66c6970 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c | |||
| @@ -282,16 +282,6 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, | |||
| 282 | return ret; | 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 | * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state | 286 | * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state |
| 297 | * @dev_priv: i915 device instance | 287 | * @dev_priv: i915 device instance |
| @@ -352,9 +342,15 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, | |||
| 352 | void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, | 342 | void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, |
| 353 | enum pipe pipe) | 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 | /* GMCH can't disable fifo underruns, filter them. */ | 351 | /* GMCH can't disable fifo underruns, filter them. */ |
| 356 | if (HAS_GMCH_DISPLAY(dev_priv->dev) && | 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 | return; | 354 | return; |
| 359 | 355 | ||
| 360 | if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) | 356 | if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) |
