Commit 3ffe82d7 authored by Daniele Ceraolo Spurio's avatar Daniele Ceraolo Spurio Committed by Matt Roper
Browse files

drm/i915/xehp: handle new steering options



Xe_HP is more modular than its predecessors and as a consequence it has
more types of replicated registers.  As with l3bank regions on previous
platforms, we may need to explicitly re-steer accesses to these new
types of ranges at runtime if we can't find a single default steering
value that satisfies the fusing of all types.

v2:
 - Add a local 'i915' variable to reduce gt->i915 usage.  (Caz)
 - Drop unused 'intel_gt_read_register' prototype.  (Caz)

v3:
 - Drop unnecessary comment text.  (Lucas)
 - Drop unused register bit definition.  (Lucas)

Bspec: 66534
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Caz Yokoyama <caz.yokoyama@intel.com>
Signed-off-by: default avatarDaniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Reviewed-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210729170008.2836648-2-matthew.d.roper@intel.com
parent b65a9489
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -89,18 +89,40 @@ static const struct intel_mmio_range icl_l3bank_steering_table[] = {
	{},
};

static u16 slicemask(struct intel_gt *gt, int count)
{
	u64 dss_mask = intel_sseu_get_subslices(&gt->info.sseu, 0);

	return intel_slicemask_from_dssmask(dss_mask, count);
}

int intel_gt_init_mmio(struct intel_gt *gt)
{
	struct drm_i915_private *i915 = gt->i915;

	intel_gt_init_clock_frequency(gt);

	intel_uc_init_mmio(&gt->uc);
	intel_sseu_info_init(gt);

	if (GRAPHICS_VER(gt->i915) >= 11) {
	/*
	 * An mslice is unavailable only if both the meml3 for the slice is
	 * disabled *and* all of the DSS in the slice (quadrant) are disabled.
	 */
	if (HAS_MSLICES(i915))
		gt->info.mslice_mask =
			slicemask(gt, GEN_DSS_PER_MSLICE) |
			(intel_uncore_read(gt->uncore, GEN10_MIRROR_FUSE3) &
			 GEN12_MEML3_EN_MASK);

	if (GRAPHICS_VER(i915) >= 11 &&
		   GRAPHICS_VER_FULL(i915) < IP_VER(12, 50)) {
		gt->steering_table[L3BANK] = icl_l3bank_steering_table;
		gt->info.l3bank_mask =
			~intel_uncore_read(gt->uncore, GEN10_MIRROR_FUSE3) &
			GEN10_L3BANK_MASK;
	} else if (HAS_MSLICES(i915)) {
		MISSING_CASE(INTEL_INFO(i915)->platform);
	}

	return intel_engines_init_mmio(gt);
@@ -787,6 +809,22 @@ static void intel_gt_get_valid_steering(struct intel_gt *gt,
		*sliceid = 0;		/* unused */
		*subsliceid = __ffs(gt->info.l3bank_mask);
		break;
	case MSLICE:
		GEM_DEBUG_WARN_ON(!gt->info.mslice_mask); /* should be impossible! */

		*sliceid = __ffs(gt->info.mslice_mask);
		*subsliceid = 0;	/* unused */
		break;
	case LNCF:
		GEM_DEBUG_WARN_ON(!gt->info.mslice_mask); /* should be impossible! */

		/*
		 * An LNCF is always present if its mslice is present, so we
		 * can safely just steer to LNCF 0 in all cases.
		 */
		*sliceid = __ffs(gt->info.mslice_mask) << 1;
		*subsliceid = 0;	/* unused */
		break;
	default:
		MISSING_CASE(type);
		*sliceid = 0;
+7 −0
Original line number Diff line number Diff line
@@ -47,9 +47,14 @@ struct intel_mmio_range {
 * of multicast registers.  If another type of steering does not have any
 * overlap in valid steering targets with 'subslice' style registers, we will
 * need to explicitly re-steer reads of registers of the other type.
 *
 * Only the replication types that may need additional non-default steering
 * are listed here.
 */
enum intel_steering_type {
	L3BANK,
	MSLICE,
	LNCF,

	NUM_STEERING_TYPES
};
@@ -184,6 +189,8 @@ struct intel_gt {

		/* Slice/subslice/EU info */
		struct sseu_dev_info sseu;

		unsigned long mslice_mask;
	} info;
};

+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include "gem/i915_gem_lmem.h"
#include "gem/i915_gem_region.h"
#include "gem/i915_gem_ttm.h"
#include "gt/intel_gt.h"

static int init_fake_lmem_bar(struct intel_memory_region *mem)
{
+18 −0
Original line number Diff line number Diff line
@@ -699,3 +699,21 @@ void intel_sseu_print_topology(const struct sseu_dev_info *sseu,
		}
	}
}

u16 intel_slicemask_from_dssmask(u64 dss_mask, int dss_per_slice)
{
	u16 slice_mask = 0;
	int i;

	WARN_ON(sizeof(dss_mask) * 8 / dss_per_slice > 8 * sizeof(slice_mask));

	for (i = 0; dss_mask; i++) {
		if (dss_mask & GENMASK(dss_per_slice - 1, 0))
			slice_mask |= BIT(i);

		dss_mask >>= dss_per_slice;
	}

	return slice_mask;
}
+6 −0
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ struct drm_printer;
#define GEN_MAX_EUS		(16) /* TGL upper bound */
#define GEN_MAX_EU_STRIDE GEN_SSEU_STRIDE(GEN_MAX_EUS)

#define GEN_DSS_PER_GSLICE	4
#define GEN_DSS_PER_CSLICE	8
#define GEN_DSS_PER_MSLICE	8

struct sseu_dev_info {
	u8 slice_mask;
	u8 subslice_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICE_STRIDE];
@@ -104,4 +108,6 @@ void intel_sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p);
void intel_sseu_print_topology(const struct sseu_dev_info *sseu,
			       struct drm_printer *p);

u16 intel_slicemask_from_dssmask(u64 dss_mask, int dss_per_slice);

#endif /* __INTEL_SSEU_H__ */
Loading