drm/i915: Try to fix the messy IVB sprite scaling workaround
We now have a very clear method of disabling LP1+ wartermarks, and we can actually detect if we actually did disable them, or if they were already disabled. Use that to clean up the WaCxSRDisabledForSpriteScaling:ivb handling. I was hoping to apply the workaround in a way that wouldn't require a blocking wait, but sadly IVB really does appear to require LP1+ watermarks to be off for an entire frame before enabling sprite scaling. Simply disabling LP1+ watermarks during the previous frame is not enough, no matter how early in the frame we do it :( Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:

committed by
Daniel Vetter

parent
96f90c5421
commit
8553c18ea6
@@ -230,7 +230,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
u32 sprctl, sprscale = 0;
|
||||
unsigned long sprsurf_offset, linear_offset;
|
||||
int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
|
||||
bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
|
||||
|
||||
sprctl = I915_READ(SPRCTL(pipe));
|
||||
|
||||
@@ -291,21 +290,8 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
crtc_w--;
|
||||
crtc_h--;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (crtc_w != src_w || crtc_h != src_h) {
|
||||
dev_priv->sprite_scaling_enabled |= 1 << pipe;
|
||||
|
||||
if (!scaling_was_enabled) {
|
||||
intel_update_watermarks(crtc);
|
||||
intel_wait_for_vblank(dev, pipe);
|
||||
}
|
||||
if (crtc_w != src_w || crtc_h != src_h)
|
||||
sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
|
||||
} else
|
||||
dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
|
||||
|
||||
I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
|
||||
I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
|
||||
@@ -332,10 +318,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
I915_MODIFY_DISPBASE(SPRSURF(pipe),
|
||||
i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
|
||||
POSTING_READ(SPRSURF(pipe));
|
||||
|
||||
/* potentially re-enable LP watermarks */
|
||||
if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
|
||||
intel_update_watermarks(crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -345,7 +327,6 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_plane *intel_plane = to_intel_plane(plane);
|
||||
int pipe = intel_plane->pipe;
|
||||
bool scaling_was_enabled = dev_priv->sprite_scaling_enabled;
|
||||
|
||||
I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
|
||||
/* Can't leave the scaler enabled... */
|
||||
@@ -355,13 +336,7 @@ ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
|
||||
I915_MODIFY_DISPBASE(SPRSURF(pipe), 0);
|
||||
POSTING_READ(SPRSURF(pipe));
|
||||
|
||||
dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
|
||||
|
||||
intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false);
|
||||
|
||||
/* potentially re-enable LP watermarks */
|
||||
if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled)
|
||||
intel_update_watermarks(crtc);
|
||||
}
|
||||
|
||||
static int
|
||||
|
Reference in New Issue
Block a user