[PATCH 4.2.y-ckt 085/305] drm/i915: Mark uneven memory banks on gen4 desktop as unknown swizzling

From: Kamal Mostafa
Date: Fri Jan 15 2016 - 20:17:11 EST


4.2.8-ckt2 -stable review patch. If anyone has any objections, please let me know.

---8<------------------------------------------------------------

From: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>

commit 0b466dc238cb660bbdb9ef6e121e1757057484c3 upstream.

We have varied reports of swizzling corruption on gen4 desktop, and
confirmation that one at least is triggered by uneven memory banks
(L-shaped memory). The implication is that the swizzling varies between
the paired channels and the remainder of memory on the single channel. As
the object then has unpredictable swizzling (it will vary depending on
exact page allocation and may even change during the object's lifetime as
the pages are replaced), we have to report to userspace that the swizzling
is unknown.

However, some existing userspace is buggy when it meets an unknown
swizzling configuration and so we need to tell another white lie and
mark the swizzling as NONE but report it as UNKNOWN through the extended
get-tiling-ioctl. See

commit 5eb3e5a5e11d14f9deb2a4b83555443b69ab9940
Author: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Date: Sun Jun 28 09:19:26 2015 +0100

drm/i915: Declare the swizzling unknown for L-shaped configurations

for the previous example where we found that telling the truth to
userspace just ends up in a world of hurt.

Also since we don't truly know what the swizzling is on the pages, we
need to keep them pinned to prevent swapping as the reports also
suggest that some gen4 devices have previously undetected bit17
swizzling.

v2: Combine unknown + quirk patches to prevent userspace ever seeing
unknown swizzling through the normal get-tiling-ioctl. Also use the same
path for the existing uneven bank detection for mobile gen4.

Reported-by: Matti HÃmÃlÃinen <ccr@xxxxxxxx>
Tested-by: Matti HÃmÃlÃinen <ccr@xxxxxxxx>
References: https://bugs.freedesktop.org/show_bug.cgi?id=90725
Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Cc: Matti HÃmÃlÃinen <ccr@xxxxxxxx>
Cc: Daniel Vetter <daniel.vetter@xxxxxxxx>
Cc: Jani Nikula <jani.nikula@xxxxxxxxx>
Reviewed-by: Daniel Vetter <daniel.vetter@xxxxxxxx>
Link: http://patchwork.freedesktop.org/patch/msgid/1447927085-31726-1-git-send-email-chris@xxxxxxxxxxxxxxxxxx
Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx>
[ kamal: backport to 4.2-stable: applied to i915_gem_tiling.c ]
Signed-off-by: Kamal Mostafa <kamal@xxxxxxxxxxxxx>
---
drivers/gpu/drm/i915/i915_gem_tiling.c | 36 +++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index d19c9db..f19bd4f 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -180,11 +180,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
}

/* check for L-shaped memory aka modified enhanced addressing */
- if (IS_GEN4(dev)) {
- uint32_t ddc2 = I915_READ(DCC2);
-
- if (!(ddc2 & DCC2_MODIFIED_ENHANCED_DISABLE))
- dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
+ if (IS_GEN4(dev) &&
+ !(I915_READ(DCC2) & DCC2_MODIFIED_ENHANCED_DISABLE)) {
+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
}

if (dcc == 0xffffffff) {
@@ -213,16 +212,35 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
* matching, which was the case for the swizzling required in
* the table above, or from the 1-ch value being less than
* the minimum size of a rank.
+ *
+ * Reports indicate that the swizzling actually
+ * varies depending upon page placement inside the
+ * channels, i.e. we see swizzled pages where the
+ * banks of memory are paired and unswizzled on the
+ * uneven portion, so leave that as unknown.
*/
- if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
- swizzle_x = I915_BIT_6_SWIZZLE_NONE;
- swizzle_y = I915_BIT_6_SWIZZLE_NONE;
- } else {
+ if (I915_READ16(C0DRB3) == I915_READ16(C1DRB3)) {
swizzle_x = I915_BIT_6_SWIZZLE_9_10;
swizzle_y = I915_BIT_6_SWIZZLE_9;
}
}

+ if (swizzle_x == I915_BIT_6_SWIZZLE_UNKNOWN ||
+ swizzle_y == I915_BIT_6_SWIZZLE_UNKNOWN) {
+ /* Userspace likes to explode if it sees unknown swizzling,
+ * so lie. We will finish the lie when reporting through
+ * the get-tiling-ioctl by reporting the physical swizzle
+ * mode as unknown instead.
+ *
+ * As we don't strictly know what the swizzling is, it may be
+ * bit17 dependent, and so we need to also prevent the pages
+ * from being moved.
+ */
+ dev_priv->quirks |= QUIRK_PIN_SWIZZLED_PAGES;
+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+ }
+
dev_priv->mm.bit_6_swizzle_x = swizzle_x;
dev_priv->mm.bit_6_swizzle_y = swizzle_y;
}
--
1.9.1