Definition of the Additional Data Structure (ADS) object and some of its sub-structs has been updated in the GuC firmware. Signed-off-by: Michal Wajdeczko <michal.wajdeczko@xxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@xxxxxxxxx> Cc: Michel Thierry <michel.thierry@xxxxxxxxx> Cc: Tomasz Lis <tomasz.lis@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_engine_cs.c | 5 ++ drivers/gpu/drm/i915/intel_guc_ads.c | 91 ++++++++++++++++++++++++--------- drivers/gpu/drm/i915/intel_guc_fwif.h | 89 ++++++++++++++++++-------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 + 4 files changed, 126 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index bc81354..6cefe26 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -270,6 +270,11 @@ static void __sprint_engine_name(char *name, const struct engine_info *info) info->instance) >= INTEL_ENGINE_CS_MAX_NAME); } +u32 intel_class_context_size(struct drm_i915_private *dev_priv, u8 class) +{ + return __intel_engine_context_size(dev_priv, class); +} + static int intel_engine_setup(struct drm_i915_private *dev_priv, enum intel_engine_id id) diff --git a/drivers/gpu/drm/i915/intel_guc_ads.c b/drivers/gpu/drm/i915/intel_guc_ads.c index f0db628..8e59a64 100644 --- a/drivers/gpu/drm/i915/intel_guc_ads.c +++ b/drivers/gpu/drm/i915/intel_guc_ads.c @@ -51,7 +51,7 @@ static void guc_policies_init(struct guc_policies *policies) policies->max_num_work_items = POLICY_MAX_NUM_WI; for (p = 0; p < GUC_CLIENT_PRIORITY_NUM; p++) { - for (i = GUC_RENDER_ENGINE; i < GUC_MAX_ENGINES_NUM; i++) { + for (i = 0; i < GUC_MAX_ENGINE_CLASSES; i++) { policy = &policies->policy[p][i]; guc_policy_init(policy); @@ -61,12 +61,35 @@ static void guc_policies_init(struct guc_policies *policies) policies->is_valid = 1; } +static u8 guc_class_to_intel_class(u8 guc_class) +{ + switch (guc_class) { + default: + MISSING_CASE(guc_class); + /* fall through */ + case GUC_RENDER_CLASS: + return RENDER_CLASS; + case GUC_VIDEO_CLASS: + return VIDEO_DECODE_CLASS; + case GUC_VIDEOENHANCE_CLASS: + return VIDEO_ENHANCEMENT_CLASS; + case GUC_BLITTER_CLASS: + return COPY_ENGINE_CLASS; + } +} + /* * The first 80 dwords of the register state context, containing the * execlists and ppgtt registers. */ #define LR_HW_CONTEXT_SIZE (80 * sizeof(u32)) +static void +guc_master_cmd_transport_pool_init(struct guc_master_cmd_transport_pool *pool) +{ + memset(pool, 0, sizeof(*pool)); +} + /** * intel_guc_ads_create() - creates GuC ADS * @guc: intel_guc struct @@ -76,19 +99,22 @@ int intel_guc_ads_create(struct intel_guc *guc) { struct drm_i915_private *dev_priv = guc_to_i915(guc); struct i915_vma *vma, *kernel_ctx_vma; - struct page *page; /* The ads obj includes the struct itself and buffers passed to GuC */ struct { struct guc_ads ads; struct guc_policies policies; struct guc_mmio_reg_state reg_state; + struct guc_gt_system_info system_info; + struct guc_gt_system_additional_info add_system_info; + struct guc_master_cmd_transport_pool ct_pool; u8 reg_state_buffer[GUC_S3_SAVE_SPACE_PAGES * PAGE_SIZE]; } __packed *blob; - struct intel_engine_cs *engine; - enum intel_engine_id id; const u32 skipped_offset = LRC_HEADER_PAGES * PAGE_SIZE; const u32 skipped_size = LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE; + u32 media_fuse; u32 base; + u8 class; + int ret; GEM_BUG_ON(guc->ads_vma); @@ -98,21 +124,15 @@ int intel_guc_ads_create(struct intel_guc *guc) guc->ads_vma = vma; - page = i915_vma_first_page(vma); - blob = kmap(page); + blob = i915_gem_object_pin_map(guc->ads_vma->obj, I915_MAP_WB); + if (IS_ERR(blob)) { + ret = PTR_ERR(blob); + goto err_vma; + } /* GuC scheduling policies */ guc_policies_init(&blob->policies); - /* MMIO reg state */ - for_each_engine(engine, dev_priv, id) { - blob->reg_state.white_list[engine->guc_id].mmio_start = - engine->mmio_base + GUC_MMIO_WHITE_LIST_START; - - /* Nothing to be saved or restored for now. */ - blob->reg_state.white_list[engine->guc_id].count = 0; - } - /* * The GuC requires a "Golden Context" when it reinitialises * engines after a reset. Here we use the Render ring default @@ -123,27 +143,50 @@ int intel_guc_ads_create(struct intel_guc *guc) */ kernel_ctx_vma = to_intel_context(dev_priv->kernel_context, dev_priv->engine[RCS])->state; - blob->ads.golden_context_lrca = + blob->ads.golden_context_lrca[GUC_RENDER_CLASS] = intel_guc_ggtt_offset(guc, kernel_ctx_vma) + skipped_offset; /* - * The GuC expects us to exclude the portion of the context image that - * it skips from the size it is to read. It starts reading from after - * the execlist context (so skipping the first page [PPHWSP] and 80 - * dwords). Weird guc is weird. + * We only care about the golden context for the render class, really + * (but skipping the execlist part of the context) */ - for_each_engine(engine, dev_priv, id) - blob->ads.eng_state_size[engine->guc_id] = - engine->context_size - skipped_size; + class = guc_class_to_intel_class(GUC_RENDER_CLASS); + blob->ads.eng_state_size[GUC_RENDER_CLASS] = + intel_class_context_size(dev_priv, class) - skipped_size; + + /* System info */ + blob->system_info.slice_enabled = hweight8(INTEL_INFO(dev_priv)->sseu.slice_mask); + blob->system_info.rcs_enabled = 1; + blob->system_info.bcs_enabled = 1; + + media_fuse = I915_READ(GEN11_GT_VEBOX_VDBOX_DISABLE); + blob->system_info.vdbox_enable_mask = ~(media_fuse & GEN11_GT_VDBOX_DISABLE_MASK); + blob->system_info.vebox_enable_mask = ~((media_fuse & GEN11_GT_VEBOX_DISABLE_MASK) >> + GEN11_GT_VEBOX_DISABLE_SHIFT); base = intel_guc_ggtt_offset(guc, vma); + + /* Additional info */ + guc_master_cmd_transport_pool_init(&blob->ct_pool); + + blob->add_system_info.gfx_address_command_transport_pool = + base + ptr_offset(blob, ct_pool); + blob->add_system_info.command_transport_pool_count = GUC_CT_POOL_SIZE; + + /* ADS */ blob->ads.scheduler_policies = base + ptr_offset(blob, policies); blob->ads.reg_state_buffer = base + ptr_offset(blob, reg_state_buffer); blob->ads.reg_state_addr = base + ptr_offset(blob, reg_state); + blob->ads.gt_system_info = base + ptr_offset(blob, system_info); + blob->ads.gt_system_additional_info = base + ptr_offset(blob, add_system_info); - kunmap(page); + i915_gem_object_unpin_map(guc->ads_vma->obj); return 0; + +err_vma: + i915_vma_unpin_and_release(&guc->ads_vma, 0); + return ret; } void intel_guc_ads_destroy(struct intel_guc *guc) diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 5b7a05b..2b41538 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -45,6 +45,7 @@ #define GUC_BLITTER_CLASS 3 #define GUC_RESERVED_CLASS 4 #define GUC_MAX_ENGINE_CLASSES (GUC_RESERVED_CLASS + 1) +#define GUC_MAX_INSTANCES_PER_CLASS 4 /* Work queue item header definitions */ #define WQ_STATUS_ACTIVE 1 @@ -447,23 +448,19 @@ struct guc_ct_buffer_desc { struct guc_policy { /* Time for one workload to execute. (in micro seconds) */ u32 execution_quantum; - u32 reserved1; - /* Time to wait for a preemption request to completed before issuing a * reset. (in micro seconds). */ u32 preemption_time; - /* How much time to allow to run after the first fault is observed. * Then preempt afterwards. (in micro seconds) */ u32 fault_time; - u32 policy_flags; - u32 reserved[2]; + u32 reserved[8]; } __packed; struct guc_policies { - struct guc_policy policy[GUC_CLIENT_PRIORITY_NUM][GUC_MAX_ENGINES_NUM]; - + struct guc_policy policy[GUC_CLIENT_PRIORITY_NUM][GUC_MAX_ENGINE_CLASSES]; + u32 submission_queue_depth[GUC_MAX_ENGINE_CLASSES]; /* In micro seconds. How much time to allow before DPC processing is * called back via interrupt (to prevent DPC queue drain starving). * Typically 1000s of micro seconds (example only, not granularity). */ @@ -476,57 +473,75 @@ struct guc_policies { * idle. */ u32 max_num_work_items; - u32 reserved[19]; + u32 reserved[4]; } __packed; /* GuC MMIO reg state struct */ -#define GUC_REGSET_FLAGS_NONE 0x0 -#define GUC_REGSET_POWERCYCLE 0x1 -#define GUC_REGSET_MASKED 0x2 -#define GUC_REGSET_ENGINERESET 0x4 -#define GUC_REGSET_SAVE_DEFAULT_VALUE 0x8 -#define GUC_REGSET_SAVE_CURRENT_VALUE 0x10 -#define GUC_REGSET_MAX_REGISTERS 25 -#define GUC_MMIO_WHITE_LIST_START 0x24d0 -#define GUC_MMIO_WHITE_LIST_MAX 12 +#define GUC_REGSET_MAX_REGISTERS 64 #define GUC_S3_SAVE_SPACE_PAGES 10 -struct guc_mmio_regset { - struct __packed { - u32 offset; - u32 value; - u32 flags; - } registers[GUC_REGSET_MAX_REGISTERS]; +struct guc_mmio_reg { + u32 offset; + u32 value; + u32 flags; +#define GUC_REGSET_MASKED (1 << 0) +} __packed; +struct guc_mmio_regset { + struct guc_mmio_reg registers[GUC_REGSET_MAX_REGISTERS]; u32 values_valid; u32 number_of_registers; } __packed; -/* MMIO registers that are set as non privileged */ -struct mmio_white_list { - u32 mmio_start; - u32 offsets[GUC_MMIO_WHITE_LIST_MAX]; - u32 count; +/* GuC register sets */ +struct guc_mmio_reg_state { + struct guc_mmio_regset engine_reg[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS]; + u32 reserved[98]; +} __packed; + +/* Gen11+ HW info */ +struct guc_gt_system_info { + u32 slice_enabled; + u32 rcs_enabled; + u32 reserved0; + u32 bcs_enabled; + u32 vdbox_enable_mask; + u32 vdbox_sfc_support_mask; + u32 vebox_enable_mask; + u32 reserved[9]; } __packed; -struct guc_mmio_reg_state { - struct guc_mmio_regset global_reg; - struct guc_mmio_regset engine_reg[GUC_MAX_ENGINES_NUM]; - struct mmio_white_list white_list[GUC_MAX_ENGINES_NUM]; +struct guc_gt_system_additional_info { + u32 reserved0[14]; + u32 gfx_address_command_transport_pool; + u32 command_transport_pool_count; + u32 reserved1[95]; } __packed; -/* GuC Additional Data Struct */ +struct guc_master_cmd_transport_buffer_alloc { + struct guc_ct_buffer_desc desc; + u32 reserved[7]; +} __packed; +#define GUC_CT_POOL_SIZE 2 + +struct guc_master_cmd_transport_pool { + struct guc_master_cmd_transport_buffer_alloc pool[GUC_CT_POOL_SIZE]; +} __packed; + +/* GuC Additional Data Struct */ struct guc_ads { u32 reg_state_addr; u32 reg_state_buffer; - u32 golden_context_lrca; u32 scheduler_policies; - u32 reserved0[3]; - u32 eng_state_size[GUC_MAX_ENGINES_NUM]; - u32 reserved2[4]; + u32 gt_system_info; + u32 gt_system_additional_info; + u32 control_data; + u32 golden_context_lrca[GUC_MAX_ENGINE_CLASSES]; + u32 eng_state_size[GUC_MAX_ENGINE_CLASSES]; + u32 reserved[16]; } __packed; /* GuC logging structures */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index f47009f..ec13d39 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -1183,6 +1183,8 @@ static inline void intel_engine_context_out(struct intel_engine_cs *engine) ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine); +u32 intel_class_context_size(struct drm_i915_private *dev_priv, u8 class); + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) static inline bool inject_preempt_hang(struct intel_engine_execlists *execlists) -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx