Commit f6bec6ea authored by Dave Airlie's avatar Dave Airlie

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
parents b0b20ce3 ab3be73f
...@@ -622,7 +622,7 @@ static int i915_drm_suspend(struct drm_device *dev) ...@@ -622,7 +622,7 @@ static int i915_drm_suspend(struct drm_device *dev)
return 0; return 0;
} }
static int i915_drm_suspend_late(struct drm_device *drm_dev) static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)
{ {
struct drm_i915_private *dev_priv = drm_dev->dev_private; struct drm_i915_private *dev_priv = drm_dev->dev_private;
int ret; int ret;
...@@ -636,6 +636,16 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev) ...@@ -636,6 +636,16 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev)
} }
pci_disable_device(drm_dev->pdev); pci_disable_device(drm_dev->pdev);
/*
* During hibernation on some GEN4 platforms the BIOS may try to access
* the device even though it's already in D3 and hang the machine. So
* leave the device in D0 on those platforms and hope the BIOS will
* power down the device properly. Platforms where this was seen:
* Lenovo Thinkpad X301, X61s
*/
if (!(hibernation &&
drm_dev->pdev->subsystem_vendor == PCI_VENDOR_ID_LENOVO &&
INTEL_INFO(dev_priv)->gen == 4))
pci_set_power_state(drm_dev->pdev, PCI_D3hot); pci_set_power_state(drm_dev->pdev, PCI_D3hot);
return 0; return 0;
...@@ -662,7 +672,7 @@ int i915_suspend_legacy(struct drm_device *dev, pm_message_t state) ...@@ -662,7 +672,7 @@ int i915_suspend_legacy(struct drm_device *dev, pm_message_t state)
if (error) if (error)
return error; return error;
return i915_drm_suspend_late(dev); return i915_drm_suspend_late(dev, false);
} }
static int i915_drm_resume(struct drm_device *dev) static int i915_drm_resume(struct drm_device *dev)
...@@ -950,7 +960,17 @@ static int i915_pm_suspend_late(struct device *dev) ...@@ -950,7 +960,17 @@ static int i915_pm_suspend_late(struct device *dev)
if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0; return 0;
return i915_drm_suspend_late(drm_dev); return i915_drm_suspend_late(drm_dev, false);
}
static int i915_pm_poweroff_late(struct device *dev)
{
struct drm_device *drm_dev = dev_to_i915(dev)->dev;
if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
return 0;
return i915_drm_suspend_late(drm_dev, true);
} }
static int i915_pm_resume_early(struct device *dev) static int i915_pm_resume_early(struct device *dev)
...@@ -1520,7 +1540,7 @@ static const struct dev_pm_ops i915_pm_ops = { ...@@ -1520,7 +1540,7 @@ static const struct dev_pm_ops i915_pm_ops = {
.thaw_early = i915_pm_resume_early, .thaw_early = i915_pm_resume_early,
.thaw = i915_pm_resume, .thaw = i915_pm_resume,
.poweroff = i915_pm_suspend, .poweroff = i915_pm_suspend,
.poweroff_late = i915_pm_suspend_late, .poweroff_late = i915_pm_poweroff_late,
.restore_early = i915_pm_resume_early, .restore_early = i915_pm_resume_early,
.restore = i915_pm_resume, .restore = i915_pm_resume,
......
...@@ -282,16 +282,6 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, ...@@ -282,16 +282,6 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
return ret; return ret;
} }
static bool
__cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv,
enum pipe pipe)
{
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
return !intel_crtc->cpu_fifo_underrun_disabled;
}
/** /**
* intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state
* @dev_priv: i915 device instance * @dev_priv: i915 device instance
...@@ -352,9 +342,15 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, ...@@ -352,9 +342,15 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
enum pipe pipe) enum pipe pipe)
{ {
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
/* We may be called too early in init, thanks BIOS! */
if (crtc == NULL)
return;
/* GMCH can't disable fifo underruns, filter them. */ /* GMCH can't disable fifo underruns, filter them. */
if (HAS_GMCH_DISPLAY(dev_priv->dev) && if (HAS_GMCH_DISPLAY(dev_priv->dev) &&
!__cpu_fifo_underrun_reporting_enabled(dev_priv, pipe)) to_intel_crtc(crtc)->cpu_fifo_underrun_disabled)
return; return;
if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment