[PATCH v2] drm/xe/mocs: Add debugfs node to dump mocs

Kumar, Janga Rahul janga.rahul.kumar at intel.com
Tue Apr 30 18:11:26 UTC 2024



> -----Original Message-----
> From: De Marchi, Lucas <lucas.demarchi at intel.com>
> Sent: Thursday, April 25, 2024 9:42 PM
> To: Kumar, Janga Rahul <janga.rahul.kumar at intel.com>
> Cc: intel-xe at lists.freedesktop.org; Gandi, Ramadevi
> <ramadevi.gandi at intel.com>; Roper, Matthew D
> <matthew.d.roper at intel.com>
> Subject: Re: [PATCH v2] drm/xe/mocs: Add debugfs node to dump mocs
> 
> On Mon, Apr 22, 2024 at 03:35:50PM GMT, Janga Rahul Kumar wrote:
> >This is useful to check mocs configuration. Tests/Tools can use this
> >debugfs entry to get mocs info.
> >
> >v2: Address review comments. Change debugfs output style similar to pat
> >debugfs. (Lucas De Marchi)
> 
> it looks like there's an igt series that is supposed to use this?
> 
> Please add a "Test-with: <msgid>" to point out to that series
Done. Updated in v4 series.

> 
> >
> >Cc: Matt Roper <matthew.d.roper at intel.com>
> >Cc: Lucas De Marchi <lucas.demarchi at intel.com>
> >Signed-off-by: Janga Rahul Kumar <janga.rahul.kumar at intel.com>
> >---
> > drivers/gpu/drm/xe/xe_gt_debugfs.c |  11 ++
> > drivers/gpu/drm/xe/xe_mocs.c       | 274 +++++++++++++++++++++++++++--
> > drivers/gpu/drm/xe/xe_mocs.h       |   8 +
> > 3 files changed, 283 insertions(+), 10 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/xe/xe_gt_debugfs.c
> >b/drivers/gpu/drm/xe/xe_gt_debugfs.c
> >index ff7f4cf52fa9..041eef92b705 100644
> >--- a/drivers/gpu/drm/xe/xe_gt_debugfs.c
> >+++ b/drivers/gpu/drm/xe/xe_gt_debugfs.c
> >@@ -17,6 +17,7 @@
> > #include "xe_hw_engine.h"
> > #include "xe_lrc.h"
> > #include "xe_macros.h"
> >+#include "xe_mocs.h"
> > #include "xe_pat.h"
> > #include "xe_pm.h"
> > #include "xe_reg_sr.h"
> >@@ -198,6 +199,15 @@ static int pat(struct xe_gt *gt, struct drm_printer *p)
> > 	return 0;
> > }
> >
> >+static int mocs(struct xe_gt *gt, struct drm_printer *p) {
> >+	xe_pm_runtime_get(gt_to_xe(gt));
> >+	xe_mocs_dump(gt, p);
> >+	xe_pm_runtime_put(gt_to_xe(gt));
> >+
> >+	return 0;
> >+}
> >+
> > static int rcs_default_lrc(struct xe_gt *gt, struct drm_printer *p)  {
> > 	xe_pm_runtime_get(gt_to_xe(gt));
> >@@ -253,6 +263,7 @@ static const struct drm_info_list debugfs_list[] = {
> > 	{"register-save-restore", .show = xe_gt_debugfs_simple_show, .data =
> register_save_restore},
> > 	{"workarounds", .show = xe_gt_debugfs_simple_show, .data =
> workarounds},
> > 	{"pat", .show = xe_gt_debugfs_simple_show, .data = pat},
> >+	{"mocs", .show = xe_gt_debugfs_simple_show, .data = mocs},
> > 	{"default_lrc_rcs", .show = xe_gt_debugfs_simple_show, .data =
> rcs_default_lrc},
> > 	{"default_lrc_ccs", .show = xe_gt_debugfs_simple_show, .data =
> ccs_default_lrc},
> > 	{"default_lrc_bcs", .show = xe_gt_debugfs_simple_show, .data =
> >bcs_default_lrc}, diff --git a/drivers/gpu/drm/xe/xe_mocs.c
> >b/drivers/gpu/drm/xe/xe_mocs.c index 1e92f8ee07ba..e45d2b2caadf 100644
> >--- a/drivers/gpu/drm/xe/xe_mocs.c
> >+++ b/drivers/gpu/drm/xe/xe_mocs.c
> >@@ -43,6 +43,8 @@ struct xe_mocs_info {
> > 	u8 uc_index;
> > 	u8 wb_index;
> > 	u8 unused_entries_index;
> >+	void (*dump)(struct xe_mocs_info *mocs, unsigned int flags,
> >+		     struct xe_gt *gt, struct drm_printer *p);
> 
> please follow the same pattern as xe_pat.c. Everywhere we use function
> pointers we put them into a ops struct.
Done.

> 
> > };
> >
> > /* Defines for the tables (XXX_MOCS_0 - XXX_MOCS_63) */ @@ -57,6
> >+59,17 @@ struct xe_mocs_info {
> > #define LE_COS(value)		((value) << 15)
> > #define LE_SSE(value)		((value) << 17)
> >
> >+#define LE_CACHEABILITY_MASK	REG_GENMASK(1, 0)
> >+#define LE_TGT_CACHE_MASK	REG_GENMASK(3, 2)
> >+#define LE_LRUM_MASK		REG_GENMASK(5, 4)
> >+#define LE_AOM_MASK		REG_BIT(6)
> >+#define LE_RSC_MASK		REG_BIT(7)
> >+#define LE_SCC_MASK		REG_GENMASK(10, 8)
> >+#define LE_PFM_MASK		REG_GENMASK(13, 11)
> >+#define LE_SCF_MASK		REG_BIT(14)
> >+#define LE_COS_MASK		REG_GENMASK(16, 15)
> >+#define LE_SSE_MASK		REG_GENMASK(18, 17)
> 
> convention for register in regs/ is:
> 
>   * Define the register contents (i.e. bit and bit field macros) from most
>   * significant to least significant bit. Indent the register content macros
>   * using two extra spaces between ``#define`` and the macro name.
I saw 2 spaces between #defien and macro name in xe_reg file and updated the same in v4.

> 
> it would be good to follow it here too, even if not technically in the regs/ dir. So,
> let's define those masks with LE_SSE_MASK first.[Janga Rahul Kumar] 
Done.

> However.... are we too verbose here? Main use for this is to double check with
> the spec. Do we need to spell out each field individually? 
Spelling out each field individually helps  in mapping with spec easily.
this pattern dump will be very helpful while programming mocs for future
Platforms as well.

We were already
> logging them to kernel log:
> 
> 	mocs_dbg(gt, "GLOB_MOCS[%d] 0x%x 0x%x\n", i,
> 		 XELP_GLOBAL_MOCS(i).addr, mocs);
> 
> Similarly to xe_pat.c, I think the output should match and the only difference
> being the time in which we are outputing it. +Matt who added the PAT ones for
> his opinion... it seems the PAT ones are also a little verbose, but we don't print
> to kernel log on probe.
> 
> >+
> > /* Defines for the tables (LNCFMOCS0 - LNCFMOCS31) - two entries per word
> */
> > #define L3_ESC(value)		((value) << 0)
> > #define L3_SCC(value)		((value) << 1)
> >@@ -64,6 +77,17 @@ struct xe_mocs_info {
> > #define L3_GLBGO(value)		((value) << 6)
> > #define L3_LKUP(value)		((value) << 7)
> >
> >+#define L3_ESC_MASK			REG_BIT(0)
> >+#define L3_SCC_MASK			REG_GENMASK(3, 1)
> >+#define L3_CACHEABILITY_MASK		REG_GENMASK(5, 4)
> >+#define L3_GLBGO_MASK			REG_BIT(6)
> >+#define L3_LKUP_MASK			REG_BIT(7)
> >+#define L3_UPPER_IDX_ESC_MASK		REG_BIT(16)
> >+#define L3_UPPER_IDX_SCC_MASK		REG_GENMASK(19, 17)
> >+#define L3_UPPER_IDX_CACHEABILITY_MASK	REG_GENMASK(21, 20)
> >+#define L3_UPPER_GLBGO_MASK		REG_BIT(22)
> >+#define L3_UPPER_LKUP_MASK		REG_BIT(23)
> >+
> > /* Defines for the tables (GLOB_MOCS_0 - GLOB_MOCS_16) */
> > #define IG_PAT				REG_BIT(8)
> > #define L3_CACHE_POLICY_MASK		REG_GENMASK(5, 4)
> >@@ -107,6 +131,8 @@ struct xe_mocs_info {
> > #define XE2_L3_1_XD		REG_FIELD_PREP(L3_CACHE_POLICY_MASK, 1)
> > #define XE2_L3_3_UC		REG_FIELD_PREP(L3_CACHE_POLICY_MASK, 3)
> >
> >+#define XE2_L3_CLOS_MASK	REG_GENMASK(7, 6)
> >+
> > #define MOCS_ENTRY(__idx, __control_value, __l3cc_value) \
> > 	[__idx] = { \
> > 		.control_value = __control_value, \
> >@@ -255,6 +281,82 @@ static const struct xe_mocs_entry
> gen12_mocs_desc[] = {
> > 		   L3_1_UC)
> > };
> >
> >+static bool regs_are_mcr(struct xe_gt *gt) {
> >+	struct xe_device *xe = gt_to_xe(gt);
> >+
> >+	if (xe_gt_is_media_type(gt))
> >+		return MEDIA_VER(xe) >= 20;
> >+	else
> >+		return GRAPHICS_VERx100(xe) >= 1250; }
> 
> this is a prep patch moving the function
Done.

> 
> >+
> >+static void xelp_lncf_dump(struct xe_mocs_info *info, struct xe_gt
> >+*gt, struct drm_printer *p) {
> >+	unsigned int i, j;
> >+	u32 reg_val;
> >+
> >+	drm_printf(p, "LNCFCMOCS[idx] = [ESC, SCC, L3CC] (value)\n\n");
> >+
> >+	for (i = 0, j = 0; i < (info->n_entries + 1) / 2; i++, j++) {
> >+		if (regs_are_mcr(gt))
> >+			reg_val = xe_gt_mcr_unicast_read_any(gt,
> XEHP_LNCFCMOCS(i));
> >+		else
> >+			reg_val = xe_mmio_read32(gt, XELP_LNCFCMOCS(i));
> >+
> >+		drm_printf(p, "LNCFCMOCS[%2d] = [%u, %u, %u] (%#8x)\n",
> >+			   j++,
> >+			   !!(reg_val & L3_ESC_MASK),
> >+			   REG_FIELD_GET(L3_SCC_MASK, reg_val),
> >+			   REG_FIELD_GET(L3_CACHEABILITY_MASK, reg_val),
> >+			   reg_val);
> >+
> >+		drm_printf(p, "LNCFCMOCS[%2d] = [%u, %u, %u] (%#8x)\n",
> >+			   j,
> >+			   !!(reg_val & L3_UPPER_IDX_ESC_MASK),
> >+			   REG_FIELD_GET(L3_UPPER_IDX_SCC_MASK, reg_val),
> >+
> REG_FIELD_GET(L3_UPPER_IDX_CACHEABILITY_MASK, reg_val),
> >+			   reg_val);
> >+	}
> >+}
> >+
> >+static void gen12_mocs_dump(struct xe_mocs_info *info, unsigned int
> >+flags,
> 
> s/gen12/xelp/
Done.

> 
> >+			    struct xe_gt *gt, struct drm_printer *p) {
> >+	unsigned int i;
> >+	u32 reg_val;
> >+
> >+	if (flags & HAS_GLOBAL_MOCS) {
> >+		drm_printf(p, "Global mocs table configuration:\n");
> >+		drm_printf(p, "GLOB_MOCS[idx] = [LeCC, TC, LRUM, AOM, RSC,
> SCC, PFM,
> >+SCF, CoS, SSE] (value)\n\n");
> >+
> >+		for (i = 0; i < info->n_entries; i++) {
> >+			if (regs_are_mcr(gt))
> >+				reg_val = xe_gt_mcr_unicast_read_any(gt,
> XEHP_GLOBAL_MOCS(i));
> >+			else
> >+				reg_val = xe_mmio_read32(gt,
> XELP_GLOBAL_MOCS(i));
> >+
> >+		drm_printf(p, "GLOB_MOCS[%2d] = [%u, %u, %u, %u, %u, %u,
> %u, %u, %u, %u ] (%#8x)\n",
> >+			   i,
> >+			   REG_FIELD_GET(LE_CACHEABILITY_MASK, reg_val),
> >+			   REG_FIELD_GET(LE_TGT_CACHE_MASK, reg_val),
> >+			   REG_FIELD_GET(LE_LRUM_MASK, reg_val),
> >+			   !!(reg_val & LE_AOM_MASK),
> >+			   !!(reg_val & LE_RSC_MASK),
> >+			   REG_FIELD_GET(LE_SCC_MASK, reg_val),
> >+			   REG_FIELD_GET(LE_PFM_MASK, reg_val),
> >+			   !!(reg_val & LE_SCF_MASK),
> >+			   REG_FIELD_GET(LE_COS_MASK, reg_val),
> >+			   REG_FIELD_GET(LE_SSE_MASK, reg_val),
> >+			   reg_val);
> >+		}
> >+	}
> >+
> >+	if (flags & HAS_LNCF_MOCS) {
> 
> watch out for coding style... shouldn't have the { }, here and in other places.
> 
> >+		xelp_lncf_dump(info, gt, p);
> >+	}
> >+}
> >+
> > static const struct xe_mocs_entry dg1_mocs_desc[] = {
> > 	/* UC */
> > 	MOCS_ENTRY(1, 0, L3_1_UC),
> >@@ -279,6 +381,14 @@ static const struct xe_mocs_entry dg1_mocs_desc[] =
> {
> > 	MOCS_ENTRY(63, 0, L3_1_UC),
> > };
> >
> >+static void dg1_mocs_dump(struct xe_mocs_info *info, unsigned int flags,
> struct xe_gt *gt,
> >+			  struct drm_printer *p)
> >+{
> >+	if (flags & HAS_LNCF_MOCS) {
> 
> you should eather uses flags or use the function pointers to differentiate these.
Removed flags wherever they are not required.

-Janga Rahul Kumar

> From flags we have:
> 
> 	if (!IS_DGFX(xe) || GRAPHICS_VER(xe) >= 20)
> 		flags |= HAS_GLOBAL_MOCS;
>          if (GRAPHICS_VER(xe) < 20)
>                  flags |= HAS_LNCF_MOCS;
> 
> So if keeping the flags, dg1_mocs_dump() would be gone and you'd simply use
> xelp_mocs_dump()
> 
> >+		xelp_lncf_dump(info, gt, p);
> >+	}
> >+}
> >+
> > static const struct xe_mocs_entry dg2_mocs_desc[] = {
> > 	/* UC - Coherent; GO:L3 */
> > 	MOCS_ENTRY(0, 0, L3_1_UC | L3_LKUP(1)), @@ -291,6 +401,43 @@
> static
> >const struct xe_mocs_entry dg2_mocs_desc[] = {
> > 	MOCS_ENTRY(3, 0, L3_3_WB | L3_LKUP(1)),  };
> >
> >+static void xehp_lncf_dump(struct xe_mocs_info *info, struct xe_gt
> >+*gt, struct drm_printer *p) {
> >+	unsigned int i, j;
> >+	u32 reg_val;
> >+
> >+	drm_printf(p, "LNCFCMOCS[idx] = [UCL3LOOKUP, GLBGO, L3CC]
> >+(value)\n\n");
> >+
> >+	for (i = 0, j = 0; i < (info->n_entries + 1) / 2; i++, j++) {
> >+		if (regs_are_mcr(gt))
> >+			reg_val = xe_gt_mcr_unicast_read_any(gt,
> XEHP_LNCFCMOCS(i));
> >+		else
> >+			reg_val = xe_mmio_read32(gt, XELP_LNCFCMOCS(i));
> >+
> >+		drm_printf(p, "LNCFCMOCS[%2d] = [%u, %u, %u] (%#8x)\n",
> >+			   j++,
> >+			   !!(reg_val & L3_LKUP_MASK),
> >+			   !!(reg_val & L3_GLBGO_MASK),
> >+			   REG_FIELD_GET(L3_CACHEABILITY_MASK, reg_val),
> >+			   reg_val);
> >+
> >+		drm_printf(p, "LNCFCMOCS[%2d] = [%u, %u, %u] (%#8x)\n",
> >+			   j,
> >+			   !!(reg_val & L3_UPPER_LKUP_MASK),
> >+			   !!(reg_val & L3_UPPER_GLBGO_MASK),
> >+
> REG_FIELD_GET(L3_UPPER_IDX_CACHEABILITY_MASK, reg_val),
> >+			   reg_val);
> >+	}
> >+}
> >+
> >+static void dg2_mocs_dump(struct xe_mocs_info *info, unsigned int flags,
> struct xe_gt *gt,
> >+			  struct drm_printer *p)
> >+{
> >+	if (flags & HAS_LNCF_MOCS) {
> 
> same comment as for DG1
> 
> >+		xehp_lncf_dump(info, gt, p);
> >+	}
> >+}
> >+
> > static const struct xe_mocs_entry pvc_mocs_desc[] = {
> > 	/* Error */
> > 	MOCS_ENTRY(0, 0, L3_3_WB),
> >@@ -302,6 +449,34 @@ static const struct xe_mocs_entry pvc_mocs_desc[] =
> {
> > 	MOCS_ENTRY(2, 0, L3_3_WB),
> > };
> >
> >+static void pvc_mocs_dump(struct xe_mocs_info *info, unsigned int flags,
> struct xe_gt *gt,
> >+			  struct drm_printer *p)
> >+{
> >+	unsigned int i, j;
> >+	u32 reg_val;
> >+
> >+	if (flags & HAS_LNCF_MOCS) {
> 
> if it's a pvc-only function, we know what it has, no need to check flags.
> 
> >+		drm_printf(p, "LNCFCMOCS[idx] = [ L3CC ] (value)\n\n");
> >+
> >+		for (i = 0, j = 0; i < (info->n_entries + 1) / 2; i++, j++) {
> >+			if (regs_are_mcr(gt))
> >+				reg_val = xe_gt_mcr_unicast_read_any(gt,
> XEHP_LNCFCMOCS(i));
> >+			else
> >+				reg_val = xe_mmio_read32(gt,
> XELP_LNCFCMOCS(i));
> >+
> >+			drm_printf(p, "LNCFCMOCS[%2d] = [ %u ] (%#8x)\n",
> >+				   j++,
> >+				   REG_FIELD_GET(L3_CACHEABILITY_MASK,
> reg_val),
> >+				   reg_val);
> >+
> >+			drm_printf(p, "LNCFCMOCS[%2d] = [ %u ] (%#8x)\n",
> >+				   j,
> >+
> REG_FIELD_GET(L3_UPPER_IDX_CACHEABILITY_MASK, reg_val),
> >+				   reg_val);
> >+		}
> >+	}
> >+}
> >+
> > static const struct xe_mocs_entry mtl_mocs_desc[] = {
> > 	/* Error - Reserved for Non-Use */
> > 	MOCS_ENTRY(0,
> >@@ -353,6 +528,36 @@ static const struct xe_mocs_entry mtl_mocs_desc[] =
> {
> > 		   L3_GLBGO(1) | L3_1_UC),
> > };
> >
> >+static void mtl_mocs_dump(struct xe_mocs_info *info, unsigned int flags,
> >+			  struct xe_gt *gt, struct drm_printer *p) {
> >+	unsigned int i;
> >+	u32 reg_val;
> >+
> >+	if (flags & HAS_GLOBAL_MOCS) {
> 
> ditto... if it's MTL-only function, we know what it has.
> 
> >+		drm_printf(p, "Global mocs table configuration:\n");
> >+		drm_printf(p, "GLOB_MOCS[idx] = [IG_PAT, L4_CACHE_POLICY]
> >+(value)\n\n");
> >+
> >+		for (i = 0; i < info->n_entries; i++) {
> >+			if (regs_are_mcr(gt))
> >+				reg_val = xe_gt_mcr_unicast_read_any(gt,
> XEHP_GLOBAL_MOCS(i));
> >+			else
> >+				reg_val = xe_mmio_read32(gt,
> XELP_GLOBAL_MOCS(i));
> >+
> >+			drm_printf(p, "GLOB_MOCS[%2d] = [%u, %u]
> (%#8x)\n",
> >+				   i,
> >+				   !!(reg_val & IG_PAT),
> >+				   REG_FIELD_GET(L4_CACHE_POLICY_MASK,
> reg_val),
> >+				   reg_val);
> >+		}
> >+	}
> >+
> >+	if (flags & HAS_LNCF_MOCS) {
> >+		/* MTL lncf mocs table pattern is similar to that of xehp */
> >+		xehp_lncf_dump(info, gt, p);
> >+	}
> >+}
> >+
> > static const struct xe_mocs_entry xe2_mocs_table[] = {
> > 	/* Defer to PAT */
> > 	MOCS_ENTRY(0, XE2_L3_0_WB | L4_3_UC, 0), @@ -366,6 +571,32 @@
> static
> >const struct xe_mocs_entry xe2_mocs_table[] = {
> > 	MOCS_ENTRY(4, IG_PAT | XE2_L3_0_WB | L4_0_WB, 0),  };
> >
> >+static void xe2_mocs_dump(struct xe_mocs_info *info, unsigned int flags,
> >+			  struct xe_gt *gt, struct drm_printer *p) {
> >+	unsigned int i;
> >+	u32 reg_val;
> >+
> >+	if (flags & HAS_GLOBAL_MOCS) {
> 
> xe2 always has global mocs, regardless of dgfx or igfx.
> 
> Lucas De Marchi
> 
> >+		drm_printf(p, "Global mocs table configuration:\n");
> >+		drm_printf(p, "GLOB_MOCS[idx] = [IG_PAT, L3_CLOS,
> L3_CACHE_POLICY,
> >+L4_CACHE_POLICY] (value)\n\n");
> >+
> >+		for (i = 0; i < info->n_entries; i++) {
> >+			if (regs_are_mcr(gt))
> >+				reg_val = xe_gt_mcr_unicast_read_any(gt,
> XEHP_GLOBAL_MOCS(i));
> >+			else
> >+				reg_val = xe_mmio_read32(gt,
> XELP_GLOBAL_MOCS(i));
> >+
> >+			drm_printf(p, "GLOB_MOCS[%2d] = [%u, %u, %u]
> (%#8x)\n",
> >+				   i,
> >+				   !!(reg_val & IG_PAT),
> >+				   REG_FIELD_GET(XE2_L3_CLOS_MASK,
> reg_val),
> >+				   REG_FIELD_GET(L4_CACHE_POLICY_MASK,
> reg_val),
> >+				   reg_val);
> >+		}
> >+	}
> >+}
> >+
> > static unsigned int get_mocs_settings(struct xe_device *xe,
> > 				      struct xe_mocs_info *info)
> > {
> >@@ -382,6 +613,7 @@ static unsigned int get_mocs_settings(struct xe_device
> *xe,
> > 		info->uc_index = 3;
> > 		info->wb_index = 4;
> > 		info->unused_entries_index = 4;
> >+		info->dump = xe2_mocs_dump;
> > 		break;
> > 	case XE_PVC:
> > 		info->size = ARRAY_SIZE(pvc_mocs_desc); @@ -390,6 +622,7
> @@ static
> >unsigned int get_mocs_settings(struct xe_device *xe,
> > 		info->uc_index = 1;
> > 		info->wb_index = 2;
> > 		info->unused_entries_index = 2;
> >+		info->dump = pvc_mocs_dump;
> > 		break;
> > 	case XE_METEORLAKE:
> > 		info->size = ARRAY_SIZE(mtl_mocs_desc); @@ -397,6 +630,7
> @@ static
> >unsigned int get_mocs_settings(struct xe_device *xe,
> > 		info->n_entries = MTL_NUM_MOCS_ENTRIES;
> > 		info->uc_index = 9;
> > 		info->unused_entries_index = 1;
> >+		info->dump = mtl_mocs_dump;
> > 		break;
> > 	case XE_DG2:
> > 		info->size = ARRAY_SIZE(dg2_mocs_desc); @@ -408,6 +642,7
> @@ static
> >unsigned int get_mocs_settings(struct xe_device *xe,
> > 		 */
> > 		info->n_entries = XELP_NUM_MOCS_ENTRIES - 1;
> > 		info->unused_entries_index = 3;
> >+		info->dump = dg2_mocs_dump;
> > 		break;
> > 	case XE_DG1:
> > 		info->size = ARRAY_SIZE(dg1_mocs_desc); @@ -415,6 +650,7
> @@ static
> >unsigned int get_mocs_settings(struct xe_device *xe,
> > 		info->uc_index = 1;
> > 		info->n_entries = XELP_NUM_MOCS_ENTRIES;
> > 		info->unused_entries_index = 5;
> >+		info->dump = dg1_mocs_dump;
> > 		break;
> > 	case XE_TIGERLAKE:
> > 	case XE_ROCKETLAKE:
> >@@ -426,6 +662,7 @@ static unsigned int get_mocs_settings(struct xe_device
> *xe,
> > 		info->n_entries = XELP_NUM_MOCS_ENTRIES;
> > 		info->uc_index = 3;
> > 		info->unused_entries_index = 2;
> >+		info->dump = gen12_mocs_dump;
> > 		break;
> > 	default:
> > 		drm_err(&xe->drm, "Platform that should have a MOCS table
> does
> >not.\n"); @@ -467,16 +704,6 @@ static u32 get_entry_control(const struct
> xe_mocs_info *info,
> > 	return info->table[info->unused_entries_index].control_value;
> > }
> >
> >-static bool regs_are_mcr(struct xe_gt *gt) -{
> >-	struct xe_device *xe = gt_to_xe(gt);
> >-
> >-	if (xe_gt_is_media_type(gt))
> >-		return MEDIA_VER(xe) >= 20;
> >-	else
> >-		return GRAPHICS_VERx100(xe) >= 1250;
> >-}
> >-
> > static void __init_mocs_table(struct xe_gt *gt,
> > 			      const struct xe_mocs_info *info)  { @@ -578,6
> +805,33 @@ void
> >xe_mocs_init(struct xe_gt *gt)
> > 		init_l3cc_table(gt, &table);
> > }
> >
> >+void xe_mocs_dump(struct xe_gt *gt, struct drm_printer *p) {
> >+	struct xe_mocs_info table;
> >+	unsigned int flags;
> >+	u32 ret;
> >+	struct xe_device *xe = gt_to_xe(gt);
> >+
> >+	flags = get_mocs_settings(xe, &table);
> >+
> >+	if (!table.dump)
> >+		return;
> >+
> >+	xe_device_mem_access_get(xe);
> >+	ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
> >+
> >+	if (ret)
> >+		goto err_fw;
> >+
> >+	table.dump(&table, flags, gt, p);
> >+
> >+	xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
> >+
> >+err_fw:
> >+	xe_assert(xe, !ret);
> >+	xe_device_mem_access_put(xe);
> >+}
> >+
> > #if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
> > #include "tests/xe_mocs.c"
> > #endif
> >diff --git a/drivers/gpu/drm/xe/xe_mocs.h
> >b/drivers/gpu/drm/xe/xe_mocs.h index 053754c5a94e..d6fa4485a6e9 100644
> >--- a/drivers/gpu/drm/xe/xe_mocs.h
> >+++ b/drivers/gpu/drm/xe/xe_mocs.h
> >@@ -10,8 +10,16 @@
> >
> > struct xe_exec_queue;
> > struct xe_gt;
> >+struct drm_printer;
> >
> > void xe_mocs_init_early(struct xe_gt *gt); void xe_mocs_init(struct
> > xe_gt *gt);
> >
> >+/**
> >+ * xe_mocs_dump - Dump mocs table
> >+ * @gt: GT structure
> >+ * @p: Printer to dump info to
> >+ */
> >+void xe_mocs_dump(struct xe_gt *gt, struct drm_printer *p);
> >+
> > #endif
> >--
> >2.25.1
> >


More information about the Intel-xe mailing list