[Intel-gfx] [PATCH 6/8] drm/i915/skl: Updated watermark programming

Damien Lespiau damien.lespiau at intel.com
Thu Feb 26 08:45:12 PST 2015


On Wed, Feb 25, 2015 at 04:47:22PM +0000, Tvrtko Ursulin wrote:
> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> 
> Recent BSpect updates have changed the watermark calculation to avoid
> display flickering in some cases.
> 
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> ---

There are really several changes in this patch, it would have been
easier for the review to split them (and that's usually how we are
supposed to split patches).

  - Convert the inner computations to number of blocks
  - W/A to increase the nb of blocks for level 1-7 by 1
  - Move max block test to >= instead of >

Anyway, which the couple of comments below addressd (of which only the
'>=' is a real problem), this is:

Reviewed-by: Damien Lespiau <damien.lespiau at intel.com>

>  drivers/gpu/drm/i915/intel_pm.c | 52 +++++++++++++++++++++++++----------------
>  1 file changed, 32 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index f7c9938..626c3c2 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2595,7 +2595,7 @@ static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel,
>  	if (latency == 0)
>  		return UINT_MAX;
>  
> -	wm_intermediate_val = latency * pixel_rate * bytes_per_pixel;
> +	wm_intermediate_val = latency * pixel_rate * bytes_per_pixel / 512;
>  	ret = DIV_ROUND_UP(wm_intermediate_val, 1000);
>  
>  	return ret;
> @@ -2605,15 +2605,18 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
>  			       uint32_t horiz_pixels, uint8_t bytes_per_pixel,
>  			       uint32_t latency)
>  {
> -	uint32_t ret, plane_bytes_per_line, wm_intermediate_val;
> +	uint32_t ret;
> +	uint32_t plane_bytes_per_line, plane_blocks_per_line;
> +	uint32_t wm_intermediate_val;
>  
>  	if (latency == 0)
>  		return UINT_MAX;
>  
>  	plane_bytes_per_line = horiz_pixels * bytes_per_pixel;
> +	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
>  	wm_intermediate_val = latency * pixel_rate;
>  	ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
> -				plane_bytes_per_line;
> +				plane_blocks_per_line;
>  
>  	return ret;
>  }
> @@ -2693,39 +2696,47 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
>  	}
>  }
>  
> -static bool skl_compute_plane_wm(struct skl_pipe_wm_parameters *p,
> +static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
> +				 struct skl_pipe_wm_parameters *p,
>  				 struct intel_plane_wm_parameters *p_params,
>  				 uint16_t ddb_allocation,
> -				 uint32_t mem_value,
> +				 int level,
>  				 uint16_t *out_blocks, /* out */
>  				 uint8_t *out_lines /* out */)
>  {
> -	uint32_t method1, method2, plane_bytes_per_line, res_blocks, res_lines;
> -	uint32_t result_bytes;
> +	uint32_t latency = dev_priv->wm.skl_latency[level];
> +	uint32_t method1, method2;
> +	uint32_t plane_bytes_per_line, plane_blocks_per_line;
> +	uint32_t res_blocks, res_lines;
> +	uint32_t result_blocks;

we now have res_blocks and result_blocks, a bit confusing. Maybe rename
result_blocks to selected_result (which happens to be in blocks)

>  
> -	if (mem_value == 0 || !p->active || !p_params->enabled)
> +	if (latency == 0 || !p->active || !p_params->enabled)
>  		return false;
>  
>  	method1 = skl_wm_method1(p->pixel_rate,
>  				 p_params->bytes_per_pixel,
> -				 mem_value);
> +				 latency);
>  	method2 = skl_wm_method2(p->pixel_rate,
>  				 p->pipe_htotal,
>  				 p_params->horiz_pixels,
>  				 p_params->bytes_per_pixel,
> -				 mem_value);
> +				 latency);
>  
>  	plane_bytes_per_line = p_params->horiz_pixels *
>  					p_params->bytes_per_pixel;
> +	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
>  
>  	/* For now xtile and linear */
> -	if (((ddb_allocation * 512) / plane_bytes_per_line) >= 1)
> -		result_bytes = min(method1, method2);
> +	if ((ddb_allocation / plane_blocks_per_line) >= 1)
> +		result_blocks = min(method1, method2);
>  	else
> -		result_bytes = method1;
> +		result_blocks = method1;
> +
> +	res_blocks = result_blocks + 1;
> +	res_lines = DIV_ROUND_UP(result_blocks, plane_blocks_per_line);
>  
> -	res_blocks = DIV_ROUND_UP(result_bytes, 512) + 1;
> -	res_lines = DIV_ROUND_UP(result_bytes, plane_bytes_per_line);
> +	if (level >=1 && level <= 7)

a space is missing before the 1 :)

> +		res_blocks++;
>  
>  	if (res_blocks > ddb_allocation || res_lines > 31)

res_blocks >= ddb_allocation

>  		return false;
> @@ -2744,23 +2755,24 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
>  				 int num_planes,
>  				 struct skl_wm_level *result)
>  {
> -	uint16_t latency = dev_priv->wm.skl_latency[level];
>  	uint16_t ddb_blocks;
>  	int i;
>  
>  	for (i = 0; i < num_planes; i++) {
>  		ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
>  
> -		result->plane_en[i] = skl_compute_plane_wm(p, &p->plane[i],
> +		result->plane_en[i] = skl_compute_plane_wm(dev_priv,
> +						p, &p->plane[i],
>  						ddb_blocks,
> -						latency,
> +						level,
>  						&result->plane_res_b[i],
>  						&result->plane_res_l[i]);
>  	}
>  
>  	ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
> -	result->cursor_en = skl_compute_plane_wm(p, &p->cursor, ddb_blocks,
> -						 latency, &result->cursor_res_b,
> +	result->cursor_en = skl_compute_plane_wm(dev_priv, p, &p->cursor,
> +						 ddb_blocks, level,
> +						 &result->cursor_res_b,
>  						 &result->cursor_res_l);
>  }
>  
> -- 
> 2.3.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx


More information about the Intel-gfx mailing list