Commit 0fda6568 authored by Tvrtko Ursulin's avatar Tvrtko Ursulin Committed by Daniel Vetter

drm/i915/skl: Update watermarks for Y tiling

Display watermarks need different programming for different tiling
modes.

Set the relevant flag so this happens during the plane commit and
add relevant data into a structure made available to the watermark
computation code.

v2: Pass in tiling info to sprite plane updates as well.
v3: Rebased for plane handling changes.
v4: Handle fb == NULL when plane is disabled.
v5: Refactored for addfb2 interface.
v6: Refactored for fb modifier changes.
v7: Updated for atomic commit by only updating watermarks when tiling changes.
v8: BSpec watermark calculation updates.
v9: Restrict scope of y_tile_minimum variable. (Damien Lespiau)
v10: Get fb from plane state otherwise we are working on old state.
Signed-off-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Acked-by: default avatarAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Acked-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> (v9)
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent d4c2aa60
...@@ -12005,6 +12005,12 @@ intel_check_primary_plane(struct drm_plane *plane, ...@@ -12005,6 +12005,12 @@ intel_check_primary_plane(struct drm_plane *plane,
INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe); INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe);
intel_crtc->atomic.update_fbc = true; intel_crtc->atomic.update_fbc = true;
/* Update watermarks on tiling changes. */
if (!plane->state->fb || !state->base.fb ||
plane->state->fb->modifier[0] !=
state->base.fb->modifier[0])
intel_crtc->atomic.update_wm = true;
} }
return 0; return 0;
......
...@@ -501,6 +501,7 @@ struct intel_plane_wm_parameters { ...@@ -501,6 +501,7 @@ struct intel_plane_wm_parameters {
uint8_t bytes_per_pixel; uint8_t bytes_per_pixel;
bool enabled; bool enabled;
bool scaled; bool scaled;
u64 tiling;
}; };
struct intel_plane { struct intel_plane {
......
...@@ -2617,7 +2617,7 @@ static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel, ...@@ -2617,7 +2617,7 @@ static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t bytes_per_pixel,
static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, 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 horiz_pixels, uint8_t bytes_per_pixel,
uint32_t latency) uint64_t tiling, uint32_t latency)
{ {
uint32_t ret; uint32_t ret;
uint32_t plane_bytes_per_line, plane_blocks_per_line; uint32_t plane_bytes_per_line, plane_blocks_per_line;
...@@ -2627,7 +2627,16 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal, ...@@ -2627,7 +2627,16 @@ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
return UINT_MAX; return UINT_MAX;
plane_bytes_per_line = horiz_pixels * bytes_per_pixel; plane_bytes_per_line = horiz_pixels * bytes_per_pixel;
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
if (tiling == I915_FORMAT_MOD_Y_TILED ||
tiling == I915_FORMAT_MOD_Yf_TILED) {
plane_bytes_per_line *= 4;
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
plane_blocks_per_line /= 4;
} else {
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
}
wm_intermediate_val = latency * pixel_rate; wm_intermediate_val = latency * pixel_rate;
ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) * ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
plane_blocks_per_line; plane_blocks_per_line;
...@@ -2679,6 +2688,7 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc, ...@@ -2679,6 +2688,7 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum pipe pipe = intel_crtc->pipe; enum pipe pipe = intel_crtc->pipe;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_framebuffer *fb;
int i = 1; /* Index for sprite planes start */ int i = 1; /* Index for sprite planes start */
p->active = intel_crtc_active(crtc); p->active = intel_crtc_active(crtc);
...@@ -2694,6 +2704,14 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc, ...@@ -2694,6 +2704,14 @@ static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
crtc->primary->fb->bits_per_pixel / 8; crtc->primary->fb->bits_per_pixel / 8;
p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w; p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h; p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
fb = crtc->primary->state->fb;
/*
* Framebuffer can be NULL on plane disable, but it does not
* matter for watermarks if we assume no tiling in that case.
*/
if (fb)
p->plane[0].tiling = fb->modifier[0];
p->cursor.enabled = true; p->cursor.enabled = true;
p->cursor.bytes_per_pixel = 4; p->cursor.bytes_per_pixel = 4;
...@@ -2734,23 +2752,34 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, ...@@ -2734,23 +2752,34 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
p->pipe_htotal, p->pipe_htotal,
p_params->horiz_pixels, p_params->horiz_pixels,
p_params->bytes_per_pixel, p_params->bytes_per_pixel,
p_params->tiling,
latency); latency);
plane_bytes_per_line = p_params->horiz_pixels * plane_bytes_per_line = p_params->horiz_pixels *
p_params->bytes_per_pixel; p_params->bytes_per_pixel;
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
/* For now xtile and linear */ if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
if ((ddb_allocation / plane_blocks_per_line) >= 1) p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
selected_result = min(method1, method2); uint32_t y_tile_minimum = plane_blocks_per_line * 4;
else selected_result = max(method2, y_tile_minimum);
selected_result = method1; } else {
if ((ddb_allocation / plane_blocks_per_line) >= 1)
selected_result = min(method1, method2);
else
selected_result = method1;
}
res_blocks = selected_result + 1; res_blocks = selected_result + 1;
res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line); res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
if (level >= 1 && level <= 7) if (level >= 1 && level <= 7) {
res_blocks++; if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
p_params->tiling == I915_FORMAT_MOD_Yf_TILED)
res_lines += 4;
else
res_blocks++;
}
if (res_blocks >= ddb_allocation || res_lines > 31) if (res_blocks >= ddb_allocation || res_lines > 31)
return false; return false;
...@@ -3179,12 +3208,20 @@ skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -3179,12 +3208,20 @@ skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
int pixel_size, bool enabled, bool scaled) int pixel_size, bool enabled, bool scaled)
{ {
struct intel_plane *intel_plane = to_intel_plane(plane); struct intel_plane *intel_plane = to_intel_plane(plane);
struct drm_framebuffer *fb = plane->state->fb;
intel_plane->wm.enabled = enabled; intel_plane->wm.enabled = enabled;
intel_plane->wm.scaled = scaled; intel_plane->wm.scaled = scaled;
intel_plane->wm.horiz_pixels = sprite_width; intel_plane->wm.horiz_pixels = sprite_width;
intel_plane->wm.vert_pixels = sprite_height; intel_plane->wm.vert_pixels = sprite_height;
intel_plane->wm.bytes_per_pixel = pixel_size; intel_plane->wm.bytes_per_pixel = pixel_size;
intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE;
/*
* Framebuffer can be NULL on plane disable, but it does not
* matter for watermarks if we assume no tiling in that case.
*/
if (fb)
intel_plane->wm.tiling = fb->modifier[0];
skl_update_wm(crtc); skl_update_wm(crtc);
} }
......
...@@ -1256,6 +1256,12 @@ intel_check_sprite_plane(struct drm_plane *plane, ...@@ -1256,6 +1256,12 @@ intel_check_sprite_plane(struct drm_plane *plane,
if (!intel_crtc->primary_enabled && !state->hides_primary) if (!intel_crtc->primary_enabled && !state->hides_primary)
intel_crtc->atomic.post_enable_primary = true; intel_crtc->atomic.post_enable_primary = true;
/* Update watermarks on tiling changes. */
if (!plane->state->fb || !state->base.fb ||
plane->state->fb->modifier[0] !=
state->base.fb->modifier[0])
intel_crtc->atomic.update_wm = true;
} }
return 0; return 0;
......
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