Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/i915/vrr: Configure VRR timings after enabling TRANS_DDI_FUNC_CTL

Apparently ICL may hang with an MCE if we write TRANS_VRR_VMAX/FLIPLINE
before enabling TRANS_DDI_FUNC_CTL.

Personally I was only able to reproduce a hang (on an Dell XPS 7390
2-in-1) with an external display connected via a dock using a dodgy
type-C cable that made the link training fail. After the failed
link training the machine would hang. TGL seemed immune to the
problem for whatever reason.

BSpec does tell us to configure VRR after enabling TRANS_DDI_FUNC_CTL
as well. The DMC firmware also does the VRR restore in two stages:
- first stage seems to be unconditional and includes TRANS_VRR_CTL
and a few other VRR registers, among other things
- second stage is conditional on the DDI being enabled,
and includes TRANS_DDI_FUNC_CTL and TRANS_VRR_VMAX/VMIN/FLIPLINE,
among other things

So let's reorder the steps to match to avoid the hang, and
toss in an extra WARN to make sure we don't screw this up later.

BSpec: 22243
Cc: stable@vger.kernel.org
Cc: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reported-by: Benjamin Tissoires <bentiss@kernel.org>
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/15777
Tested-by: Benjamin Tissoires <bentiss@kernel.org>
Fixes: dda7dcd9da73 ("drm/i915/vrr: Use fixed timings for platforms that support VRR")
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20260303095414.4331-1-ville.syrjala@linux.intel.com
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>

+14 -1
-1
drivers/gpu/drm/i915/display/intel_display.c
··· 1637 1637 } 1638 1638 1639 1639 intel_set_transcoder_timings(crtc_state); 1640 - intel_vrr_set_transcoder_timings(crtc_state); 1641 1640 1642 1641 if (cpu_transcoder != TRANSCODER_EDP) 1643 1642 intel_de_write(display, TRANS_MULT(display, cpu_transcoder),
+14
drivers/gpu/drm/i915/display/intel_vrr.c
··· 600 600 return; 601 601 602 602 /* 603 + * Bspec says: 604 + * "(note: VRR needs to be programmed after 605 + * TRANS_DDI_FUNC_CTL and before TRANS_CONF)." 606 + * 607 + * In practice it turns out that ICL can hang if 608 + * TRANS_VRR_VMAX/FLIPLINE are written before 609 + * enabling TRANS_DDI_FUNC_CTL. 610 + */ 611 + drm_WARN_ON(display->drm, 612 + !(intel_de_read(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE)); 613 + 614 + /* 603 615 * This bit seems to have two meanings depending on the platform: 604 616 * TGL: generate VRR "safe window" for DSB vblank waits 605 617 * ADL/DG2: make TRANS_SET_CONTEXT_LATENCY effective with VRR ··· 972 960 void intel_vrr_transcoder_enable(const struct intel_crtc_state *crtc_state) 973 961 { 974 962 struct intel_display *display = to_intel_display(crtc_state); 963 + 964 + intel_vrr_set_transcoder_timings(crtc_state); 975 965 976 966 if (!intel_vrr_possible(crtc_state)) 977 967 return;