intel_vrr_set_transcoder_timings() already programs TRANS_VRR_VSYNC and EMP_AS_SDP_TL after TRANS_DDI_FUNC_CTL and before TRANS_CONF. The Adaptive-Sync SDP itself is still written from intel_dp_set_infoframes() in intel_ddi_enable_dp(), after intel_enable_transcoder().
On this Panther Lake eDP, Adaptive Sync = Always still streaks on lid s2idle resume after the previous two patches. That path sends AVT_DYNAMIC_VTOTAL (operation mode 0), not the fixed-RR mode-1 packet. The same policy is clean when userspace toggles Adaptive Sync on an already-lit panel, so the sink can handle the SDP once the pipe is up. Write the SDP from intel_ddi_enable() immediately after intel_vrr_transcoder_enable(), before intel_enable_transcoder(). intel_ddi_enable_dp() runs after TRANS_CONF and must not rewrite it: keep intel_dp_set_infoframes() from clearing VIDEO_DIP_ENABLE_AS_ADL on enable, and stop writing AS SDP from there. Fastset still goes through intel_ddi_update_pipe_dp() on a live pipe. Call intel_dp_set_as_sdp() there so a VRR toggle can keep the stock fastset path: intel_crtc_check_fastset() will still clear mode_changed when only the AS enable bit differs. When the packet is not needed, the helper clears VIDEO_DIP_ENABLE_AS_ADL instead of leaving a stale transmission. The send path does not OR VIDEO_DIP_ENABLE_AS_ADL in the helper: intel_write_dp_sdp() calls write_infoframe (hsw_write_infoframe on this eDP), which sets the DIP enable bit after the payload, same as VSC. Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/9252 Signed-off-by: Xizhe Tang <[email protected]> Tested-by: Xizhe Tang <[email protected]> # 7.2.8 xe.ko and drm-tip, PTL eDP, Adaptive Sync=Always lid resume --- Changes in v3: - New. Needed on this panel for Always + s2idle; 1+2 alone are not enough there. Optional if you only want the Never/Automatic fix. - Do not touch intel_pipe_config_compare(). Forcing as_sdp onto the fastset compare, or switching the AS enable-bit exclude from || to &&, turns a runtime Adaptive Sync toggle into a full modeset. Keep intel_ddi_update_pipe_dp() writing or clearing the packet. - Comment that hsw_write_infoframe() sets VIDEO_DIP_ENABLE_AS_ADL after the payload; do not OR the HW bit again in the helper. - Hunks retargeted to drm-tip line numbers. drivers/gpu/drm/i915/display/intel_ddi.c | 4 ++++ drivers/gpu/drm/i915/display/intel_dp.c | 27 ++++++++++++++++++++++-- drivers/gpu/drm/i915/display/intel_dp.h | 2 ++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index a46ab5d..c80e246 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3555,6 +3555,9 @@ static void intel_ddi_enable(struct intel_atomic_state *state, intel_vrr_transcoder_enable(crtc_state); + if (!is_hdmi) + intel_dp_set_as_sdp(encoder, crtc_state); + /* 128b/132b SST */ if (!is_hdmi && intel_dp_is_uhbr(crtc_state)) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -3651,6 +3654,7 @@ static void intel_ddi_update_pipe_dp(struct intel_atomic_state *state, intel_ddi_set_dp_msa(crtc_state, conn_state); intel_dp_set_infoframes(encoder, true, crtc_state, conn_state); + intel_dp_set_as_sdp(encoder, crtc_state); intel_backlight_update(state, encoder, crtc_state, conn_state); drm_connector_update_privacy_screen(conn_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 95efc99..a8d1958 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5403,6 +5403,30 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder, dig_port->write_infoframe(encoder, crtc_state, type, &sdp, len); } +void intel_dp_set_as_sdp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(encoder); + intel_reg_t reg = HSW_TVIDEO_DIP_CTL(display, crtc_state->cpu_transcoder); + + if (crtc_state->infoframes.enable & + intel_hdmi_infoframe_enable(DP_SDP_ADAPTIVE_SYNC)) { + /* + * hsw_write_infoframe() sets VIDEO_DIP_ENABLE_AS_ADL + * after the payload. + */ + intel_write_dp_sdp(encoder, crtc_state, DP_SDP_ADAPTIVE_SYNC); + return; + } + + if (!HAS_AS_SDP(display)) + return; + + intel_de_write(display, reg, + intel_de_read(display, reg) & ~VIDEO_DIP_ENABLE_AS_ADL); + intel_de_posting_read(display, reg); +} + void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable, const struct intel_crtc_state *crtc_state, @@ -5414,7 +5438,7 @@ void intel_dp_set_infoframes(struct intel_encoder *encoder, VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW | VIDEO_DIP_ENABLE_SPD_HSW | VIDEO_DIP_ENABLE_DRM_GLK; - if (HAS_AS_SDP(display)) + if (!enable && HAS_AS_SDP(display)) dip_enable |= VIDEO_DIP_ENABLE_AS_ADL; u32 val = intel_de_read(display, reg) & ~dip_enable; @@ -5437,7 +5461,6 @@ void intel_dp_set_infoframes(struct intel_encoder *encoder, return; intel_write_dp_sdp(encoder, crtc_state, DP_SDP_VSC); - intel_write_dp_sdp(encoder, crtc_state, DP_SDP_ADAPTIVE_SYNC); intel_write_dp_sdp(encoder, crtc_state, HDMI_PACKET_TYPE_GAMUT_METADATA); } diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 04fae20..342ed75 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -133,6 +133,8 @@ bool intel_dp_needs_vsc_colorimetry(const struct intel_crtc_state *crtc_state, void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); +void intel_dp_set_as_sdp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); void intel_read_dp_sdp(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, unsigned int type); -- 2.55.0
