@@ -869,12 +869,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) {
@@ -913,6 +916,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_atomic(ads);
}
@@ -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 {