<snip>
--- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -84,17 +84,46 @@ void intel_device_info_dump_flags(const struct intel_device_info *info, #undef PRINT_FLAG }+#define SS_STR_MAX_SIZE (GEN_MAX_SUBSLICE_STRIDE * 2 + 1)+ +static char * +subslice_per_slice_str(char *buf, u8 size, const struct sseu_dev_info *sseu, + u8 slice) +{ + int i; + u8 ss_offset = slice * sseu->ss_stride; + + GEM_BUG_ON(slice >= sseu->max_slices); + + /* Two ASCII character hex plus null terminator */ + GEM_BUG_ON(size < sseu->ss_stride * 2 + 1); + + memset(buf, 0, size); + + /* + * Print subslice information in reverse order to match + * userspace expectations. + */ + for (i = 0; i < sseu->ss_stride; i++) + sprintf(&buf[i * 2], "%02x", + sseu->subslice_mask[ss_offset + sseu->ss_stride - + (i + 1)]); + + return buf; +} + static void sseu_dump(const struct sseu_dev_info *sseu, struct drm_printer *p) { int s; + char buf[SS_STR_MAX_SIZE];drm_printf(p, "slice total: %u, mask=%04x\n",hweight8(sseu->slice_mask), sseu->slice_mask); drm_printf(p, "subslice total: %u\n", intel_sseu_subslice_total(sseu)); 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=%s\n", s, intel_sseu_subslices_per_slice(sseu, s), - sseu->subslice_mask[s]); + subslice_per_slice_str(buf, ARRAY_SIZE(buf), sseu, s));Now that we have intel_sseu_get_subslices() can't we just print the return from that instead of using the buffer?I personally would prefer we keep the stringify function as it gives a little more flexibility. Do you have a strong preference to move to a direct printk formatted string?
I do not, it just seemed like duplication since you're not really using any extra formatting or other flexibility in filling the buffer. This isn't a lot of code, so maybe we can switch to just using the u32 for now and add this back if/when we do require the flexibility?
} drm_printf(p, "EU total: %u\n", sseu->eu_total); drm_printf(p, "EU per subslice: %u\n", sseu->eu_per_subslice);<snip>@@ -555,6 +570,7 @@ static void haswell_sseu_info_init(struct drm_i915_private *dev_priv) struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu; u32 fuse1; int s, ss; + u32 subslice_mask;/** There isn't a register to tell us how many slices/subslices. We @@ -566,22 +582,18 @@ static void haswell_sseu_info_init(struct drm_i915_private *dev_priv) /* fall through */ case 1: sseu->slice_mask = BIT(0); - sseu->subslice_mask[0] = BIT(0); + subslice_mask = BIT(0); break; case 2: sseu->slice_mask = BIT(0); - sseu->subslice_mask[0] = BIT(0) | BIT(1); + subslice_mask = BIT(0) | BIT(1); break; case 3: sseu->slice_mask = BIT(0) | BIT(1); - sseu->subslice_mask[0] = BIT(0) | BIT(1); - sseu->subslice_mask[1] = BIT(0) | BIT(1); + subslice_mask = BIT(0) | BIT(1); break; }- sseu->max_slices = hweight8(sseu->slice_mask);- sseu->max_subslices = hweight8(sseu->subslice_mask[0]); - fuse1 = I915_READ(HSW_PAVP_FUSE1); switch ((fuse1 & HSW_F1_EU_DIS_MASK) >> HSW_F1_EU_DIS_SHIFT) { default: @@ -598,9 +610,14 @@ static void haswell_sseu_info_init(struct drm_i915_private *dev_priv) sseu->eu_per_subslice = 6; break; } - sseu->max_eus_per_subslice = sseu->eu_per_subslice; + + intel_sseu_set_info(sseu, hweight8(sseu->slice_mask), + hweight8(subslice_mask), + sseu->eu_per_subslice);I'd still prefer this to use a local variable so that we always only set sseu->eu_per_subslice from within intel_sseu_set_info.So the reason I kept this is in intel_sseu_set_info we are really just setting the max_eus_per_subslice, not the eu_per_subslice. Are you saying you'd also like to move the code that sets eu_per_subslice in each generation's handler to local variables and/or just passed directly as an argument to intel_sseu_set_info?
My bad, I confused eu_per_subslice and max_eus_per_subslice as the same variable. Just ignore this comment :)
Daniele
I.e. should we use intel_sseu_set_info to set most or all of the members of the intel_sseu structure? Or is it OK to keep the current implementation of only using this to set default maximums per platform? -StuartDanielefor (s = 0; s < sseu->max_slices; s++) {+ intel_sseu_set_subslices(sseu, s, subslice_mask); + for (ss = 0; ss < sseu->max_subslices; ss++) { intel_sseu_set_eus(sseu, s, ss, (1UL << sseu-eu_per_subslice) - 1);
_______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx