[Intel-gfx] [PATCH 1/1] drm/i915: Update GEN6_PMINTRMSK setup with GuC submission
Sagar Arun Kamble
sagar.a.kamble at intel.com
Mon May 30 09:52:31 UTC 2016
On Loading, GuC sets PM interrupts routing (bit 31) and unmasks ARAT
expired interrupt (bit 9). Host turbo also updates this register
in RPS flows. This patch ensures bit 31 and bit 9 setup by GuC persists.
ARAT timer interrupt is needed in GuC for various features. It also
facilitates halting GuC and hence achieving RC6. PM interrupt routing
will not impact RPS interrupt reception by host as GuC will redirect
them.
This patch fixes igt test pm_rc6_residency. Tested with SKL GuC v6.1
and BXT GuC v5.1 and v8.7.
Cc: Chris Harris <chris.harris at intel.com>
Cc: Zhe Wang <zhe1.wang at intel.com>
Cc: Deepak S <deepak.s at intel.com>
Cc: Satyanantha, Rama Gopal M <rama.gopal.m.satyanantha at intel.com>
Cc: Akash Goel <akash.goel at intel.com>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble at intel.com>
---
drivers/gpu/drm/i915/i915_guc_submission.c | 8 ++++++++
drivers/gpu/drm/i915/i915_irq.c | 14 ++++++++++++--
drivers/gpu/drm/i915/i915_reg.h | 3 ++-
drivers/gpu/drm/i915/intel_guc.h | 3 +++
drivers/gpu/drm/i915/intel_guc_loader.c | 2 ++
drivers/gpu/drm/i915/intel_pm.c | 16 +++++++++++++++-
6 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c
index 169242a..4749588 100644
--- a/drivers/gpu/drm/i915/i915_guc_submission.c
+++ b/drivers/gpu/drm/i915/i915_guc_submission.c
@@ -941,6 +941,14 @@ void i915_guc_submission_disable(struct drm_device *dev)
guc->execbuf_client = NULL;
}
+void i915_guc_get_pm_state(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_guc *guc = &dev_priv->guc;
+
+ guc->pm_intr_mask = I915_READ(GEN6_PMINTRMSK);
+}
+
void i915_guc_submission_fini(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index f0d9414..25c0b192 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -364,6 +364,8 @@ void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv)
u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask)
{
+ struct intel_guc *guc = &dev_priv->guc;
+
/*
* SNB,IVB can while VLV,CHV may hard hang on looping batchbuffer
* if GEN6_PM_UP_EI_EXPIRED is masked.
@@ -373,8 +375,16 @@ u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask)
if (INTEL_INFO(dev_priv)->gen <= 7 && !IS_HASWELL(dev_priv))
mask &= ~GEN6_PM_RP_UP_EI_EXPIRED;
- if (INTEL_INFO(dev_priv)->gen >= 8)
- mask &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP;
+ /*
+ * If PM interrupts are routed to GuC, Set mask for ARAT Expired
+ * interrupt based on mask set by GuC.
+ */
+ if (INTEL_INFO(dev_priv)->gen >= 8) {
+ if (guc->pm_intr_mask & GEN8_PMINTR_REDIRECT_TO_NON_DISP)
+ mask &= guc->pm_intr_mask | ~GEN8_ARAT_EXPIRED_INT_MASK;
+ else
+ mask &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP;
+ }
return mask;
}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 86fbf72..98c20d7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7030,7 +7030,8 @@ enum skl_disp_power_wells {
#define VLV_RCEDATA _MMIO(0xA0BC)
#define GEN6_RC6pp_THRESHOLD _MMIO(0xA0C0)
#define GEN6_PMINTRMSK _MMIO(0xA168)
-#define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31)
+#define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31)
+#define GEN8_ARAT_EXPIRED_INT_MASK (1<<9)
#define VLV_PWRDWNUPCTL _MMIO(0xA294)
#define GEN9_MEDIA_PG_IDLE_HYSTERESIS _MMIO(0xA0C4)
#define GEN9_RENDER_PG_IDLE_HYSTERESIS _MMIO(0xA0C8)
diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h
index 9d79c4c..65904ab 100644
--- a/drivers/gpu/drm/i915/intel_guc.h
+++ b/drivers/gpu/drm/i915/intel_guc.h
@@ -135,6 +135,8 @@ struct intel_guc {
uint64_t submissions[GUC_MAX_ENGINES_NUM];
uint32_t last_seqno[GUC_MAX_ENGINES_NUM];
+
+ uint32_t pm_intr_mask;
};
/* intel_guc_loader.c */
@@ -151,6 +153,7 @@ int i915_guc_submission_enable(struct drm_device *dev);
int i915_guc_submit(struct i915_guc_client *client,
struct drm_i915_gem_request *rq);
void i915_guc_submission_disable(struct drm_device *dev);
+void i915_guc_get_pm_state(struct drm_device *dev);
void i915_guc_submission_fini(struct drm_device *dev);
int i915_guc_wq_check_space(struct i915_guc_client *client);
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
index 23345e1..33c6046 100644
--- a/drivers/gpu/drm/i915/intel_guc_loader.c
+++ b/drivers/gpu/drm/i915/intel_guc_loader.c
@@ -476,6 +476,8 @@ int intel_guc_ucode_load(struct drm_device *dev)
/* The execbuf_client will be recreated. Release it first. */
i915_guc_submission_disable(dev);
+ i915_guc_get_pm_state(dev);
+
err = i915_guc_submission_enable(dev);
if (err)
goto fail;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index adb6463..c5e2311 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4708,6 +4708,9 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv)
void gen6_rps_idle(struct drm_i915_private *dev_priv)
{
+ struct intel_guc *guc = &dev_priv->guc;
+ u32 mask = 0xffffffff;
+
mutex_lock(&dev_priv->rps.hw_lock);
if (dev_priv->rps.enabled) {
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
@@ -4715,7 +4718,18 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
else
gen6_set_rps(dev_priv, dev_priv->rps.idle_freq);
dev_priv->rps.last_adj = 0;
- I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
+
+ /*
+ * If PM interrupts are routed to GuC, Set mask for ARAT Expired
+ * interrupt based on mask set by GuC.
+ */
+ if (INTEL_INFO(dev_priv)->gen >= 8) {
+ if (guc->pm_intr_mask & GEN8_PMINTR_REDIRECT_TO_NON_DISP)
+ mask &= guc->pm_intr_mask | ~GEN8_ARAT_EXPIRED_INT_MASK;
+ else
+ mask &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP;
+ }
+ I915_WRITE(GEN6_PMINTRMSK, mask);
}
mutex_unlock(&dev_priv->rps.hw_lock);
--
1.9.1
More information about the Intel-gfx
mailing list