Skip to content

Commit

Permalink
drm/i915/skl+: calculate ddb minimum allocation (v6)
Browse files Browse the repository at this point in the history
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).

v6 (by Matt):
 - Calculate plane_bpp correctly for non-NV12 formats. (Mahesh)

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>
Reviewed-by: Kumar Mahesh <mahesh1.kumar@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1464713939-10440-1-git-send-email-matthew.d.roper@intel.com
  • Loading branch information
Kumar, Mahesh authored and Matt Roper committed Jun 1, 2016
1 parent edd4156 commit cbcfd14
Showing 1 changed file with 65 additions and 5 deletions.
70 changes: 65 additions & 5 deletions drivers/gpu/drm/i915/intel_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3042,6 +3042,69 @@ 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;
}

if (fb->pixel_format == DRM_FORMAT_NV12 && !y)
plane_bpp = drm_format_plane_cpp(fb->pixel_format, 1);
else
plane_bpp = drm_format_plane_cpp(fb->pixel_format, 0);

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 */)
Expand Down Expand Up @@ -3104,11 +3167,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++) {
Expand Down

0 comments on commit cbcfd14

Please sign in to comment.