[RFC] drm/i915/pm: Add a new module parameter for customized ring multiplier

Jackie Li yaodong.li at intel.com
Mon Dec 18 17:23:04 UTC 2017


From: Zhipeng Gong <zhipeng.gong at intel.com>

A known issue that performance will drop while using the fixed
2x ring multiplier on SKL if the 2 * GT freq was less than CPU freq.
Currently, there's no way to override the 2x ring multiplier.

This patch adds a new module parameter to allow the overriding of
ring multiplier for Gen9 platforms.

Cc: Ben Widawsky <benjamin.widawsky at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Sagar Arun Kamble <sagar.a.kamble at intel.com>
Cc: Zhipeng Gong <zhipeng.gong at intel.com>
Signed-off-by: Jackie Li <yaodong.li at intel.com>
---
 drivers/gpu/drm/i915/i915_params.c |  4 +++
 drivers/gpu/drm/i915/i915_params.h |  1 +
 drivers/gpu/drm/i915/intel_pm.c    | 57 ++++++++++++++++++++++++++++++++------
 3 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 8dfea03..f3dd179 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -101,6 +101,10 @@ i915_param_named_unsafe(disable_power_well, int, 0400,
 	"Disable display power wells when possible "
 	"(-1=auto [default], 0=power wells always on, 1=power wells disabled when possible)");
 
+i915_param_named_unsafe(ring_multiplier, uint, 0400,
+	"Override Ring/GT frequency multiplier."
+	"(2=2x ring multiplier [defaut], 3=3x ring multiplier)");
+
 i915_param_named_unsafe(enable_ips, int, 0600, "Enable IPS (default: true)");
 
 i915_param_named(fastboot, bool, 0600,
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index 792ce26..6073d1c 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -43,6 +43,7 @@
 	param(int, enable_ppgtt, -1) \
 	param(int, enable_psr, -1) \
 	param(int, disable_power_well, -1) \
+	param(unsigned int, ring_multiplier, 2) \
 	param(int, enable_ips, 1) \
 	param(int, invert_brightness, 0) \
 	param(int, enable_guc, 0) \
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a349c4f..080051b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6818,6 +6818,34 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv)
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
+static inline void sanitize_ring_multiplier(struct drm_i915_private *i915)
+{
+	unsigned int m = i915_modparams.ring_multiplier;
+
+	/* Currently, only support 2x or 3x multipliers */
+	if (m != 2 && m != 3)
+		i915_modparams.ring_multiplier = 2;
+}
+
+static inline void get_ring_multiplier(struct drm_i915_private *i915,
+				      unsigned int *numer,
+				      unsigned int *denom)
+{
+	sanitize_ring_multiplier(i915);
+
+	if (IS_GEN9(i915)) {
+		*numer = i915_modparams.ring_multiplier;
+		*denom = 1;
+	} else if IS_HASWELL(i915) {
+		*numer = 5;
+		*denom = 2;
+	} else {
+		/* Use a 2x ring multiplier by default */
+		*numer = 2;
+		*denom = 1;
+	}
+}
+
 static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 {
 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
@@ -6825,6 +6853,8 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 	unsigned int gpu_freq;
 	unsigned int max_ia_freq, min_ring_freq;
 	unsigned int max_gpu_freq, min_gpu_freq;
+	unsigned int ring_mul_numer, ring_mul_denom;
+	unsigned int ring_request_freq;
 	int scaling_factor = 180;
 	struct cpufreq_policy *policy;
 
@@ -6858,6 +6888,9 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 		max_gpu_freq = rps->max_freq;
 	}
 
+
+	get_ring_multiplier(dev_priv, &ring_mul_numer, &ring_mul_denom);
+
 	/*
 	 * For each potential GPU frequency, load a ring frequency we'd like
 	 * to use for memory access.  We do this by specifying the IA frequency
@@ -6867,18 +6900,24 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 		int diff = max_gpu_freq - gpu_freq;
 		unsigned int ia_freq = 0, ring_freq = 0;
 
+		/*
+		 * ring_request_freq = ring_multiplier * GPU frequency.
+		 * Ring freq is in 100MHz units while GPU frequency is in 50MHz
+		 * units.
+		 */
+		ring_request_freq = mult_frac(gpu_freq, ring_mul_numer,
+					      2 * ring_mul_denom);
+
 		if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
 			/*
-			 * ring_freq = 2 * GT. ring_freq is in 100MHz units
-			 * No floor required for ring frequency on SKL.
+			 * ring_freq = ring request freq. No floor required for
+			 * ring frequency on SKL.
 			 */
-			ring_freq = gpu_freq;
-		} else if (INTEL_INFO(dev_priv)->gen >= 8) {
-			/* max(2 * GT, DDR). NB: GT is 50MHz units */
-			ring_freq = max(min_ring_freq, gpu_freq);
-		} else if (IS_HASWELL(dev_priv)) {
-			ring_freq = mult_frac(gpu_freq, 5, 4);
-			ring_freq = max(min_ring_freq, ring_freq);
+			ring_freq = ring_request_freq;
+		} else if (INTEL_INFO(dev_priv)->gen >= 8 ||
+			IS_HASWELL(dev_priv)) {
+			/* max(ring request freq, DDR). NB: GT is 50MHz units */
+			ring_freq = max(min_ring_freq, ring_request_freq);
 			/* leave ia_freq as the default, chosen by cpufreq */
 		} else {
 			/* On older processors, there is no separate ring
-- 
2.7.4



More information about the Intel-gfx-trybot mailing list