New GuC firmwares use updated definitions for the Additional Data
Structures (ADS).

v2: add note about Gen9 definition mismatch (Daniele)
    rename __intel_engine_context_size (Daniele)

Signed-off-by: Michal Wajdeczko <michal.wajdec...@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospu...@intel.com>
Signed-off-by: Fernando Pacheco <fernando.pach...@intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Cc: John Spotswood <john.a.spotsw...@intel.com>
Cc: Tomasz Lis <tomasz....@intel.com>
---
 drivers/gpu/drm/i915/intel_engine_cs.c  |  9 ++-
 drivers/gpu/drm/i915/intel_guc_ads.c    | 95 +++++++++++++++----------
 drivers/gpu/drm/i915/intel_guc_fwif.h   | 94 ++++++++++++++----------
 drivers/gpu/drm/i915/intel_ringbuffer.h |  2 +
 4 files changed, 122 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c 
b/drivers/gpu/drm/i915/intel_engine_cs.c
index eea9bec04f1b..5255e3ef81d4 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -165,7 +165,7 @@ static const struct engine_info intel_engines[] = {
 };
 
 /**
- * ___intel_engine_context_size() - return the size of the context for an 
engine
+ * intel_engine_context_size() - return the size of the context for an engine
  * @dev_priv: i915 device private
  * @class: engine class
  *
@@ -178,8 +178,7 @@ static const struct engine_info intel_engines[] = {
  * in LRC mode, but does not include the "shared data page" used with
  * GuC submission. The caller should account for this if using the GuC.
  */
-static u32
-__intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class)
+u32 intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class)
 {
        u32 cxt_size;
 
@@ -314,8 +313,8 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
 
        engine->uabi_class = intel_engine_classes[info->class].uabi_class;
 
-       engine->context_size = __intel_engine_context_size(dev_priv,
-                                                          engine->class);
+       engine->context_size = intel_engine_context_size(dev_priv,
+                                                        engine->class);
        if (WARN_ON(engine->context_size > BIT(20)))
                engine->context_size = 0;
        if (engine->context_size)
diff --git a/drivers/gpu/drm/i915/intel_guc_ads.c 
b/drivers/gpu/drm/i915/intel_guc_ads.c
index bec62f34b15a..1aa1ec0ff4a1 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,6 +61,11 @@ static void guc_policies_init(struct guc_policies *policies)
        policies->is_valid = 1;
 }
 
+static void guc_ct_pool_entries_init(struct guc_ct_pool_entry *pool, u32 num)
+{
+       memset(pool, 0, num * sizeof(*pool));
+}
+
 /*
  * The first 80 dwords of the register state context, containing the
  * execlists and ppgtt registers.
@@ -75,20 +80,21 @@ static void guc_policies_init(struct guc_policies *policies)
 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;
+       struct i915_vma *vma;
        /* 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_clients_info clients_info;
+               struct guc_ct_pool_entry ct_pool[GUC_CT_POOL_SIZE];
                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 base;
+       u8 engine_class;
+       int ret;
 
        GEM_BUG_ON(guc->ads_vma);
 
@@ -98,51 +104,68 @@ 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
-        * context, which must already exist and be pinned in the GGTT,
-        * so its address won't change after we've told the GuC where
-        * to find it. Note that we have to skip our header (1 page),
-        * because our GuC shared data is there.
+        * GuC expects a per-engine-class context image and size
+        * (minus hwsp and ring context). The context image will be
+        * used to reinitialize engines after a reset. It must exist
+        * and be pinned in the GGTT, so that the address won't change after
+        * we have told GuC where to find it. The context size will be used
+        * to validate that the LRC base + size fall within allowed GGTT.
         */
-       kernel_ctx_vma = dev_priv->engine[RCS0]->kernel_context->state;
-       blob->ads.golden_context_lrca =
-               intel_guc_ggtt_offset(guc, kernel_ctx_vma) + skipped_offset;
+       for (engine_class = 0; engine_class <= MAX_ENGINE_CLASS; 
++engine_class) {
+               if (engine_class == OTHER_CLASS)
+                       continue;
+               /*
+                * TODO: Set context pointer to default state to allow
+                * GuC to re-init guilty contexts after internal reset.
+                */
+               blob->ads.golden_context_lrca[engine_class] = 0;
+               blob->ads.eng_state_size[engine_class] =
+                       intel_engine_context_size(dev_priv, engine_class) -
+                       skipped_size;
+       }
 
-       /*
-        * 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.
-        */
-       for_each_engine(engine, dev_priv, id)
-               blob->ads.eng_state_size[engine->guc_id] =
-                       engine->context_size - skipped_size;
+       /* System info */
+       blob->system_info.slice_enabled = 
hweight8(RUNTIME_INFO(dev_priv)->sseu.slice_mask);
+       blob->system_info.rcs_enabled = 1;
+       blob->system_info.bcs_enabled = 1;
+
+       blob->system_info.vdbox_enable_mask = VDBOX_MASK(dev_priv);
+       blob->system_info.vebox_enable_mask = VEBOX_MASK(dev_priv);
+       blob->system_info.vdbox_sfc_support_mask = 
RUNTIME_INFO(dev_priv)->vdbox_sfc_access;
 
        base = intel_guc_ggtt_offset(guc, vma);
+
+       /* Clients info  */
+       guc_ct_pool_entries_init(blob->ct_pool, ARRAY_SIZE(blob->ct_pool));
+
+       blob->clients_info.clients_num = 1;
+       blob->clients_info.ct_pool_addr = base + ptr_offset(blob, ct_pool);
+       blob->clients_info.ct_pool_count = ARRAY_SIZE(blob->ct_pool);
+
+       /* 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.clients_info = base + ptr_offset(blob, clients_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 9b4436acba17..fa745a58d38d 100644
--- a/drivers/gpu/drm/i915/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/intel_guc_fwif.h
@@ -39,6 +39,14 @@
 #define GUC_VIDEO_ENGINE2              4
 #define GUC_MAX_ENGINES_NUM            (GUC_VIDEO_ENGINE2 + 1)
 
+/*
+ * XXX: Beware that Gen9 firmware 32.x uses wrong definition for
+ * GUC_MAX_INSTANCES_PER_CLASS (1) but this is harmless for us now
+ * as we are not enabling GuC submission mode where this will be used
+ */
+#define GUC_MAX_ENGINE_CLASSES         5
+#define GUC_MAX_INSTANCES_PER_CLASS    4
+
 #define GUC_DOORBELL_INVALID           256
 
 #define GUC_DB_SIZE                    (PAGE_SIZE)
@@ -386,23 +394,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). */
@@ -415,57 +419,73 @@ 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;
 
-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];
+/* 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;
 
-/* GuC Additional Data Struct */
+/* Clients info */
+struct guc_ct_pool_entry {
+       struct guc_ct_buffer_desc desc;
+       u32 reserved[7];
+} __packed;
 
+#define GUC_CT_POOL_SIZE       2
+
+struct guc_clients_info {
+       u32 clients_num;
+       u32 reserved0[13];
+       u32 ct_pool_addr;
+       u32 ct_pool_count;
+       u32 reserved[4];
+} __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 clients_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 72c7c337ace9..0107a39f3ec2 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -547,6 +547,8 @@ ktime_t intel_engine_get_busy_time(struct intel_engine_cs 
*engine);
 struct i915_request *
 intel_engine_find_active_request(struct intel_engine_cs *engine);
 
+u32 intel_engine_context_size(struct drm_i915_private *i915, u8 class);
+
 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
 
 static inline bool inject_preempt_hang(struct intel_engine_execlists 
*execlists)
-- 
2.19.2

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to