diff mbox

drm/i915/hsw: add missing disabled EUs registers reads

Message ID 20180216153101.30998-1-lionel.g.landwerlin@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lionel Landwerlin Feb. 16, 2018, 3:31 p.m. UTC
It turns out that HSW has a register that tells us how many EUs are
disabled per half-slice (roughly a similar notion to subslice). We
didn't read those registers so far as most userspace drivers didn't
need those values prior to Gen8, but an internal library would like to
have access to this.

Since we already have the getparam interface, there is no harm in
exposing this.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h          |  7 ++++
 drivers/gpu/drm/i915/intel_device_info.c | 56 +++++++++++++++++++++++++++++++-
 2 files changed, 62 insertions(+), 1 deletion(-)

Comments

Joonas Lahtinen Feb. 21, 2018, 6:50 p.m. UTC | #1
Quoting Lionel Landwerlin (2018-02-16 17:31:01)
> +static void haswell_sseu_info_init(struct drm_i915_private *dev_priv)
> +{
> +       struct intel_device_info *info = mkwrite_device_info(dev_priv);
> +       struct sseu_dev_info *sseu = &info->sseu;
> +       u32 fuse1;
> +
> +       /*
> +        * There isn't a register to tell us how many slices/subslices. We
> +        * work off the PCI-ids here.
> +        */
> +       switch (info->gt) {
> +       case 1:
> +               sseu->slice_mask = BIT(0);
> +               sseu->subslice_mask = BIT(0);
> +               break;
> +       case 2:
> +               sseu->slice_mask = BIT(0);
> +               sseu->subslice_mask = BIT(0) | BIT(1);
> +               break;
> +       case 3:
> +               sseu->slice_mask = BIT(0) | BIT(1);
> +               sseu->subslice_mask = BIT(0) | BIT(1);
> +               break;
> +       default:
> +               GEM_BUG_ON(true);

MISSING_CASE() and maybe return GT1 values in the default case? So how
about:

	default:
		MISSING_CASE(info->gt);
	case 1:
		...

> +               break;
> +       }
> +
> +       fuse1 = I915_READ(HSW_PAVP_FUSE1);
> +       switch ((fuse1 & HSW_F1_EU_DIS_MASK) >> HSW_F1_EU_DIS_SHIFT) {
> +       case HSW_F1_EU_DIS_MASK_10EUS:
> +               sseu->eu_per_subslice = 10;
> +               break;
> +       case HSW_F1_EU_DIS_MASK_8EUS:
> +               sseu->eu_per_subslice = 8;
> +               break;
> +       case HSW_F1_EU_DIS_MASK_6EUS:
> +               sseu->eu_per_subslice = 6;
> +               break;
> +       default:
> +               GEM_BUG_ON(true);
> +               break;

Ditto.

With at least s/GEM_BUG_ON(true)/MISSING_CASE(val)/, this is:

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 1412abcb27d4..ff3c2ba59612 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2807,6 +2807,13 @@  enum i915_power_well_id {
 #define GEN9_RCS_FE_FSM2 _MMIO(0x22a4)
 
 /* Fuse readout registers for GT */
+#define HSW_PAVP_FUSE1			_MMIO(0x911C)
+#define   HSW_F1_EU_DIS_SHIFT		16
+#define   HSW_F1_EU_DIS_MASK		(0x3 << HSW_F1_EU_DIS_SHIFT)
+#define   HSW_F1_EU_DIS_MASK_10EUS	0
+#define   HSW_F1_EU_DIS_MASK_8EUS	1
+#define   HSW_F1_EU_DIS_MASK_6EUS	2
+
 #define CHV_FUSE_GT			_MMIO(VLV_DISPLAY_BASE + 0x2168)
 #define   CHV_FGT_DISABLE_SS0		(1 << 10)
 #define   CHV_FGT_DISABLE_SS1		(1 << 11)
diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c
index 298f8996cc54..fb269eca4486 100644
--- a/drivers/gpu/drm/i915/intel_device_info.c
+++ b/drivers/gpu/drm/i915/intel_device_info.c
@@ -357,6 +357,58 @@  static void broadwell_sseu_info_init(struct drm_i915_private *dev_priv)
 	sseu->has_eu_pg = 0;
 }
 
+static void haswell_sseu_info_init(struct drm_i915_private *dev_priv)
+{
+	struct intel_device_info *info = mkwrite_device_info(dev_priv);
+	struct sseu_dev_info *sseu = &info->sseu;
+	u32 fuse1;
+
+	/*
+	 * There isn't a register to tell us how many slices/subslices. We
+	 * work off the PCI-ids here.
+	 */
+	switch (info->gt) {
+	case 1:
+		sseu->slice_mask = BIT(0);
+		sseu->subslice_mask = BIT(0);
+		break;
+	case 2:
+		sseu->slice_mask = BIT(0);
+		sseu->subslice_mask = BIT(0) | BIT(1);
+		break;
+	case 3:
+		sseu->slice_mask = BIT(0) | BIT(1);
+		sseu->subslice_mask = BIT(0) | BIT(1);
+		break;
+	default:
+		GEM_BUG_ON(true);
+		break;
+	}
+
+	fuse1 = I915_READ(HSW_PAVP_FUSE1);
+	switch ((fuse1 & HSW_F1_EU_DIS_MASK) >> HSW_F1_EU_DIS_SHIFT) {
+	case HSW_F1_EU_DIS_MASK_10EUS:
+		sseu->eu_per_subslice = 10;
+		break;
+	case HSW_F1_EU_DIS_MASK_8EUS:
+		sseu->eu_per_subslice = 8;
+		break;
+	case HSW_F1_EU_DIS_MASK_6EUS:
+		sseu->eu_per_subslice = 6;
+		break;
+	default:
+		GEM_BUG_ON(true);
+		break;
+	}
+
+	sseu->eu_total = sseu_subslice_total(sseu) * sseu->eu_per_subslice;
+
+	/* No powergating for you. */
+	sseu->has_slice_pg = 0;
+	sseu->has_subslice_pg = 0;
+	sseu->has_eu_pg = 0;
+}
+
 static u32 read_reference_ts_freq(struct drm_i915_private *dev_priv)
 {
 	u32 ts_override = I915_READ(GEN9_TIMESTAMP_OVERRIDE);
@@ -574,7 +626,9 @@  void intel_device_info_runtime_init(struct intel_device_info *info)
 	}
 
 	/* Initialize slice/subslice/EU info */
-	if (IS_CHERRYVIEW(dev_priv))
+	if (IS_HASWELL(dev_priv))
+		haswell_sseu_info_init(dev_priv);
+	else if (IS_CHERRYVIEW(dev_priv))
 		cherryview_sseu_info_init(dev_priv);
 	else if (IS_BROADWELL(dev_priv))
 		broadwell_sseu_info_init(dev_priv);