@@ -1677,6 +1677,11 @@ static void gen8_update_reg_state_unlocked(struct i915_gem_context *ctx,
CTX_REG(reg_state, state_offset, flex_regs[i], value);
}
+
+ CTX_REG(reg_state, CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE,
+ gen8_make_rpcs(dev_priv,
+ &to_intel_context(ctx,
+ dev_priv->engine[RCS])->sseu));
}
/*
@@ -2092,6 +2097,9 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
if (ret)
goto err_lock;
+ stream->ops = &i915_oa_stream_ops;
+ dev_priv->perf.oa.exclusive_stream = stream;
+
ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv,
stream->oa_config);
if (ret) {
@@ -2099,15 +2107,12 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
goto err_enable;
}
- stream->ops = &i915_oa_stream_ops;
-
- dev_priv->perf.oa.exclusive_stream = stream;
-
mutex_unlock(&dev_priv->drm.struct_mutex);
return 0;
err_enable:
+ dev_priv->perf.oa.exclusive_stream = NULL;
dev_priv->perf.oa.ops.disable_metric_set(dev_priv);
mutex_unlock(&dev_priv->drm.struct_mutex);
@@ -1305,9 +1305,6 @@ static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma)
return i915_vma_pin(vma, 0, 0, flags);
}
-static u32
-make_rpcs(struct drm_i915_private *i915, struct intel_sseu *ctx_sseu);
-
static void
__execlists_update_reg_state(struct intel_engine_cs *engine,
struct intel_context *ce)
@@ -1322,7 +1319,7 @@ __execlists_update_reg_state(struct intel_engine_cs *engine,
/* RPCS */
if (engine->class == RENDER_CLASS) {
ce->lrc_reg_state[CTX_R_PWR_CLK_STATE + 1] =
- make_rpcs(engine->i915, &ce->sseu);
+ gen8_make_rpcs(engine->i915, &ce->sseu);
}
}
@@ -2508,13 +2505,12 @@ int logical_xcs_ring_init(struct intel_engine_cs *engine)
return logical_ring_init(engine);
}
-static u32
-make_rpcs(struct drm_i915_private *i915, struct intel_sseu *ctx_sseu)
+u32 gen8_make_rpcs(struct drm_i915_private *i915, struct intel_sseu *req_sseu)
{
const struct sseu_dev_info *sseu = &INTEL_INFO(i915)->sseu;
bool subslice_pg = sseu->has_subslice_pg;
- u8 slices = hweight8(ctx_sseu->slice_mask);
- u8 subslices = hweight8(ctx_sseu->subslice_mask);
+ struct intel_sseu ctx_sseu;
+ u8 slices, subslices;
u32 rpcs = 0;
/*
@@ -2524,6 +2520,19 @@ make_rpcs(struct drm_i915_private *i915, struct intel_sseu *ctx_sseu)
if (INTEL_GEN(i915) < 9)
return 0;
+ /*
+ * If i915/perf is active, we want a stable powergating configuration
+ * on the system. The most natural configuration to take in that case
+ * is the default (i.e maximum the hardware can do).
+ */
+ if (unlikely(i915->perf.oa.exclusive_stream))
+ ctx_sseu = intel_device_default_sseu(i915);
+ else
+ ctx_sseu = *req_sseu;
+
+ slices = hweight8(ctx_sseu.slice_mask);
+ subslices = hweight8(ctx_sseu.subslice_mask);
+
/*
* Since the SScount bitfield in GEN8_R_PWR_CLK_STATE is only three bits
* wide and Icelake has up to eight subslices, specfial programming is
@@ -2593,13 +2602,13 @@ make_rpcs(struct drm_i915_private *i915, struct intel_sseu *ctx_sseu)
if (sseu->has_eu_pg) {
u32 val;
- val = ctx_sseu->min_eus_per_subslice << GEN8_RPCS_EU_MIN_SHIFT;
+ val = ctx_sseu.min_eus_per_subslice << GEN8_RPCS_EU_MIN_SHIFT;
GEM_BUG_ON(val & ~GEN8_RPCS_EU_MIN_MASK);
val &= GEN8_RPCS_EU_MIN_MASK;
rpcs |= val;
- val = ctx_sseu->max_eus_per_subslice << GEN8_RPCS_EU_MAX_SHIFT;
+ val = ctx_sseu.max_eus_per_subslice << GEN8_RPCS_EU_MAX_SHIFT;
GEM_BUG_ON(val & ~GEN8_RPCS_EU_MAX_MASK);
val &= GEN8_RPCS_EU_MAX_MASK;
@@ -104,4 +104,6 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv);
void intel_execlists_set_default_submission(struct intel_engine_cs *engine);
+u32 gen8_make_rpcs(struct drm_i915_private *i915, struct intel_sseu *ctx_sseu);
+
#endif /* _INTEL_LRC_H_ */