Commit 1800ad25 authored by Sagar Arun Kamble's avatar Sagar Arun Kamble Committed by Matt Roper

drm/i915: Update GEN6_PMINTRMSK setup with GuC enabled

On Loading, GuC sets PM interrupts routing (bit 31) and clears 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 that was failing with guc
load/submission enabled. Tested with SKL GuC v6.1 and BXT GuC v5.1 and v8.7.

v2: i915_irq/i915_pm decoupling from intel_guc. (ChrisW)

v3: restructuring the mask update and rebase w.r.t Ville's patch. (ChrisW)

v4: Updating the pm_intr_keep during direct_interrupts_to_guc. (Sagar)

Cc: Chris Harris <chris.harris@intel.com>
Cc: Zhe Wang <zhe1.wang@intel.com>
Cc: Deepak S <deepak.s@intel.com>
Cc: Satyanantha, Rama Gopal M <rama.gopal.m.satyanantha@intel.com>
Cc: Akash Goel <akash.goel@intel.com>
Testcase: igt/pm_rc6_residency
Signed-off-by: default avatarSagar Arun Kamble <sagar.a.kamble@intel.com>
Tested-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1464683307-19475-1-git-send-email-sagar.a.kamble@intel.com
parent 1d577e02
...@@ -1308,6 +1308,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) ...@@ -1308,6 +1308,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
} }
seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n", seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n",
pm_ier, pm_imr, pm_isr, pm_iir, pm_mask); pm_ier, pm_imr, pm_isr, pm_iir, pm_mask);
seq_printf(m, "pm_intr_keep: 0x%08x\n", dev_priv->rps.pm_intr_keep);
seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
seq_printf(m, "Render p-state ratio: %d\n", seq_printf(m, "Render p-state ratio: %d\n",
(gt_perf_status & (IS_GEN9(dev) ? 0x1ff00 : 0xff00)) >> 8); (gt_perf_status & (IS_GEN9(dev) ? 0x1ff00 : 0xff00)) >> 8);
......
...@@ -1127,6 +1127,8 @@ struct intel_gen6_power_mgmt { ...@@ -1127,6 +1127,8 @@ struct intel_gen6_power_mgmt {
bool interrupts_enabled; bool interrupts_enabled;
u32 pm_iir; u32 pm_iir;
u32 pm_intr_keep;
/* Frequencies are stored in potentially platform dependent multiples. /* Frequencies are stored in potentially platform dependent multiples.
* In other words, *_freq needs to be multiplied by X to be interesting. * In other words, *_freq needs to be multiplied by X to be interesting.
* Soft limits are those which are used for the dynamic reclocking done * Soft limits are those which are used for the dynamic reclocking done
......
...@@ -364,19 +364,7 @@ void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv) ...@@ -364,19 +364,7 @@ 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) u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask)
{ {
/* return (mask & ~dev_priv->rps.pm_intr_keep);
* SNB,IVB can while VLV,CHV may hard hang on looping batchbuffer
* if GEN6_PM_UP_EI_EXPIRED is masked.
*
* TODO: verify if this can be reproduced on VLV,CHV.
*/
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;
return mask;
} }
void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv)
...@@ -4578,6 +4566,20 @@ void intel_irq_init(struct drm_i915_private *dev_priv) ...@@ -4578,6 +4566,20 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
else else
dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
dev_priv->rps.pm_intr_keep = 0;
/*
* SNB,IVB can while VLV,CHV may hard hang on looping batchbuffer
* if GEN6_PM_UP_EI_EXPIRED is masked.
*
* TODO: verify if this can be reproduced on VLV,CHV.
*/
if (INTEL_INFO(dev_priv)->gen <= 7 && !IS_HASWELL(dev_priv))
dev_priv->rps.pm_intr_keep |= GEN6_PM_RP_UP_EI_EXPIRED;
if (INTEL_INFO(dev_priv)->gen >= 8)
dev_priv->rps.pm_intr_keep |= GEN8_PMINTR_REDIRECT_TO_NON_DISP;
INIT_DELAYED_WORK(&dev_priv->gpu_error.hangcheck_work, INIT_DELAYED_WORK(&dev_priv->gpu_error.hangcheck_work,
i915_hangcheck_elapsed); i915_hangcheck_elapsed);
......
...@@ -7031,7 +7031,7 @@ enum skl_disp_power_wells { ...@@ -7031,7 +7031,7 @@ enum skl_disp_power_wells {
#define VLV_RCEDATA _MMIO(0xA0BC) #define VLV_RCEDATA _MMIO(0xA0BC)
#define GEN6_RC6pp_THRESHOLD _MMIO(0xA0C0) #define GEN6_RC6pp_THRESHOLD _MMIO(0xA0C0)
#define GEN6_PMINTRMSK _MMIO(0xA168) #define GEN6_PMINTRMSK _MMIO(0xA168)
#define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31) #define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31)
#define VLV_PWRDWNUPCTL _MMIO(0xA294) #define VLV_PWRDWNUPCTL _MMIO(0xA294)
#define GEN9_MEDIA_PG_IDLE_HYSTERESIS _MMIO(0xA0C4) #define GEN9_MEDIA_PG_IDLE_HYSTERESIS _MMIO(0xA0C4)
#define GEN9_RENDER_PG_IDLE_HYSTERESIS _MMIO(0xA0C8) #define GEN9_RENDER_PG_IDLE_HYSTERESIS _MMIO(0xA0C8)
......
...@@ -103,6 +103,7 @@ static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) ...@@ -103,6 +103,7 @@ static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv)
{ {
struct intel_engine_cs *engine; struct intel_engine_cs *engine;
int irqs; int irqs;
u32 tmp;
/* tell all command streamers to forward interrupts and vblank to GuC */ /* tell all command streamers to forward interrupts and vblank to GuC */
irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_ALWAYS); irqs = _MASKED_FIELD(GFX_FORWARD_VBLANK_MASK, GFX_FORWARD_VBLANK_ALWAYS);
...@@ -117,6 +118,16 @@ static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) ...@@ -117,6 +118,16 @@ static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv)
I915_WRITE(GUC_BCS_RCS_IER, ~irqs); I915_WRITE(GUC_BCS_RCS_IER, ~irqs);
I915_WRITE(GUC_VCS2_VCS1_IER, ~irqs); I915_WRITE(GUC_VCS2_VCS1_IER, ~irqs);
I915_WRITE(GUC_WD_VECS_IER, ~irqs); I915_WRITE(GUC_WD_VECS_IER, ~irqs);
/*
* If GuC has routed PM interrupts to itself, don't keep it.
* and keep other interrupts those are unmasked by GuC.
*/
tmp = I915_READ(GEN6_PMINTRMSK);
if (tmp & GEN8_PMINTR_REDIRECT_TO_NON_DISP) {
dev_priv->rps.pm_intr_keep |= ~(tmp & ~GEN8_PMINTR_REDIRECT_TO_NON_DISP);
dev_priv->rps.pm_intr_keep &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP;
}
} }
static u32 get_gttype(struct drm_i915_private *dev_priv) static u32 get_gttype(struct drm_i915_private *dev_priv)
......
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