[Intel-gfx] [PATCH 07/21] drm/i915/guc: New GuC ADS object definition

Michal Wajdeczko michal.wajdeczko at intel.com
Wed Aug 29 19:15:12 UTC 2018


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 at intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
Cc: Michel Thierry <michel.thierry at intel.com>
Cc: Tomasz Lis <tomasz.lis at intel.com>
---
 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



More information about the Intel-gfx mailing list