Skip to content

Commit 59fe122

Browse files
vsyrjalamehmetb0
authored andcommitted
drm/i915/color: Stop using non-posted DSB writes for legacy LUT
BugLink: https://bugs.launchpad.net/bugs/2102181 commit cd3da56 upstream. DSB LUT register writes vs. palette anti-collision logic appear to interact in interesting ways: - posted DSB writes simply vanish into thin air while anti-collision is active - non-posted DSB writes actually get blocked by the anti-collision logic, but unfortunately this ends up hogging the bus for long enough that unrelated parallel CPU MMIO accesses start to disappear instead Even though we are updating the LUT during vblank we aren't immune to the anti-collision logic because it kicks in briefly for pipe prefill (initiated at frame start). The safe time window for performing the LUT update is thus between the undelayed vblank and frame start. Turns out that with low enough CDCLK frequency (DSB execution speed depends on CDCLK) we can exceed that. As we are currently using non-posted writes for the legacy LUT updates, in which case we can hit the far more severe failure mode. The problem is exacerbated by the fact that non-posted writes are much slower than posted writes (~4x it seems). To mititage the problem let's switch to using posted DSB writes for legacy LUT updates (which will involve using the double write approach to avoid other problems with DSB vs. legacy LUT writes). Despite writing each register twice this will in fact make the legacy LUT update faster when compared to the non-posted write approach, making the problem less likely to appear. The failure mode is also less severe. This isn't the 100% solution we need though. That will involve estimating how long the LUT update will take, and pushing frame start and/or delayed vblank forward to guarantee that the update will have finished by the time the pipe prefill starts... Cc: [email protected] Fixes: 34d8311 ("drm/i915/dsb: Re-instate DSB for LUT updates") Fixes: 25ea341 ("drm/i915/dsb: Use non-posted register writes for legacy LUT") Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12494 Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Uma Shankar <[email protected]> (cherry picked from commit 2504a31) Signed-off-by: Tvrtko Ursulin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> [koichiroden: adjusted due to missing commit: 07226d0 ("drm/i915/dsb: s/dsb/dsb_color_vblank/")] Signed-off-by: Koichiro Den <[email protected]> Signed-off-by: Mehmet Basaran <[email protected]>
1 parent d959d46 commit 59fe122

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

drivers/gpu/drm/i915/display/intel_color.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,19 +1328,29 @@ static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state,
13281328
lut = blob->data;
13291329

13301330
/*
1331-
* DSB fails to correctly load the legacy LUT
1332-
* unless we either write each entry twice,
1333-
* or use non-posted writes
1331+
* DSB fails to correctly load the legacy LUT unless
1332+
* we either write each entry twice when using posted
1333+
* writes, or we use non-posted writes.
1334+
*
1335+
* If palette anti-collision is active during LUT
1336+
* register writes:
1337+
* - posted writes simply get dropped and thus the LUT
1338+
* contents may not be correctly updated
1339+
* - non-posted writes are blocked and thus the LUT
1340+
* contents are always correct, but simultaneous CPU
1341+
* MMIO access will start to fail
1342+
*
1343+
* Choose the lesser of two evils and use posted writes.
1344+
* Using posted writes is also faster, even when having
1345+
* to write each register twice.
13341346
*/
1335-
if (crtc_state->dsb)
1336-
intel_dsb_nonpost_start(crtc_state->dsb);
1337-
1338-
for (i = 0; i < 256; i++)
1347+
for (i = 0; i < 256; i++) {
13391348
ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
13401349
i9xx_lut_8(&lut[i]));
1341-
1342-
if (crtc_state->dsb)
1343-
intel_dsb_nonpost_end(crtc_state->dsb);
1350+
if (crtc_state->dsb)
1351+
ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
1352+
i9xx_lut_8(&lut[i]));
1353+
}
13441354
}
13451355

13461356
static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state,

0 commit comments

Comments
 (0)