drm/i915/ivb: Move WaCxSRDisabledForSpriteScaling w/a to atomic check
Determine whether we need to apply this workaround at atomic check time and just set a flag that will be used by the main watermark update routine. Moving this workaround into the atomic framework reduces ilk_update_sprite_wm() to just a standard watermark update, so drop it completely and just ensure that ilk_update_wm() is called whenever a sprite plane is updated in a way that would affect watermarks. Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Smoke-tested-by: Paulo Zanoni <przanoni@gmail.com> Link: http://patchwork.freedesktop.org/patch/60367/
This commit is contained in:
parent
e4ba99b97e
commit
d21fbe87ce
|
@ -94,6 +94,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
|
|||
__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
|
||||
|
||||
crtc_state->update_pipe = false;
|
||||
crtc_state->disable_lp_wm = false;
|
||||
|
||||
return &crtc_state->base;
|
||||
}
|
||||
|
|
|
@ -11581,18 +11581,32 @@ retry:
|
|||
static bool intel_wm_need_update(struct drm_plane *plane,
|
||||
struct drm_plane_state *state)
|
||||
{
|
||||
/* Update watermarks on tiling changes. */
|
||||
struct intel_plane_state *new = to_intel_plane_state(state);
|
||||
struct intel_plane_state *cur = to_intel_plane_state(plane->state);
|
||||
|
||||
/* Update watermarks on tiling or size changes. */
|
||||
if (!plane->state->fb || !state->fb ||
|
||||
plane->state->fb->modifier[0] != state->fb->modifier[0] ||
|
||||
plane->state->rotation != state->rotation)
|
||||
return true;
|
||||
|
||||
if (plane->state->crtc_w != state->crtc_w)
|
||||
plane->state->rotation != state->rotation ||
|
||||
drm_rect_width(&new->src) != drm_rect_width(&cur->src) ||
|
||||
drm_rect_height(&new->src) != drm_rect_height(&cur->src) ||
|
||||
drm_rect_width(&new->dst) != drm_rect_width(&cur->dst) ||
|
||||
drm_rect_height(&new->dst) != drm_rect_height(&cur->dst))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool needs_scaling(struct intel_plane_state *state)
|
||||
{
|
||||
int src_w = drm_rect_width(&state->src) >> 16;
|
||||
int src_h = drm_rect_height(&state->src) >> 16;
|
||||
int dst_w = drm_rect_width(&state->dst);
|
||||
int dst_h = drm_rect_height(&state->dst);
|
||||
|
||||
return (src_w != dst_w || src_h != dst_h);
|
||||
}
|
||||
|
||||
int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
|
||||
struct drm_plane_state *plane_state)
|
||||
{
|
||||
|
@ -11608,7 +11622,6 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
|
|||
bool mode_changed = needs_modeset(crtc_state);
|
||||
bool was_crtc_enabled = crtc->state->active;
|
||||
bool is_crtc_enabled = crtc_state->active;
|
||||
|
||||
bool turn_off, turn_on, visible, was_visible;
|
||||
struct drm_framebuffer *fb = plane_state->fb;
|
||||
|
||||
|
@ -11718,11 +11731,23 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
|
|||
case DRM_PLANE_TYPE_CURSOR:
|
||||
break;
|
||||
case DRM_PLANE_TYPE_OVERLAY:
|
||||
if (turn_off && !mode_changed) {
|
||||
/*
|
||||
* WaCxSRDisabledForSpriteScaling:ivb
|
||||
*
|
||||
* cstate->update_wm was already set above, so this flag will
|
||||
* take effect when we commit and program watermarks.
|
||||
*/
|
||||
if (IS_IVYBRIDGE(dev) &&
|
||||
needs_scaling(to_intel_plane_state(plane_state)) &&
|
||||
!needs_scaling(old_plane_state)) {
|
||||
to_intel_crtc_state(crtc_state)->disable_lp_wm = true;
|
||||
} else if (turn_off && !mode_changed) {
|
||||
intel_crtc->atomic.wait_vblank = true;
|
||||
intel_crtc->atomic.update_sprite_watermarks |=
|
||||
1 << i;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -468,6 +468,9 @@ struct intel_crtc_state {
|
|||
|
||||
/* w/a for waiting 2 vblanks during crtc enable */
|
||||
enum pipe hsw_workaround_pipe;
|
||||
|
||||
/* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
|
||||
bool disable_lp_wm;
|
||||
};
|
||||
|
||||
struct vlv_wm_state {
|
||||
|
|
|
@ -3674,6 +3674,18 @@ static void ilk_update_wm(struct drm_crtc *crtc)
|
|||
|
||||
WARN_ON(cstate->base.active != intel_crtc->active);
|
||||
|
||||
/*
|
||||
* IVB workaround: must disable low power watermarks for at least
|
||||
* one frame before enabling scaling. LP watermarks can be re-enabled
|
||||
* when scaling is disabled.
|
||||
*
|
||||
* WaCxSRDisabledForSpriteScaling:ivb
|
||||
*/
|
||||
if (cstate->disable_lp_wm) {
|
||||
ilk_disable_lp_wm(dev);
|
||||
intel_wait_for_vblank(dev, intel_crtc->pipe);
|
||||
}
|
||||
|
||||
intel_compute_pipe_wm(cstate, &pipe_wm);
|
||||
|
||||
if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
|
||||
|
@ -3705,28 +3717,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
|
|||
ilk_write_wm_values(dev_priv, &results);
|
||||
}
|
||||
|
||||
static void
|
||||
ilk_update_sprite_wm(struct drm_plane *plane,
|
||||
struct drm_crtc *crtc,
|
||||
uint32_t sprite_width, uint32_t sprite_height,
|
||||
int pixel_size, bool enabled, bool scaled)
|
||||
{
|
||||
struct drm_device *dev = plane->dev;
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
|
||||
/*
|
||||
* IVB workaround: must disable low power watermarks for at least
|
||||
* one frame before enabling scaling. LP watermarks can be re-enabled
|
||||
* when scaling is disabled.
|
||||
*
|
||||
* WaCxSRDisabledForSpriteScaling:ivb
|
||||
*/
|
||||
if (IS_IVYBRIDGE(dev) && scaled && ilk_disable_lp_wm(dev))
|
||||
intel_wait_for_vblank(dev, intel_plane->pipe);
|
||||
|
||||
ilk_update_wm(crtc);
|
||||
}
|
||||
|
||||
static void skl_pipe_wm_active_state(uint32_t val,
|
||||
struct skl_pipe_wm *active,
|
||||
bool is_transwm,
|
||||
|
@ -7040,7 +7030,6 @@ void intel_init_pm(struct drm_device *dev)
|
|||
(!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
|
||||
dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
|
||||
dev_priv->display.update_wm = ilk_update_wm;
|
||||
dev_priv->display.update_sprite_wm = ilk_update_sprite_wm;
|
||||
} else {
|
||||
DRM_DEBUG_KMS("Failed to read display plane latency. "
|
||||
"Disable CxSR\n");
|
||||
|
|
Loading…
Reference in New Issue