@@ -3479,6 +3479,20 @@ mkwrite_device_info(struct drm_i915_private *dev_priv)
return (struct intel_device_info *)&dev_priv->info;
}
+static inline struct intel_sseu
+intel_device_default_sseu(struct drm_i915_private *i915)
+{
+ const struct sseu_dev_info *sseu = &INTEL_INFO(i915)->sseu;
+ struct intel_sseu value = {
+ .slice_mask = sseu->slice_mask,
+ .subslice_mask = sseu->subslice_mask[0],
+ .min_eus_per_subslice = sseu->max_eus_per_subslice,
+ .max_eus_per_subslice = sseu->max_eus_per_subslice,
+ };
+
+ return value;
+}
+
/* modesetting */
extern void intel_modeset_init_hw(struct drm_device *dev);
extern int intel_modeset_init(struct drm_device *dev);
@@ -343,6 +343,8 @@ __create_hw_context(struct drm_i915_private *dev_priv,
struct intel_context *ce = &ctx->__engine[n];
ce->gem_context = ctx;
+ /* Use the whole device by default */
+ ce->sseu = intel_device_default_sseu(dev_priv);
}
INIT_RADIX_TREE(&ctx->handles_vma, GFP_KERNEL);
@@ -31,6 +31,7 @@
#include "i915_gem.h"
#include "i915_scheduler.h"
+#include "intel_device_info.h"
struct pid;
@@ -170,6 +171,9 @@ struct i915_gem_context {
int pin_count;
const struct intel_context_ops *ops;
+
+ /** sseu: Control eu/slice partitioning */
+ struct intel_sseu sseu;
} __engine[I915_NUM_ENGINES];
/** ring_size: size for allocating the per-engine ring buffer */
@@ -39,6 +39,16 @@ struct drm_i915_gem_object;
struct i915_request;
struct i915_timeline;
+/*
+ * Powergating configuration for a particular (context,engine).
+ */
+struct intel_sseu {
+ u8 slice_mask;
+ u8 subslice_mask;
+ u8 min_eus_per_subslice;
+ u8 max_eus_per_subslice;
+};
+
struct intel_wait {
struct rb_node node;
struct task_struct *tsk;
@@ -1305,7 +1305,8 @@ 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 *dev_priv);
+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,
@@ -1320,7 +1321,8 @@ __execlists_update_reg_state(struct intel_engine_cs *engine,
/* RPCS */
if (engine->class == RENDER_CLASS)
- regs[CTX_R_PWR_CLK_STATE + 1] = make_rpcs(engine->i915);
+ regs[CTX_R_PWR_CLK_STATE + 1] = make_rpcs(engine->i915,
+ &ce->sseu);
}
static struct intel_context *
@@ -2506,18 +2508,19 @@ int logical_xcs_ring_init(struct intel_engine_cs *engine)
}
static u32
-make_rpcs(struct drm_i915_private *dev_priv)
+make_rpcs(struct drm_i915_private *i915, struct intel_sseu *ctx_sseu)
{
- bool subslice_pg = INTEL_INFO(dev_priv)->sseu.has_subslice_pg;
- u8 slices = hweight8(INTEL_INFO(dev_priv)->sseu.slice_mask);
- u8 subslices = hweight8(INTEL_INFO(dev_priv)->sseu.subslice_mask[0]);
+ 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);
u32 rpcs = 0;
/*
* No explicit RPCS request is needed to ensure full
* slice/subslice/EU enablement prior to Gen9.
*/
- if (INTEL_GEN(dev_priv) < 9)
+ if (INTEL_GEN(i915) < 9)
return 0;
/*
@@ -2545,7 +2548,7 @@ make_rpcs(struct drm_i915_private *dev_priv)
* subslices are enabled, or a count between one and four on the first
* slice.
*/
- if (IS_GEN11(dev_priv) && slices == 1 && subslices >= 4) {
+ if (IS_GEN11(i915) && slices == 1 && subslices >= 4) {
GEM_BUG_ON(subslices & 1);
subslice_pg = false;
@@ -2558,10 +2561,10 @@ make_rpcs(struct drm_i915_private *dev_priv)
* must make an explicit request through RPCS for full
* enablement.
*/
- if (INTEL_INFO(dev_priv)->sseu.has_slice_pg) {
+ if (sseu->has_slice_pg) {
u32 mask, val = slices;
- if (INTEL_GEN(dev_priv) >= 11) {
+ if (INTEL_GEN(i915) >= 11) {
mask = GEN11_RPCS_S_CNT_MASK;
val <<= GEN11_RPCS_S_CNT_SHIFT;
} else {
@@ -2586,18 +2589,16 @@ make_rpcs(struct drm_i915_private *dev_priv)
rpcs |= GEN8_RPCS_ENABLE | GEN8_RPCS_SS_CNT_ENABLE | val;
}
- if (INTEL_INFO(dev_priv)->sseu.has_eu_pg) {
+ if (sseu->has_eu_pg) {
u32 val;
- val = INTEL_INFO(dev_priv)->sseu.eu_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 = INTEL_INFO(dev_priv)->sseu.eu_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;