[Intel-gfx] [PATCH v5 02/10] drm/i915/guc: Add XE_LP registers for GuC error state capture.
Alan Previn
alan.previn.teres.alexis at intel.com
Wed Jan 26 10:48:14 UTC 2022
Add device specific tables and register lists to cover different engines
class types for GuC error state capture for XE_LP products.
Also, add runtime allocation and freeing of extended register lists
for registers that need steering identifiers that depend on
the detected HW config.
Signed-off-by: Alan Previn <alan.previn.teres.alexis at intel.com>
---
drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h | 2 +
.../gpu/drm/i915/gt/uc/intel_guc_capture.c | 207 +++++++++++++++---
drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 4 +-
3 files changed, 180 insertions(+), 33 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h b/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h
index 15b8c02b8a76..a2f97d04ff18 100644
--- a/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/guc_capture_fwif.h
@@ -24,6 +24,8 @@ struct __guc_mmio_reg_descr_group {
u32 owner; /* see enum guc_capture_owner */
u32 type; /* see enum guc_capture_type */
u32 engine; /* as per MAX_ENGINE_CLASS */
+ int num_ext;
+ struct __guc_mmio_reg_descr *ext;
};
struct __guc_state_capture_priv {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index 06873d617b8b..b6882074fc8d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -19,40 +19,101 @@
* NOTE: For engine-registers, GuC only needs the register offsets
* from the engine-mmio-base
*/
+#define COMMON_GEN12BASE_GLOBAL() \
+ {GEN12_FAULT_TLB_DATA0, 0, 0, "GEN12_FAULT_TLB_DATA0"}, \
+ {GEN12_FAULT_TLB_DATA1, 0, 0, "GEN12_FAULT_TLB_DATA1"}, \
+ {FORCEWAKE_MT, 0, 0, "FORCEWAKE_MT"}, \
+ {GEN12_AUX_ERR_DBG, 0, 0, "GEN12_AUX_ERR_DBG"}, \
+ {GEN12_GAM_DONE, 0, 0, "GEN12_GAM_DONE"}, \
+ {GEN12_RING_FAULT_REG, 0, 0, "GEN12_RING_FAULT_REG"}
+
+#define COMMON_GEN12BASE_ENGINE_INSTANCE() \
+ {RING_PSMI_CTL(0), 0, 0, "RING_PSMI_CTL"}, \
+ {RING_ESR(0), 0, 0, "RING_ESR"}, \
+ {RING_DMA_FADD(0), 0, 0, "RING_DMA_FADD_LOW32"}, \
+ {RING_DMA_FADD_UDW(0), 0, 0, "RING_DMA_FADD_UP32"}, \
+ {RING_IPEIR(0), 0, 0, "RING_IPEIR"}, \
+ {RING_IPEHR(0), 0, 0, "RING_IPEHR"}, \
+ {RING_INSTPS(0), 0, 0, "RING_INSTPS"}, \
+ {RING_BBADDR(0), 0, 0, "RING_BBADDR_LOW32"}, \
+ {RING_BBADDR_UDW(0), 0, 0, "RING_BBADDR_UP32"}, \
+ {RING_BBSTATE(0), 0, 0, "RING_BBSTATE"}, \
+ {CCID(0), 0, 0, "CCID"}, \
+ {RING_ACTHD(0), 0, 0, "RING_ACTHD_LOW32"}, \
+ {RING_ACTHD_UDW(0), 0, 0, "RING_ACTHD_UP32"}, \
+ {RING_INSTPM(0), 0, 0, "RING_INSTPM"}, \
+ {RING_NOPID(0), 0, 0, "RING_NOPID"}, \
+ {RING_START(0), 0, 0, "RING_START"}, \
+ {RING_HEAD(0), 0, 0, "RING_HEAD"}, \
+ {RING_TAIL(0), 0, 0, "RING_TAIL"}, \
+ {RING_CTL(0), 0, 0, "RING_CTL"}, \
+ {RING_MI_MODE(0), 0, 0, "RING_MI_MODE"}, \
+ {RING_CONTEXT_CONTROL(0), 0, 0, "RING_CONTEXT_CONTROL"}, \
+ {RING_INSTDONE(0), 0, 0, "RING_INSTDONE"}, \
+ {RING_HWS_PGA(0), 0, 0, "RING_HWS_PGA"}, \
+ {RING_MODE_GEN7(0), 0, 0, "RING_MODE_GEN7"}, \
+ {GEN8_RING_PDP_LDW(0, 0), 0, 0, "GEN8_RING_PDP0_LDW"}, \
+ {GEN8_RING_PDP_UDW(0, 0), 0, 0, "GEN8_RING_PDP0_UDW"}, \
+ {GEN8_RING_PDP_LDW(0, 1), 0, 0, "GEN8_RING_PDP1_LDW"}, \
+ {GEN8_RING_PDP_UDW(0, 1), 0, 0, "GEN8_RING_PDP1_UDW"}, \
+ {GEN8_RING_PDP_LDW(0, 2), 0, 0, "GEN8_RING_PDP2_LDW"}, \
+ {GEN8_RING_PDP_UDW(0, 2), 0, 0, "GEN8_RING_PDP2_UDW"}, \
+ {GEN8_RING_PDP_LDW(0, 3), 0, 0, "GEN8_RING_PDP3_LDW"}, \
+ {GEN8_RING_PDP_UDW(0, 3), 0, 0, "GEN8_RING_PDP3_UDW"}
+
+#define COMMON_GEN12BASE_HAS_EU() \
+ {EIR, 0, 0, "EIR"}
+
+#define COMMON_GEN12BASE_RENDER() \
+ {GEN7_SC_INSTDONE, 0, 0, "GEN7_SC_INSTDONE"}, \
+ {GEN12_SC_INSTDONE_EXTRA, 0, 0, "GEN12_SC_INSTDONE_EXTRA"}, \
+ {GEN12_SC_INSTDONE_EXTRA2, 0, 0, "GEN12_SC_INSTDONE_EXTRA2"}
+
+#define COMMON_GEN12BASE_VEC() \
+ {GEN12_SFC_DONE(0), 0, 0, "GEN12_SFC_DONE0"}, \
+ {GEN12_SFC_DONE(1), 0, 0, "GEN12_SFC_DONE1"}, \
+ {GEN12_SFC_DONE(2), 0, 0, "GEN12_SFC_DONE2"}, \
+ {GEN12_SFC_DONE(3), 0, 0, "GEN12_SFC_DONE3"}
+
/* XE_LPD - Global */
static struct __guc_mmio_reg_descr xe_lpd_global_regs[] = {
- {GEN12_RING_FAULT_REG, 0, 0, "GEN12_RING_FAULT_REG"}
+ COMMON_GEN12BASE_GLOBAL(),
};
/* XE_LPD - Render / Compute Per-Class */
static struct __guc_mmio_reg_descr xe_lpd_rc_class_regs[] = {
- {EIR, 0, 0, "EIR"}
+ COMMON_GEN12BASE_HAS_EU(),
+ COMMON_GEN12BASE_RENDER(),
};
/* XE_LPD - Render / Compute Per-Engine-Instance */
static struct __guc_mmio_reg_descr xe_lpd_rc_inst_regs[] = {
- {RING_HEAD(0), 0, 0, "RING_HEAD"},
- {RING_TAIL(0), 0, 0, "RING_TAIL"},
-};
-
-/* XE_LPD - Media Decode/Encode Per-Class */
-static struct __guc_mmio_reg_descr xe_lpd_vd_class_regs[] = {
+ COMMON_GEN12BASE_ENGINE_INSTANCE(),
};
/* XE_LPD - Media Decode/Encode Per-Engine-Instance */
static struct __guc_mmio_reg_descr xe_lpd_vd_inst_regs[] = {
- {RING_HEAD(0), 0, 0, "RING_HEAD"},
- {RING_TAIL(0), 0, 0, "RING_TAIL"},
+ COMMON_GEN12BASE_ENGINE_INSTANCE(),
};
/* XE_LPD - Video Enhancement Per-Class */
static struct __guc_mmio_reg_descr xe_lpd_vec_class_regs[] = {
+ COMMON_GEN12BASE_VEC(),
};
/* XE_LPD - Video Enhancement Per-Engine-Instance */
static struct __guc_mmio_reg_descr xe_lpd_vec_inst_regs[] = {
- {RING_HEAD(0), 0, 0, "RING_HEAD"},
- {RING_TAIL(0), 0, 0, "RING_TAIL"},
+ COMMON_GEN12BASE_ENGINE_INSTANCE(),
+};
+
+/* XE_LPD - Blitter Per-Engine-Instance */
+static struct __guc_mmio_reg_descr xe_lpd_blt_inst_regs[] = {
+ COMMON_GEN12BASE_ENGINE_INSTANCE(),
+};
+
+/* XE_LPD - Blitter Per-Class */
+/* XE_LPD - Media Decode/Encode Per-Class */
+static struct __guc_mmio_reg_descr empty_regs_list[] = {
};
#define TO_GCAP_DEF_OWNER(x) (GUC_CAPTURE_LIST_INDEX_##x)
@@ -64,6 +125,8 @@ static struct __guc_mmio_reg_descr xe_lpd_vec_inst_regs[] = {
.owner = TO_GCAP_DEF_OWNER(regsowner), \
.type = TO_GCAP_DEF_TYPE(regstype), \
.engine = class, \
+ .num_ext = 0, \
+ .ext = NULL, \
}
/* List of lists */
@@ -71,13 +134,96 @@ static struct __guc_mmio_reg_descr_group xe_lpd_lists[] = {
MAKE_REGLIST(xe_lpd_global_regs, PF, GLOBAL, 0),
MAKE_REGLIST(xe_lpd_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS),
- MAKE_REGLIST(xe_lpd_vd_class_regs, PF, ENGINE_CLASS, GUC_VIDEO_CLASS),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_VIDEO_CLASS),
MAKE_REGLIST(xe_lpd_vd_inst_regs, PF, ENGINE_INSTANCE, GUC_VIDEO_CLASS),
MAKE_REGLIST(xe_lpd_vec_class_regs, PF, ENGINE_CLASS, GUC_VIDEOENHANCE_CLASS),
MAKE_REGLIST(xe_lpd_vec_inst_regs, PF, ENGINE_INSTANCE, GUC_VIDEOENHANCE_CLASS),
+ MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_BLITTER_CLASS),
+ MAKE_REGLIST(xe_lpd_blt_inst_regs, PF, ENGINE_INSTANCE, GUC_BLITTER_CLASS),
{}
};
+static struct __guc_mmio_reg_descr_group *
+guc_capture_get_one_list(struct __guc_mmio_reg_descr_group *reglists, u32 owner, u32 type, u32 id)
+{
+ int i;
+
+ if (!reglists)
+ return NULL;
+
+ for (i = 0; reglists[i].list; i++) {
+ if (reglists[i].owner == owner && reglists[i].type == type &&
+ (reglists[i].engine == id || reglists[i].type == GUC_CAPTURE_LIST_TYPE_GLOBAL))
+ return ®lists[i];
+ }
+
+ return NULL;
+}
+
+static void guc_capture_clear_ext_regs(struct __guc_mmio_reg_descr_group *lists)
+{
+ while (lists->list) {
+ kfree(lists->ext);
+ lists->ext = NULL;
+ ++lists;
+ }
+}
+
+struct __ext_steer_reg {
+ const char *name;
+ i915_reg_t reg;
+};
+
+static struct __ext_steer_reg xelpd_extregs[] = {
+ {"GEN7_SAMPLER_INSTDONE", GEN7_SAMPLER_INSTDONE},
+ {"GEN7_ROW_INSTDONE", GEN7_ROW_INSTDONE}
+};
+
+static void
+guc_capture_alloc_steered_list_xelpd(struct intel_guc *guc,
+ struct __guc_mmio_reg_descr_group *lists)
+{
+ struct intel_gt *gt = guc_to_gt(guc);
+ struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+ struct sseu_dev_info *sseu;
+ int slice, subslice, i, num_tot_regs = 0;
+ struct __guc_mmio_reg_descr_group *list;
+ struct __guc_mmio_reg_descr *extarray;
+ int num_steer_regs = ARRAY_SIZE(xelpd_extregs);
+
+ /* In XE_LP we only care about render-class steering registers during error-capture */
+ list = guc_capture_get_one_list(lists, GUC_CAPTURE_LIST_INDEX_PF,
+ GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, GUC_RENDER_CLASS);
+ if (!list)
+ return;
+
+ if (list->ext)
+ return; /* already populated */
+
+ sseu = >->info.sseu;
+ for_each_instdone_slice_subslice(i915, sseu, slice, subslice) {
+ num_tot_regs += num_steer_regs;
+ }
+ if (!num_tot_regs)
+ return;
+
+ list->ext = kcalloc(num_tot_regs, sizeof(struct __guc_mmio_reg_descr), GFP_KERNEL);
+ if (!list->ext)
+ return;
+
+ extarray = list->ext;
+ for_each_instdone_slice_subslice(i915, sseu, slice, subslice) {
+ for (i = 0; i < num_steer_regs; i++) {
+ extarray->reg = xelpd_extregs[i].reg;
+ extarray->flags = FIELD_PREP(GUC_REGSET_STEERING_GROUP, slice);
+ extarray->flags |= FIELD_PREP(GUC_REGSET_STEERING_INSTANCE, subslice);
+ extarray->regname = xelpd_extregs[i].name;
+ ++extarray;
+ }
+ }
+ list->num_ext = num_tot_regs;
+}
+
static struct __guc_mmio_reg_descr_group *
guc_capture_get_device_reglist(struct intel_guc *guc)
{
@@ -91,29 +237,13 @@ guc_capture_get_device_reglist(struct intel_guc *guc)
* these at init time based on hw config add it as an extension
* list at the end of the pre-populated render list.
*/
+ guc_capture_alloc_steered_list_xelpd(guc, xe_lpd_lists);
return xe_lpd_lists;
}
return NULL;
}
-static struct __guc_mmio_reg_descr_group *
-guc_capture_get_one_list(struct __guc_mmio_reg_descr_group *reglists, u32 owner, u32 type, u32 id)
-{
- int i;
-
- if (!reglists)
- return NULL;
-
- for (i = 0; reglists[i].list; i++) {
- if (reglists[i].owner == owner && reglists[i].type == type &&
- (reglists[i].engine == id || reglists[i].type == GUC_CAPTURE_LIST_TYPE_GLOBAL))
- return ®lists[i];
- }
-
- return NULL;
-}
-
static const char *
guc_capture_stringify_owner(u32 owner)
{
@@ -184,7 +314,7 @@ static int
guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
struct guc_mmio_reg *ptr, u16 num_entries)
{
- u32 j = 0;
+ u32 j = 0, k = 0;
struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
struct __guc_mmio_reg_descr_group *reglists = guc->capture.priv->reglists;
struct __guc_mmio_reg_descr_group *match;
@@ -200,6 +330,18 @@ guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
ptr[j].flags = match->list[j].flags;
ptr[j].mask = match->list[j].mask;
}
+ if (match->ext) {
+ for (j = match->num_regs, k = 0; j < num_entries &&
+ j < (match->num_regs + match->num_ext); ++j, ++k) {
+ ptr[j].offset = match->ext[k].reg.reg;
+ ptr[j].value = 0xDEADF00D;
+ ptr[j].flags = match->ext[k].flags;
+ ptr[j].mask = match->ext[k].mask;
+ }
+ }
+ if (j < num_entries)
+ drm_dbg(&i915->drm, "GuC-capture: Init reglist short %d out %d.\n",
+ (int)j, (int)num_entries);
return 0;
}
@@ -282,7 +424,7 @@ guc_capture_list_count(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
return -ENODATA;
}
- *num_entries = match->num_regs;
+ *num_entries = match->num_regs + match->num_ext;
return 0;
}
@@ -435,6 +577,7 @@ int intel_guc_capture_prep_lists(struct intel_guc *guc, struct guc_ads *blob, u3
void intel_guc_capture_destroy(struct intel_guc *guc)
{
+ guc_capture_clear_ext_regs(guc->capture.priv->reglists);
kfree(guc->capture.priv);
guc->capture.priv = NULL;
}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
index 92bfe25a5e85..50fcd987f2a2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -271,10 +271,12 @@ struct guc_mmio_reg {
u32 offset;
u32 value;
u32 flags;
- u32 mask;
#define GUC_REGSET_MASKED BIT(0)
#define GUC_REGSET_MASKED_WITH_VALUE BIT(2)
#define GUC_REGSET_RESTORE_ONLY BIT(3)
+#define GUC_REGSET_STEERING_GROUP GENMASK(15, 12)
+#define GUC_REGSET_STEERING_INSTANCE GENMASK(23, 20)
+ u32 mask;
} __packed;
/* GuC register sets */
--
2.25.1
More information about the Intel-gfx
mailing list