[2/2] drm/i915/bxt: Add WaEnablePooledEuFor2x6

Submitted by arun.siluvery@linux.intel.com on May 12, 2016, 9:37 a.m.

Details

Message ID 1463045835-6297-3-git-send-email-arun.siluvery@linux.intel.com
State New
Headers show
Series "BXT Pooled EU kernel support" ( rev: 1 ) in Intel GFX

Not browsing as part of any series.

Commit Message

arun.siluvery@linux.intel.com May 12, 2016, 9:37 a.m.
Pooled EU is enabled by default for BXT but for fused down 2x6 parts it is
advised to turn it off. But there is another HW issue in these parts (fused
down 2x6 parts) before C0 that requires Pooled EU to be enabled as a
workaround. In this case the pool configuration changes depending upon
which subslice is disabled. This doesn't affect if the device has all 3
subslices enabled.

Userspace need to know min no. of eus in a pool as it varies based on which
subslice is disabled, this is exported using a new private getparam ioctl
as there is no opensource user available for this feature yet.

Cc: Winiarski, Michal <michal.winiarski@intel.com>
Cc: Zou, Nanhai <nanhai.zou@intel.com>
Cc: Yang, Rong R <rong.r.yang@intel.com>
Cc: Tim Gore <tim.gore@intel.com>
Signed-off-by: Arun Siluvery <arun.siluvery@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c          |  5 +++++
 drivers/gpu/drm/i915/i915_dma.c              | 33 ++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.c              |  2 +-
 drivers/gpu/drm/i915/i915_drv.h              |  1 +
 drivers/gpu/drm/i915/i915_gem_render_state.c | 17 +++++++++++---
 include/uapi/drm/i915_drm.h                  |  1 +
 6 files changed, 55 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 5e5b5cc..a61a4f9 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -5274,6 +5274,11 @@  static int i915_sseu_status(struct seq_file *m, void *unused)
 		   INTEL_INFO(dev)->eu_total);
 	seq_printf(m, "  Available EU Per Subslice: %u\n",
 		   INTEL_INFO(dev)->eu_per_subslice);
+	seq_printf(m, "  Has Pooled EU: %s\n",
+		   yesno(HAS_POOLED_EU(dev)));
+	if (HAS_POOLED_EU(dev))
+		seq_printf(m, "  Min EU in pool: %u\n",
+			   INTEL_INFO(dev)->min_eu_in_pool);
 	seq_printf(m, "  Has Slice Power Gating: %s\n",
 		   yesno(INTEL_INFO(dev)->has_slice_pg));
 	seq_printf(m, "  Has Subslice Power Gating: %s\n",
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 5cd2ad4..eab53fd 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -225,6 +225,9 @@  static int i915_getparam(struct drm_device *dev, void *data,
 	case I915_PARAM_HAS_POOLED_EU:
 		value = HAS_POOLED_EU(dev);
 		break;
+	case I915_PARAM_MIN_EU_IN_POOL:
+		value = INTEL_INFO(dev)->min_eu_in_pool;
+		break;
 	case I915_PARAM_HAS_GPU_RESET:
 		value = i915.enable_hangcheck && intel_has_gpu_reset(dev_priv);
 		break;
@@ -770,6 +773,32 @@  static void gen9_sseu_info_init(struct drm_device *dev)
 			       (info->slice_total > 1));
 	info->has_subslice_pg = (IS_BROXTON(dev) && (info->subslice_total > 1));
 	info->has_eu_pg = (info->eu_per_subslice > 2);
+
+	if (IS_BROXTON(dev)) {
+#define IS_SS_DISABLED(_ss_disable, ss)    (_ss_disable & (0x1 << ss))
+		/*
+		 * There is a HW issue in 2x6 fused down parts that requires
+		 * Pooled EU to be enabled as a WA. The pool configuration
+		 * changes depending upon which subslice is fused down. This
+		 * doesn't affect if the device has all 3 subslices enabled.
+		 */
+		/* WaEnablePooledEuFor2x6:bxt */
+		info->has_pooled_eu = ((info->subslice_total == 3) ||
+				       (info->subslice_total == 2 &&
+					INTEL_REVID(dev) < BXT_REVID_C0));
+
+		info->min_eu_in_pool = 0;
+		if (info->has_pooled_eu) {
+			if (IS_SS_DISABLED(ss_disable, 0) ||
+			    IS_SS_DISABLED(ss_disable, 2))
+				info->min_eu_in_pool = 3;
+			else if (IS_SS_DISABLED(ss_disable, 1))
+				info->min_eu_in_pool = 6;
+			else
+				info->min_eu_in_pool = 9;
+		}
+#undef IS_SS_DISABLED
+	}
 }
 
 static void broadwell_sseu_info_init(struct drm_device *dev)
@@ -966,6 +995,10 @@  static void intel_device_info_runtime_init(struct drm_device *dev)
 	DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice);
 	DRM_DEBUG_DRIVER("EU total: %u\n", info->eu_total);
 	DRM_DEBUG_DRIVER("EU per subslice: %u\n", info->eu_per_subslice);
+	DRM_DEBUG_DRIVER("Has Pooled EU: %s\n",
+			 HAS_POOLED_EU(dev) ? "y" : "n");
+	if (HAS_POOLED_EU(dev))
+		DRM_DEBUG_DRIVER("Min EU in pool: %u\n", info->min_eu_in_pool);
 	DRM_DEBUG_DRIVER("has slice power gating: %s\n",
 			 info->has_slice_pg ? "y" : "n");
 	DRM_DEBUG_DRIVER("has subslice power gating: %s\n",
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 33e0fd0..4d6052d 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -357,7 +357,7 @@  static const struct intel_device_info intel_broxton_info = {
 	.has_ddi = 1,
 	.has_fpga_dbg = 1,
 	.has_fbc = 1,
-	.has_pooled_eu = 1,
+	.has_pooled_eu = 0,
 	GEN_DEFAULT_PIPEOFFSETS,
 	IVB_CURSOR_OFFSETS,
 	BDW_COLORS,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5b2a7a3..d87f43c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -777,6 +777,7 @@  struct intel_device_info {
 	u8 subslice_per_slice;
 	u8 eu_total;
 	u8 eu_per_subslice;
+	u8 min_eu_in_pool;
 	/* For each slice, which subslice(s) has(have) 7 EUs (bitfield)? */
 	u8 subslice_7eu[3];
 	u8 has_slice_pg:1;
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 1284f99..33bd8ce 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -137,12 +137,23 @@  static int render_state_setup(struct render_state *so)
 	so->aux_batch_offset = i * sizeof(u32);
 
 	if (HAS_POOLED_EU(dev)) {
-		u32 pool_config = (INTEL_INFO(dev)->subslice_total == 3 ?
-				   0x00777000 : 0);
+		/*
+		 * We always program 3x6 pool config but depending upon which
+		 * subslice is disabled HW drops down to appropriate config
+		 * shown below.
+		 *
+		 * SNo  subslices config                eu pool configuration
+		 * -----------------------------------------------------------
+		 * 1    3 subslices enabled (3x6)  -    0x00777000  (9+9)
+		 * 2    ss0 disabled (2x6)         -    0x00777000  (3+9)
+		 * 3    ss1 disabled (2x6)         -    0x00770000  (6+6)
+		 * 4    ss2 disabled (2x6)         -    0x00007000  (9+3)
+		 */
+		u32 eu_pool_config = 0x00777000;
 
 		OUT_BATCH(d, i, GEN9_MEDIA_POOL_STATE);
 		OUT_BATCH(d, i, GEN9_MEDIA_POOL_ENABLE);
-		OUT_BATCH(d, i, pool_config);
+		OUT_BATCH(d, i, eu_pool_config);
 		OUT_BATCH(d, i, 0);
 		OUT_BATCH(d, i, 0);
 		OUT_BATCH(d, i, 0);
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 0b0acad..7efba36 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -358,6 +358,7 @@  typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_RESOURCE_STREAMER 36
 #define I915_PARAM_HAS_EXEC_SOFTPIN	 37
 #define I915_PARAM_HAS_POOLED_EU	 38
+#define I915_PARAM_MIN_EU_IN_POOL	 39
 
 typedef struct drm_i915_getparam {
 	__s32 param;