diff mbox

[10/12] drm/i915/skl+: use linetime latency if ddb size is not available

Message ID 20170517115831.13830-11-mahesh1.kumar@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kumar, Mahesh May 17, 2017, 11:58 a.m. UTC
From: "Kumar, Mahesh" <mahesh1.kumar@intel.com>

This patch make changes to use linetime latency if allocated
DDB size during plane watermark calculation is not available.
linetime is the time, display engine takes to fetch one line worth of
pixels with given pixel clock rate.
This is required to implement new DDB allocation algorithm.

In New Algorithm DDB is allocated based on WM values, because of which
number of DDB blocks will not be available during WM calculation,
So this "linetime latency" is suggested by SV/HW team to be used during
switch-case for WM blocks selection.
linetime latency us = pipe horizontal total pixels/adjusted pixel rate MHz

Changes since v1:
 - Rebase on top of Paulo's patch series
Changes since v2:
 - Fix if-else condition (pointed by Maarten)
Changes since v3:
 - Use common function for timetime_us calculation (Paulo)
 - rebase on drm-tip
Changes since v4:
 - Use consistent name for fixed_point operation
Changes since v5:
 - Improve commit message
 - rename skl_get_linetime_us to intel_get_linetime_us
 - fix watermark result selection (Matt)

Signed-off-by: "Mahesh Kumar" <mahesh1.kumar@intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |  7 +++++++
 drivers/gpu/drm/i915/intel_pm.c | 42 ++++++++++++++++++++++++++++++++---------
 2 files changed, 40 insertions(+), 9 deletions(-)

Comments

Matt Roper May 17, 2017, 9:16 p.m. UTC | #1
On Wed, May 17, 2017 at 05:28:29PM +0530, Mahesh Kumar wrote:
> From: "Kumar, Mahesh" <mahesh1.kumar@intel.com>
> 
> This patch make changes to use linetime latency if allocated
> DDB size during plane watermark calculation is not available.
> linetime is the time, display engine takes to fetch one line worth of
> pixels with given pixel clock rate.
> This is required to implement new DDB allocation algorithm.
> 
> In New Algorithm DDB is allocated based on WM values, because of which
> number of DDB blocks will not be available during WM calculation,
> So this "linetime latency" is suggested by SV/HW team to be used during
> switch-case for WM blocks selection.
> linetime latency us = pipe horizontal total pixels/adjusted pixel rate MHz
> 
> Changes since v1:
>  - Rebase on top of Paulo's patch series
> Changes since v2:
>  - Fix if-else condition (pointed by Maarten)
> Changes since v3:
>  - Use common function for timetime_us calculation (Paulo)
>  - rebase on drm-tip
> Changes since v4:
>  - Use consistent name for fixed_point operation
> Changes since v5:
>  - Improve commit message
>  - rename skl_get_linetime_us to intel_get_linetime_us
>  - fix watermark result selection (Matt)
> 
> Signed-off-by: "Mahesh Kumar" <mahesh1.kumar@intel.com>
> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_drv.h |  7 +++++++
>  drivers/gpu/drm/i915/intel_pm.c | 42 ++++++++++++++++++++++++++++++++---------
>  2 files changed, 40 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index e9144634e720..0100100fdaf9 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -115,6 +115,13 @@ typedef struct {
>  	fp; \
>  })
>  
> +static inline bool is_fixed16_zero(uint_fixed_16_16_t val)
> +{
> +	if (val.val == 0)
> +		return true;
> +	return false;
> +}
> +
>  static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val)
>  {
>  	uint_fixed_16_16_t fp;
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 0f1d9f672e83..936eef1634c7 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4197,6 +4197,27 @@ static uint_fixed_16_16_t skl_wm_method2(uint32_t pixel_rate,
>  	return ret;
>  }
>  
> +static uint_fixed_16_16_t
> +intel_get_linetime_us(struct intel_crtc_state *cstate)
> +{
> +	uint32_t pixel_rate;
> +	uint32_t crtc_htotal;
> +	uint_fixed_16_16_t linetime_us;
> +
> +	if (!cstate->base.active)
> +		return u32_to_fixed_16_16(0);
> +
> +	pixel_rate = cstate->pixel_rate;
> +
> +	if (WARN_ON(pixel_rate == 0))
> +		return u32_to_fixed_16_16(0);
> +
> +	crtc_htotal = cstate->base.adjusted_mode.crtc_htotal;
> +	linetime_us = fixed_16_16_div_u64(crtc_htotal * 1000, pixel_rate);
> +
> +	return linetime_us;
> +}
> +
>  static uint32_t
>  skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *cstate,
>  			      const struct intel_plane_state *pstate)
> @@ -4331,12 +4352,18 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
>  	if (y_tiled) {
>  		selected_result = max_fixed_16_16(method2, y_tile_minimum);
>  	} else {
> +		uint32_t linetime_us;
> +
> +		linetime_us = fixed_16_16_to_u32_round_up(
> +				intel_get_linetime_us(cstate));
>  		if ((cpp * cstate->base.adjusted_mode.crtc_htotal / 512 < 1) &&
>  		    (plane_bytes_per_line / 512 < 1))
>  			selected_result = method2;
> -		else if ((ddb_allocation /
> +		else if ((ddb_allocation && ddb_allocation /
>  			fixed_16_16_to_u32_round_up(plane_blocks_per_line)) >= 1)
>  			selected_result = min_fixed_16_16(method1, method2);
> +		else if (latency >= linetime_us)
> +			selected_result = min_fixed_16_16(method1, method2);
>  		else
>  			selected_result = method1;
>  	}
> @@ -4424,19 +4451,16 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
>  {
>  	struct drm_atomic_state *state = cstate->base.state;
>  	struct drm_i915_private *dev_priv = to_i915(state->dev);
> -	uint32_t pixel_rate;
> +	uint_fixed_16_16_t linetime_us;
>  	uint32_t linetime_wm;
>  
> -	if (!cstate->base.active)
> -		return 0;
> +	linetime_us = intel_get_linetime_us(cstate);
>  
> -	pixel_rate = cstate->pixel_rate;
> -
> -	if (WARN_ON(pixel_rate == 0))
> +	if (is_fixed16_zero(linetime_us))
>  		return 0;
>  
> -	linetime_wm = DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal *
> -				   1000, pixel_rate);
> +	linetime_wm = fixed_16_16_to_u32_round_up(mul_u32_fixed_16_16(8,
> +				linetime_us));
>  
>  	/* Display WA #1135: bxt. */
>  	if (IS_BROXTON(dev_priv) && dev_priv->ipc_enabled)
> -- 
> 2.11.0
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e9144634e720..0100100fdaf9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -115,6 +115,13 @@  typedef struct {
 	fp; \
 })
 
+static inline bool is_fixed16_zero(uint_fixed_16_16_t val)
+{
+	if (val.val == 0)
+		return true;
+	return false;
+}
+
 static inline uint_fixed_16_16_t u32_to_fixed_16_16(uint32_t val)
 {
 	uint_fixed_16_16_t fp;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0f1d9f672e83..936eef1634c7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4197,6 +4197,27 @@  static uint_fixed_16_16_t skl_wm_method2(uint32_t pixel_rate,
 	return ret;
 }
 
+static uint_fixed_16_16_t
+intel_get_linetime_us(struct intel_crtc_state *cstate)
+{
+	uint32_t pixel_rate;
+	uint32_t crtc_htotal;
+	uint_fixed_16_16_t linetime_us;
+
+	if (!cstate->base.active)
+		return u32_to_fixed_16_16(0);
+
+	pixel_rate = cstate->pixel_rate;
+
+	if (WARN_ON(pixel_rate == 0))
+		return u32_to_fixed_16_16(0);
+
+	crtc_htotal = cstate->base.adjusted_mode.crtc_htotal;
+	linetime_us = fixed_16_16_div_u64(crtc_htotal * 1000, pixel_rate);
+
+	return linetime_us;
+}
+
 static uint32_t
 skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *cstate,
 			      const struct intel_plane_state *pstate)
@@ -4331,12 +4352,18 @@  static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
 	if (y_tiled) {
 		selected_result = max_fixed_16_16(method2, y_tile_minimum);
 	} else {
+		uint32_t linetime_us;
+
+		linetime_us = fixed_16_16_to_u32_round_up(
+				intel_get_linetime_us(cstate));
 		if ((cpp * cstate->base.adjusted_mode.crtc_htotal / 512 < 1) &&
 		    (plane_bytes_per_line / 512 < 1))
 			selected_result = method2;
-		else if ((ddb_allocation /
+		else if ((ddb_allocation && ddb_allocation /
 			fixed_16_16_to_u32_round_up(plane_blocks_per_line)) >= 1)
 			selected_result = min_fixed_16_16(method1, method2);
+		else if (latency >= linetime_us)
+			selected_result = min_fixed_16_16(method1, method2);
 		else
 			selected_result = method1;
 	}
@@ -4424,19 +4451,16 @@  skl_compute_linetime_wm(struct intel_crtc_state *cstate)
 {
 	struct drm_atomic_state *state = cstate->base.state;
 	struct drm_i915_private *dev_priv = to_i915(state->dev);
-	uint32_t pixel_rate;
+	uint_fixed_16_16_t linetime_us;
 	uint32_t linetime_wm;
 
-	if (!cstate->base.active)
-		return 0;
+	linetime_us = intel_get_linetime_us(cstate);
 
-	pixel_rate = cstate->pixel_rate;
-
-	if (WARN_ON(pixel_rate == 0))
+	if (is_fixed16_zero(linetime_us))
 		return 0;
 
-	linetime_wm = DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal *
-				   1000, pixel_rate);
+	linetime_wm = fixed_16_16_to_u32_round_up(mul_u32_fixed_16_16(8,
+				linetime_us));
 
 	/* Display WA #1135: bxt. */
 	if (IS_BROXTON(dev_priv) && dev_priv->ipc_enabled)