Commit b879d58f authored by Mahesh Kumar's avatar Mahesh Kumar Committed by Maarten Lankhorst

drm/i915/skl+: refactor WM calculation for NV12

Current code calculates DDB for planar formats in such a way that we
store DDB of plane-0 in plane 1 & vice-versa.
In order to make this clean this patch refactors WM/DDB calculation for
NV12 planar formats.

v2: Addressed review comments by Maarten

v3: Rebased and addressed review comments by Maarten

v4: Fixed a compilation issue of string replacement is_nv12 to
is_planar

v5: Added reviewed by from Juha-Pekka Heikkila

v6: Rebased the series
Reviewed-by: default avatarJuha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Reviewed-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: default avatarMahesh Kumar <mahesh1.kumar@intel.com>
Signed-off-by: default avatarVidya Srinivas <vidya.srinivas@intel.com>
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1523245273-30264-3-git-send-email-vidya.srinivas@intel.com
parent 60f8e873
...@@ -1182,8 +1182,9 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1, ...@@ -1182,8 +1182,9 @@ static inline bool skl_ddb_entry_equal(const struct skl_ddb_entry *e1,
} }
struct skl_ddb_allocation { struct skl_ddb_allocation {
struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES]; /* packed/uv */ /* packed/y */
struct skl_ddb_entry y_plane[I915_MAX_PIPES][I915_MAX_PLANES]; struct skl_ddb_entry plane[I915_MAX_PIPES][I915_MAX_PLANES];
struct skl_ddb_entry uv_plane[I915_MAX_PIPES][I915_MAX_PLANES];
}; };
struct skl_ddb_values { struct skl_ddb_values {
......
...@@ -603,6 +603,7 @@ struct intel_pipe_wm { ...@@ -603,6 +603,7 @@ struct intel_pipe_wm {
struct skl_plane_wm { struct skl_plane_wm {
struct skl_wm_level wm[8]; struct skl_wm_level wm[8];
struct skl_wm_level trans_wm; struct skl_wm_level trans_wm;
bool is_planar;
}; };
struct skl_pipe_wm { struct skl_pipe_wm {
......
...@@ -4009,9 +4009,9 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, ...@@ -4009,9 +4009,9 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
static unsigned int static unsigned int
skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
const struct drm_plane_state *pstate, const struct drm_plane_state *pstate,
int y) const int plane)
{ {
struct intel_plane *plane = to_intel_plane(pstate->plane); struct intel_plane *intel_plane = to_intel_plane(pstate->plane);
struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
uint32_t data_rate; uint32_t data_rate;
uint32_t width = 0, height = 0; uint32_t width = 0, height = 0;
...@@ -4025,9 +4025,9 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, ...@@ -4025,9 +4025,9 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
fb = pstate->fb; fb = pstate->fb;
format = fb->format->format; format = fb->format->format;
if (plane->id == PLANE_CURSOR) if (intel_plane->id == PLANE_CURSOR)
return 0; return 0;
if (y && format != DRM_FORMAT_NV12) if (plane == 1 && format != DRM_FORMAT_NV12)
return 0; return 0;
/* /*
...@@ -4038,19 +4038,14 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, ...@@ -4038,19 +4038,14 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
width = drm_rect_width(&intel_pstate->base.src) >> 16; width = drm_rect_width(&intel_pstate->base.src) >> 16;
height = drm_rect_height(&intel_pstate->base.src) >> 16; height = drm_rect_height(&intel_pstate->base.src) >> 16;
/* for planar format */ /* UV plane does 1/2 pixel sub-sampling */
if (format == DRM_FORMAT_NV12) { if (plane == 1 && format == DRM_FORMAT_NV12) {
if (y) /* y-plane data rate */ width /= 2;
data_rate = width * height * height /= 2;
fb->format->cpp[0];
else /* uv-plane data rate */
data_rate = (width / 2) * (height / 2) *
fb->format->cpp[1];
} else {
/* for packed formats */
data_rate = width * height * fb->format->cpp[0];
} }
data_rate = width * height * fb->format->cpp[plane];
down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate); down_scale_amount = skl_plane_downscale_amount(cstate, intel_pstate);
return mul_round_up_u32_fixed16(data_rate, down_scale_amount); return mul_round_up_u32_fixed16(data_rate, down_scale_amount);
...@@ -4063,8 +4058,8 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, ...@@ -4063,8 +4058,8 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
*/ */
static unsigned int static unsigned int
skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate, skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
unsigned *plane_data_rate, unsigned int *plane_data_rate,
unsigned *plane_y_data_rate) unsigned int *uv_plane_data_rate)
{ {
struct drm_crtc_state *cstate = &intel_cstate->base; struct drm_crtc_state *cstate = &intel_cstate->base;
struct drm_atomic_state *state = cstate->state; struct drm_atomic_state *state = cstate->state;
...@@ -4080,17 +4075,17 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate, ...@@ -4080,17 +4075,17 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
enum plane_id plane_id = to_intel_plane(plane)->id; enum plane_id plane_id = to_intel_plane(plane)->id;
unsigned int rate; unsigned int rate;
/* packed/uv */ /* packed/y */
rate = skl_plane_relative_data_rate(intel_cstate, rate = skl_plane_relative_data_rate(intel_cstate,
pstate, 0); pstate, 0);
plane_data_rate[plane_id] = rate; plane_data_rate[plane_id] = rate;
total_data_rate += rate; total_data_rate += rate;
/* y-plane */ /* uv-plane */
rate = skl_plane_relative_data_rate(intel_cstate, rate = skl_plane_relative_data_rate(intel_cstate,
pstate, 1); pstate, 1);
plane_y_data_rate[plane_id] = rate; uv_plane_data_rate[plane_id] = rate;
total_data_rate += rate; total_data_rate += rate;
} }
...@@ -4099,8 +4094,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate, ...@@ -4099,8 +4094,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate,
} }
static uint16_t static uint16_t
skl_ddb_min_alloc(const struct drm_plane_state *pstate, skl_ddb_min_alloc(const struct drm_plane_state *pstate, const int plane)
const int y)
{ {
struct drm_framebuffer *fb = pstate->fb; struct drm_framebuffer *fb = pstate->fb;
struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate);
...@@ -4111,8 +4105,8 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate, ...@@ -4111,8 +4105,8 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
if (WARN_ON(!fb)) if (WARN_ON(!fb))
return 0; return 0;
/* For packed formats, no y-plane, return 0 */ /* For packed formats, and uv-plane, return 0 */
if (y && fb->format->format != DRM_FORMAT_NV12) if (plane == 1 && fb->format->format != DRM_FORMAT_NV12)
return 0; return 0;
/* For Non Y-tile return 8-blocks */ /* For Non Y-tile return 8-blocks */
...@@ -4131,15 +4125,12 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate, ...@@ -4131,15 +4125,12 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
src_h = drm_rect_height(&intel_pstate->base.src) >> 16; src_h = drm_rect_height(&intel_pstate->base.src) >> 16;
/* Halve UV plane width and height for NV12 */ /* Halve UV plane width and height for NV12 */
if (fb->format->format == DRM_FORMAT_NV12 && !y) { if (plane == 1) {
src_w /= 2; src_w /= 2;
src_h /= 2; src_h /= 2;
} }
if (fb->format->format == DRM_FORMAT_NV12 && !y) plane_bpp = fb->format->cpp[plane];
plane_bpp = fb->format->cpp[1];
else
plane_bpp = fb->format->cpp[0];
if (drm_rotation_90_or_270(pstate->rotation)) { if (drm_rotation_90_or_270(pstate->rotation)) {
switch (plane_bpp) { switch (plane_bpp) {
...@@ -4167,7 +4158,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate, ...@@ -4167,7 +4158,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate,
static void static void
skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active, skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active,
uint16_t *minimum, uint16_t *y_minimum) uint16_t *minimum, uint16_t *uv_minimum)
{ {
const struct drm_plane_state *pstate; const struct drm_plane_state *pstate;
struct drm_plane *plane; struct drm_plane *plane;
...@@ -4182,7 +4173,7 @@ skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active, ...@@ -4182,7 +4173,7 @@ skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active,
continue; continue;
minimum[plane_id] = skl_ddb_min_alloc(pstate, 0); minimum[plane_id] = skl_ddb_min_alloc(pstate, 0);
y_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1); uv_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1);
} }
minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active); minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active);
...@@ -4200,17 +4191,17 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, ...@@ -4200,17 +4191,17 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb; struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb;
uint16_t alloc_size, start; uint16_t alloc_size, start;
uint16_t minimum[I915_MAX_PLANES] = {}; uint16_t minimum[I915_MAX_PLANES] = {};
uint16_t y_minimum[I915_MAX_PLANES] = {}; uint16_t uv_minimum[I915_MAX_PLANES] = {};
unsigned int total_data_rate; unsigned int total_data_rate;
enum plane_id plane_id; enum plane_id plane_id;
int num_active; int num_active;
unsigned plane_data_rate[I915_MAX_PLANES] = {}; unsigned int plane_data_rate[I915_MAX_PLANES] = {};
unsigned plane_y_data_rate[I915_MAX_PLANES] = {}; unsigned int uv_plane_data_rate[I915_MAX_PLANES] = {};
uint16_t total_min_blocks = 0; uint16_t total_min_blocks = 0;
/* Clear the partitioning for disabled planes. */ /* Clear the partitioning for disabled planes. */
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe])); memset(ddb->uv_plane[pipe], 0, sizeof(ddb->uv_plane[pipe]));
if (WARN_ON(!state)) if (WARN_ON(!state))
return 0; return 0;
...@@ -4225,7 +4216,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, ...@@ -4225,7 +4216,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
if (alloc_size == 0) if (alloc_size == 0)
return 0; return 0;
skl_ddb_calc_min(cstate, num_active, minimum, y_minimum); skl_ddb_calc_min(cstate, num_active, minimum, uv_minimum);
/* /*
* 1. Allocate the mininum required blocks for each active plane * 1. Allocate the mininum required blocks for each active plane
...@@ -4235,7 +4226,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, ...@@ -4235,7 +4226,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
for_each_plane_id_on_crtc(intel_crtc, plane_id) { for_each_plane_id_on_crtc(intel_crtc, plane_id) {
total_min_blocks += minimum[plane_id]; total_min_blocks += minimum[plane_id];
total_min_blocks += y_minimum[plane_id]; total_min_blocks += uv_minimum[plane_id];
} }
if (total_min_blocks > alloc_size) { if (total_min_blocks > alloc_size) {
...@@ -4257,14 +4248,14 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, ...@@ -4257,14 +4248,14 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
*/ */
total_data_rate = skl_get_total_relative_data_rate(cstate, total_data_rate = skl_get_total_relative_data_rate(cstate,
plane_data_rate, plane_data_rate,
plane_y_data_rate); uv_plane_data_rate);
if (total_data_rate == 0) if (total_data_rate == 0)
return 0; return 0;
start = alloc->start; start = alloc->start;
for_each_plane_id_on_crtc(intel_crtc, plane_id) { for_each_plane_id_on_crtc(intel_crtc, plane_id) {
unsigned int data_rate, y_data_rate; unsigned int data_rate, uv_data_rate;
uint16_t plane_blocks, y_plane_blocks = 0; uint16_t plane_blocks, uv_plane_blocks;
if (plane_id == PLANE_CURSOR) if (plane_id == PLANE_CURSOR)
continue; continue;
...@@ -4288,21 +4279,20 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, ...@@ -4288,21 +4279,20 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
start += plane_blocks; start += plane_blocks;
/* /* Allocate DDB for UV plane for planar format/NV12 */
* allocation for y_plane part of planar format: uv_data_rate = uv_plane_data_rate[plane_id];
*/
y_data_rate = plane_y_data_rate[plane_id];
y_plane_blocks = y_minimum[plane_id]; uv_plane_blocks = uv_minimum[plane_id];
y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, uv_plane_blocks += div_u64((uint64_t)alloc_size * uv_data_rate,
total_data_rate); total_data_rate);
if (y_data_rate) { if (uv_data_rate) {
ddb->y_plane[pipe][plane_id].start = start; ddb->uv_plane[pipe][plane_id].start = start;
ddb->y_plane[pipe][plane_id].end = start + y_plane_blocks; ddb->uv_plane[pipe][plane_id].end =
start + uv_plane_blocks;
} }
start += y_plane_blocks; start += uv_plane_blocks;
} }
return 0; return 0;
...@@ -4430,8 +4420,7 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv, ...@@ -4430,8 +4420,7 @@ skl_compute_plane_wm_params(const struct drm_i915_private *dev_priv,
wp->width = drm_rect_width(&intel_pstate->base.src) >> 16; wp->width = drm_rect_width(&intel_pstate->base.src) >> 16;
} }
wp->cpp = (fb->format->format == DRM_FORMAT_NV12) ? fb->format->cpp[1] : wp->cpp = fb->format->cpp[0];
fb->format->cpp[0];
wp->plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, wp->plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate,
intel_pstate); intel_pstate);
...@@ -4660,6 +4649,9 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv, ...@@ -4660,6 +4649,9 @@ skl_compute_wm_levels(const struct drm_i915_private *dev_priv,
return ret; return ret;
} }
if (intel_pstate->base.fb->format->format == DRM_FORMAT_NV12)
wm->is_planar = true;
return 0; return 0;
} }
...@@ -4833,10 +4825,21 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc, ...@@ -4833,10 +4825,21 @@ static void skl_write_plane_wm(struct intel_crtc *intel_crtc,
skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id), skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
&ddb->plane[pipe][plane_id]); &ddb->plane[pipe][plane_id]);
if (INTEL_GEN(dev_priv) < 11) if (INTEL_GEN(dev_priv) >= 11)
return skl_ddb_entry_write(dev_priv,
PLANE_BUF_CFG(pipe, plane_id),
&ddb->plane[pipe][plane_id]);
if (wm->is_planar) {
skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
&ddb->uv_plane[pipe][plane_id]);
skl_ddb_entry_write(dev_priv, skl_ddb_entry_write(dev_priv,
PLANE_NV12_BUF_CFG(pipe, plane_id), PLANE_NV12_BUF_CFG(pipe, plane_id),
&ddb->y_plane[pipe][plane_id]); &ddb->plane[pipe][plane_id]);
} else {
skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane_id),
&ddb->plane[pipe][plane_id]);
I915_WRITE(PLANE_NV12_BUF_CFG(pipe, plane_id), 0x0);
}
} }
static void skl_write_cursor_wm(struct intel_crtc *intel_crtc, static void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
...@@ -4951,8 +4954,8 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate) ...@@ -4951,8 +4954,8 @@ skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id], if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][plane_id],
&new_ddb->plane[pipe][plane_id]) && &new_ddb->plane[pipe][plane_id]) &&
skl_ddb_entry_equal(&cur_ddb->y_plane[pipe][plane_id], skl_ddb_entry_equal(&cur_ddb->uv_plane[pipe][plane_id],
&new_ddb->y_plane[pipe][plane_id])) &new_ddb->uv_plane[pipe][plane_id]))
continue; continue;
plane_state = drm_atomic_get_plane_state(state, plane); plane_state = drm_atomic_get_plane_state(state, plane);
...@@ -5046,8 +5049,8 @@ skl_copy_ddb_for_pipe(struct skl_ddb_values *dst, ...@@ -5046,8 +5049,8 @@ skl_copy_ddb_for_pipe(struct skl_ddb_values *dst,
struct skl_ddb_values *src, struct skl_ddb_values *src,
enum pipe pipe) enum pipe pipe)
{ {
memcpy(dst->ddb.y_plane[pipe], src->ddb.y_plane[pipe], memcpy(dst->ddb.uv_plane[pipe], src->ddb.uv_plane[pipe],
sizeof(dst->ddb.y_plane[pipe])); sizeof(dst->ddb.uv_plane[pipe]));
memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe], memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe],
sizeof(dst->ddb.plane[pipe])); sizeof(dst->ddb.plane[pipe]));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment