drm/i915: Eliminate usage of plane_wm_parameters from ILK-style WM code (v2)

Just pull the info out of the plane state structure rather than staging
it in an additional structure.

v2: Add 'visible' condition to sprites_scaled so that we don't limit the
    WM level when the sprite isn't enabled.  (Ville)

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by(v1): Ander Conselvan de Oliveira <conselvan2@gmail.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Matt Roper 2015-09-24 15:53:07 -07:00 committed by Daniel Vetter
parent 37d9078b9b
commit 43d59eda1f

View file

@ -1777,9 +1777,6 @@ struct ilk_pipe_wm_parameters {
bool active; bool active;
uint32_t pipe_htotal; uint32_t pipe_htotal;
uint32_t pixel_rate; uint32_t pixel_rate;
struct intel_plane_wm_parameters pri;
struct intel_plane_wm_parameters spr;
struct intel_plane_wm_parameters cur;
}; };
struct ilk_wm_maximums { struct ilk_wm_maximums {
@ -1801,25 +1798,25 @@ struct intel_wm_config {
* mem_value must be in 0.1us units. * mem_value must be in 0.1us units.
*/ */
static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params, static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
const struct intel_plane_state *pstate,
uint32_t mem_value, uint32_t mem_value,
bool is_lp) bool is_lp)
{ {
int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
uint32_t method1, method2; uint32_t method1, method2;
if (!params->active || !params->pri.enabled) if (!params->active || !pstate->visible)
return 0; return 0;
method1 = ilk_wm_method1(params->pixel_rate, method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
params->pri.bytes_per_pixel,
mem_value);
if (!is_lp) if (!is_lp)
return method1; return method1;
method2 = ilk_wm_method2(params->pixel_rate, method2 = ilk_wm_method2(params->pixel_rate,
params->pipe_htotal, params->pipe_htotal,
params->pri.horiz_pixels, drm_rect_width(&pstate->dst),
params->pri.bytes_per_pixel, bpp,
mem_value); mem_value);
return min(method1, method2); return min(method1, method2);
@ -1830,20 +1827,20 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
* mem_value must be in 0.1us units. * mem_value must be in 0.1us units.
*/ */
static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params, static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
const struct intel_plane_state *pstate,
uint32_t mem_value) uint32_t mem_value)
{ {
int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
uint32_t method1, method2; uint32_t method1, method2;
if (!params->active || !params->spr.enabled) if (!params->active || !pstate->visible)
return 0; return 0;
method1 = ilk_wm_method1(params->pixel_rate, method1 = ilk_wm_method1(params->pixel_rate, bpp, mem_value);
params->spr.bytes_per_pixel,
mem_value);
method2 = ilk_wm_method2(params->pixel_rate, method2 = ilk_wm_method2(params->pixel_rate,
params->pipe_htotal, params->pipe_htotal,
params->spr.horiz_pixels, drm_rect_width(&pstate->dst),
params->spr.bytes_per_pixel, bpp,
mem_value); mem_value);
return min(method1, method2); return min(method1, method2);
} }
@ -1853,28 +1850,32 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
* mem_value must be in 0.1us units. * mem_value must be in 0.1us units.
*/ */
static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params, static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
const struct intel_plane_state *pstate,
uint32_t mem_value) uint32_t mem_value)
{ {
if (!params->active || !params->cur.enabled) int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
if (!params->active || !pstate->visible)
return 0; return 0;
return ilk_wm_method2(params->pixel_rate, return ilk_wm_method2(params->pixel_rate,
params->pipe_htotal, params->pipe_htotal,
params->cur.horiz_pixels, drm_rect_width(&pstate->dst),
params->cur.bytes_per_pixel, bpp,
mem_value); mem_value);
} }
/* Only for WM_LP. */ /* Only for WM_LP. */
static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params, static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
const struct intel_plane_state *pstate,
uint32_t pri_val) uint32_t pri_val)
{ {
if (!params->active || !params->pri.enabled) int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
if (!params->active || !pstate->visible)
return 0; return 0;
return ilk_wm_fbc(pri_val, return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
params->pri.horiz_pixels,
params->pri.bytes_per_pixel);
} }
static unsigned int ilk_display_fifo_size(const struct drm_device *dev) static unsigned int ilk_display_fifo_size(const struct drm_device *dev)
@ -2039,10 +2040,12 @@ static bool ilk_validate_wm_level(int level,
} }
static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
const struct intel_crtc *intel_crtc,
int level, int level,
const struct ilk_pipe_wm_parameters *p, const struct ilk_pipe_wm_parameters *p,
struct intel_wm_level *result) struct intel_wm_level *result)
{ {
struct intel_plane *intel_plane;
uint16_t pri_latency = dev_priv->wm.pri_latency[level]; uint16_t pri_latency = dev_priv->wm.pri_latency[level];
uint16_t spr_latency = dev_priv->wm.spr_latency[level]; uint16_t spr_latency = dev_priv->wm.spr_latency[level];
uint16_t cur_latency = dev_priv->wm.cur_latency[level]; uint16_t cur_latency = dev_priv->wm.cur_latency[level];
@ -2054,10 +2057,29 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
cur_latency *= 5; cur_latency *= 5;
} }
result->pri_val = ilk_compute_pri_wm(p, pri_latency, level); for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) {
result->spr_val = ilk_compute_spr_wm(p, spr_latency); struct intel_plane_state *pstate =
result->cur_val = ilk_compute_cur_wm(p, cur_latency); to_intel_plane_state(intel_plane->base.state);
result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val);
switch (intel_plane->base.type) {
case DRM_PLANE_TYPE_PRIMARY:
result->pri_val = ilk_compute_pri_wm(p, pstate,
pri_latency,
level);
result->fbc_val = ilk_compute_fbc_wm(p, pstate,
result->pri_val);
break;
case DRM_PLANE_TYPE_OVERLAY:
result->spr_val = ilk_compute_spr_wm(p, pstate,
spr_latency);
break;
case DRM_PLANE_TYPE_CURSOR:
result->cur_val = ilk_compute_cur_wm(p, pstate,
cur_latency);
break;
}
}
result->enable = true; result->enable = true;
} }
@ -2319,10 +2341,7 @@ static void skl_setup_wm_latency(struct drm_device *dev)
static void ilk_compute_wm_parameters(struct drm_crtc *crtc, static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
struct ilk_pipe_wm_parameters *p) struct ilk_pipe_wm_parameters *p)
{ {
struct drm_device *dev = crtc->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
enum pipe pipe = intel_crtc->pipe;
struct drm_plane *plane;
if (!intel_crtc->active) if (!intel_crtc->active)
return; return;
@ -2330,32 +2349,6 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
p->active = true; p->active = true;
p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal; p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config); p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
if (crtc->primary->state->fb)
p->pri.bytes_per_pixel =
crtc->primary->state->fb->bits_per_pixel / 8;
else
p->pri.bytes_per_pixel = 4;
p->cur.bytes_per_pixel = 4;
/*
* TODO: for now, assume primary and cursor planes are always enabled.
* Setting them to false makes the screen flicker.
*/
p->pri.enabled = true;
p->cur.enabled = true;
p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w;
drm_for_each_legacy_plane(plane, dev) {
struct intel_plane *intel_plane = to_intel_plane(plane);
if (intel_plane->pipe == pipe) {
p->spr = intel_plane->wm;
break;
}
}
} }
static void ilk_compute_wm_config(struct drm_device *dev, static void ilk_compute_wm_config(struct drm_device *dev,
@ -2383,28 +2376,42 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
const struct drm_i915_private *dev_priv = dev->dev_private; const struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane;
struct intel_plane_state *sprstate = NULL;
int level, max_level = ilk_wm_max_level(dev); int level, max_level = ilk_wm_max_level(dev);
/* LP0 watermark maximums depend on this pipe alone */ /* LP0 watermark maximums depend on this pipe alone */
struct intel_wm_config config = { struct intel_wm_config config = {
.num_pipes_active = 1, .num_pipes_active = 1,
.sprites_enabled = params->spr.enabled,
.sprites_scaled = params->spr.scaled,
}; };
struct ilk_wm_maximums max; struct ilk_wm_maximums max;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
sprstate = to_intel_plane_state(intel_plane->base.state);
break;
}
}
config.sprites_enabled = sprstate->visible;
config.sprites_scaled = sprstate->visible &&
(drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16);
pipe_wm->pipe_enabled = params->active; pipe_wm->pipe_enabled = params->active;
pipe_wm->sprites_enabled = params->spr.enabled; pipe_wm->sprites_enabled = sprstate->visible;
pipe_wm->sprites_scaled = params->spr.scaled; pipe_wm->sprites_scaled = config.sprites_scaled;
/* ILK/SNB: LP2+ watermarks only w/o sprites */ /* ILK/SNB: LP2+ watermarks only w/o sprites */
if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled) if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)
max_level = 1; max_level = 1;
/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */
if (params->spr.scaled) if (config.sprites_scaled)
max_level = 0; max_level = 0;
ilk_compute_wm_level(dev_priv, 0, params, &pipe_wm->wm[0]); ilk_compute_wm_level(dev_priv, intel_crtc, 0, params, &pipe_wm->wm[0]);
if (IS_HASWELL(dev) || IS_BROADWELL(dev)) if (IS_HASWELL(dev) || IS_BROADWELL(dev))
pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc); pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
@ -2421,7 +2428,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
for (level = 1; level <= max_level; level++) { for (level = 1; level <= max_level; level++) {
struct intel_wm_level wm = {}; struct intel_wm_level wm = {};
ilk_compute_wm_level(dev_priv, level, params, &wm); ilk_compute_wm_level(dev_priv, intel_crtc, level, params, &wm);
/* /*
* Disable any watermark level that exceeds the * Disable any watermark level that exceeds the