Commit 4f3059dc authored by Matthew Brost's avatar Matthew Brost Committed by John Harrison

drm/i915: Add logical engine mapping

Add logical engine mapping. This is required for split-frame, as
workloads need to be placed on engines in a logically contiguous manner.

v2:
 (Daniel Vetter)
  - Add kernel doc for new fields
v3:
 (Tvrtko)
  - Update comment for new logical_mask field
v4:
 (John Harrison)
  - Update comment for new logical_mask field
Signed-off-by: default avatarMatthew Brost <matthew.brost@intel.com>
Reviewed-by: default avatarJohn Harrison <John.C.Harrison@Intel.com>
Signed-off-by: default avatarJohn Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211014172005.27155-6-matthew.brost@intel.com
parent 36332429
...@@ -290,7 +290,8 @@ static void nop_irq_handler(struct intel_engine_cs *engine, u16 iir) ...@@ -290,7 +290,8 @@ static void nop_irq_handler(struct intel_engine_cs *engine, u16 iir)
GEM_DEBUG_WARN_ON(iir); GEM_DEBUG_WARN_ON(iir);
} }
static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id) static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
u8 logical_instance)
{ {
const struct engine_info *info = &intel_engines[id]; const struct engine_info *info = &intel_engines[id];
struct drm_i915_private *i915 = gt->i915; struct drm_i915_private *i915 = gt->i915;
...@@ -335,6 +336,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id) ...@@ -335,6 +336,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
engine->class = info->class; engine->class = info->class;
engine->instance = info->instance; engine->instance = info->instance;
engine->logical_mask = BIT(logical_instance);
__sprint_engine_name(engine); __sprint_engine_name(engine);
engine->props.heartbeat_interval_ms = engine->props.heartbeat_interval_ms =
...@@ -588,6 +590,37 @@ static intel_engine_mask_t init_engine_mask(struct intel_gt *gt) ...@@ -588,6 +590,37 @@ static intel_engine_mask_t init_engine_mask(struct intel_gt *gt)
return info->engine_mask; return info->engine_mask;
} }
static void populate_logical_ids(struct intel_gt *gt, u8 *logical_ids,
u8 class, const u8 *map, u8 num_instances)
{
int i, j;
u8 current_logical_id = 0;
for (j = 0; j < num_instances; ++j) {
for (i = 0; i < ARRAY_SIZE(intel_engines); ++i) {
if (!HAS_ENGINE(gt, i) ||
intel_engines[i].class != class)
continue;
if (intel_engines[i].instance == map[j]) {
logical_ids[intel_engines[i].instance] =
current_logical_id++;
break;
}
}
}
}
static void setup_logical_ids(struct intel_gt *gt, u8 *logical_ids, u8 class)
{
int i;
u8 map[MAX_ENGINE_INSTANCE + 1];
for (i = 0; i < MAX_ENGINE_INSTANCE + 1; ++i)
map[i] = i;
populate_logical_ids(gt, logical_ids, class, map, ARRAY_SIZE(map));
}
/** /**
* intel_engines_init_mmio() - allocate and prepare the Engine Command Streamers * intel_engines_init_mmio() - allocate and prepare the Engine Command Streamers
* @gt: pointer to struct intel_gt * @gt: pointer to struct intel_gt
...@@ -599,7 +632,8 @@ int intel_engines_init_mmio(struct intel_gt *gt) ...@@ -599,7 +632,8 @@ int intel_engines_init_mmio(struct intel_gt *gt)
struct drm_i915_private *i915 = gt->i915; struct drm_i915_private *i915 = gt->i915;
const unsigned int engine_mask = init_engine_mask(gt); const unsigned int engine_mask = init_engine_mask(gt);
unsigned int mask = 0; unsigned int mask = 0;
unsigned int i; unsigned int i, class;
u8 logical_ids[MAX_ENGINE_INSTANCE + 1];
int err; int err;
drm_WARN_ON(&i915->drm, engine_mask == 0); drm_WARN_ON(&i915->drm, engine_mask == 0);
...@@ -609,15 +643,23 @@ int intel_engines_init_mmio(struct intel_gt *gt) ...@@ -609,15 +643,23 @@ int intel_engines_init_mmio(struct intel_gt *gt)
if (i915_inject_probe_failure(i915)) if (i915_inject_probe_failure(i915))
return -ENODEV; return -ENODEV;
for (i = 0; i < ARRAY_SIZE(intel_engines); i++) { for (class = 0; class < MAX_ENGINE_CLASS + 1; ++class) {
if (!HAS_ENGINE(gt, i)) setup_logical_ids(gt, logical_ids, class);
continue;
err = intel_engine_setup(gt, i); for (i = 0; i < ARRAY_SIZE(intel_engines); ++i) {
if (err) u8 instance = intel_engines[i].instance;
goto cleanup;
if (intel_engines[i].class != class ||
!HAS_ENGINE(gt, i))
continue;
mask |= BIT(i); err = intel_engine_setup(gt, i,
logical_ids[instance]);
if (err)
goto cleanup;
mask |= BIT(i);
}
} }
/* /*
......
...@@ -269,6 +269,13 @@ struct intel_engine_cs { ...@@ -269,6 +269,13 @@ struct intel_engine_cs {
unsigned int guc_id; unsigned int guc_id;
intel_engine_mask_t mask; intel_engine_mask_t mask;
/**
* @logical_mask: logical mask of engine, reported to user space via
* query IOCTL and used to communicate with the GuC in logical space.
* The logical instance of a physical engine can change based on product
* and fusing.
*/
intel_engine_mask_t logical_mask;
u8 class; u8 class;
u8 instance; u8 instance;
......
...@@ -3877,6 +3877,7 @@ execlists_create_virtual(struct intel_engine_cs **siblings, unsigned int count) ...@@ -3877,6 +3877,7 @@ execlists_create_virtual(struct intel_engine_cs **siblings, unsigned int count)
ve->siblings[ve->num_siblings++] = sibling; ve->siblings[ve->num_siblings++] = sibling;
ve->base.mask |= sibling->mask; ve->base.mask |= sibling->mask;
ve->base.logical_mask |= sibling->logical_mask;
/* /*
* All physical engines must be compatible for their emission * All physical engines must be compatible for their emission
......
...@@ -176,7 +176,7 @@ static void guc_mapping_table_init(struct intel_gt *gt, ...@@ -176,7 +176,7 @@ static void guc_mapping_table_init(struct intel_gt *gt,
for_each_engine(engine, gt, id) { for_each_engine(engine, gt, id) {
u8 guc_class = engine_class_to_guc_class(engine->class); u8 guc_class = engine_class_to_guc_class(engine->class);
system_info->mapping_table[guc_class][engine->instance] = system_info->mapping_table[guc_class][ilog2(engine->logical_mask)] =
engine->instance; engine->instance;
} }
} }
......
...@@ -1423,23 +1423,6 @@ static int deregister_context(struct intel_context *ce, u32 guc_id) ...@@ -1423,23 +1423,6 @@ static int deregister_context(struct intel_context *ce, u32 guc_id)
return __guc_action_deregister_context(guc, guc_id); return __guc_action_deregister_context(guc, guc_id);
} }
static intel_engine_mask_t adjust_engine_mask(u8 class, intel_engine_mask_t mask)
{
switch (class) {
case RENDER_CLASS:
return mask >> RCS0;
case VIDEO_ENHANCEMENT_CLASS:
return mask >> VECS0;
case VIDEO_DECODE_CLASS:
return mask >> VCS0;
case COPY_ENGINE_CLASS:
return mask >> BCS0;
default:
MISSING_CASE(class);
return 0;
}
}
static void guc_context_policy_init(struct intel_engine_cs *engine, static void guc_context_policy_init(struct intel_engine_cs *engine,
struct guc_lrc_desc *desc) struct guc_lrc_desc *desc)
{ {
...@@ -1481,8 +1464,7 @@ static int guc_lrc_desc_pin(struct intel_context *ce, bool loop) ...@@ -1481,8 +1464,7 @@ static int guc_lrc_desc_pin(struct intel_context *ce, bool loop)
desc = __get_lrc_desc(guc, desc_idx); desc = __get_lrc_desc(guc, desc_idx);
desc->engine_class = engine_class_to_guc_class(engine->class); desc->engine_class = engine_class_to_guc_class(engine->class);
desc->engine_submit_mask = adjust_engine_mask(engine->class, desc->engine_submit_mask = engine->logical_mask;
engine->mask);
desc->hw_context_desc = ce->lrc.lrca; desc->hw_context_desc = ce->lrc.lrca;
desc->priority = ce->guc_state.prio; desc->priority = ce->guc_state.prio;
desc->context_flags = CONTEXT_REGISTRATION_FLAG_KMD; desc->context_flags = CONTEXT_REGISTRATION_FLAG_KMD;
...@@ -3271,6 +3253,7 @@ guc_create_virtual(struct intel_engine_cs **siblings, unsigned int count) ...@@ -3271,6 +3253,7 @@ guc_create_virtual(struct intel_engine_cs **siblings, unsigned int count)
} }
ve->base.mask |= sibling->mask; ve->base.mask |= sibling->mask;
ve->base.logical_mask |= sibling->logical_mask;
if (n != 0 && ve->base.class != sibling->class) { if (n != 0 && ve->base.class != sibling->class) {
DRM_DEBUG("invalid mixing of engine class, sibling %d, already %d\n", DRM_DEBUG("invalid mixing of engine class, sibling %d, already %d\n",
......
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