diff mbox

[2/4] drm/i915/skl+: calculate ddb minimum allocation (v5)

Message ID 1464300828-13605-1-git-send-email-matthew.d.roper@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Matt Roper May 26, 2016, 10:13 p.m. UTC
From: "Kumar, Mahesh" <mahesh1.kumar@intel.com>

don't always use 8 ddb as minimum, instead calculate using proper
algorithm.

v2: optimizations as per Matt's comments.

v3 (by Matt):
 - Fix boolean logic for !fb test in skl_ddb_min_alloc()
 - Adjust negative tiling format comparisons in skl_ddb_min_alloc() to
   improve readability.

v4 (by Matt):
 - Rebase onto recent atomic watermark changes
 - Slight tweaks to code flow to make the logic more closely match the
   description in the bspec.

v5 (by Matt):
 - Handle minimum scanline calculation properly for 4 & 8 bpp formats.
   8bpp isn't actually possible right now, but it's listed in the bspec
   so I've included it here for forward compatibility (similar to how
   we have logic for NV12).

Cc: matthew.d.roper@intel.com
Signed-off-by: Kumar, Mahesh <mahesh1.kumar@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 68 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 5 deletions(-)

Comments

Kumar, Mahesh May 30, 2016, 5:05 a.m. UTC | #1
On Friday 27 May 2016 03:43 AM, Matt Roper wrote:
> From: "Kumar, Mahesh" <mahesh1.kumar@intel.com>
>
> don't always use 8 ddb as minimum, instead calculate using proper
> algorithm.
>
> v2: optimizations as per Matt's comments.
>
> v3 (by Matt):
>   - Fix boolean logic for !fb test in skl_ddb_min_alloc()
>   - Adjust negative tiling format comparisons in skl_ddb_min_alloc() to
>     improve readability.
>
> v4 (by Matt):
>   - Rebase onto recent atomic watermark changes
>   - Slight tweaks to code flow to make the logic more closely match the
>     description in the bspec.
>
> v5 (by Matt):
>   - Handle minimum scanline calculation properly for 4 & 8 bpp formats.
>     8bpp isn't actually possible right now, but it's listed in the bspec
>     so I've included it here for forward compatibility (similar to how
>     we have logic for NV12).
>
> Cc: matthew.d.roper@intel.com
> Signed-off-by: Kumar, Mahesh <mahesh1.kumar@intel.com>
> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_pm.c | 68 ++++++++++++++++++++++++++++++++++++++---
>   1 file changed, 63 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 3cf36dc..00b50bf 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3042,6 +3042,67 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate)
>   	return total_data_rate;
>   }
>   
> +static uint16_t
> +skl_ddb_min_alloc(const struct drm_plane_state *pstate,
> +		  const int y)
> +{
> +	struct drm_framebuffer *fb = pstate->fb;
> +	struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
> +	uint32_t src_w, src_h;
> +	uint32_t min_scanlines = 8;
> +	uint8_t plane_bpp;
> +
> +	if (WARN_ON(!fb))
> +		return 0;
> +
> +	/* For packed formats, no y-plane, return 0 */
> +	if (y && fb->pixel_format != DRM_FORMAT_NV12)
> +		return 0;
> +
> +	/* For Non Y-tile return 8-blocks */
> +	if (fb->modifier[0] != I915_FORMAT_MOD_Y_TILED &&
> +	    fb->modifier[0] != I915_FORMAT_MOD_Yf_TILED)
> +		return 8;
> +
> +	src_w = drm_rect_width(&intel_pstate->src) >> 16;
> +	src_h = drm_rect_height(&intel_pstate->src) >> 16;
> +
> +	if (intel_rotation_90_or_270(pstate->rotation))
> +		swap(src_w, src_h);
> +
> +	/* Halve UV plane width and height for NV12 */
> +	if (fb->pixel_format == DRM_FORMAT_NV12 && !y) {
> +		src_w /= 2;
> +		src_h /= 2;
> +	}
> +
> +	plane_bpp = y ? drm_format_plane_cpp(fb->pixel_format, 0) :
> +		drm_format_plane_cpp(fb->pixel_format, 1);
Here in case of y=0 we should call drm_format_plane_cpp with argument 0, 
(pixel formats which have number of plane 1)
else above function will return zero as plane BPP.

regards,
-Mahesh
> +
> +	if (intel_rotation_90_or_270(pstate->rotation)) {
> +		switch (plane_bpp) {
> +		case 1:
> +			min_scanlines = 32;
> +			break;
> +		case 2:
> +			min_scanlines = 16;
> +			break;
> +		case 4:
> +			min_scanlines = 8;
> +			break;
> +		case 8:
> +			min_scanlines = 4;
> +			break;
> +		default:
> +			WARN(1, "Unsupported pixel depth %u for rotation",
> +			     plane_bpp);
> +			min_scanlines = 32;
> +		}
> +	}
> +
> +	return DIV_ROUND_UP((4 * src_w * plane_bpp), 512) * min_scanlines/4 + 3;
> +}
> +
>   static int
>   skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>   		      struct skl_ddb_allocation *ddb /* out */)
> @@ -3104,11 +3165,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
>   			continue;
>   		}
>   
> -		minimum[id] = 8;
> -		if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
> -			y_minimum[id] = 8;
> -		else
> -			y_minimum[id] = 0;
> +		minimum[id] = skl_ddb_min_alloc(pstate, 0);
> +		y_minimum[id] = skl_ddb_min_alloc(pstate, 1);
>   	}
>   
>   	for (i = 0; i < PLANE_CURSOR; i++) {
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 3cf36dc..00b50bf 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3042,6 +3042,67 @@  skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate)
 	return total_data_rate;
 }
 
