drm/i915/guc: Add GuC ADS - MMIO reg state
authorAlex Dai <yu.dai@intel.com>
Fri, 18 Dec 2015 20:00:11 +0000 (12:00 -0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 5 Jan 2016 10:34:41 +0000 (11:34 +0100)
GuC needs to know which registers and how they will be saved and
restored during event such as engine reset or power state changes.
For now only the base address of reg state is initialized. The
detail register table probably will be setup in future GuC TDR or
Preemption patch series.

Signed-off-by: Alex Dai <yu.dai@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1450468812-4882-5-git-send-email-yu.dai@intel.com
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_guc_submission.c
drivers/gpu/drm/i915/intel_guc_fwif.h

index 1eb8db8d1febc5e824959dff54196b5f2fff66c8..9c244247c13e879bb3a5c0918a4319c03f4bdc36 100644 (file)
@@ -867,12 +867,15 @@ static void guc_create_ads(struct intel_guc *guc)
        struct drm_i915_gem_object *obj;
        struct guc_ads *ads;
        struct guc_policies *policies;
+       struct guc_mmio_reg_state *reg_state;
        struct intel_engine_cs *ring;
        struct page *page;
        u32 size, i;
 
        /* The ads obj includes the struct itself and buffers passed to GuC */
-       size = sizeof(struct guc_ads) + sizeof(struct guc_policies);
+       size = sizeof(struct guc_ads) + sizeof(struct guc_policies) +
+                       sizeof(struct guc_mmio_reg_state) +
+                       GUC_S3_SAVE_SPACE_PAGES * PAGE_SIZE;
 
        obj = guc->ads_obj;
        if (!obj) {
@@ -906,6 +909,23 @@ static void guc_create_ads(struct intel_guc *guc)
        ads->scheduler_policies = i915_gem_obj_ggtt_offset(obj) +
                        sizeof(struct guc_ads);
 
+       /* MMIO reg state */
+       reg_state = (void *)policies + sizeof(struct guc_policies);
+
+       for (i = 0; i < I915_NUM_RINGS; i++) {
+               reg_state->mmio_white_list[i].mmio_start =
+                       dev_priv->ring[i].mmio_base + GUC_MMIO_WHITE_LIST_START;
+
+               /* Nothing to be saved or restored for now. */
+               reg_state->mmio_white_list[i].count = 0;
+       }
+
+       ads->reg_state_addr = ads->scheduler_policies +
+                       sizeof(struct guc_policies);
+
+       ads->reg_state_buffer = ads->reg_state_addr +
+                       sizeof(struct guc_mmio_reg_state);
+
        kunmap(page);
 }
 
index 1ce5f5ba31478c84e55910a10a09eac303efc0e2..b4632f0bf7b2b6c383bfbd9064a1214d1d20aa20 100644 (file)
@@ -361,6 +361,43 @@ struct guc_policies {
        u32 reserved[19];
 } __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       20
+#define GUC_MMIO_WHITE_LIST_START      0x24d0
+#define GUC_MMIO_WHITE_LIST_MAX                12
+#define GUC_S3_SAVE_SPACE_PAGES                10
+
+struct guc_mmio_regset {
+       struct __packed {
+               u32 offset;
+               u32 value;
+               u32 flags;
+       } registers[GUC_REGSET_MAX_REGISTERS];
+
+       u32 values_valid;
+       u32 number_of_registers;
+} __packed;
+
+struct guc_mmio_reg_state {
+       struct guc_mmio_regset global_reg;
+       struct guc_mmio_regset engine_reg[I915_NUM_RINGS];
+
+       /* MMIO registers that are set as non privileged */
+       struct __packed {
+               u32 mmio_start;
+               u32 offsets[GUC_MMIO_WHITE_LIST_MAX];
+               u32 count;
+       } mmio_white_list[I915_NUM_RINGS];
+} __packed;
+
 /* GuC Additional Data Struct */
 
 struct guc_ads {