@@ -733,6 +733,53 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
info->has_slice_pg = (info->slice_total > 1) ? 1 : 0;
info->has_subslice_pg = 0;
info->has_eu_pg = (info->eu_per_subslice > 2) ? 1 : 0;
+ } else if (IS_BROXTON(dev)) {
+ const int ss_max = 4;
+ int ss;
+ u32 fuse2, eu_disable, ss_disable;
+
+ fuse2 = I915_READ(GEN8_FUSE2);
+ ss_disable = (fuse2 & GEN9_F2_SS_DIS_MASK) >>
+ GEN9_F2_SS_DIS_SHIFT;
+ eu_disable = I915_READ(GEN8_EU_DISABLE0);
+
+ info->slice_total = 1;
+ info->subslice_per_slice = ss_max - hweight32(ss_disable);
+ info->subslice_total = info->subslice_per_slice;
+
+ /*
+ * Iterate through enabled subslices to count the total
+ * enabled EU.
+ */
+ for (ss = 0; ss < ss_max; ss++) {
+ if (ss_disable & (0x1 << ss))
+ /* skip disabled subslice */
+ continue;
+
+ /*
+ * BXT can have at most 6 EU per subslice. So only the
+ * lowest 6 bits of the 8-bit EU disable field are
+ * valid.
+ */
+ info->eu_total += 6 - hweight8((eu_disable >>
+ (ss * 8)) & 0x3f);
+ }
+
+ /*
+ * BXT expected to always have a uniform distribution of EU
+ * across subslices.
+ */
+ info->eu_per_subslice = info->subslice_total ?
+ info->eu_total / info->subslice_total :
+ 0;
+ /*
+ * BXT supports subslice power gating on devices with more than
+ * one subslice, and supports EU power gating on devices with
+ * more than one EU pair per subslice.
+ */
+ info->has_slice_pg = 0;
+ info->has_subslice_pg = (info->subslice_total > 1);
+ info->has_eu_pg = (info->eu_per_subslice > 2);
}
DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total);
DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total);