+static uint16_t
+skl_ddb_min_alloc(const struct drm_plane_state *pstate,
+		  const int y)
+{
+	struct drm_framebuffer *fb = pstate->fb;
+	struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
+	uint32_t src_w, src_h;
+	uint32_t min_scanlines = 8;
+	uint8_t plane_bpp;
+
+	if (WARN_ON(!fb))
+		return 0;
+
+	/* For packed formats, no y-plane, return 0 */
+	if (y && fb->pixel_format != DRM_FORMAT_NV12)
+		return 0;
+
+	/* For Non Y-tile return 8-blocks */
+	if (fb->modifier[0] != I915_FORMAT_MOD_Y_TILED &&
+	    fb->modifier[0] != I915_FORMAT_MOD_Yf_TILED)
+		return 8;
+
+	src_w = drm_rect_width(&intel_pstate->src) >> 16;
+	src_h = drm_rect_height(&intel_pstate->src) >> 16;
+
+	if (intel_rotation_90_or_270(pstate->rotation))
+		swap(src_w, src_h);
+
+	/* Halve UV plane width and height for NV12 */
+	if (fb->pixel_format == DRM_FORMAT_NV12 && !y) {
+		src_w /= 2;
+		src_h /= 2;
+	}
+
+	plane_bpp = y ? drm_format_plane_cpp(fb->pixel_format, 0) :
+		drm_format_plane_cpp(fb->pixel_format, 1);
+
+	if (intel_rotation_90_or_270(pstate->rotation)) {
+		switch (plane_bpp) {
+		case 1:
+			min_scanlines = 32;
+			break;
+		case 2:
+			min_scanlines = 16;
+			break;
+		case 4:
+			min_scanlines = 8;
+			break;
+		case 8:
+			min_scanlines = 4;
+			break;
+		default:
+			WARN(1, "Unsupported pixel depth %u for rotation",
+			     plane_bpp);
+			min_scanlines = 32;
+		}
+	}
+
+	return DIV_ROUND_UP((4 * src_w * plane_bpp), 512) * min_scanlines/4 + 3;
+}
+
 static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 		      struct skl_ddb_allocation *ddb /* out */)
@@ -3104,11 +3165,8 @@  skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
 			continue;
 		}
 
-		minimum[id] = 8;
-		if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
-			y_minimum[id] = 8;
-		else
-			y_minimum[id] = 0;
+		minimum[id] = skl_ddb_min_alloc(pstate, 0);
+		y_minimum[id] = skl_ddb_min_alloc(pstate, 1);
 	}
 
 	for (i = 0; i < PLANE_CURSOR; i++) {