Commit 100f5f7f authored by Stuart Summers's avatar Stuart Summers Committed by Chris Wilson

drm/i915: Expand subslice mask

Currently, the subslice_mask runtime parameter is stored as an
array of subslices per slice. Expand the subslice mask array to
better match what is presented to userspace through the
I915_QUERY_TOPOLOGY_INFO ioctl. The index into this array is
then calculated:
  slice * subslice stride + subslice index / 8

v2: Fix 32-bit build
v3: Use new helper function in SSEU workaround warning message
v4: Use GEM_BUG_ON to force developers to use valid SSEU configurations
    per platform (Chris)
Signed-off-by: default avatarStuart Summers <stuart.summers@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190823160307.180813-12-stuart.summers@intel.com
parent 668df17f
...@@ -32,6 +32,20 @@ intel_sseu_subslice_total(const struct sseu_dev_info *sseu) ...@@ -32,6 +32,20 @@ intel_sseu_subslice_total(const struct sseu_dev_info *sseu)
return total; return total;
} }
u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice)
{
int i, offset = slice * sseu->ss_stride;
u32 mask = 0;
GEM_BUG_ON(slice >= sseu->max_slices);
for (i = 0; i < sseu->ss_stride; i++)
mask |= (u32)sseu->subslice_mask[offset + i] <<
i * BITS_PER_BYTE;
return mask;
}
void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice, void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice,
u32 ss_mask) u32 ss_mask)
{ {
...@@ -43,7 +57,7 @@ void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice, ...@@ -43,7 +57,7 @@ void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice,
unsigned int unsigned int
intel_sseu_subslices_per_slice(const struct sseu_dev_info *sseu, u8 slice) intel_sseu_subslices_per_slice(const struct sseu_dev_info *sseu, u8 slice)
{ {
return hweight8(sseu->subslice_mask[slice]); return hweight32(intel_sseu_get_subslices(sseu, slice));
} }
u32 intel_sseu_make_rpcs(struct drm_i915_private *i915, u32 intel_sseu_make_rpcs(struct drm_i915_private *i915,
......
...@@ -23,7 +23,7 @@ struct drm_i915_private; ...@@ -23,7 +23,7 @@ struct drm_i915_private;
struct sseu_dev_info { struct sseu_dev_info {
u8 slice_mask; u8 slice_mask;
u8 subslice_mask[GEN_MAX_SLICES]; u8 subslice_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICE_STRIDE];
u16 eu_total; u16 eu_total;
u8 eu_per_subslice; u8 eu_per_subslice;
u8 min_eu_in_pool; u8 min_eu_in_pool;
...@@ -94,6 +94,8 @@ intel_sseu_subslice_total(const struct sseu_dev_info *sseu); ...@@ -94,6 +94,8 @@ intel_sseu_subslice_total(const struct sseu_dev_info *sseu);
unsigned int unsigned int
intel_sseu_subslices_per_slice(const struct sseu_dev_info *sseu, u8 slice); intel_sseu_subslices_per_slice(const struct sseu_dev_info *sseu, u8 slice);
u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice);
void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice, void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice,
u32 ss_mask); u32 ss_mask);
......
...@@ -801,11 +801,10 @@ wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal) ...@@ -801,11 +801,10 @@ wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal)
} }
slice = fls(sseu->slice_mask) - 1; slice = fls(sseu->slice_mask) - 1;
GEM_BUG_ON(slice >= ARRAY_SIZE(sseu->subslice_mask)); subslice = fls(l3_en & intel_sseu_get_subslices(sseu, slice));
subslice = fls(l3_en & sseu->subslice_mask[slice]);
if (!subslice) { if (!subslice) {
DRM_WARN("No common index found between subslice mask %x and L3 bank mask %x!\n", DRM_WARN("No common index found between subslice mask %x and L3 bank mask %x!\n",
sseu->subslice_mask[slice], l3_en); intel_sseu_get_subslices(sseu, slice), l3_en);
subslice = fls(l3_en); subslice = fls(l3_en);
WARN_ON(!subslice); WARN_ON(!subslice);
} }
......
...@@ -3864,13 +3864,16 @@ static void gen9_sseu_device_status(struct drm_i915_private *dev_priv, ...@@ -3864,13 +3864,16 @@ static void gen9_sseu_device_status(struct drm_i915_private *dev_priv,
for (ss = 0; ss < info->sseu.max_subslices; ss++) { for (ss = 0; ss < info->sseu.max_subslices; ss++) {
unsigned int eu_cnt; unsigned int eu_cnt;
u8 ss_idx = s * info->sseu.ss_stride +
ss / BITS_PER_BYTE;
if (IS_GEN9_LP(dev_priv)) { if (IS_GEN9_LP(dev_priv)) {
if (!(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss)))) if (!(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss))))
/* skip disabled subslice */ /* skip disabled subslice */
continue; continue;
sseu->subslice_mask[s] |= BIT(ss); sseu->subslice_mask[ss_idx] |=
BIT(ss % BITS_PER_BYTE);
} }
eu_cnt = 2 * hweight32(eu_reg[2*s + ss/2] & eu_cnt = 2 * hweight32(eu_reg[2*s + ss/2] &
......
...@@ -93,9 +93,9 @@ static void sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p) ...@@ -93,9 +93,9 @@ static void sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p)
hweight8(sseu->slice_mask), sseu->slice_mask); hweight8(sseu->slice_mask), sseu->slice_mask);
drm_printf(p, "subslice total: %u\n", intel_sseu_subslice_total(sseu)); drm_printf(p, "subslice total: %u\n", intel_sseu_subslice_total(sseu));
for (s = 0; s < sseu->max_slices; s++) { for (s = 0; s < sseu->max_slices; s++) {
drm_printf(p, "slice%d: %u subslices, mask=%04x\n", drm_printf(p, "slice%d: %u subslices, mask=%08x\n",
s, intel_sseu_subslices_per_slice(sseu, s), s, intel_sseu_subslices_per_slice(sseu, s),
sseu->subslice_mask[s]); intel_sseu_get_subslices(sseu, s));
} }
drm_printf(p, "EU total: %u\n", sseu->eu_total); drm_printf(p, "EU total: %u\n", sseu->eu_total);
drm_printf(p, "EU per subslice: %u\n", sseu->eu_per_subslice); drm_printf(p, "EU per subslice: %u\n", sseu->eu_per_subslice);
...@@ -159,9 +159,9 @@ void intel_device_info_dump_topology(const struct sseu_dev_info *sseu, ...@@ -159,9 +159,9 @@ void intel_device_info_dump_topology(const struct sseu_dev_info *sseu,
} }
for (s = 0; s < sseu->max_slices; s++) { for (s = 0; s < sseu->max_slices; s++) {
drm_printf(p, "slice%d: %u subslice(s) (0x%hhx):\n", drm_printf(p, "slice%d: %u subslice(s) (0x%08x):\n",
s, intel_sseu_subslices_per_slice(sseu, s), s, intel_sseu_subslices_per_slice(sseu, s),
sseu->subslice_mask[s]); intel_sseu_get_subslices(sseu, s));
for (ss = 0; ss < sseu->max_subslices; ss++) { for (ss = 0; ss < sseu->max_subslices; ss++) {
u16 enabled_eus = sseu_get_eus(sseu, s, ss); u16 enabled_eus = sseu_get_eus(sseu, s, ss);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment