Re: [PATCH 48/89 v6] drm/i915/skl: Allocate DDB portions for display planes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Sep 27, 2014 at 03:15:00PM +0100, Damien Lespiau wrote:
> v2: Fix the 3rd plane/cursor logic (Pradeep Bhat)
> v3: Fix one-by-one error in the DDB allocation code
> v4: Rebase on top of the skl_pipe_pixel_rate() argument change
> v5: Replace the available/start/end output parameters of
>     skl_ddb_get_pipe_allocation_limits() by a single ddb entry constify
>     a few arguments
>     Make nth_active_pipe 0 indexed
>     Use sizeof(variable) instead of sizeof(type)
>     (Ville)
> v6: Use the for_each_crtc() macro instead of list_for_each_entry()
> 
> Signed-off-by: Damien Lespiau <damien.lespiau@xxxxxxxxx>

Looks good.

Reviewed-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>

> ---
>  drivers/gpu/drm/i915/intel_pm.c | 148 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 1db4aa8..3dc689e 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -2965,6 +2965,153 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
>  	return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL);
>  }
>  
> +/*
> + * On gen9, we need to allocate Display Data Buffer (DDB) portions to the
> + * different active planes.
> + */
> +
> +#define SKL_DDB_SIZE		896	/* in blocks */
> +
> +static void
> +skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
> +				   struct drm_crtc *for_crtc,
> +				   const struct intel_wm_config *config,
> +				   const struct skl_pipe_wm_parameters *params,
> +				   struct skl_ddb_entry *alloc /* out */)
> +{
> +	struct drm_crtc *crtc;
> +	unsigned int pipe_size, ddb_size;
> +	int nth_active_pipe;
> +
> +	if (!params->active) {
> +		alloc->start = 0;
> +		alloc->end = 0;
> +		return;
> +	}
> +
> +	ddb_size = SKL_DDB_SIZE;
> +
> +	ddb_size -= 4; /* 4 blocks for bypass path allocation */
> +
> +	nth_active_pipe = 0;
> +	for_each_crtc(dev, crtc) {
> +		if (!intel_crtc_active(crtc))
> +			continue;
> +
> +		if (crtc == for_crtc)
> +			break;
> +
> +		nth_active_pipe++;
> +	}
> +
> +	pipe_size = ddb_size / config->num_pipes_active;
> +	alloc->start = nth_active_pipe * ddb_size / config->num_pipes_active;
> +	alloc->end = alloc->start + pipe_size - 1;
> +}
> +
> +static unsigned int skl_cursor_allocation(const struct intel_wm_config *config)
> +{
> +	if (config->num_pipes_active == 1)
> +		return 32;
> +
> +	return 8;
> +}
> +
> +static unsigned int
> +skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p)
> +{
> +	return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
> +}
> +
> +/*
> + * We don't overflow 32 bits. Worst case is 3 planes enabled, each fetching
> + * a 8192x4096@32bpp framebuffer:
> + *   3 * 4096 * 8192  * 4 < 2^32
> + */
> +static unsigned int
> +skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
> +				 const struct skl_pipe_wm_parameters *params)
> +{
> +	unsigned int total_data_rate = 0;
> +	int plane;
> +
> +	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
> +		const struct intel_plane_wm_parameters *p;
> +
> +		p = &params->plane[plane];
> +		if (!p->enabled)
> +			continue;
> +
> +		total_data_rate += skl_plane_relative_data_rate(p);
> +	}
> +
> +	return total_data_rate;
> +}
> +
> +static void
> +skl_allocate_pipe_ddb(struct drm_crtc *crtc,
> +		      const struct intel_wm_config *config,
> +		      const struct skl_pipe_wm_parameters *params,
> +		      struct skl_ddb_allocation *ddb /* out */)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	enum pipe pipe = intel_crtc->pipe;
> +	struct skl_ddb_entry alloc;
> +	uint16_t alloc_size, start, cursor_blocks;
> +	unsigned int total_data_rate;
> +	int plane;
> +
> +	skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, &alloc);
> +	alloc_size = skl_ddb_entry_size(&alloc);
> +	if (alloc_size == 0) {
> +		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
> +		memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe]));
> +		return;
> +	}
> +
> +	cursor_blocks = skl_cursor_allocation(config);
> +	ddb->cursor[pipe].start = alloc.end - cursor_blocks + 1;
> +	ddb->cursor[pipe].end = alloc.end;
> +
> +	alloc_size -= cursor_blocks;
> +	alloc.end -= cursor_blocks;
> +
> +	/*
> +	 * Each active plane get a portion of the remaining space, in
> +	 * proportion to the amount of data they need to fetch from memory.
> +	 *
> +	 * FIXME: we may not allocate every single block here.
> +	 */
> +	total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
> +
> +	start = alloc.start;
> +	for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
> +		const struct intel_plane_wm_parameters *p;
> +		unsigned int data_rate;
> +		uint16_t plane_blocks;
> +
> +		p = &params->plane[plane];
> +		if (!p->enabled)
> +			continue;
> +
> +		data_rate = skl_plane_relative_data_rate(p);
> +
> +		/*
> +		 * promote the expression to 64 bits to avoid overflowing, the
> +		 * result is < available as data_rate / total_data_rate < 1
> +		 */
> +		plane_blocks = div_u64((uint64_t)alloc_size * data_rate,
> +				       total_data_rate);
> +
> +		ddb->plane[pipe][plane].start = start;
> +		ddb->plane[pipe][plane].end = start + plane_blocks - 1;
> +
> +		start += plane_blocks;
> +	}
> +
> +}
> +
>  static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_config *config)
>  {
>  	/* TODO: Take into account the scalers once we support them */
> @@ -3286,6 +3433,7 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  
>  	skl_compute_wm_pipe_parameters(crtc, params);
> +	skl_allocate_pipe_ddb(crtc, config, params, ddb);
>  	skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
>  
>  	if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
> -- 
> 1.8.3.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx





[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux