* [PATCH] drm/i915/bdw: Check for slice, subslice and EU count for BDW
@ 2015-08-13 12:38 Łukasz Daniluk
2015-08-13 21:34 ` Bish, Jim
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Łukasz Daniluk @ 2015-08-13 12:38 UTC (permalink / raw)
To: intel-gfx
Added checks for available slices, subslices and EUs for Broadwell. This
information is filled in intel_device_info and is available to user with
GET_PARAM.
Added checks for enabled slices, subslices and EU for Broadwell. This
information is based on available counts but takes power gated slices
into account. It can be read in debugfs.
Introduce new register defines that contain information on slices on
Broadwell.
Cc: Jeff Mcgee <jeff.mcgee@intel.com>
Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 35 +++++++++++++--
drivers/gpu/drm/i915/i915_dma.c | 89 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/i915_reg.h | 19 +++++++-
3 files changed, 138 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 23a69307..a17f912 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4838,7 +4838,6 @@ struct sseu_dev_status {
static void cherryview_sseu_device_status(struct drm_device *dev,
struct sseu_dev_status *stat)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
const int ss_max = 2;
int ss;
u32 sig1[ss_max], sig2[ss_max];
@@ -4870,7 +4869,6 @@ static void cherryview_sseu_device_status(struct drm_device *dev,
static void gen9_sseu_device_status(struct drm_device *dev,
struct sseu_dev_status *stat)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
int s_max = 3, ss_max = 4;
int s, ss;
u32 s_reg[s_max], eu_reg[2*s_max], eu_mask[2];
@@ -4932,13 +4930,42 @@ static void gen9_sseu_device_status(struct drm_device *dev,
}
}
+static void broadwell_sseu_device_status(struct drm_device *dev,
+ struct sseu_dev_status *stat)
+{
+ int s;
+ u32 slice_info = I915_READ(GEN8_R_PWR_CLK_STATE);
+
+ /*
+ * If first bit of slice_info is 0, there is no specific power
+ * state set. Otherwise we read the count of enabled slices
+ * from it.
+ */
+ if (slice_info & (1<<31))
+ stat->slice_total = (slice_info & GEN8_RPCS_S_CNT_MASK)
+ >> GEN8_RPCS_S_CNT_SHIFT;
+ else
+ stat->slice_total = INTEL_INFO(dev)->slice_total;
+
+ stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
+ stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
+ stat->subslice_total = stat->slice_total * stat->subslice_per_slice;
+ stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
+
+ /* subtract fused off EU(s) from enabled slice(s) */
+ for (s = 0; s < stat.slice_total; s++) {
+ u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
+ stat->eu_total -= hweight8(subslice_7eu);
+ }
+}
+
static int i915_sseu_status(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct sseu_dev_status stat;
- if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
+ if ((INTEL_INFO(dev)->gen < 8))
return -ENODEV;
seq_puts(m, "SSEU Device Info\n");
@@ -4963,6 +4990,8 @@ static int i915_sseu_status(struct seq_file *m, void *unused)
memset(&stat, 0, sizeof(stat));
if (IS_CHERRYVIEW(dev)) {
cherryview_sseu_device_status(dev, &stat);
+ } else if (IS_BROADWELL(dev)) {
+ broadwell_sseu_device_status(dev, &stat);
} else if (INTEL_INFO(dev)->gen >= 9) {
gen9_sseu_device_status(dev, &stat);
}
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index ab37d11..2d52b1e 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -705,6 +705,93 @@ static void gen9_sseu_info_init(struct drm_device *dev)
info->has_eu_pg = (info->eu_per_subslice > 2);
}
+static void broadwell_sseu_info_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_device_info *info;
+ const int s_max = 3, ss_max = 3, eu_max = 8;
+ int s, ss;
+ u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
+
+ fuse2 = I915_READ(GEN8_FUSE2);
+ s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
+ GEN8_F2_S_ENA_SHIFT;
+ ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >>
+ GEN8_F2_SS_DIS_SHIFT;
+
+ eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) &
+ GEN8_EU_DIS0_S0_MASK;
+ eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >>
+ GEN8_EU_DIS0_S1_SHIFT) |
+ ((I915_READ(GEN8_EU_DISABLE1) &
+ GEN8_EU_DIS1_S1_MASK) <<
+ (32 - GEN8_EU_DIS0_S1_SHIFT));
+ eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >>
+ GEN8_EU_DIS1_S2_SHIFT) |
+ ((I915_READ(GEN8_EU_DISABLE2) &
+ GEN8_EU_DIS2_S2_MASK) <<
+ (32 - GEN8_EU_DIS1_S2_SHIFT));
+
+
+ info = (struct intel_device_info *)&dev_priv->info;
+ info->slice_total = hweight32(s_enable);
+
+ /*
+ * The subslice disable field is global, i.e. it applies
+ * to each of the enabled slices.
+ */
+ info->subslice_per_slice = ss_max - hweight32(ss_disable);
+ info->subslice_total = info->slice_total *
+ info->subslice_per_slice;
+
+ /*
+ * Iterate through enabled slices and subslices to
+ * count the total enabled EU.
+ */
+ for (s = 0; s < s_max; s++) {
+ if (!(s_enable & (0x1 << s)))
+ /* skip disabled slice */
+ continue;
+
+ for (ss = 0; ss < ss_max; ss++) {
+ u32 n_disabled;
+
+ if (ss_disable & (0x1 << ss))
+ /* skip disabled subslice */
+ continue;
+
+ n_disabled = hweight8(eu_disable[s] >>
+ (ss * eu_max));
+
+ /*
+ * Record which subslice(s) has(have) 7 EUs. we
+ * can tune the hash used to spread work among
+ * subslices if they are unbalanced.
+ */
+ if (eu_max - n_disabled == 7)
+ info->subslice_7eu[s] |= 1 << ss;
+
+ info->eu_total += eu_max - n_disabled;
+ }
+ }
+
+ /*
+ * BDW is expected to always have a uniform distribution of EU across
+ * subslices with the exception that any one EU in any one subslice may
+ * be fused off for die recovery.
+ */
+ info->eu_per_subslice = info->subslice_total ?
+ DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
+
+ /*
+ * BDW supports slice power gating on devices with more than
+ * one slice.
+ */
+ info->has_slice_pg = (info->slice_total > 1);
+ info->has_subslice_pg = 0;
+ info->has_eu_pg = 0;
+}
+
/*
* Determine various intel_device_info fields at runtime.
*
@@ -775,6 +862,8 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
/* Initialize slice/subslice/EU info */
if (IS_CHERRYVIEW(dev))
cherryview_sseu_info_init(dev);
+ else if (IS_BROADWELL(dev))
+ broadwell_sseu_info_init(dev);
else if (INTEL_INFO(dev)->gen >= 9)
gen9_sseu_info_init(dev);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index be87e3b..77e043e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1841,11 +1841,26 @@ enum skl_disp_power_wells {
#define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
#define GEN8_FUSE2 0x9120
+#define GEN8_F2_SS_DIS_SHIFT 21
+#define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT)
#define GEN8_F2_S_ENA_SHIFT 25
#define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT)
-#define GEN9_F2_SS_DIS_SHIFT 20
-#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
+#define GEN8_EU_DISABLE0 0x9134
+#define GEN8_EU_DIS0_S0_MASK 0xffffff
+#define GEN8_EU_DIS0_S1_SHIFT 24
+#define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT)
+
+#define GEN8_EU_DISABLE1 0x9138
+#define GEN8_EU_DIS1_S1_MASK 0xffff
+#define GEN8_EU_DIS1_S2_SHIFT 16
+#define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT)
+
+#define GEN8_EU_DISABLE2 0x913c
+#define GEN8_EU_DIS2_S2_MASK 0xff
+
+#define GEN9_F2_SS_DIS_SHIFT 20
+#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
#define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
--
Lukasz Daniluk
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-08-13 12:38 [PATCH] drm/i915/bdw: Check for slice, subslice and EU count for BDW Łukasz Daniluk
@ 2015-08-13 21:34 ` Bish, Jim
2015-08-14 0:11 ` Jeff McGee
2015-09-02 15:47 ` [PATCH v2] " Łukasz Daniluk
2 siblings, 0 replies; 13+ messages in thread
From: Bish, Jim @ 2015-08-13 21:34 UTC (permalink / raw)
To: intel-gfx@lists.freedesktop.org
On Thu, 2015-08-13 at 14:38 +0200, Łukasz Daniluk wrote:
> Added checks for available slices, subslices and EUs for Broadwell.
> This
> information is filled in intel_device_info and is available to user
> with
> GET_PARAM.
> Added checks for enabled slices, subslices and EU for Broadwell. This
> information is based on available counts but takes power gated slices
> into account. It can be read in debugfs.
> Introduce new register defines that contain information on slices on
> Broadwell.
>
> Cc: Jeff Mcgee <jeff.mcgee@intel.com>
> Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 35 +++++++++++++--
> drivers/gpu/drm/i915/i915_dma.c | 89
> +++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_reg.h | 19 +++++++-
> 3 files changed, 138 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
> b/drivers/gpu/drm/i915/i915_debugfs.c
> index 23a69307..a17f912 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -4838,7 +4838,6 @@ struct sseu_dev_status {
> static void cherryview_sseu_device_status(struct drm_device *dev,
> struct sseu_dev_status *stat)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> const int ss_max = 2;
> int ss;
> u32 sig1[ss_max], sig2[ss_max];
> @@ -4870,7 +4869,6 @@ static void
> cherryview_sseu_device_status(struct drm_device *dev,
> static void gen9_sseu_device_status(struct drm_device *dev,
> struct sseu_dev_status *stat)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
> int s_max = 3, ss_max = 4;
> int s, ss;
> u32 s_reg[s_max], eu_reg[2*s_max], eu_mask[2];
> @@ -4932,13 +4930,42 @@ static void gen9_sseu_device_status(struct
> drm_device *dev,
> }
> }
>
> +static void broadwell_sseu_device_status(struct drm_device *dev,
> + struct sseu_dev_status *stat)
> +{
> + int s;
> + u32 slice_info = I915_READ(GEN8_R_PWR_CLK_STATE);
> +
> + /*
> + * If first bit of slice_info is 0, there is no specific power
> + * state set. Otherwise we read the count of enabled slices
> + * from it.
> + */
> + if (slice_info & (1<<31))
> + stat->slice_total = (slice_info & GEN8_RPCS_S_CNT_MASK)
> + >> GEN8_RPCS_S_CNT_SHIFT;
> + else
> + stat->slice_total = INTEL_INFO(dev)->slice_total;
> +
> + stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
> + stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
> + stat->subslice_total = stat->slice_total * stat-
> >subslice_per_slice;
> + stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
> +
> + /* subtract fused off EU(s) from enabled slice(s) */
> + for (s = 0; s < stat.slice_total; s++) {
> + u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
> + stat->eu_total -= hweight8(subslice_7eu);
> + }
> +}
> +
> static int i915_sseu_status(struct seq_file *m, void *unused)
> {
> struct drm_info_node *node = (struct drm_info_node *) m->private;
> struct drm_device *dev = node->minor->dev;
> struct sseu_dev_status stat;
>
> - if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
> + if ((INTEL_INFO(dev)->gen < 8))
> return -ENODEV;
>
> seq_puts(m, "SSEU Device Info\n");
> @@ -4963,6 +4990,8 @@ static int i915_sseu_status(struct seq_file
> *m, void *unused)
> memset(&stat, 0, sizeof(stat));
> if (IS_CHERRYVIEW(dev)) {
> cherryview_sseu_device_status(dev, &stat);
> + } else if (IS_BROADWELL(dev)) {
> + broadwell_sseu_device_status(dev, &stat);
> } else if (INTEL_INFO(dev)->gen >= 9) {
> gen9_sseu_device_status(dev, &stat);
> }
> diff --git a/drivers/gpu/drm/i915/i915_dma.c
> b/drivers/gpu/drm/i915/i915_dma.c
> index ab37d11..2d52b1e 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -705,6 +705,93 @@ static void gen9_sseu_info_init(struct
> drm_device *dev)
> info->has_eu_pg = (info->eu_per_subslice > 2);
> }
>
> +static void broadwell_sseu_info_init(struct drm_device *dev)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_device_info *info;
> + const int s_max = 3, ss_max = 3, eu_max = 8;
> + int s, ss;
> + u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
> +
> + fuse2 = I915_READ(GEN8_FUSE2);
> + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
> + GEN8_F2_S_ENA_SHIFT;
> + ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >>
> + GEN8_F2_SS_DIS_SHIFT;
> +
> + eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) &
> + GEN8_EU_DIS0_S0_MASK;
> + eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >>
> + GEN8_EU_DIS0_S1_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE1) &
> + GEN8_EU_DIS1_S1_MASK) <<
> + (32 - GEN8_EU_DIS0_S1_SHIFT));
> + eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >>
> + GEN8_EU_DIS1_S2_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE2) &
> + GEN8_EU_DIS2_S2_MASK) <<
> + (32 - GEN8_EU_DIS1_S2_SHIFT));
> +
> +
> + info = (struct intel_device_info *)&dev_priv->info;
> + info->slice_total = hweight32(s_enable);
> +
> + /*
> + * The subslice disable field is global, i.e. it applies
> + * to each of the enabled slices.
> + */
> + info->subslice_per_slice = ss_max - hweight32(ss_disable);
> + info->subslice_total = info->slice_total *
> + info->subslice_per_slice;
> +
> + /*
> + * Iterate through enabled slices and subslices to
> + * count the total enabled EU.
> + */
> + for (s = 0; s < s_max; s++) {
> + if (!(s_enable & (0x1 << s)))
> + /* skip disabled slice */
> + continue;
> +
> + for (ss = 0; ss < ss_max; ss++) {
> + u32 n_disabled;
> +
> + if (ss_disable & (0x1 << ss))
> + /* skip disabled subslice */
> + continue;
> +
> + n_disabled = hweight8(eu_disable[s] >>
> + (ss * eu_max));
> +
> + /*
> + * Record which subslice(s) has(have) 7 EUs. we
> + * can tune the hash used to spread work among
> + * subslices if they are unbalanced.
> + */
> + if (eu_max - n_disabled == 7)
> + info->subslice_7eu[s] |= 1 << ss;
> +
> + info->eu_total += eu_max - n_disabled;
> + }
> + }
> +
> + /*
> + * BDW is expected to always have a uniform distribution of EU
> across
> + * subslices with the exception that any one EU in any one
> subslice may
> + * be fused off for die recovery.
I like comments but wondering if fused off for die recovery is ok. W
ould it be better to indicate for sku options or something?
> + */
> + info->eu_per_subslice = info->subslice_total ?
> + DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
> +
> + /*
> + * BDW supports slice power gating on devices with more than
> + * one slice.
> + */
> + info->has_slice_pg = (info->slice_total > 1);
> + info->has_subslice_pg = 0;
> + info->has_eu_pg = 0;
> +}
> +
> /*
> * Determine various intel_device_info fields at runtime.
> *
> @@ -775,6 +862,8 @@ static void
> intel_device_info_runtime_init(struct drm_device *dev)
> /* Initialize slice/subslice/EU info */
> if (IS_CHERRYVIEW(dev))
> cherryview_sseu_info_init(dev);
> + else if (IS_BROADWELL(dev))
> + broadwell_sseu_info_init(dev);
> else if (INTEL_INFO(dev)->gen >= 9)
> gen9_sseu_info_init(dev);
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index be87e3b..77e043e 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1841,11 +1841,26 @@ enum skl_disp_power_wells {
> #define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf <<
> CHV_FGT_EU_DIS_SS1_R1_SHIFT)
>
> #define GEN8_FUSE2 0x9120
> +#define GEN8_F2_SS_DIS_SHIFT 21
> +#define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT)
> #define GEN8_F2_S_ENA_SHIFT 25
> #define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT)
>
> -#define GEN9_F2_SS_DIS_SHIFT 20
> -#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
> +#define GEN8_EU_DISABLE0 0x9134
> +#define GEN8_EU_DIS0_S0_MASK 0xffffff
> +#define GEN8_EU_DIS0_S1_SHIFT 24
> +#define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT)
> +
> +#define GEN8_EU_DISABLE1 0x9138
> +#define GEN8_EU_DIS1_S1_MASK 0xffff
> +#define GEN8_EU_DIS1_S2_SHIFT 16
> +#define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT)
> +
> +#define GEN8_EU_DISABLE2 0x913c
> +#define GEN8_EU_DIS2_S2_MASK 0xff
> +
> +#define GEN9_F2_SS_DIS_SHIFT 20
> +#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
>
> #define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-08-13 12:38 [PATCH] drm/i915/bdw: Check for slice, subslice and EU count for BDW Łukasz Daniluk
2015-08-13 21:34 ` Bish, Jim
@ 2015-08-14 0:11 ` Jeff McGee
2015-09-02 15:47 ` [PATCH v2] " Łukasz Daniluk
2 siblings, 0 replies; 13+ messages in thread
From: Jeff McGee @ 2015-08-14 0:11 UTC (permalink / raw)
To: Łukasz Daniluk; +Cc: intel-gfx
On Thu, Aug 13, 2015 at 02:38:48PM +0200, Łukasz Daniluk wrote:
> Added checks for available slices, subslices and EUs for Broadwell. This
> information is filled in intel_device_info and is available to user with
> GET_PARAM.
> Added checks for enabled slices, subslices and EU for Broadwell. This
> information is based on available counts but takes power gated slices
> into account. It can be read in debugfs.
> Introduce new register defines that contain information on slices on
> Broadwell.
>
> Cc: Jeff Mcgee <jeff.mcgee@intel.com>
> Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 35 +++++++++++++--
> drivers/gpu/drm/i915/i915_dma.c | 89 +++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_reg.h | 19 +++++++-
> 3 files changed, 138 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 23a69307..a17f912 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -4838,7 +4838,6 @@ struct sseu_dev_status {
> static void cherryview_sseu_device_status(struct drm_device *dev,
> struct sseu_dev_status *stat)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
Did you compile this? I915_READ macro requires dev_priv.
> const int ss_max = 2;
> int ss;
> u32 sig1[ss_max], sig2[ss_max];
> @@ -4870,7 +4869,6 @@ static void cherryview_sseu_device_status(struct drm_device *dev,
> static void gen9_sseu_device_status(struct drm_device *dev,
> struct sseu_dev_status *stat)
> {
> - struct drm_i915_private *dev_priv = dev->dev_private;
Did you compile this? I915_READ macro requires dev_priv.
> int s_max = 3, ss_max = 4;
> int s, ss;
> u32 s_reg[s_max], eu_reg[2*s_max], eu_mask[2];
> @@ -4932,13 +4930,42 @@ static void gen9_sseu_device_status(struct drm_device *dev,
> }
> }
>
> +static void broadwell_sseu_device_status(struct drm_device *dev,
> + struct sseu_dev_status *stat)
> +{
> + int s;
> + u32 slice_info = I915_READ(GEN8_R_PWR_CLK_STATE);
RPCS register only shows what slice state was requested, not the actual
slice state. You need to use the GEN8_GT_SLICE_INFO register that I
shared with you in my original patch for this.
> +
> + /*
> + * If first bit of slice_info is 0, there is no specific power
> + * state set. Otherwise we read the count of enabled slices
> + * from it.
> + */
> + if (slice_info & (1<<31))
> + stat->slice_total = (slice_info & GEN8_RPCS_S_CNT_MASK)
> + >> GEN8_RPCS_S_CNT_SHIFT;
> + else
> + stat->slice_total = INTEL_INFO(dev)->slice_total;
> +
> + stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
> + stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
> + stat->subslice_total = stat->slice_total * stat->subslice_per_slice;
> + stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
> +
> + /* subtract fused off EU(s) from enabled slice(s) */
> + for (s = 0; s < stat.slice_total; s++) {
> + u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
> + stat->eu_total -= hweight8(subslice_7eu);
> + }
> +}
> +
> static int i915_sseu_status(struct seq_file *m, void *unused)
> {
> struct drm_info_node *node = (struct drm_info_node *) m->private;
> struct drm_device *dev = node->minor->dev;
> struct sseu_dev_status stat;
>
> - if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
> + if ((INTEL_INFO(dev)->gen < 8))
> return -ENODEV;
>
> seq_puts(m, "SSEU Device Info\n");
> @@ -4963,6 +4990,8 @@ static int i915_sseu_status(struct seq_file *m, void *unused)
> memset(&stat, 0, sizeof(stat));
> if (IS_CHERRYVIEW(dev)) {
> cherryview_sseu_device_status(dev, &stat);
> + } else if (IS_BROADWELL(dev)) {
> + broadwell_sseu_device_status(dev, &stat);
> } else if (INTEL_INFO(dev)->gen >= 9) {
> gen9_sseu_device_status(dev, &stat);
> }
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index ab37d11..2d52b1e 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -705,6 +705,93 @@ static void gen9_sseu_info_init(struct drm_device *dev)
> info->has_eu_pg = (info->eu_per_subslice > 2);
> }
>
> +static void broadwell_sseu_info_init(struct drm_device *dev)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_device_info *info;
> + const int s_max = 3, ss_max = 3, eu_max = 8;
> + int s, ss;
> + u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
> +
> + fuse2 = I915_READ(GEN8_FUSE2);
> + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
> + GEN8_F2_S_ENA_SHIFT;
> + ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >>
> + GEN8_F2_SS_DIS_SHIFT;
> +
> + eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) &
> + GEN8_EU_DIS0_S0_MASK;
> + eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >>
> + GEN8_EU_DIS0_S1_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE1) &
> + GEN8_EU_DIS1_S1_MASK) <<
> + (32 - GEN8_EU_DIS0_S1_SHIFT));
> + eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >>
> + GEN8_EU_DIS1_S2_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE2) &
> + GEN8_EU_DIS2_S2_MASK) <<
> + (32 - GEN8_EU_DIS1_S2_SHIFT));
> +
> +
> + info = (struct intel_device_info *)&dev_priv->info;
> + info->slice_total = hweight32(s_enable);
> +
> + /*
> + * The subslice disable field is global, i.e. it applies
> + * to each of the enabled slices.
> + */
> + info->subslice_per_slice = ss_max - hweight32(ss_disable);
> + info->subslice_total = info->slice_total *
> + info->subslice_per_slice;
> +
> + /*
> + * Iterate through enabled slices and subslices to
> + * count the total enabled EU.
> + */
> + for (s = 0; s < s_max; s++) {
> + if (!(s_enable & (0x1 << s)))
> + /* skip disabled slice */
> + continue;
> +
> + for (ss = 0; ss < ss_max; ss++) {
> + u32 n_disabled;
> +
> + if (ss_disable & (0x1 << ss))
> + /* skip disabled subslice */
> + continue;
> +
> + n_disabled = hweight8(eu_disable[s] >>
> + (ss * eu_max));
> +
> + /*
> + * Record which subslice(s) has(have) 7 EUs. we
> + * can tune the hash used to spread work among
> + * subslices if they are unbalanced.
> + */
> + if (eu_max - n_disabled == 7)
> + info->subslice_7eu[s] |= 1 << ss;
> +
> + info->eu_total += eu_max - n_disabled;
> + }
> + }
> +
> + /*
> + * BDW is expected to always have a uniform distribution of EU across
> + * subslices with the exception that any one EU in any one subslice may
> + * be fused off for die recovery.
> + */
> + info->eu_per_subslice = info->subslice_total ?
> + DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
> +
> + /*
> + * BDW supports slice power gating on devices with more than
> + * one slice.
> + */
> + info->has_slice_pg = (info->slice_total > 1);
> + info->has_subslice_pg = 0;
> + info->has_eu_pg = 0;
> +}
> +
> /*
> * Determine various intel_device_info fields at runtime.
> *
> @@ -775,6 +862,8 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
> /* Initialize slice/subslice/EU info */
> if (IS_CHERRYVIEW(dev))
> cherryview_sseu_info_init(dev);
> + else if (IS_BROADWELL(dev))
> + broadwell_sseu_info_init(dev);
> else if (INTEL_INFO(dev)->gen >= 9)
> gen9_sseu_info_init(dev);
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index be87e3b..77e043e 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1841,11 +1841,26 @@ enum skl_disp_power_wells {
> #define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
>
> #define GEN8_FUSE2 0x9120
> +#define GEN8_F2_SS_DIS_SHIFT 21
> +#define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT)
> #define GEN8_F2_S_ENA_SHIFT 25
> #define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT)
>
> -#define GEN9_F2_SS_DIS_SHIFT 20
> -#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
> +#define GEN8_EU_DISABLE0 0x9134
> +#define GEN8_EU_DIS0_S0_MASK 0xffffff
> +#define GEN8_EU_DIS0_S1_SHIFT 24
> +#define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT)
> +
> +#define GEN8_EU_DISABLE1 0x9138
> +#define GEN8_EU_DIS1_S1_MASK 0xffff
> +#define GEN8_EU_DIS1_S2_SHIFT 16
> +#define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT)
> +
> +#define GEN8_EU_DISABLE2 0x913c
> +#define GEN8_EU_DIS2_S2_MASK 0xff
> +
> +#define GEN9_F2_SS_DIS_SHIFT 20
> +#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
>
> #define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
>
> --
> Lukasz Daniluk
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-09-02 15:47 ` [PATCH v2] " Łukasz Daniluk
@ 2015-09-02 14:03 ` Chris Wilson
2015-09-08 11:29 ` Daniluk, Lukasz
2015-09-02 15:08 ` Arun Siluvery
2015-09-17 11:51 ` [PATCH v3] " Łukasz Daniluk
2 siblings, 1 reply; 13+ messages in thread
From: Chris Wilson @ 2015-09-02 14:03 UTC (permalink / raw)
To: Łukasz Daniluk; +Cc: intel-gfx
On Wed, Sep 02, 2015 at 05:47:58PM +0200, Łukasz Daniluk wrote:
> +static void broadwell_sseu_device_status(struct drm_device *dev,
Why pass in dev if you only use dev_priv (and commit the sin of
repeatedly retrieving dev->dev_priv)?
> + struct sseu_dev_status *stat)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + int s;
> + u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
> +
> + stat->slice_total =
> + hweight32(slice_info & GEN8_LSLICESTAT_MASK);
> +
> + if (stat->slice_total)
> + {
Missed.
> + stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
> + stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
> + stat->subslice_total = stat->slice_total * stat->subslice_per_slice;
> + stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
> +
> + /* subtract fused off EU(s) from enabled slice(s) */
> + for (s = 0; s < stat->slice_total; s++) {
> + u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
> + stat->eu_total -= hweight8(subslice_7eu);
> + }
So why are we computing this twice? Is the debugfs to show the hw
registers or the sw tracking? Where do I see what we actually report? If
it is for the hw registers, report them. A perfect function here would
report the actual register values (possibly decoding them) and show what
the internal values are.
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-09-02 15:47 ` [PATCH v2] " Łukasz Daniluk
2015-09-02 14:03 ` Chris Wilson
@ 2015-09-02 15:08 ` Arun Siluvery
2015-09-08 12:53 ` Daniluk, Lukasz
2015-09-17 11:51 ` [PATCH v3] " Łukasz Daniluk
2 siblings, 1 reply; 13+ messages in thread
From: Arun Siluvery @ 2015-09-02 15:08 UTC (permalink / raw)
To: Łukasz Daniluk, intel-gfx
On 02/09/2015 16:47, Łukasz Daniluk wrote:
> Added checks for available slices, subslices and EUs for Broadwell. This
> information is filled in intel_device_info and is available to user with
> GET_PARAM.
> Added checks for enabled slices, subslices and EU for Broadwell. This
> information is based on available counts but takes power gated slices
> into account. It can be read in debugfs.
> Introduce new register defines that contain information on slices on
> Broadwell.
>
> v2:
> - Introduce GT_SLICE_INFO register
> - Change Broadwell sseu_device_status function to use GT_SLICE_INFO
> register instead of RPCS register
> - Undo removal of dev_priv variables in Cherryview and Gen9
> sseu_device_satus functions
>
> Cc: Jeff Mcgee <jeff.mcgee@intel.com>
> Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 29 +++++++++++-
> drivers/gpu/drm/i915/i915_dma.c | 89 +++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_reg.h | 22 ++++++++-
> 3 files changed, 137 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 23a69307..e8a62ef 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -4932,13 +4932,38 @@ static void gen9_sseu_device_status(struct drm_device *dev,
> }
> }
>
> +static void broadwell_sseu_device_status(struct drm_device *dev,
> + struct sseu_dev_status *stat)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + int s;
> + u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
I don't see this register (0x138064 as defined below) in bdw spec.
> +
> + stat->slice_total =
> + hweight32(slice_info & GEN8_LSLICESTAT_MASK);
why not in a single line, seems to fit under 80 chars.
> +
> + if (stat->slice_total)
> + {
> + stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
> + stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
> + stat->subslice_total = stat->slice_total * stat->subslice_per_slice;
> + stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
> +
Please reorder such that all subslice values are populated first
followed by EUs to follow an order.
> + /* subtract fused off EU(s) from enabled slice(s) */
> + for (s = 0; s < stat->slice_total; s++) {
> + u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
> + stat->eu_total -= hweight8(subslice_7eu);
> + }
> + }
> +}
> +
> static int i915_sseu_status(struct seq_file *m, void *unused)
> {
> struct drm_info_node *node = (struct drm_info_node *) m->private;
> struct drm_device *dev = node->minor->dev;
> struct sseu_dev_status stat;
>
> - if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
> + if (INTEL_INFO(dev)->gen < 8)
> return -ENODEV;
>
> seq_puts(m, "SSEU Device Info\n");
> @@ -4963,6 +4988,8 @@ static int i915_sseu_status(struct seq_file *m, void *unused)
> memset(&stat, 0, sizeof(stat));
> if (IS_CHERRYVIEW(dev)) {
> cherryview_sseu_device_status(dev, &stat);
> + } else if (IS_BROADWELL(dev)) {
> + broadwell_sseu_device_status(dev, &stat);
> } else if (INTEL_INFO(dev)->gen >= 9) {
> gen9_sseu_device_status(dev, &stat);
> }
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index ab37d11..2d52b1e 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -705,6 +705,93 @@ static void gen9_sseu_info_init(struct drm_device *dev)
> info->has_eu_pg = (info->eu_per_subslice > 2);
> }
>
> +static void broadwell_sseu_info_init(struct drm_device *dev)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_device_info *info;
> + const int s_max = 3, ss_max = 3, eu_max = 8;
I only see max of 2 slices for bdw in spec.
> + int s, ss;
> + u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
> +
> + fuse2 = I915_READ(GEN8_FUSE2);
> + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
> + GEN8_F2_S_ENA_SHIFT;
> + ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >>
> + GEN8_F2_SS_DIS_SHIFT;
> +
> + eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) &
> + GEN8_EU_DIS0_S0_MASK;
> + eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >>
> + GEN8_EU_DIS0_S1_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE1) &
> + GEN8_EU_DIS1_S1_MASK) <<
> + (32 - GEN8_EU_DIS0_S1_SHIFT));
> + eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >>
> + GEN8_EU_DIS1_S2_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE2) &
> + GEN8_EU_DIS2_S2_MASK) <<
> + (32 - GEN8_EU_DIS1_S2_SHIFT));
> +
GEN9_EU_DISABLE(slice) is already available, since the register
addresses are same maybe it can be reused after renaming it to GEN8
instead of creating new definitions? ofcourse shift/mask are different.
Indentation is off, in general please use () to force indentation.
first two statements can fit in single line.
regards
Arun
> +
> + info = (struct intel_device_info *)&dev_priv->info;
> + info->slice_total = hweight32(s_enable);
> +
> + /*
> + * The subslice disable field is global, i.e. it applies
> + * to each of the enabled slices.
> + */
> + info->subslice_per_slice = ss_max - hweight32(ss_disable);
> + info->subslice_total = info->slice_total *
> + info->subslice_per_slice;
> +
> + /*
> + * Iterate through enabled slices and subslices to
> + * count the total enabled EU.
> + */
> + for (s = 0; s < s_max; s++) {
> + if (!(s_enable & (0x1 << s)))
> + /* skip disabled slice */
> + continue;
> +
> + for (ss = 0; ss < ss_max; ss++) {
> + u32 n_disabled;
> +
> + if (ss_disable & (0x1 << ss))
> + /* skip disabled subslice */
> + continue;
> +
> + n_disabled = hweight8(eu_disable[s] >>
> + (ss * eu_max));
> +
> + /*
> + * Record which subslice(s) has(have) 7 EUs. we
> + * can tune the hash used to spread work among
> + * subslices if they are unbalanced.
> + */
> + if (eu_max - n_disabled == 7)
> + info->subslice_7eu[s] |= 1 << ss;
> +
> + info->eu_total += eu_max - n_disabled;
> + }
> + }
> +
> + /*
> + * BDW is expected to always have a uniform distribution of EU across
> + * subslices with the exception that any one EU in any one subslice may
> + * be fused off for die recovery.
> + */
> + info->eu_per_subslice = info->subslice_total ?
> + DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
> +
> + /*
> + * BDW supports slice power gating on devices with more than
> + * one slice.
> + */
> + info->has_slice_pg = (info->slice_total > 1);
> + info->has_subslice_pg = 0;
> + info->has_eu_pg = 0;
> +}
> +
> /*
> * Determine various intel_device_info fields at runtime.
> *
> @@ -775,6 +862,8 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
> /* Initialize slice/subslice/EU info */
> if (IS_CHERRYVIEW(dev))
> cherryview_sseu_info_init(dev);
> + else if (IS_BROADWELL(dev))
> + broadwell_sseu_info_init(dev);
> else if (INTEL_INFO(dev)->gen >= 9)
> gen9_sseu_info_init(dev);
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index be87e3b..37f658f 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1841,11 +1841,26 @@ enum skl_disp_power_wells {
> #define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
>
> #define GEN8_FUSE2 0x9120
> +#define GEN8_F2_SS_DIS_SHIFT 21
> +#define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT)
> #define GEN8_F2_S_ENA_SHIFT 25
> #define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT)
>
> -#define GEN9_F2_SS_DIS_SHIFT 20
> -#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
> +#define GEN8_EU_DISABLE0 0x9134
> +#define GEN8_EU_DIS0_S0_MASK 0xffffff
> +#define GEN8_EU_DIS0_S1_SHIFT 24
> +#define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT)
> +
> +#define GEN8_EU_DISABLE1 0x9138
> +#define GEN8_EU_DIS1_S1_MASK 0xffff
> +#define GEN8_EU_DIS1_S2_SHIFT 16
> +#define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT)
> +
> +#define GEN8_EU_DISABLE2 0x913c
> +#define GEN8_EU_DIS2_S2_MASK 0xff
> +
> +#define GEN9_F2_SS_DIS_SHIFT 20
> +#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
>
> #define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
>
> @@ -6822,6 +6837,9 @@ enum skl_disp_power_wells {
> #define GEN6_RC6 3
> #define GEN6_RC7 4
>
> +#define GEN8_GT_SLICE_INFO 0x138064
> +#define GEN8_LSLICESTAT_MASK 0x7
> +
> #define CHV_POWER_SS0_SIG1 0xa720
> #define CHV_POWER_SS1_SIG1 0xa728
> #define CHV_SS_PG_ENABLE (1<<1)
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-08-13 12:38 [PATCH] drm/i915/bdw: Check for slice, subslice and EU count for BDW Łukasz Daniluk
2015-08-13 21:34 ` Bish, Jim
2015-08-14 0:11 ` Jeff McGee
@ 2015-09-02 15:47 ` Łukasz Daniluk
2015-09-02 14:03 ` Chris Wilson
` (2 more replies)
2 siblings, 3 replies; 13+ messages in thread
From: Łukasz Daniluk @ 2015-09-02 15:47 UTC (permalink / raw)
To: intel-gfx
Added checks for available slices, subslices and EUs for Broadwell. This
information is filled in intel_device_info and is available to user with
GET_PARAM.
Added checks for enabled slices, subslices and EU for Broadwell. This
information is based on available counts but takes power gated slices
into account. It can be read in debugfs.
Introduce new register defines that contain information on slices on
Broadwell.
v2:
- Introduce GT_SLICE_INFO register
- Change Broadwell sseu_device_status function to use GT_SLICE_INFO
register instead of RPCS register
- Undo removal of dev_priv variables in Cherryview and Gen9
sseu_device_satus functions
Cc: Jeff Mcgee <jeff.mcgee@intel.com>
Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 29 +++++++++++-
drivers/gpu/drm/i915/i915_dma.c | 89 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/i915_reg.h | 22 ++++++++-
3 files changed, 137 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 23a69307..e8a62ef 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4932,13 +4932,38 @@ static void gen9_sseu_device_status(struct drm_device *dev,
}
}
+static void broadwell_sseu_device_status(struct drm_device *dev,
+ struct sseu_dev_status *stat)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int s;
+ u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
+
+ stat->slice_total =
+ hweight32(slice_info & GEN8_LSLICESTAT_MASK);
+
+ if (stat->slice_total)
+ {
+ stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
+ stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
+ stat->subslice_total = stat->slice_total * stat->subslice_per_slice;
+ stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
+
+ /* subtract fused off EU(s) from enabled slice(s) */
+ for (s = 0; s < stat->slice_total; s++) {
+ u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
+ stat->eu_total -= hweight8(subslice_7eu);
+ }
+ }
+}
+
static int i915_sseu_status(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct sseu_dev_status stat;
- if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
+ if (INTEL_INFO(dev)->gen < 8)
return -ENODEV;
seq_puts(m, "SSEU Device Info\n");
@@ -4963,6 +4988,8 @@ static int i915_sseu_status(struct seq_file *m, void *unused)
memset(&stat, 0, sizeof(stat));
if (IS_CHERRYVIEW(dev)) {
cherryview_sseu_device_status(dev, &stat);
+ } else if (IS_BROADWELL(dev)) {
+ broadwell_sseu_device_status(dev, &stat);
} else if (INTEL_INFO(dev)->gen >= 9) {
gen9_sseu_device_status(dev, &stat);
}
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index ab37d11..2d52b1e 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -705,6 +705,93 @@ static void gen9_sseu_info_init(struct drm_device *dev)
info->has_eu_pg = (info->eu_per_subslice > 2);
}
+static void broadwell_sseu_info_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_device_info *info;
+ const int s_max = 3, ss_max = 3, eu_max = 8;
+ int s, ss;
+ u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
+
+ fuse2 = I915_READ(GEN8_FUSE2);
+ s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
+ GEN8_F2_S_ENA_SHIFT;
+ ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >>
+ GEN8_F2_SS_DIS_SHIFT;
+
+ eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) &
+ GEN8_EU_DIS0_S0_MASK;
+ eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >>
+ GEN8_EU_DIS0_S1_SHIFT) |
+ ((I915_READ(GEN8_EU_DISABLE1) &
+ GEN8_EU_DIS1_S1_MASK) <<
+ (32 - GEN8_EU_DIS0_S1_SHIFT));
+ eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >>
+ GEN8_EU_DIS1_S2_SHIFT) |
+ ((I915_READ(GEN8_EU_DISABLE2) &
+ GEN8_EU_DIS2_S2_MASK) <<
+ (32 - GEN8_EU_DIS1_S2_SHIFT));
+
+
+ info = (struct intel_device_info *)&dev_priv->info;
+ info->slice_total = hweight32(s_enable);
+
+ /*
+ * The subslice disable field is global, i.e. it applies
+ * to each of the enabled slices.
+ */
+ info->subslice_per_slice = ss_max - hweight32(ss_disable);
+ info->subslice_total = info->slice_total *
+ info->subslice_per_slice;
+
+ /*
+ * Iterate through enabled slices and subslices to
+ * count the total enabled EU.
+ */
+ for (s = 0; s < s_max; s++) {
+ if (!(s_enable & (0x1 << s)))
+ /* skip disabled slice */
+ continue;
+
+ for (ss = 0; ss < ss_max; ss++) {
+ u32 n_disabled;
+
+ if (ss_disable & (0x1 << ss))
+ /* skip disabled subslice */
+ continue;
+
+ n_disabled = hweight8(eu_disable[s] >>
+ (ss * eu_max));
+
+ /*
+ * Record which subslice(s) has(have) 7 EUs. we
+ * can tune the hash used to spread work among
+ * subslices if they are unbalanced.
+ */
+ if (eu_max - n_disabled == 7)
+ info->subslice_7eu[s] |= 1 << ss;
+
+ info->eu_total += eu_max - n_disabled;
+ }
+ }
+
+ /*
+ * BDW is expected to always have a uniform distribution of EU across
+ * subslices with the exception that any one EU in any one subslice may
+ * be fused off for die recovery.
+ */
+ info->eu_per_subslice = info->subslice_total ?
+ DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
+
+ /*
+ * BDW supports slice power gating on devices with more than
+ * one slice.
+ */
+ info->has_slice_pg = (info->slice_total > 1);
+ info->has_subslice_pg = 0;
+ info->has_eu_pg = 0;
+}
+
/*
* Determine various intel_device_info fields at runtime.
*
@@ -775,6 +862,8 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
/* Initialize slice/subslice/EU info */
if (IS_CHERRYVIEW(dev))
cherryview_sseu_info_init(dev);
+ else if (IS_BROADWELL(dev))
+ broadwell_sseu_info_init(dev);
else if (INTEL_INFO(dev)->gen >= 9)
gen9_sseu_info_init(dev);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index be87e3b..37f658f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1841,11 +1841,26 @@ enum skl_disp_power_wells {
#define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
#define GEN8_FUSE2 0x9120
+#define GEN8_F2_SS_DIS_SHIFT 21
+#define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT)
#define GEN8_F2_S_ENA_SHIFT 25
#define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT)
-#define GEN9_F2_SS_DIS_SHIFT 20
-#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
+#define GEN8_EU_DISABLE0 0x9134
+#define GEN8_EU_DIS0_S0_MASK 0xffffff
+#define GEN8_EU_DIS0_S1_SHIFT 24
+#define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT)
+
+#define GEN8_EU_DISABLE1 0x9138
+#define GEN8_EU_DIS1_S1_MASK 0xffff
+#define GEN8_EU_DIS1_S2_SHIFT 16
+#define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT)
+
+#define GEN8_EU_DISABLE2 0x913c
+#define GEN8_EU_DIS2_S2_MASK 0xff
+
+#define GEN9_F2_SS_DIS_SHIFT 20
+#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
#define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
@@ -6822,6 +6837,9 @@ enum skl_disp_power_wells {
#define GEN6_RC6 3
#define GEN6_RC7 4
+#define GEN8_GT_SLICE_INFO 0x138064
+#define GEN8_LSLICESTAT_MASK 0x7
+
#define CHV_POWER_SS0_SIG1 0xa720
#define CHV_POWER_SS1_SIG1 0xa728
#define CHV_SS_PG_ENABLE (1<<1)
--
Lukasz Daniluk
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-09-02 14:03 ` Chris Wilson
@ 2015-09-08 11:29 ` Daniluk, Lukasz
0 siblings, 0 replies; 13+ messages in thread
From: Daniluk, Lukasz @ 2015-09-08 11:29 UTC (permalink / raw)
To: Chris Wilson; +Cc: intel-gfx@lists.freedesktop.org
> -----Original Message-----
> From: Chris Wilson [mailto:chris@chris-wilson.co.uk]
> Sent: Wednesday, September 2, 2015 16:03
> To: Daniluk, Lukasz
> Cc: intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH v2] drm/i915/bdw: Check for slice, subslice and
> EU count for BDW
>
> On Wed, Sep 02, 2015 at 05:47:58PM +0200, Łukasz Daniluk wrote:
> > +static void broadwell_sseu_device_status(struct drm_device *dev,
>
> Why pass in dev if you only use dev_priv (and commit the sin of repeatedly
> retrieving dev->dev_priv)?
I was following the style of other _sseu_device_status functions.
Also, I use INTEL_INFO that wants dev argument.
>
> > + struct sseu_dev_status *stat)
> > +{
> > + struct drm_i915_private *dev_priv = dev->dev_private;
> > + int s;
> > + u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
> > +
> > + stat->slice_total =
> > + hweight32(slice_info & GEN8_LSLICESTAT_MASK);
> > +
> > + if (stat->slice_total)
> > + {
> Missed.
Do you mean anything else than bracket here?
>
> > + stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
> > + stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
> > + stat->subslice_total = stat->slice_total * stat-
> >subslice_per_slice;
> > + stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
> > +
> > + /* subtract fused off EU(s) from enabled slice(s) */
> > + for (s = 0; s < stat->slice_total; s++) {
> > + u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
> > + stat->eu_total -= hweight8(subslice_7eu);
> > + }
>
> So why are we computing this twice? Is the debugfs to show the hw registers or
> the sw tracking? Where do I see what we actually report? If it is for the hw
> registers, report them. A perfect function here would report the actual register
> values (possibly decoding them) and show what the internal values are.
> -Chris
>
> --
> Chris Wilson, Intel Open Source Technology Centre
Nothing is computed twice here - all values that are unchanged are read using INTEL_INFO macro.
What is computed however is amount of active (not simply present on the system) subslices and EUs.
These values depend on number of active slices. The for loop checks if the one of the active slice is
the one with EU fused off for die recovery. When you read i915_sseu_status the first part (SSEU Device
Info) gives you information on general capabilities (things that can be read using INTEL_INFO(dev)),
the second part (SSEU Device Status) is giving you the contents of stat struct.
---
Łukasz Daniluk
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-09-02 15:08 ` Arun Siluvery
@ 2015-09-08 12:53 ` Daniluk, Lukasz
2015-09-08 15:15 ` Arun Siluvery
0 siblings, 1 reply; 13+ messages in thread
From: Daniluk, Lukasz @ 2015-09-08 12:53 UTC (permalink / raw)
To: Arun Siluvery, intel-gfx@lists.freedesktop.org
> -----Original Message-----
> From: Arun Siluvery [mailto:arun.siluvery@linux.intel.com]
> Sent: Wednesday, September 2, 2015 17:08
> To: Daniluk, Lukasz; intel-gfx@lists.freedesktop.org
> Subject: Re: [Intel-gfx] [PATCH v2] drm/i915/bdw: Check for slice, subslice and
> EU count for BDW
>
> On 02/09/2015 16:47, Łukasz Daniluk wrote:
> > Added checks for available slices, subslices and EUs for Broadwell.
> > This information is filled in intel_device_info and is available to
> > user with GET_PARAM.
> > Added checks for enabled slices, subslices and EU for Broadwell. This
> > information is based on available counts but takes power gated slices
> > into account. It can be read in debugfs.
> > Introduce new register defines that contain information on slices on
> > Broadwell.
> >
> > v2:
> > - Introduce GT_SLICE_INFO register
> > - Change Broadwell sseu_device_status function to use GT_SLICE_INFO
> > register instead of RPCS register
> > - Undo removal of dev_priv variables in Cherryview and Gen9
> > sseu_device_satus functions
> >
> > Cc: Jeff Mcgee <jeff.mcgee@intel.com>
> > Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
> > ---
> > drivers/gpu/drm/i915/i915_debugfs.c | 29 +++++++++++-
> > drivers/gpu/drm/i915/i915_dma.c | 89
> +++++++++++++++++++++++++++++++++++++
> > drivers/gpu/drm/i915/i915_reg.h | 22 ++++++++-
> > 3 files changed, 137 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
> > b/drivers/gpu/drm/i915/i915_debugfs.c
> > index 23a69307..e8a62ef 100644
> > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > @@ -4932,13 +4932,38 @@ static void gen9_sseu_device_status(struct
> drm_device *dev,
> > }
> > }
> >
> > +static void broadwell_sseu_device_status(struct drm_device *dev,
> > + struct sseu_dev_status *stat)
> > +{
> > + struct drm_i915_private *dev_priv = dev->dev_private;
> > + int s;
> > + u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
> I don't see this register (0x138064 as defined below) in bdw spec.
>
Yes, this register isn't listed in spec. I am unsure when the full spec for this register
will be published.
> > +
> > + stat->slice_total =
> > + hweight32(slice_info & GEN8_LSLICESTAT_MASK);
>
> why not in a single line, seems to fit under 80 chars.
>
I was using longer define name and didn't recheck if this line fits under 80. Thanks for catch.
> > +
> > + if (stat->slice_total)
> > + {
> > + stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
> > + stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
> > + stat->subslice_total = stat->slice_total * stat-
> >subslice_per_slice;
> > + stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
> > +
> Please reorder such that all subslice values are populated first followed by EUs
> to follow an order.
>
Okay. My idea was to order them based on where value comes from (is it computed here or
simply read with INTEL_INFO).
> > + /* subtract fused off EU(s) from enabled slice(s) */
> > + for (s = 0; s < stat->slice_total; s++) {
> > + u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
> > + stat->eu_total -= hweight8(subslice_7eu);
> > + }
> > + }
> > +}
> > +
> > static int i915_sseu_status(struct seq_file *m, void *unused)
> > {
> > struct drm_info_node *node = (struct drm_info_node *) m->private;
> > struct drm_device *dev = node->minor->dev;
> > struct sseu_dev_status stat;
> >
> > - if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
> > + if (INTEL_INFO(dev)->gen < 8)
> > return -ENODEV;
> >
> > seq_puts(m, "SSEU Device Info\n");
> > @@ -4963,6 +4988,8 @@ static int i915_sseu_status(struct seq_file *m, void
> *unused)
> > memset(&stat, 0, sizeof(stat));
> > if (IS_CHERRYVIEW(dev)) {
> > cherryview_sseu_device_status(dev, &stat);
> > + } else if (IS_BROADWELL(dev)) {
> > + broadwell_sseu_device_status(dev, &stat);
> > } else if (INTEL_INFO(dev)->gen >= 9) {
> > gen9_sseu_device_status(dev, &stat);
> > }
> > diff --git a/drivers/gpu/drm/i915/i915_dma.c
> > b/drivers/gpu/drm/i915/i915_dma.c index ab37d11..2d52b1e 100644
> > --- a/drivers/gpu/drm/i915/i915_dma.c
> > +++ b/drivers/gpu/drm/i915/i915_dma.c
> > @@ -705,6 +705,93 @@ static void gen9_sseu_info_init(struct drm_device
> *dev)
> > info->has_eu_pg = (info->eu_per_subslice > 2);
> > }
> >
> > +static void broadwell_sseu_info_init(struct drm_device *dev) {
> > + struct drm_i915_private *dev_priv = dev->dev_private;
> > + struct intel_device_info *info;
> > + const int s_max = 3, ss_max = 3, eu_max = 8;
> I only see max of 2 slices for bdw in spec.
>
Register values assume that there can be 3 slices (slice 0,1 and 2) and that’s why
I used 3 here as max slices count.
> > + int s, ss;
> > + u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
> > +
> > + fuse2 = I915_READ(GEN8_FUSE2);
> > + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
> > + GEN8_F2_S_ENA_SHIFT;
> > + ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >>
> > + GEN8_F2_SS_DIS_SHIFT;
> > +
> > + eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) &
> > + GEN8_EU_DIS0_S0_MASK;
> > + eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >>
> > + GEN8_EU_DIS0_S1_SHIFT) |
> > + ((I915_READ(GEN8_EU_DISABLE1) &
> > + GEN8_EU_DIS1_S1_MASK) <<
> > + (32 - GEN8_EU_DIS0_S1_SHIFT));
> > + eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >>
> > + GEN8_EU_DIS1_S2_SHIFT) |
> > + ((I915_READ(GEN8_EU_DISABLE2) &
> > + GEN8_EU_DIS2_S2_MASK) <<
> > + (32 - GEN8_EU_DIS1_S2_SHIFT));
> > +
>
> GEN9_EU_DISABLE(slice) is already available, since the register addresses are
> same maybe it can be reused after renaming it to GEN8 instead of creating new
> definitions? ofcourse shift/mask are different.
I wouldn't use renaming of register from other generation. Since contents of this register
are read in different way I treated these as different registers and that’s why I choose
to create new define without any references to GEN9 register. However, if the renaming
(or even using existing define) is preferred approach I will modify the patch.
>
> Indentation is off, in general please use () to force indentation.
> first two statements can fit in single line.
>
> regards
> Arun
>
Thank you for questions and style suggestions. I will reformat the lines before submitting
updated patch.
---
Łukasz Daniluk
> > +
> > + info = (struct intel_device_info *)&dev_priv->info;
> > + info->slice_total = hweight32(s_enable);
> > +
> > + /*
> > + * The subslice disable field is global, i.e. it applies
> > + * to each of the enabled slices.
> > + */
> > + info->subslice_per_slice = ss_max - hweight32(ss_disable);
> > + info->subslice_total = info->slice_total *
> > + info->subslice_per_slice;
> > +
> > + /*
> > + * Iterate through enabled slices and subslices to
> > + * count the total enabled EU.
> > + */
> > + for (s = 0; s < s_max; s++) {
> > + if (!(s_enable & (0x1 << s)))
> > + /* skip disabled slice */
> > + continue;
> > +
> > + for (ss = 0; ss < ss_max; ss++) {
> > + u32 n_disabled;
> > +
> > + if (ss_disable & (0x1 << ss))
> > + /* skip disabled subslice */
> > + continue;
> > +
> > + n_disabled = hweight8(eu_disable[s] >>
> > + (ss * eu_max));
> > +
> > + /*
> > + * Record which subslice(s) has(have) 7 EUs. we
> > + * can tune the hash used to spread work among
> > + * subslices if they are unbalanced.
> > + */
> > + if (eu_max - n_disabled == 7)
> > + info->subslice_7eu[s] |= 1 << ss;
> > +
> > + info->eu_total += eu_max - n_disabled;
> > + }
> > + }
> > +
> > + /*
> > + * BDW is expected to always have a uniform distribution of EU across
> > + * subslices with the exception that any one EU in any one subslice may
> > + * be fused off for die recovery.
> > + */
> > + info->eu_per_subslice = info->subslice_total ?
> > + DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
> > +
> > + /*
> > + * BDW supports slice power gating on devices with more than
> > + * one slice.
> > + */
> > + info->has_slice_pg = (info->slice_total > 1);
> > + info->has_subslice_pg = 0;
> > + info->has_eu_pg = 0;
> > +}
> > +
> > /*
> > * Determine various intel_device_info fields at runtime.
> > *
> > @@ -775,6 +862,8 @@ static void intel_device_info_runtime_init(struct
> drm_device *dev)
> > /* Initialize slice/subslice/EU info */
> > if (IS_CHERRYVIEW(dev))
> > cherryview_sseu_info_init(dev);
> > + else if (IS_BROADWELL(dev))
> > + broadwell_sseu_info_init(dev);
> > else if (INTEL_INFO(dev)->gen >= 9)
> > gen9_sseu_info_init(dev);
> >
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > b/drivers/gpu/drm/i915/i915_reg.h index be87e3b..37f658f 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -1841,11 +1841,26 @@ enum skl_disp_power_wells {
> > #define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf <<
> CHV_FGT_EU_DIS_SS1_R1_SHIFT)
> >
> > #define GEN8_FUSE2 0x9120
> > +#define GEN8_F2_SS_DIS_SHIFT 21
> > +#define GEN8_F2_SS_DIS_MASK (0x7 <<
> GEN8_F2_SS_DIS_SHIFT)
> > #define GEN8_F2_S_ENA_SHIFT 25
> > #define GEN8_F2_S_ENA_MASK (0x7 <<
> GEN8_F2_S_ENA_SHIFT)
> >
> > -#define GEN9_F2_SS_DIS_SHIFT 20
> > -#define GEN9_F2_SS_DIS_MASK (0xf <<
> GEN9_F2_SS_DIS_SHIFT)
> > +#define GEN8_EU_DISABLE0 0x9134
> > +#define GEN8_EU_DIS0_S0_MASK 0xffffff
> > +#define GEN8_EU_DIS0_S1_SHIFT 24
> > +#define GEN8_EU_DIS0_S1_MASK (0xff <<
> GEN8_EU_DIS0_S1_SHIFT)
> > +
> > +#define GEN8_EU_DISABLE1 0x9138
> > +#define GEN8_EU_DIS1_S1_MASK 0xffff
> > +#define GEN8_EU_DIS1_S2_SHIFT 16
> > +#define GEN8_EU_DIS1_S2_MASK (0xffff <<
> GEN8_EU_DIS1_S2_SHIFT)
> > +
> > +#define GEN8_EU_DISABLE2 0x913c
> > +#define GEN8_EU_DIS2_S2_MASK 0xff
> > +
> > +#define GEN9_F2_SS_DIS_SHIFT 20
> > +#define GEN9_F2_SS_DIS_MASK (0xf <<
> GEN9_F2_SS_DIS_SHIFT)
> >
> > #define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
> >
> > @@ -6822,6 +6837,9 @@ enum skl_disp_power_wells {
> > #define GEN6_RC6 3
> > #define GEN6_RC7 4
> >
> > +#define GEN8_GT_SLICE_INFO 0x138064
> > +#define GEN8_LSLICESTAT_MASK 0x7
> > +
> > #define CHV_POWER_SS0_SIG1 0xa720
> > #define CHV_POWER_SS1_SIG1 0xa728
> > #define CHV_SS_PG_ENABLE (1<<1)
> >
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-09-08 12:53 ` Daniluk, Lukasz
@ 2015-09-08 15:15 ` Arun Siluvery
0 siblings, 0 replies; 13+ messages in thread
From: Arun Siluvery @ 2015-09-08 15:15 UTC (permalink / raw)
To: Daniluk, Lukasz, intel-gfx@lists.freedesktop.org
On 08/09/2015 13:53, Daniluk, Lukasz wrote:
>> -----Original Message-----
>> From: Arun Siluvery [mailto:arun.siluvery@linux.intel.com]
>> Sent: Wednesday, September 2, 2015 17:08
>> To: Daniluk, Lukasz; intel-gfx@lists.freedesktop.org
>> Subject: Re: [Intel-gfx] [PATCH v2] drm/i915/bdw: Check for slice, subslice and
>> EU count for BDW
>>
>> On 02/09/2015 16:47, Łukasz Daniluk wrote:
>>> Added checks for available slices, subslices and EUs for Broadwell.
>>> This information is filled in intel_device_info and is available to
>>> user with GET_PARAM.
>>> Added checks for enabled slices, subslices and EU for Broadwell. This
>>> information is based on available counts but takes power gated slices
>>> into account. It can be read in debugfs.
>>> Introduce new register defines that contain information on slices on
>>> Broadwell.
>>>
>>> v2:
>>> - Introduce GT_SLICE_INFO register
>>> - Change Broadwell sseu_device_status function to use GT_SLICE_INFO
>>> register instead of RPCS register
>>> - Undo removal of dev_priv variables in Cherryview and Gen9
>>> sseu_device_satus functions
>>>
>>> Cc: Jeff Mcgee <jeff.mcgee@intel.com>
>>> Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
>>> ---
>>> drivers/gpu/drm/i915/i915_debugfs.c | 29 +++++++++++-
>>> drivers/gpu/drm/i915/i915_dma.c | 89
>> +++++++++++++++++++++++++++++++++++++
>>> drivers/gpu/drm/i915/i915_reg.h | 22 ++++++++-
>>> 3 files changed, 137 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c
>>> b/drivers/gpu/drm/i915/i915_debugfs.c
>>> index 23a69307..e8a62ef 100644
>>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>>> @@ -4932,13 +4932,38 @@ static void gen9_sseu_device_status(struct
>> drm_device *dev,
>>> }
>>> }
>>>
>>> +static void broadwell_sseu_device_status(struct drm_device *dev,
>>> + struct sseu_dev_status *stat)
>>> +{
>>> + struct drm_i915_private *dev_priv = dev->dev_private;
>>> + int s;
>>> + u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
>> I don't see this register (0x138064 as defined below) in bdw spec.
>>
>
> Yes, this register isn't listed in spec. I am unsure when the full spec for this register
> will be published.
>
>>> +
>>> + stat->slice_total =
>>> + hweight32(slice_info & GEN8_LSLICESTAT_MASK);
>>
>> why not in a single line, seems to fit under 80 chars.
>>
>
> I was using longer define name and didn't recheck if this line fits under 80. Thanks for catch.
>
>>> +
>>> + if (stat->slice_total)
>>> + {
>>> + stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
>>> + stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
>>> + stat->subslice_total = stat->slice_total * stat-
>>> subslice_per_slice;
>>> + stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
>>> +
>> Please reorder such that all subslice values are populated first followed by EUs
>> to follow an order.
>>
>
> Okay. My idea was to order them based on where value comes from (is it computed here or
> simply read with INTEL_INFO).
>
>>> + /* subtract fused off EU(s) from enabled slice(s) */
>>> + for (s = 0; s < stat->slice_total; s++) {
>>> + u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
>>> + stat->eu_total -= hweight8(subslice_7eu);
>>> + }
>>> + }
>>> +}
>>> +
>>> static int i915_sseu_status(struct seq_file *m, void *unused)
>>> {
>>> struct drm_info_node *node = (struct drm_info_node *) m->private;
>>> struct drm_device *dev = node->minor->dev;
>>> struct sseu_dev_status stat;
>>>
>>> - if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
>>> + if (INTEL_INFO(dev)->gen < 8)
>>> return -ENODEV;
>>>
>>> seq_puts(m, "SSEU Device Info\n");
>>> @@ -4963,6 +4988,8 @@ static int i915_sseu_status(struct seq_file *m, void
>> *unused)
>>> memset(&stat, 0, sizeof(stat));
>>> if (IS_CHERRYVIEW(dev)) {
>>> cherryview_sseu_device_status(dev, &stat);
>>> + } else if (IS_BROADWELL(dev)) {
>>> + broadwell_sseu_device_status(dev, &stat);
>>> } else if (INTEL_INFO(dev)->gen >= 9) {
>>> gen9_sseu_device_status(dev, &stat);
>>> }
>>> diff --git a/drivers/gpu/drm/i915/i915_dma.c
>>> b/drivers/gpu/drm/i915/i915_dma.c index ab37d11..2d52b1e 100644
>>> --- a/drivers/gpu/drm/i915/i915_dma.c
>>> +++ b/drivers/gpu/drm/i915/i915_dma.c
>>> @@ -705,6 +705,93 @@ static void gen9_sseu_info_init(struct drm_device
>> *dev)
>>> info->has_eu_pg = (info->eu_per_subslice > 2);
>>> }
>>>
>>> +static void broadwell_sseu_info_init(struct drm_device *dev) {
>>> + struct drm_i915_private *dev_priv = dev->dev_private;
>>> + struct intel_device_info *info;
>>> + const int s_max = 3, ss_max = 3, eu_max = 8;
>> I only see max of 2 slices for bdw in spec.
>>
>
> Register values assume that there can be 3 slices (slice 0,1 and 2) and that’s why
> I used 3 here as max slices count.
>
>>> + int s, ss;
>>> + u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
>>> +
>>> + fuse2 = I915_READ(GEN8_FUSE2);
>>> + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >>
>>> + GEN8_F2_S_ENA_SHIFT;
>>> + ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >>
>>> + GEN8_F2_SS_DIS_SHIFT;
>>> +
>>> + eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) &
>>> + GEN8_EU_DIS0_S0_MASK;
>>> + eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >>
>>> + GEN8_EU_DIS0_S1_SHIFT) |
>>> + ((I915_READ(GEN8_EU_DISABLE1) &
>>> + GEN8_EU_DIS1_S1_MASK) <<
>>> + (32 - GEN8_EU_DIS0_S1_SHIFT));
>>> + eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >>
>>> + GEN8_EU_DIS1_S2_SHIFT) |
>>> + ((I915_READ(GEN8_EU_DISABLE2) &
>>> + GEN8_EU_DIS2_S2_MASK) <<
>>> + (32 - GEN8_EU_DIS1_S2_SHIFT));
>>> +
>>
>> GEN9_EU_DISABLE(slice) is already available, since the register addresses are
>> same maybe it can be reused after renaming it to GEN8 instead of creating new
>> definitions? ofcourse shift/mask are different.
>
> I wouldn't use renaming of register from other generation. Since contents of this register
> are read in different way I treated these as different registers and that’s why I choose
> to create new define without any references to GEN9 register. However, if the renaming
> (or even using existing define) is preferred approach I will modify the patch.
Normally we create a new define for newer Gen if the existing one cannot
be reused, in this case it is the opposite, I am not sure what is best
way to handle this, better to check with Daniel.
regards
Arun
>
>>
>> Indentation is off, in general please use () to force indentation.
>> first two statements can fit in single line.
>>
>> regards
>> Arun
>>
>
> Thank you for questions and style suggestions. I will reformat the lines before submitting
> updated patch.
>
> ---
> Łukasz Daniluk
>
>>> +
>>> + info = (struct intel_device_info *)&dev_priv->info;
>>> + info->slice_total = hweight32(s_enable);
>>> +
>>> + /*
>>> + * The subslice disable field is global, i.e. it applies
>>> + * to each of the enabled slices.
>>> + */
>>> + info->subslice_per_slice = ss_max - hweight32(ss_disable);
>>> + info->subslice_total = info->slice_total *
>>> + info->subslice_per_slice;
>>> +
>>> + /*
>>> + * Iterate through enabled slices and subslices to
>>> + * count the total enabled EU.
>>> + */
>>> + for (s = 0; s < s_max; s++) {
>>> + if (!(s_enable & (0x1 << s)))
>>> + /* skip disabled slice */
>>> + continue;
>>> +
>>> + for (ss = 0; ss < ss_max; ss++) {
>>> + u32 n_disabled;
>>> +
>>> + if (ss_disable & (0x1 << ss))
>>> + /* skip disabled subslice */
>>> + continue;
>>> +
>>> + n_disabled = hweight8(eu_disable[s] >>
>>> + (ss * eu_max));
>>> +
>>> + /*
>>> + * Record which subslice(s) has(have) 7 EUs. we
>>> + * can tune the hash used to spread work among
>>> + * subslices if they are unbalanced.
>>> + */
>>> + if (eu_max - n_disabled == 7)
>>> + info->subslice_7eu[s] |= 1 << ss;
>>> +
>>> + info->eu_total += eu_max - n_disabled;
>>> + }
>>> + }
>>> +
>>> + /*
>>> + * BDW is expected to always have a uniform distribution of EU across
>>> + * subslices with the exception that any one EU in any one subslice may
>>> + * be fused off for die recovery.
>>> + */
>>> + info->eu_per_subslice = info->subslice_total ?
>>> + DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
>>> +
>>> + /*
>>> + * BDW supports slice power gating on devices with more than
>>> + * one slice.
>>> + */
>>> + info->has_slice_pg = (info->slice_total > 1);
>>> + info->has_subslice_pg = 0;
>>> + info->has_eu_pg = 0;
>>> +}
>>> +
>>> /*
>>> * Determine various intel_device_info fields at runtime.
>>> *
>>> @@ -775,6 +862,8 @@ static void intel_device_info_runtime_init(struct
>> drm_device *dev)
>>> /* Initialize slice/subslice/EU info */
>>> if (IS_CHERRYVIEW(dev))
>>> cherryview_sseu_info_init(dev);
>>> + else if (IS_BROADWELL(dev))
>>> + broadwell_sseu_info_init(dev);
>>> else if (INTEL_INFO(dev)->gen >= 9)
>>> gen9_sseu_info_init(dev);
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_reg.h
>>> b/drivers/gpu/drm/i915/i915_reg.h index be87e3b..37f658f 100644
>>> --- a/drivers/gpu/drm/i915/i915_reg.h
>>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>>> @@ -1841,11 +1841,26 @@ enum skl_disp_power_wells {
>>> #define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf <<
>> CHV_FGT_EU_DIS_SS1_R1_SHIFT)
>>>
>>> #define GEN8_FUSE2 0x9120
>>> +#define GEN8_F2_SS_DIS_SHIFT 21
>>> +#define GEN8_F2_SS_DIS_MASK (0x7 <<
>> GEN8_F2_SS_DIS_SHIFT)
>>> #define GEN8_F2_S_ENA_SHIFT 25
>>> #define GEN8_F2_S_ENA_MASK (0x7 <<
>> GEN8_F2_S_ENA_SHIFT)
>>>
>>> -#define GEN9_F2_SS_DIS_SHIFT 20
>>> -#define GEN9_F2_SS_DIS_MASK (0xf <<
>> GEN9_F2_SS_DIS_SHIFT)
>>> +#define GEN8_EU_DISABLE0 0x9134
>>> +#define GEN8_EU_DIS0_S0_MASK 0xffffff
>>> +#define GEN8_EU_DIS0_S1_SHIFT 24
>>> +#define GEN8_EU_DIS0_S1_MASK (0xff <<
>> GEN8_EU_DIS0_S1_SHIFT)
>>> +
>>> +#define GEN8_EU_DISABLE1 0x9138
>>> +#define GEN8_EU_DIS1_S1_MASK 0xffff
>>> +#define GEN8_EU_DIS1_S2_SHIFT 16
>>> +#define GEN8_EU_DIS1_S2_MASK (0xffff <<
>> GEN8_EU_DIS1_S2_SHIFT)
>>> +
>>> +#define GEN8_EU_DISABLE2 0x913c
>>> +#define GEN8_EU_DIS2_S2_MASK 0xff
>>> +
>>> +#define GEN9_F2_SS_DIS_SHIFT 20
>>> +#define GEN9_F2_SS_DIS_MASK (0xf <<
>> GEN9_F2_SS_DIS_SHIFT)
>>>
>>> #define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
>>>
>>> @@ -6822,6 +6837,9 @@ enum skl_disp_power_wells {
>>> #define GEN6_RC6 3
>>> #define GEN6_RC7 4
>>>
>>> +#define GEN8_GT_SLICE_INFO 0x138064
>>> +#define GEN8_LSLICESTAT_MASK 0x7
>>> +
>>> #define CHV_POWER_SS0_SIG1 0xa720
>>> #define CHV_POWER_SS1_SIG1 0xa728
>>> #define CHV_SS_PG_ENABLE (1<<1)
>>>
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-09-02 15:47 ` [PATCH v2] " Łukasz Daniluk
2015-09-02 14:03 ` Chris Wilson
2015-09-02 15:08 ` Arun Siluvery
@ 2015-09-17 11:51 ` Łukasz Daniluk
2015-09-17 14:40 ` Jeff McGee
2015-09-25 9:54 ` [PATCH v4] " Łukasz Daniluk
2 siblings, 2 replies; 13+ messages in thread
From: Łukasz Daniluk @ 2015-09-17 11:51 UTC (permalink / raw)
To: intel-gfx
Added checks for available slices, subslices and EUs for Broadwell. This
information is filled in intel_device_info and is available to user with
GET_PARAM.
Added checks for enabled slices, subslices and EU for Broadwell. This
information is based on available counts but takes power gated slices
into account. It can be read in debugfs.
Introduce new register defines that contain information on slices on
Broadwell.
v2:
- Introduce GT_SLICE_INFO register
- Change Broadwell sseu_device_status function to use GT_SLICE_INFO
register instead of RPCS register
- Undo removal of dev_priv variables in Cherryview and Gen9
sseu_device_satus functions
v3:
- Fix style issues
Cc: Jeff Mcgee <jeff.mcgee@intel.com>
Cc: Arun Siluvery <arun.siluvery@linux.intel.com>
Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 29 +++++++++++++-
drivers/gpu/drm/i915/i915_dma.c | 80 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/i915_reg.h | 22 +++++++++-
3 files changed, 128 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 72ae347..d0f784d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -5037,13 +5037,38 @@ static void gen9_sseu_device_status(struct drm_device *dev,
}
}
+static void broadwell_sseu_device_status(struct drm_device *dev,
+ struct sseu_dev_status *stat)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int s;
+ u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
+
+ stat->slice_total = hweight32(slice_info & GEN8_LSLICESTAT_MASK);
+
+ if (stat->slice_total) {
+ stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
+ stat->subslice_total = stat->slice_total *
+ stat->subslice_per_slice;
+ stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
+ stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
+
+ /* subtract fused off EU(s) from enabled slice(s) */
+ for (s = 0; s < stat->slice_total; s++) {
+ u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
+
+ stat->eu_total -= hweight8(subslice_7eu);
+ }
+ }
+}
+
static int i915_sseu_status(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct sseu_dev_status stat;
- if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
+ if (INTEL_INFO(dev)->gen < 8)
return -ENODEV;
seq_puts(m, "SSEU Device Info\n");
@@ -5068,6 +5093,8 @@ static int i915_sseu_status(struct seq_file *m, void *unused)
memset(&stat, 0, sizeof(stat));
if (IS_CHERRYVIEW(dev)) {
cherryview_sseu_device_status(dev, &stat);
+ } else if (IS_BROADWELL(dev)) {
+ broadwell_sseu_device_status(dev, &stat);
} else if (INTEL_INFO(dev)->gen >= 9) {
gen9_sseu_device_status(dev, &stat);
}
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 066a0ef..6ec3ed6 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -713,6 +713,84 @@ static void gen9_sseu_info_init(struct drm_device *dev)
info->has_eu_pg = (info->eu_per_subslice > 2);
}
+static void broadwell_sseu_info_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_device_info *info;
+ const int s_max = 3, ss_max = 3, eu_max = 8;
+ int s, ss;
+ u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
+
+ fuse2 = I915_READ(GEN8_FUSE2);
+ s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
+ ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT;
+
+ eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK;
+ eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) |
+ ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) <<
+ (32 - GEN8_EU_DIS0_S1_SHIFT));
+ eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) |
+ ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) <<
+ (32 - GEN8_EU_DIS1_S2_SHIFT));
+
+
+ info = (struct intel_device_info *)&dev_priv->info;
+ info->slice_total = hweight32(s_enable);
+
+ /*
+ * The subslice disable field is global, i.e. it applies
+ * to each of the enabled slices.
+ */
+ info->subslice_per_slice = ss_max - hweight32(ss_disable);
+ info->subslice_total = info->slice_total * info->subslice_per_slice;
+
+ /*
+ * Iterate through enabled slices and subslices to
+ * count the total enabled EU.
+ */
+ for (s = 0; s < s_max; s++) {
+ if (!(s_enable & (0x1 << s)))
+ /* skip disabled slice */
+ continue;
+
+ for (ss = 0; ss < ss_max; ss++) {
+ u32 n_disabled;
+
+ if (ss_disable & (0x1 << ss))
+ /* skip disabled subslice */
+ continue;
+
+ n_disabled = hweight8(eu_disable[s] >> (ss * eu_max));
+
+ /*
+ * Record which subslice(s) has(have) 7 EUs. we
+ * can tune the hash used to spread work among
+ * subslices if they are unbalanced.
+ */
+ if (eu_max - n_disabled == 7)
+ info->subslice_7eu[s] |= 1 << ss;
+
+ info->eu_total += eu_max - n_disabled;
+ }
+ }
+
+ /*
+ * BDW is expected to always have a uniform distribution of EU across
+ * subslices with the exception that any one EU in any one subslice may
+ * be fused off for die recovery.
+ */
+ info->eu_per_subslice = info->subslice_total ?
+ DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
+
+ /*
+ * BDW supports slice power gating on devices with more than
+ * one slice.
+ */
+ info->has_slice_pg = (info->slice_total > 1);
+ info->has_subslice_pg = 0;
+ info->has_eu_pg = 0;
+}
+
/*
* Determine various intel_device_info fields at runtime.
*
@@ -783,6 +861,8 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
/* Initialize slice/subslice/EU info */
if (IS_CHERRYVIEW(dev))
cherryview_sseu_info_init(dev);
+ else if (IS_BROADWELL(dev))
+ broadwell_sseu_info_init(dev);
else if (INTEL_INFO(dev)->gen >= 9)
gen9_sseu_info_init(dev);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 67bf205..da84488 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1876,11 +1876,26 @@ enum skl_disp_power_wells {
#define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
#define GEN8_FUSE2 0x9120
+#define GEN8_F2_SS_DIS_SHIFT 21
+#define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT)
#define GEN8_F2_S_ENA_SHIFT 25
#define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT)
-#define GEN9_F2_SS_DIS_SHIFT 20
-#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
+#define GEN8_EU_DISABLE0 0x9134
+#define GEN8_EU_DIS0_S0_MASK 0xffffff
+#define GEN8_EU_DIS0_S1_SHIFT 24
+#define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT)
+
+#define GEN8_EU_DISABLE1 0x9138
+#define GEN8_EU_DIS1_S1_MASK 0xffff
+#define GEN8_EU_DIS1_S2_SHIFT 16
+#define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT)
+
+#define GEN8_EU_DISABLE2 0x913c
+#define GEN8_EU_DIS2_S2_MASK 0xff
+
+#define GEN9_F2_SS_DIS_SHIFT 20
+#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
#define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
@@ -6867,6 +6882,9 @@ enum skl_disp_power_wells {
#define GEN6_RC6 3
#define GEN6_RC7 4
+#define GEN8_GT_SLICE_INFO 0x138064
+#define GEN8_LSLICESTAT_MASK 0x7
+
#define CHV_POWER_SS0_SIG1 0xa720
#define CHV_POWER_SS1_SIG1 0xa728
#define CHV_SS_PG_ENABLE (1<<1)
--
Lukasz Daniluk
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v3] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-09-17 11:51 ` [PATCH v3] " Łukasz Daniluk
@ 2015-09-17 14:40 ` Jeff McGee
2015-09-25 9:54 ` [PATCH v4] " Łukasz Daniluk
1 sibling, 0 replies; 13+ messages in thread
From: Jeff McGee @ 2015-09-17 14:40 UTC (permalink / raw)
To: Łukasz Daniluk; +Cc: intel-gfx
On Thu, Sep 17, 2015 at 01:51:58PM +0200, Łukasz Daniluk wrote:
> Added checks for available slices, subslices and EUs for Broadwell. This
> information is filled in intel_device_info and is available to user with
> GET_PARAM.
> Added checks for enabled slices, subslices and EU for Broadwell. This
> information is based on available counts but takes power gated slices
> into account. It can be read in debugfs.
> Introduce new register defines that contain information on slices on
> Broadwell.
>
> v2:
> - Introduce GT_SLICE_INFO register
> - Change Broadwell sseu_device_status function to use GT_SLICE_INFO
> register instead of RPCS register
> - Undo removal of dev_priv variables in Cherryview and Gen9
> sseu_device_satus functions
>
> v3:
> - Fix style issues
>
> Cc: Jeff Mcgee <jeff.mcgee@intel.com>
> Cc: Arun Siluvery <arun.siluvery@linux.intel.com>
> Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 29 +++++++++++++-
> drivers/gpu/drm/i915/i915_dma.c | 80 +++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_reg.h | 22 +++++++++-
> 3 files changed, 128 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 72ae347..d0f784d 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -5037,13 +5037,38 @@ static void gen9_sseu_device_status(struct drm_device *dev,
> }
> }
>
> +static void broadwell_sseu_device_status(struct drm_device *dev,
> + struct sseu_dev_status *stat)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + int s;
> + u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
> +
> + stat->slice_total = hweight32(slice_info & GEN8_LSLICESTAT_MASK);
> +
> + if (stat->slice_total) {
> + stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
> + stat->subslice_total = stat->slice_total *
> + stat->subslice_per_slice;
> + stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
> + stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
> +
> + /* subtract fused off EU(s) from enabled slice(s) */
> + for (s = 0; s < stat->slice_total; s++) {
> + u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
> +
> + stat->eu_total -= hweight8(subslice_7eu);
> + }
> + }
> +}
> +
> static int i915_sseu_status(struct seq_file *m, void *unused)
> {
> struct drm_info_node *node = (struct drm_info_node *) m->private;
> struct drm_device *dev = node->minor->dev;
> struct sseu_dev_status stat;
>
> - if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
> + if (INTEL_INFO(dev)->gen < 8)
> return -ENODEV;
>
> seq_puts(m, "SSEU Device Info\n");
> @@ -5068,6 +5093,8 @@ static int i915_sseu_status(struct seq_file *m, void *unused)
> memset(&stat, 0, sizeof(stat));
> if (IS_CHERRYVIEW(dev)) {
> cherryview_sseu_device_status(dev, &stat);
> + } else if (IS_BROADWELL(dev)) {
> + broadwell_sseu_device_status(dev, &stat);
> } else if (INTEL_INFO(dev)->gen >= 9) {
> gen9_sseu_device_status(dev, &stat);
> }
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index 066a0ef..6ec3ed6 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -713,6 +713,84 @@ static void gen9_sseu_info_init(struct drm_device *dev)
> info->has_eu_pg = (info->eu_per_subslice > 2);
> }
>
> +static void broadwell_sseu_info_init(struct drm_device *dev)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_device_info *info;
> + const int s_max = 3, ss_max = 3, eu_max = 8;
> + int s, ss;
> + u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
> +
> + fuse2 = I915_READ(GEN8_FUSE2);
> + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
> + ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT;
> +
> + eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK;
> + eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) <<
> + (32 - GEN8_EU_DIS0_S1_SHIFT));
> + eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) <<
> + (32 - GEN8_EU_DIS1_S2_SHIFT));
> +
> +
> + info = (struct intel_device_info *)&dev_priv->info;
> + info->slice_total = hweight32(s_enable);
> +
> + /*
> + * The subslice disable field is global, i.e. it applies
> + * to each of the enabled slices.
> + */
> + info->subslice_per_slice = ss_max - hweight32(ss_disable);
> + info->subslice_total = info->slice_total * info->subslice_per_slice;
> +
> + /*
> + * Iterate through enabled slices and subslices to
> + * count the total enabled EU.
> + */
> + for (s = 0; s < s_max; s++) {
> + if (!(s_enable & (0x1 << s)))
> + /* skip disabled slice */
> + continue;
> +
> + for (ss = 0; ss < ss_max; ss++) {
> + u32 n_disabled;
> +
> + if (ss_disable & (0x1 << ss))
> + /* skip disabled subslice */
> + continue;
> +
> + n_disabled = hweight8(eu_disable[s] >> (ss * eu_max));
> +
> + /*
> + * Record which subslice(s) has(have) 7 EUs. we
> + * can tune the hash used to spread work among
> + * subslices if they are unbalanced.
> + */
Should probably remove the part of the above comment which refers to hash
tuning since this doesn't seem to apply for BDW, only SKL.
> + if (eu_max - n_disabled == 7)
> + info->subslice_7eu[s] |= 1 << ss;
> +
> + info->eu_total += eu_max - n_disabled;
> + }
> + }
> +
> + /*
> + * BDW is expected to always have a uniform distribution of EU across
> + * subslices with the exception that any one EU in any one subslice may
> + * be fused off for die recovery.
> + */
> + info->eu_per_subslice = info->subslice_total ?
> + DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
> +
> + /*
> + * BDW supports slice power gating on devices with more than
> + * one slice.
> + */
> + info->has_slice_pg = (info->slice_total > 1);
> + info->has_subslice_pg = 0;
> + info->has_eu_pg = 0;
> +}
> +
> /*
> * Determine various intel_device_info fields at runtime.
> *
> @@ -783,6 +861,8 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
> /* Initialize slice/subslice/EU info */
> if (IS_CHERRYVIEW(dev))
> cherryview_sseu_info_init(dev);
> + else if (IS_BROADWELL(dev))
> + broadwell_sseu_info_init(dev);
> else if (INTEL_INFO(dev)->gen >= 9)
> gen9_sseu_info_init(dev);
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 67bf205..da84488 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1876,11 +1876,26 @@ enum skl_disp_power_wells {
> #define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
>
> #define GEN8_FUSE2 0x9120
> +#define GEN8_F2_SS_DIS_SHIFT 21
> +#define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT)
> #define GEN8_F2_S_ENA_SHIFT 25
> #define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT)
>
> -#define GEN9_F2_SS_DIS_SHIFT 20
> -#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
I think it is helpful to keep the above two macros here rather than move
them down below the GEN8_EU_DISABLEX definitions. Having them here makes it
more clear that they are Gen9-specific field definitions for the GEN8_FUSE2
register.
> +#define GEN8_EU_DISABLE0 0x9134
> +#define GEN8_EU_DIS0_S0_MASK 0xffffff
> +#define GEN8_EU_DIS0_S1_SHIFT 24
> +#define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT)
> +
> +#define GEN8_EU_DISABLE1 0x9138
> +#define GEN8_EU_DIS1_S1_MASK 0xffff
> +#define GEN8_EU_DIS1_S2_SHIFT 16
> +#define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT)
> +
> +#define GEN8_EU_DISABLE2 0x913c
> +#define GEN8_EU_DIS2_S2_MASK 0xff
> +
> +#define GEN9_F2_SS_DIS_SHIFT 20
> +#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
>
> #define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
>
> @@ -6867,6 +6882,9 @@ enum skl_disp_power_wells {
> #define GEN6_RC6 3
> #define GEN6_RC7 4
>
> +#define GEN8_GT_SLICE_INFO 0x138064
> +#define GEN8_LSLICESTAT_MASK 0x7
> +
> #define CHV_POWER_SS0_SIG1 0xa720
> #define CHV_POWER_SS1_SIG1 0xa728
> #define CHV_SS_PG_ENABLE (1<<1)
> --
> Lukasz Daniluk
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v4] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-09-17 11:51 ` [PATCH v3] " Łukasz Daniluk
2015-09-17 14:40 ` Jeff McGee
@ 2015-09-25 9:54 ` Łukasz Daniluk
2015-09-29 19:58 ` Jeff McGee
1 sibling, 1 reply; 13+ messages in thread
From: Łukasz Daniluk @ 2015-09-25 9:54 UTC (permalink / raw)
To: intel-gfx
Added checks for available slices, subslices and EUs for Broadwell. This
information is filled in intel_device_info and is available to user with
GET_PARAM.
Added checks for enabled slices, subslices and EU for Broadwell. This
information is based on available counts but takes power gated slices
into account. It can be read in debugfs.
Introduce new register defines that contain information on slices on
Broadwell.
v2:
- Introduce GT_SLICE_INFO register
- Change Broadwell sseu_device_status function to use GT_SLICE_INFO
register instead of RPCS register
- Undo removal of dev_priv variables in Cherryview and Gen9
sseu_device_satus functions
v3:
- Fix style issues
v4:
- Corrected comment
- Reverted reordering of defines
Cc: Jeff Mcgee <jeff.mcgee@intel.com>
Cc: Arun Siluvery <arun.siluvery@linux.intel.com>
Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 29 +++++++++++++-
drivers/gpu/drm/i915/i915_dma.c | 78 +++++++++++++++++++++++++++++++++++++
drivers/gpu/drm/i915/i915_reg.h | 18 +++++++++
3 files changed, 124 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 72ae347..d0f784d 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -5037,13 +5037,38 @@ static void gen9_sseu_device_status(struct drm_device *dev,
}
}
+static void broadwell_sseu_device_status(struct drm_device *dev,
+ struct sseu_dev_status *stat)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int s;
+ u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
+
+ stat->slice_total = hweight32(slice_info & GEN8_LSLICESTAT_MASK);
+
+ if (stat->slice_total) {
+ stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
+ stat->subslice_total = stat->slice_total *
+ stat->subslice_per_slice;
+ stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
+ stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
+
+ /* subtract fused off EU(s) from enabled slice(s) */
+ for (s = 0; s < stat->slice_total; s++) {
+ u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
+
+ stat->eu_total -= hweight8(subslice_7eu);
+ }
+ }
+}
+
static int i915_sseu_status(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct sseu_dev_status stat;
- if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
+ if (INTEL_INFO(dev)->gen < 8)
return -ENODEV;
seq_puts(m, "SSEU Device Info\n");
@@ -5068,6 +5093,8 @@ static int i915_sseu_status(struct seq_file *m, void *unused)
memset(&stat, 0, sizeof(stat));
if (IS_CHERRYVIEW(dev)) {
cherryview_sseu_device_status(dev, &stat);
+ } else if (IS_BROADWELL(dev)) {
+ broadwell_sseu_device_status(dev, &stat);
} else if (INTEL_INFO(dev)->gen >= 9) {
gen9_sseu_device_status(dev, &stat);
}
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 066a0ef..72e2bbd 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -713,6 +713,82 @@ static void gen9_sseu_info_init(struct drm_device *dev)
info->has_eu_pg = (info->eu_per_subslice > 2);
}
+static void broadwell_sseu_info_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_device_info *info;
+ const int s_max = 3, ss_max = 3, eu_max = 8;
+ int s, ss;
+ u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
+
+ fuse2 = I915_READ(GEN8_FUSE2);
+ s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
+ ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT;
+
+ eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK;
+ eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) |
+ ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) <<
+ (32 - GEN8_EU_DIS0_S1_SHIFT));
+ eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) |
+ ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) <<
+ (32 - GEN8_EU_DIS1_S2_SHIFT));
+
+
+ info = (struct intel_device_info *)&dev_priv->info;
+ info->slice_total = hweight32(s_enable);
+
+ /*
+ * The subslice disable field is global, i.e. it applies
+ * to each of the enabled slices.
+ */
+ info->subslice_per_slice = ss_max - hweight32(ss_disable);
+ info->subslice_total = info->slice_total * info->subslice_per_slice;
+
+ /*
+ * Iterate through enabled slices and subslices to
+ * count the total enabled EU.
+ */
+ for (s = 0; s < s_max; s++) {
+ if (!(s_enable & (0x1 << s)))
+ /* skip disabled slice */
+ continue;
+
+ for (ss = 0; ss < ss_max; ss++) {
+ u32 n_disabled;
+
+ if (ss_disable & (0x1 << ss))
+ /* skip disabled subslice */
+ continue;
+
+ n_disabled = hweight8(eu_disable[s] >> (ss * eu_max));
+
+ /*
+ * Record which subslices have 7 EUs.
+ */
+ if (eu_max - n_disabled == 7)
+ info->subslice_7eu[s] |= 1 << ss;
+
+ info->eu_total += eu_max - n_disabled;
+ }
+ }
+
+ /*
+ * BDW is expected to always have a uniform distribution of EU across
+ * subslices with the exception that any one EU in any one subslice may
+ * be fused off for die recovery.
+ */
+ info->eu_per_subslice = info->subslice_total ?
+ DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
+
+ /*
+ * BDW supports slice power gating on devices with more than
+ * one slice.
+ */
+ info->has_slice_pg = (info->slice_total > 1);
+ info->has_subslice_pg = 0;
+ info->has_eu_pg = 0;
+}
+
/*
* Determine various intel_device_info fields at runtime.
*
@@ -783,6 +859,8 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
/* Initialize slice/subslice/EU info */
if (IS_CHERRYVIEW(dev))
cherryview_sseu_info_init(dev);
+ else if (IS_BROADWELL(dev))
+ broadwell_sseu_info_init(dev);
else if (INTEL_INFO(dev)->gen >= 9)
gen9_sseu_info_init(dev);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 67bf205..10761a3 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1876,12 +1876,27 @@ enum skl_disp_power_wells {
#define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
#define GEN8_FUSE2 0x9120
+#define GEN8_F2_SS_DIS_SHIFT 21
+#define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT)
#define GEN8_F2_S_ENA_SHIFT 25
#define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT)
#define GEN9_F2_SS_DIS_SHIFT 20
#define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
+#define GEN8_EU_DISABLE0 0x9134
+#define GEN8_EU_DIS0_S0_MASK 0xffffff
+#define GEN8_EU_DIS0_S1_SHIFT 24
+#define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT)
+
+#define GEN8_EU_DISABLE1 0x9138
+#define GEN8_EU_DIS1_S1_MASK 0xffff
+#define GEN8_EU_DIS1_S2_SHIFT 16
+#define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT)
+
+#define GEN8_EU_DISABLE2 0x913c
+#define GEN8_EU_DIS2_S2_MASK 0xff
+
#define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
#define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050
@@ -6867,6 +6882,9 @@ enum skl_disp_power_wells {
#define GEN6_RC6 3
#define GEN6_RC7 4
+#define GEN8_GT_SLICE_INFO 0x138064
+#define GEN8_LSLICESTAT_MASK 0x7
+
#define CHV_POWER_SS0_SIG1 0xa720
#define CHV_POWER_SS1_SIG1 0xa728
#define CHV_SS_PG_ENABLE (1<<1)
--
Lukasz Daniluk
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v4] drm/i915/bdw: Check for slice, subslice and EU count for BDW
2015-09-25 9:54 ` [PATCH v4] " Łukasz Daniluk
@ 2015-09-29 19:58 ` Jeff McGee
0 siblings, 0 replies; 13+ messages in thread
From: Jeff McGee @ 2015-09-29 19:58 UTC (permalink / raw)
To: Łukasz Daniluk; +Cc: intel-gfx
On Fri, Sep 25, 2015 at 11:54:58AM +0200, Łukasz Daniluk wrote:
> Added checks for available slices, subslices and EUs for Broadwell. This
> information is filled in intel_device_info and is available to user with
> GET_PARAM.
> Added checks for enabled slices, subslices and EU for Broadwell. This
> information is based on available counts but takes power gated slices
> into account. It can be read in debugfs.
> Introduce new register defines that contain information on slices on
> Broadwell.
>
> v2:
> - Introduce GT_SLICE_INFO register
> - Change Broadwell sseu_device_status function to use GT_SLICE_INFO
> register instead of RPCS register
> - Undo removal of dev_priv variables in Cherryview and Gen9
> sseu_device_satus functions
>
> v3:
> - Fix style issues
>
> v4:
> - Corrected comment
> - Reverted reordering of defines
>
> Cc: Jeff Mcgee <jeff.mcgee@intel.com>
> Cc: Arun Siluvery <arun.siluvery@linux.intel.com>
> Signed-off-by: Łukasz Daniluk <lukasz.daniluk@intel.com>
> ---
> drivers/gpu/drm/i915/i915_debugfs.c | 29 +++++++++++++-
> drivers/gpu/drm/i915/i915_dma.c | 78 +++++++++++++++++++++++++++++++++++++
> drivers/gpu/drm/i915/i915_reg.h | 18 +++++++++
> 3 files changed, 124 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 72ae347..d0f784d 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -5037,13 +5037,38 @@ static void gen9_sseu_device_status(struct drm_device *dev,
> }
> }
>
> +static void broadwell_sseu_device_status(struct drm_device *dev,
> + struct sseu_dev_status *stat)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + int s;
> + u32 slice_info = I915_READ(GEN8_GT_SLICE_INFO);
> +
> + stat->slice_total = hweight32(slice_info & GEN8_LSLICESTAT_MASK);
> +
> + if (stat->slice_total) {
> + stat->subslice_per_slice = INTEL_INFO(dev)->subslice_per_slice;
> + stat->subslice_total = stat->slice_total *
> + stat->subslice_per_slice;
> + stat->eu_per_subslice = INTEL_INFO(dev)->eu_per_subslice;
> + stat->eu_total = stat->eu_per_subslice * stat->subslice_total;
> +
> + /* subtract fused off EU(s) from enabled slice(s) */
> + for (s = 0; s < stat->slice_total; s++) {
> + u8 subslice_7eu = INTEL_INFO(dev)->subslice_7eu[s];
> +
> + stat->eu_total -= hweight8(subslice_7eu);
> + }
> + }
> +}
> +
> static int i915_sseu_status(struct seq_file *m, void *unused)
> {
> struct drm_info_node *node = (struct drm_info_node *) m->private;
> struct drm_device *dev = node->minor->dev;
> struct sseu_dev_status stat;
>
> - if ((INTEL_INFO(dev)->gen < 8) || IS_BROADWELL(dev))
> + if (INTEL_INFO(dev)->gen < 8)
> return -ENODEV;
>
> seq_puts(m, "SSEU Device Info\n");
> @@ -5068,6 +5093,8 @@ static int i915_sseu_status(struct seq_file *m, void *unused)
> memset(&stat, 0, sizeof(stat));
> if (IS_CHERRYVIEW(dev)) {
> cherryview_sseu_device_status(dev, &stat);
> + } else if (IS_BROADWELL(dev)) {
> + broadwell_sseu_device_status(dev, &stat);
> } else if (INTEL_INFO(dev)->gen >= 9) {
> gen9_sseu_device_status(dev, &stat);
> }
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index 066a0ef..72e2bbd 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -713,6 +713,82 @@ static void gen9_sseu_info_init(struct drm_device *dev)
> info->has_eu_pg = (info->eu_per_subslice > 2);
> }
>
> +static void broadwell_sseu_info_init(struct drm_device *dev)
> +{
> + struct drm_i915_private *dev_priv = dev->dev_private;
> + struct intel_device_info *info;
> + const int s_max = 3, ss_max = 3, eu_max = 8;
> + int s, ss;
> + u32 fuse2, eu_disable[s_max], s_enable, ss_disable;
> +
> + fuse2 = I915_READ(GEN8_FUSE2);
> + s_enable = (fuse2 & GEN8_F2_S_ENA_MASK) >> GEN8_F2_S_ENA_SHIFT;
> + ss_disable = (fuse2 & GEN8_F2_SS_DIS_MASK) >> GEN8_F2_SS_DIS_SHIFT;
> +
> + eu_disable[0] = I915_READ(GEN8_EU_DISABLE0) & GEN8_EU_DIS0_S0_MASK;
> + eu_disable[1] = (I915_READ(GEN8_EU_DISABLE0) >> GEN8_EU_DIS0_S1_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE1) & GEN8_EU_DIS1_S1_MASK) <<
> + (32 - GEN8_EU_DIS0_S1_SHIFT));
> + eu_disable[2] = (I915_READ(GEN8_EU_DISABLE1) >> GEN8_EU_DIS1_S2_SHIFT) |
> + ((I915_READ(GEN8_EU_DISABLE2) & GEN8_EU_DIS2_S2_MASK) <<
> + (32 - GEN8_EU_DIS1_S2_SHIFT));
> +
> +
> + info = (struct intel_device_info *)&dev_priv->info;
> + info->slice_total = hweight32(s_enable);
> +
> + /*
> + * The subslice disable field is global, i.e. it applies
> + * to each of the enabled slices.
> + */
> + info->subslice_per_slice = ss_max - hweight32(ss_disable);
> + info->subslice_total = info->slice_total * info->subslice_per_slice;
> +
> + /*
> + * Iterate through enabled slices and subslices to
> + * count the total enabled EU.
> + */
> + for (s = 0; s < s_max; s++) {
> + if (!(s_enable & (0x1 << s)))
> + /* skip disabled slice */
> + continue;
> +
> + for (ss = 0; ss < ss_max; ss++) {
> + u32 n_disabled;
> +
> + if (ss_disable & (0x1 << ss))
> + /* skip disabled subslice */
> + continue;
> +
> + n_disabled = hweight8(eu_disable[s] >> (ss * eu_max));
> +
> + /*
> + * Record which subslices have 7 EUs.
> + */
> + if (eu_max - n_disabled == 7)
> + info->subslice_7eu[s] |= 1 << ss;
> +
> + info->eu_total += eu_max - n_disabled;
> + }
> + }
> +
> + /*
> + * BDW is expected to always have a uniform distribution of EU across
> + * subslices with the exception that any one EU in any one subslice may
> + * be fused off for die recovery.
> + */
> + info->eu_per_subslice = info->subslice_total ?
> + DIV_ROUND_UP(info->eu_total, info->subslice_total) : 0;
> +
> + /*
> + * BDW supports slice power gating on devices with more than
> + * one slice.
> + */
> + info->has_slice_pg = (info->slice_total > 1);
> + info->has_subslice_pg = 0;
> + info->has_eu_pg = 0;
> +}
> +
> /*
> * Determine various intel_device_info fields at runtime.
> *
> @@ -783,6 +859,8 @@ static void intel_device_info_runtime_init(struct drm_device *dev)
> /* Initialize slice/subslice/EU info */
> if (IS_CHERRYVIEW(dev))
> cherryview_sseu_info_init(dev);
> + else if (IS_BROADWELL(dev))
> + broadwell_sseu_info_init(dev);
> else if (INTEL_INFO(dev)->gen >= 9)
> gen9_sseu_info_init(dev);
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 67bf205..10761a3 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1876,12 +1876,27 @@ enum skl_disp_power_wells {
> #define CHV_FGT_EU_DIS_SS1_R1_MASK (0xf << CHV_FGT_EU_DIS_SS1_R1_SHIFT)
>
> #define GEN8_FUSE2 0x9120
> +#define GEN8_F2_SS_DIS_SHIFT 21
> +#define GEN8_F2_SS_DIS_MASK (0x7 << GEN8_F2_SS_DIS_SHIFT)
> #define GEN8_F2_S_ENA_SHIFT 25
> #define GEN8_F2_S_ENA_MASK (0x7 << GEN8_F2_S_ENA_SHIFT)
>
> #define GEN9_F2_SS_DIS_SHIFT 20
> #define GEN9_F2_SS_DIS_MASK (0xf << GEN9_F2_SS_DIS_SHIFT)
>
> +#define GEN8_EU_DISABLE0 0x9134
> +#define GEN8_EU_DIS0_S0_MASK 0xffffff
> +#define GEN8_EU_DIS0_S1_SHIFT 24
> +#define GEN8_EU_DIS0_S1_MASK (0xff << GEN8_EU_DIS0_S1_SHIFT)
> +
> +#define GEN8_EU_DISABLE1 0x9138
> +#define GEN8_EU_DIS1_S1_MASK 0xffff
> +#define GEN8_EU_DIS1_S2_SHIFT 16
> +#define GEN8_EU_DIS1_S2_MASK (0xffff << GEN8_EU_DIS1_S2_SHIFT)
> +
> +#define GEN8_EU_DISABLE2 0x913c
> +#define GEN8_EU_DIS2_S2_MASK 0xff
> +
> #define GEN9_EU_DISABLE(slice) (0x9134 + (slice)*0x4)
>
> #define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050
> @@ -6867,6 +6882,9 @@ enum skl_disp_power_wells {
> #define GEN6_RC6 3
> #define GEN6_RC7 4
>
> +#define GEN8_GT_SLICE_INFO 0x138064
> +#define GEN8_LSLICESTAT_MASK 0x7
> +
> #define CHV_POWER_SS0_SIG1 0xa720
> #define CHV_POWER_SS1_SIG1 0xa728
> #define CHV_SS_PG_ENABLE (1<<1)
> --
> Lukasz Daniluk
>
Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2015-09-29 19:53 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-13 12:38 [PATCH] drm/i915/bdw: Check for slice, subslice and EU count for BDW Łukasz Daniluk
2015-08-13 21:34 ` Bish, Jim
2015-08-14 0:11 ` Jeff McGee
2015-09-02 15:47 ` [PATCH v2] " Łukasz Daniluk
2015-09-02 14:03 ` Chris Wilson
2015-09-08 11:29 ` Daniluk, Lukasz
2015-09-02 15:08 ` Arun Siluvery
2015-09-08 12:53 ` Daniluk, Lukasz
2015-09-08 15:15 ` Arun Siluvery
2015-09-17 11:51 ` [PATCH v3] " Łukasz Daniluk
2015-09-17 14:40 ` Jeff McGee
2015-09-25 9:54 ` [PATCH v4] " Łukasz Daniluk
2015-09-29 19:58 ` Jeff McGee
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox