[PATCH 2/2] drm/xe/mcr: Try to derive dss_per_grp from hwconfig attributes
Cavitt, Jonathan
jonathan.cavitt at intel.com
Thu Aug 15 18:27:40 UTC 2024
>
> -----Original Message-----
From: Intel-xe <intel-xe-bounces at lists.freedesktop.org> On Behalf Of Matt Roper
Sent: Thursday, August 15, 2024 10:26 AM
To: intel-xe at lists.freedesktop.org
Cc: Roper, Matthew D <matthew.d.roper at intel.com>
Subject: [PATCH 2/2] drm/xe/mcr: Try to derive dss_per_grp from hwconfig attributes
>
> When steering MCR register ranges of type "DSS," the group_id and
> instance_id values are calculated by dividing the DSS pool according to
> the size of a gslice or cslice, depending on the platform. These values
> haven't changed much on past platforms, so we've been able to hardcode
> the proper divisor so far. However the layout may not be so fixed on
> future platforms so the proper, future-proof way to determine this is by
> using some of the attributes from the GuC's hwconfig table. The
> hwconfig has two attributes reflecting the architectural maximum slice
> and subslice counts (i.e., before any fusing is considered) that can be
> used for the purposes of calculating MCR steering targets.
>
> If the hwconfig is lacking the necessary values (which should only be
> possible on older platforms before these attributes were added), we can
> still fall back to the old hardcoded values. Going forward the hwconfig
> is expected to always provide the information we need on newer
> platforms, and any failure to do so will be considered a bug in the
> firmware that will prevent us from switching to the buggy firmware
> release.
>
> It's worth noting that over time GuC's hwconfig has provided a couple
> different keys with similar-sounding descriptions. For our purposes
> here, we only trust the newer key "70" which has supplanted the
> similarly-named key "2" that existed on older platforms.
>
> Bspec: 73210
> Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
LGTM, though
A) I'm surprised we didn't have a hwconfig lookup function before this patch. And
B) I'm not sure how this relates to the prior patch in the series aside from modifying
the same hwconfig files, as this patch seems fairly self-contained.
I suppose we could consider moving the newly-created
xe_guc_hwconfig_lookup_u32 to separate patch, but I won't block on that. And
it's likely doing so would just cause "unused function" complaints on compile,
so there's probable reason not to do so.
Reviewed-by: Jonathan Cavitt <jonathan.cavitt at intel.com>
-Jonathan Cavitt
> ---
> drivers/gpu/drm/xe/xe_gt_mcr.c | 40 +++++++++++++++++++++++++---
> drivers/gpu/drm/xe/xe_gt_types.h | 6 +++++
> drivers/gpu/drm/xe/xe_guc_hwconfig.c | 40 ++++++++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_guc_hwconfig.h | 1 +
> 4 files changed, 83 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c
> index 6d948a469126..7d7bd0be6233 100644
> --- a/drivers/gpu/drm/xe/xe_gt_mcr.c
> +++ b/drivers/gpu/drm/xe/xe_gt_mcr.c
> @@ -8,8 +8,10 @@
> #include "regs/xe_gt_regs.h"
> #include "xe_assert.h"
> #include "xe_gt.h"
> +#include "xe_gt_printk.h"
> #include "xe_gt_topology.h"
> #include "xe_gt_types.h"
> +#include "xe_guc_hwconfig.h"
> #include "xe_mmio.h"
> #include "xe_sriov.h"
>
> @@ -297,6 +299,36 @@ static void init_steering_mslice(struct xe_gt *gt)
>
> static unsigned int dss_per_group(struct xe_gt *gt)
> {
> + struct xe_guc *guc = >->uc.guc;
> + u32 max_slices = 0, max_subslices = 0;
> + int ret;
> +
> + /*
> + * Try to query the GuC's hwconfig table for the maximum number of
> + * slices and subslices. These don't reflect the platform's actual
> + * slice/DSS counts, just the physical layout by which we should
> + * determine the steering targets. On older platforms with older GuC
> + * firmware releases it's possible that these attributes may not be
> + * included in the table, so we can always fall back to the old
> + * hardcoded layouts.
> + */
> +#define HWCONFIG_ATTR_MAX_SLICES 1
> +#define HWCONFIG_ATTR_MAX_SUBSLICES 70
> +
> + ret = xe_guc_hwconfig_lookup_u32(guc, HWCONFIG_ATTR_MAX_SLICES,
> + &max_slices);
> + if (ret < 0 || max_slices == 0)
> + goto fallback;
> +
> + ret = xe_guc_hwconfig_lookup_u32(guc, HWCONFIG_ATTR_MAX_SUBSLICES,
> + &max_subslices);
> + if (ret < 0 || max_subslices == 0)
> + goto fallback;
> +
> + return DIV_ROUND_UP(max_subslices, max_slices);
> +
> +fallback:
> + xe_gt_dbg(gt, "GuC hwconfig cannot provide dss/slice; using typical fallback values\n");
> if (gt_to_xe(gt)->info.platform == XE_PVC)
> return 8;
> else if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1250)
> @@ -314,16 +346,16 @@ static unsigned int dss_per_group(struct xe_gt *gt)
> */
> void xe_gt_mcr_get_dss_steering(struct xe_gt *gt, unsigned int dss, u16 *group, u16 *instance)
> {
> - int dss_per_grp = dss_per_group(gt);
> -
> xe_gt_assert(gt, dss < XE_MAX_DSS_FUSE_BITS);
>
> - *group = dss / dss_per_grp;
> - *instance = dss % dss_per_grp;
> + *group = dss / gt->steering_dss_per_grp;
> + *instance = dss % gt->steering_dss_per_grp;
> }
>
> static void init_steering_dss(struct xe_gt *gt)
> {
> + gt->steering_dss_per_grp = dss_per_group(gt);
> +
> xe_gt_mcr_get_dss_steering(gt,
> min(xe_dss_mask_group_ffs(gt->fuse_topo.g_dss_mask, 0, 0),
> xe_dss_mask_group_ffs(gt->fuse_topo.c_dss_mask, 0, 0)),
> diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h
> index 8e46c0969bc7..82cf9f631736 100644
> --- a/drivers/gpu/drm/xe/xe_gt_types.h
> +++ b/drivers/gpu/drm/xe/xe_gt_types.h
> @@ -376,6 +376,12 @@ struct xe_gt {
> u16 instance_target;
> } steering[NUM_STEERING_TYPES];
>
> + /**
> + * @steering_dss_per_grp: number of DSS per steering group (gslice,
> + * cslice, etc.).
> + */
> + unsigned int steering_dss_per_grp;
> +
> /**
> * @mcr_lock: protects the MCR_SELECTOR register for the duration
> * of a steered operation
> diff --git a/drivers/gpu/drm/xe/xe_guc_hwconfig.c b/drivers/gpu/drm/xe/xe_guc_hwconfig.c
> index 025bad701556..af2c817d552c 100644
> --- a/drivers/gpu/drm/xe/xe_guc_hwconfig.c
> +++ b/drivers/gpu/drm/xe/xe_guc_hwconfig.c
> @@ -160,3 +160,43 @@ void xe_guc_hwconfig_dump(struct xe_guc *guc, struct drm_printer *p)
>
> kfree(hwconfig);
> }
> +
> +/*
> + * Lookup a specific 32-bit attribute value in the GuC's hwconfig table.
> + */
> +int xe_guc_hwconfig_lookup_u32(struct xe_guc *guc, u32 attribute, u32 *val)
> +{
> + size_t size = xe_guc_hwconfig_size(guc);
> + u64 num_dw = div_u64(size, sizeof(u32));
> + u32 *hwconfig;
> + bool found = false;
> + int i = 0;
> +
> + if (num_dw == 0)
> + return -EINVAL;
> +
> + hwconfig = kzalloc(size, GFP_KERNEL);
> + if (!hwconfig)
> + return -ENOMEM;
> +
> + xe_guc_hwconfig_copy(guc, hwconfig);
> +
> + /* An entry requires at least three dwords for key, length, value */
> + while (i + 3 <= num_dw) {
> + u32 key = hwconfig[i++];
> + u32 len_dw = hwconfig[i++];
> +
> + if (key != attribute) {
> + i += len_dw;
> + continue;
> + }
> +
> + *val = hwconfig[i];
> + found = true;
> + break;
> + }
> +
> + kfree(hwconfig);
> +
> + return found ? 0 : -ENOENT;
> +}
> diff --git a/drivers/gpu/drm/xe/xe_guc_hwconfig.h b/drivers/gpu/drm/xe/xe_guc_hwconfig.h
> index 7df315900e1c..ab4e5038236e 100644
> --- a/drivers/gpu/drm/xe/xe_guc_hwconfig.h
> +++ b/drivers/gpu/drm/xe/xe_guc_hwconfig.h
> @@ -15,5 +15,6 @@ int xe_guc_hwconfig_init(struct xe_guc *guc);
> u32 xe_guc_hwconfig_size(struct xe_guc *guc);
> void xe_guc_hwconfig_copy(struct xe_guc *guc, void *dst);
> void xe_guc_hwconfig_dump(struct xe_guc *guc, struct drm_printer *p);
> +int xe_guc_hwconfig_lookup_u32(struct xe_guc *guc, u32 attribute, u32 *val);
>
> #endif
> --
> 2.45.2
>
>
More information about the Intel-xe
mailing list