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

Reply via email to