diff mbox

drm/i915: Configure GPU PM in ->suspend() if not configured

Message ID 1521454544-23891-1-git-send-email-rushikesh.s.kadam@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Rushikesh S Kadam March 19, 2018, 10:15 a.m. UTC
The patch implements workaround for a scenario, where the GPU Power
Management, if not configured prior to platform suspend entry, will block
SoC S0ix entry in suspend-to-idle.

Typically the GPU Power Management configuration is restored after a
platform suspend cycle, in the drm ioclts callbacks (such as ioclt
I915_GEM_EXECBUFFER2_WR).

There exists a corner case - if the next platform suspend cycle is
initiated quickly, before the ioctl callbacks are triggered, the GPU
Power Management is not setup at the time of suspend entry.

In such as scenario, the GPU does not enter low power state (RC6), which in
turn prevents the SoC from entering low power package state (PC2 or
deeper). This blocks SoC S0ix entry in suspend-to-idle.

The patch detects such a condition and works around by configuring GPU
Power Management in i915 driver's ->suspend().

Signed-off-by: Rushikesh S Kadam <rushikesh.s.kadam@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

Comments

Chris Wilson March 19, 2018, 10:33 a.m. UTC | #1
Quoting Rushikesh S Kadam (2018-03-19 10:15:44)
> The patch implements workaround for a scenario, where the GPU Power
> Management, if not configured prior to platform suspend entry, will block
> SoC S0ix entry in suspend-to-idle.
> 
> Typically the GPU Power Management configuration is restored after a
> platform suspend cycle, in the drm ioclts callbacks (such as ioclt
> I915_GEM_EXECBUFFER2_WR).

As I indicated on the bug report, this is not how the kernel works
currently. On load/resume, enabling powermanagement is forced.

Please do test upstream.
-Chris
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index f03555e..9f3cc4c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2076,6 +2076,7 @@  static int i915_pm_suspend(struct device *kdev)
 {
 	struct pci_dev *pdev = to_pci_dev(kdev);
 	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_i915_private *dev_priv = to_i915(dev);
 
 	if (!dev) {
 		dev_err(kdev, "DRM not initialized, aborting suspend.\n");
@@ -2085,6 +2086,31 @@  static int i915_pm_suspend(struct device *kdev)
 	if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
 		return 0;
 
+	/*
+	 * Implement workaround for a scenario, where the GPU Power
+	 * Management, if not configured prior to platform suspend
+	 * entry, will block SoC S0ix entry in suspend-to-idle.
+	 *
+	 * Typically the GPU Power Management configuration is
+	 * restored in drm runtime / ioclts callbacks (such as
+	 * I915_GEM_EXECBUFFER2_WR) after the platform has resumed
+	 * from a suspend cycle.
+	 *
+	 * There exists a corner case - if the next platform suspend
+	 * cycle is initiated quickly, before the runtime callbacks
+	 * are triggered, the GPU Power Management is not configured
+	 * at time of suspend entry. This blocks SoC S0ix entry in
+	 * suspend-to-idle
+	 *
+	 * Detect such a condition, and workaround by configuring the
+	 * GPU Power Management here.
+	 */
+	if (INTEL_GEN(dev_priv) >= 9 &&
+	    (!(I915_READ(GEN6_RC_CONTROL) & GEN6_RC_CTL_HW_ENABLE))) {
+		DRM_INFO("Detected GPU PM is not configured! Configure now.\n");
+		intel_enable_gt_powersave(dev_priv);
+	}
+
 	return i915_drm_suspend(dev);
 }