Skip to content

Commit cd3da56

Browse files
vsyrjalatursulin
authored andcommitted
drm/i915/color: Stop using non-posted DSB writes for legacy LUT
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]>
1 parent 70ec2e8 commit cd3da56

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
@@ -1368,19 +1368,29 @@ static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state,
13681368
lut = blob->data;
13691369

13701370
/*
1371-
* DSB fails to correctly load the legacy LUT
1372-
* unless we either write each entry twice,
1373-
* or use non-posted writes
1371+
* DSB fails to correctly load the legacy LUT unless
1372+
* we either write each entry twice when using posted
1373+
* writes, or we use non-posted writes.
1374+
*
1375+
* If palette anti-collision is active during LUT
1376+
* register writes:
1377+
* - posted writes simply get dropped and thus the LUT
1378+
* contents may not be correctly updated
1379+
* - non-posted writes are blocked and thus the LUT
1380+
* contents are always correct, but simultaneous CPU
1381+
* MMIO access will start to fail
1382+
*
1383+
* Choose the lesser of two evils and use posted writes.
1384+
* Using posted writes is also faster, even when having
1385+
* to write each register twice.
13741386
*/
1375-
if (crtc_state->dsb_color_vblank)
1376-
intel_dsb_nonpost_start(crtc_state->dsb_color_vblank);
1377-
1378-
for (i = 0; i < 256; i++)
1387+
for (i = 0; i < 256; i++) {
13791388
ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
13801389
i9xx_lut_8(&lut[i]));
1381-
1382-
if (crtc_state->dsb_color_vblank)
1383-
intel_dsb_nonpost_end(crtc_state->dsb_color_vblank);
1390+
if (crtc_state->dsb_color_vblank)
1391+
ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
1392+
i9xx_lut_8(&lut[i]));
1393+
}
13841394
}
13851395

13861396
static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state,

0 commit comments

Comments
 (0)