Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6bec6ea authored by Dave Airlie's avatar Dave Airlie
Browse files

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
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -622,7 +622,7 @@ static int i915_drm_suspend(struct drm_device *dev)
	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;
	int ret;
@@ -636,6 +636,16 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev)
	}

	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);

	return 0;
@@ -662,7 +672,7 @@ int i915_suspend_legacy(struct drm_device *dev, pm_message_t state)
	if (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)
@@ -950,7 +960,17 @@ static int i915_pm_suspend_late(struct device *dev)
	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		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)
@@ -1520,7 +1540,7 @@ static const struct dev_pm_ops i915_pm_ops = {
	.thaw_early = i915_pm_resume_early,
	.thaw = i915_pm_resume,
	.poweroff = i915_pm_suspend,
	.poweroff_late = i915_pm_suspend_late,
	.poweroff_late = i915_pm_poweroff_late,
	.restore_early = i915_pm_resume_early,
	.restore = i915_pm_resume,

+7 −11
Original line number Diff line number Diff line
@@ -282,16 +282,6 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
	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
 * @dev_priv: i915 device instance
@@ -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,
					 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. */
	if (HAS_GMCH_DISPLAY(dev_priv->dev) &&
	    !__cpu_fifo_underrun_reporting_enabled(dev_priv, pipe))
	    to_intel_crtc(crtc)->cpu_fifo_underrun_disabled)
		return;

	if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false))