drm/i915: Disallow plane x+w>stride on ilk+ with X-tiling
ilk+ planes get notably unhappy when the plane x+w exceeds the stride. This wasn't a problem previously because we always aligned SURF to the closest tile boundary so the x offset never got particularly large. But now with async flips we have to align to 256KiB instead and thus this becomes a real issue. On ilk/snb/ivb it looks like the accesses just wrap early to the next tile row when scanout goes past the SURF+n*stride boundary, hsw/bdw suffer more heavily and start to underrun constantly. i965/g4x appear to be immune. vlv/chv I've not yet checked. Let's borrow another trick from the skl+ code and search backwards for a better SURF offset in the hopes of getting the x offset below the limit. IIRC when I ran into a similar issue on skl years ago it was causing the hardware to fall over pretty hard as well. And let's be consistent and include i965/g4x in the check as well, just in case I just got super lucky somehow when I wasn't able to reproduce the issue. Not that it really matters since we still use 4k SURF alignment for i965/g4x anyway. Fixes:6ede6b0616
("drm/i915: Implement async flips for vlv/chv") Fixes:4bb18054ad
("drm/i915: Implement async flip for ilk/snb") Fixes:2a636e240c
("drm/i915: Implement async flip for ivb/hsw") Fixes:cda195f13a
("drm/i915: Implement async flips for bdw") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210209021918.16234-1-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
f48993e5d2
commit
59fb8218c8
@ -255,6 +255,33 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
|
||||
else
|
||||
offset = 0;
|
||||
|
||||
/*
|
||||
* When using an X-tiled surface the plane starts to
|
||||
* misbehave if the x offset + width exceeds the stride.
|
||||
* hsw/bdw: underrun galore
|
||||
* ilk/snb/ivb: wrap to the next tile row mid scanout
|
||||
* i965/g4x: so far appear immune to this
|
||||
* vlv/chv: TODO check
|
||||
*
|
||||
* Linear surfaces seem to work just fine, even on hsw/bdw
|
||||
* despite them not using the linear offset anymore.
|
||||
*/
|
||||
if (INTEL_GEN(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
|
||||
u32 alignment = intel_surf_alignment(fb, 0);
|
||||
int cpp = fb->format->cpp[0];
|
||||
|
||||
while ((src_x + src_w) * cpp > plane_state->color_plane[0].stride) {
|
||||
if (offset == 0) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Unable to find suitable display surface offset due to X-tiling\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
offset = intel_plane_adjust_aligned_offset(&src_x, &src_y, plane_state, 0,
|
||||
offset, offset - alignment);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the final coordinates back so that the src
|
||||
* coordinate checks will see the right values.
|
||||
|
Loading…
Reference in New Issue
Block a user