return intel_uncore_read_fw(gt->uncore, reg);
 }
 
+/**
+ * intel_gt_get_valid_steering_for_reg - get a valid steering for a register
+ * @gt: GT structure
+ * @reg: register for which the steering is required
+ * @sliceid: return variable for slice steering
+ * @subsliceid: return variable for subslice steering
+ *
+ * This function returns a slice/subslice pair that is guaranteed to work for
+ * read steering of the given register. Note that a value will be returned even
+ * if the register is not replicated and therefore does not actually require
+ * steering.
+ */
+void intel_gt_get_valid_steering_for_reg(struct intel_gt *gt, i915_reg_t reg,
+                                        u8 *sliceid, u8 *subsliceid)
+{
+       int type;
+
+       for (type = 0; type < NUM_STEERING_TYPES; type++) {
+               if (intel_gt_reg_needs_read_steering(gt, reg, type)) {
+                       intel_gt_get_valid_steering(gt, type, sliceid,
+                                                   subsliceid);
+                       return;
+               }
+       }
+
+       *sliceid = gt->default_steering.groupid;
+       *subsliceid = gt->default_steering.instanceid;
+}
+
 u32 intel_gt_read_register(struct intel_gt *gt, i915_reg_t reg)
 {
        int type;
 
        return slot;
 }
 
-static long __must_check guc_mmio_reg_add(struct temp_regset *regset,
-                                         u32 offset, u32 flags)
+#define GUC_REGSET_STEERING(group, instance) ( \
+       FIELD_PREP(GUC_REGSET_STEERING_GROUP, (group)) | \
+       FIELD_PREP(GUC_REGSET_STEERING_INSTANCE, (instance)) | \
+       GUC_REGSET_NEEDS_STEERING \
+)
+
+static long __must_check guc_mmio_reg_add(struct intel_gt *gt,
+                                         struct temp_regset *regset,
+                                         i915_reg_t reg, u32 flags)
 {
        u32 count = regset->storage_used - (regset->registers - regset->storage);
-       struct guc_mmio_reg reg = {
+       u32 offset = i915_mmio_reg_offset(reg);
+       struct guc_mmio_reg entry = {
                .offset = offset,
                .flags = flags,
        };
        struct guc_mmio_reg *slot;
+       u8 group, inst;
 
        /*
         * The mmio list is built using separate lists within the driver.
         * register more than once. Do not consider this an error; silently
         * move on if the register is already in the list.
         */
-       if (bsearch(®, regset->registers, count,
-                   sizeof(reg), guc_mmio_reg_cmp))
+       if (bsearch(&entry, regset->registers, count,
+                   sizeof(entry), guc_mmio_reg_cmp))
                return 0;
 
-       slot = __mmio_reg_add(regset, ®);
+       /*
+        * The GuC doesn't have a default steering, so we need to explicitly
+        * steer all registers that need steering. However, we do not keep track
+        * of all the steering ranges, only of those that have a chance of using
+        * a non-default steering from the i915 pov. Instead of adding such
+        * tracking, it is easier to just program the default steering for all
+        * regs that don't need a non-default one.
+        */
+       intel_gt_get_valid_steering_for_reg(gt, reg, &group, &inst);
+       entry.flags |= GUC_REGSET_STEERING(group, inst);
+
+       slot = __mmio_reg_add(regset, &entry);
        if (IS_ERR(slot))
                return PTR_ERR(slot);
 
        return 0;
 }
 
-#define GUC_MMIO_REG_ADD(regset, reg, masked) \
-       guc_mmio_reg_add(regset, \
-                        i915_mmio_reg_offset((reg)), \
+#define GUC_MMIO_REG_ADD(gt, regset, reg, masked) \
+       guc_mmio_reg_add(gt, \
+                        regset, \
+                        (reg), \
                         (masked) ? GUC_REGSET_MASKED : 0)
 
 static int guc_mmio_regset_init(struct temp_regset *regset,
                                struct intel_engine_cs *engine)
 {
+       struct intel_gt *gt = engine->gt;
        const u32 base = engine->mmio_base;
        struct i915_wa_list *wal = &engine->wa_list;
        struct i915_wa *wa;
         */
        regset->registers = regset->storage + regset->storage_used;
 
-       ret |= GUC_MMIO_REG_ADD(regset, RING_MODE_GEN7(base), true);
-       ret |= GUC_MMIO_REG_ADD(regset, RING_HWS_PGA(base), false);
-       ret |= GUC_MMIO_REG_ADD(regset, RING_IMR(base), false);
+       ret |= GUC_MMIO_REG_ADD(gt, regset, RING_MODE_GEN7(base), true);
+       ret |= GUC_MMIO_REG_ADD(gt, regset, RING_HWS_PGA(base), false);
+       ret |= GUC_MMIO_REG_ADD(gt, regset, RING_IMR(base), false);
 
        if ((engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE) &&
            CCS_MASK(engine->gt))
-               ret |= GUC_MMIO_REG_ADD(regset, GEN12_RCU_MODE, true);
+               ret |= GUC_MMIO_REG_ADD(gt, regset, GEN12_RCU_MODE, true);
 
        for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
-               ret |= GUC_MMIO_REG_ADD(regset, wa->reg, wa->masked_reg);
+               ret |= GUC_MMIO_REG_ADD(gt, regset, wa->reg, wa->masked_reg);
 
        /* Be extra paranoid and include all whitelist registers. */
        for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++)
-               ret |= GUC_MMIO_REG_ADD(regset,
+               ret |= GUC_MMIO_REG_ADD(gt, regset,
                                        RING_FORCE_TO_NONPRIV(base, i),
                                        false);
 
        /* add in local MOCS registers */
        for (i = 0; i < GEN9_LNCFCMOCS_REG_COUNT; i++)
-               ret |= GUC_MMIO_REG_ADD(regset, GEN9_LNCFCMOCS(i), false);
+               ret |= GUC_MMIO_REG_ADD(gt, regset, GEN9_LNCFCMOCS(i), false);
 
        return ret ? -1 : 0;
 }