intel_dsb_gosub_align() moves free_pos to the next cacheline unconditionally, but only clears the skipped bytes when at most two QW slots remain. Wa_16024917128 forbids GOSUB in slots 6 and 7 only. A larger gap is still executed. A Panther Lake DSB dump showed nonzero data in that gap, with the tail at 0x58 and GOSUB at 0x80. Advance free_pos only when the instruction would land in slot 6 or 7, and fill that gap with NOPs. Emit GOSUB in place for every other slot. intel_dsb_align_tail() still clears the rest of the cacheline. Update free_pos inside the existing gap check in intel_dsb_align_tail() as well, so the two helpers keep the same shape. Fixes: 2c41d62f6fb1 ("drm/i915/dsb: Implement intel_dsb_gosub()") Cc: stable@vger.kernel.org # v6.17+ Signed-off-by: Hanson Wang --- v2: - Advance free_pos only for QW slots 6 and 7, and NOP-fill that gap (Ville) - Update free_pos inside the existing check in intel_dsb_align_tail() so the two helpers stay in the same shape Hardware: Intel Core Ultra 5 336H (Panther Lake), 6.18-based kernel Build: 6.18 backport; both xe and i915 intel_dsb.o Upstream: not built or booted Reboots: 7/100 DSB idle timeouts before either fix v1 (always align): 0/200 v2 (this patch): 0/200 drivers/gpu/drm/i915/display/intel_dsb.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index d9a270362a82..07d864039e82 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -589,10 +589,10 @@ static void intel_dsb_align_tail(struct intel_dsb *dsb) tail = dsb->free_pos * 4; aligned_tail = ALIGN(tail, CACHELINE_BYTES); - if (aligned_tail > tail) + if (aligned_tail > tail) { dsb_buffer_fill(dsb, dsb->free_pos, 0, aligned_tail - tail); - - dsb->free_pos = aligned_tail / 4; + dsb->free_pos = aligned_tail / 4; + } } static void intel_dsb_gosub_align(struct intel_dsb *dsb) @@ -607,11 +607,15 @@ static void intel_dsb_gosub_align(struct intel_dsb *dsb) /* * Wa_16024917128 * "Ensure GOSUB is not placed in cacheline QW slot 6 or 7 (numbered 0-7)" + * + * Move to the next cacheline only for those two slots. The skipped + * bytes stay in the programmed range, so fill them with NOPs. Any + * other slot can take the GOSUB directly. */ - if (aligned_tail - tail <= 2 * 8) + if (aligned_tail - tail <= 2 * 8) { dsb_buffer_fill(dsb, dsb->free_pos, 0, aligned_tail - tail); - - dsb->free_pos = aligned_tail / 4; + dsb->free_pos = aligned_tail / 4; + } } void intel_dsb_gosub(struct intel_dsb *dsb, -- 2.34.1