[PATCH 2/3] drm/i915: Handle GEN6_PMINTRMSK for RPS interrupts with GuC

Sagar Arun Kamble sagar.a.kamble at intel.com
Fri Sep 23 09:52:27 UTC 2016


Driver needs to ensure that it doesn't mask the PM interrupts, which are
unmasked/needed by GuC firmware. For that, Driver maintains a bitmask of
interrupts to be kept enabled, pm_intr_keep.

By default, RP Up/Down Threshold Interrupt bits (and others) in
GEN6_PMINTRMSK register were unmasked (by BIOS) before GuC Load. Hence
Driver was keeping them unmasked falsely assuming GuC needed them.
As an optimization, Driver needs to mask these bits in order to
avoid redundant UP threshold interrupts when frequency is set to maximum,
RP0 or Down threshold interrupts when frequency is set to minimum, RPn.

This patch will mask all bits in GEN6_PMINTRMSK before GuC is loaded to
ensure pm_intr_keep reflects only interrupts that are needed by GuC. Post
GuC load, writing cur_freq will restore bits other than pm_intr_keep.

Cc: Chris Wilson <chris at chris-wilson.co.uk>
Testcase: igt/pm_rps/interrupt-config
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble at intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c  | 13 +++++++++++++
 drivers/gpu/drm/i915/intel_drv.h |  1 +
 drivers/gpu/drm/i915/intel_pm.c  |  2 +-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1418c1c..7db57ef 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4399,12 +4399,25 @@ i915_gem_init_hw(struct drm_device *dev)
 
 	intel_mocs_init_l3cc_table(dev);
 
+	/*
+	 * Mask all interrupts to know which interrupts are needed by GuC.
+	 * Restore host side interrupt masks post load.
+	*/
+	I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u));
+
 	/* We can't enable contexts until all firmware is loaded */
 	ret = intel_guc_setup(dev);
 	if (ret)
 		goto out;
 
 out:
+	/*
+	 * Below write will ensure mask for RPS interrupts is restored back
+	 * to what Host had configured, particularly post reset.
+	 */
+	I915_WRITE(GEN6_PMINTRMSK,
+		   gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq));
+
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index e3462a7..89542c8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1733,6 +1733,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv);
 void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv);
 void intel_disable_gt_powersave(struct drm_i915_private *dev_priv);
 void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv);
+u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val);
 void gen6_rps_busy(struct drm_i915_private *dev_priv);
 void gen6_rps_reset_ei(struct drm_i915_private *dev_priv);
 void gen6_rps_idle(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 2df06b7..fde8569 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4851,7 +4851,7 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 	dev_priv->rps.last_adj = 0;
 }
 
-static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
+u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
 {
 	u32 mask = 0;
 
-- 
1.9.1



More information about the Intel-gfx-trybot mailing list