]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/psr: Compute Panel Replay/Adaptive Sync coexistence behavior
authorJouni Högander <jouni.hogander@intel.com>
Thu, 4 Dec 2025 10:47:28 +0000 (12:47 +0200)
committerJouni Högander <jouni.hogander@intel.com>
Mon, 8 Dec 2025 06:15:59 +0000 (08:15 +0200)
Currently we are checking Panel Replay capability DPCD register in
intel_alpm.c and writing PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU
and PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE in PR_ALPM_CTL
register base on the informaion. Instead of directly accessing
intel_dp->pr_dpcd compute the behavior during psr_compute_config and store
it in intel_crtc_state.

v2:
  - inline added helpers
  - use intel_dp_attached_dp instead of passing as a parameter

Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Link: https://patch.msgid.link/20251204104733.1106145-4-jouni.hogander@intel.com
drivers/gpu/drm/i915/display/intel_alpm.c
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_psr.c

index 6372f533f65b52d98bcb4e60134a75690025c80f..7ce8c674bb0307947a6213134be0e66a115fb1c5 100644 (file)
@@ -326,11 +326,9 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
                if (intel_dp->as_sdp_supported) {
                        u32 pr_alpm_ctl = PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1;
 
-                       if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
-                           DP_PANEL_REPLAY_LINK_OFF_SUPPORTED_IN_PR_AFTER_ADAPTIVE_SYNC_SDP)
+                       if (crtc_state->link_off_after_as_sdp_when_pr_active)
                                pr_alpm_ctl |= PR_ALPM_CTL_ALLOW_LINK_OFF_BETWEEN_AS_SDP_AND_SU;
-                       if (!(intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
-                                               DP_PANEL_REPLAY_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR))
+                       if (crtc_state->disable_as_sdp_when_pr_active)
                                pr_alpm_ctl |= PR_ALPM_CTL_AS_SDP_TRANSMISSION_IN_ACTIVE_DISABLE;
 
                        intel_de_write(display, PR_ALPM_CTL(display, cpu_transcoder),
index 565d179f8780f703697477253060c4c7ff3ed781..8584292d09f5164528b8dc5d826c6b02d61f2438 100644 (file)
@@ -1162,6 +1162,8 @@ struct intel_crtc_state {
        bool enable_psr2_su_region_et;
        bool req_psr2_sdp_prior_scanline;
        bool has_panel_replay;
+       bool link_off_after_as_sdp_when_pr_active;
+       bool disable_as_sdp_when_pr_active;
        bool wm_level_disabled;
        bool pkg_c_latency_used;
        /* Only used for state verification. */
index 417a6cd2fca9d9922a35245b4026644f9a044573..c95d1e5724c32a0a32937551f1971f199861a603 100644 (file)
@@ -1708,14 +1708,25 @@ static bool _psr_compute_config(struct intel_dp *intel_dp,
        return true;
 }
 
-static bool
-_panel_replay_compute_config(struct intel_dp *intel_dp,
-                            struct intel_crtc_state *crtc_state,
-                            const struct drm_connector_state *conn_state)
+static inline bool compute_link_off_after_as_sdp_when_pr_active(struct intel_dp *intel_dp)
+{
+       return (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
+               DP_PANEL_REPLAY_LINK_OFF_SUPPORTED_IN_PR_AFTER_ADAPTIVE_SYNC_SDP);
+}
+
+static inline bool compute_disable_as_sdp_when_pr_active(struct intel_dp *intel_dp)
+{
+       return !(intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
+                DP_PANEL_REPLAY_ASYNC_VIDEO_TIMING_NOT_SUPPORTED_IN_PR);
+}
+
+static bool _panel_replay_compute_config(struct intel_crtc_state *crtc_state,
+                                        const struct drm_connector_state *conn_state)
 {
-       struct intel_display *display = to_intel_display(intel_dp);
        struct intel_connector *connector =
                to_intel_connector(conn_state->connector);
+       struct intel_dp *intel_dp = intel_attached_dp(connector);
+       struct intel_display *display = to_intel_display(intel_dp);
        struct intel_hdcp *hdcp = &connector->hdcp;
 
        if (!CAN_PANEL_REPLAY(intel_dp))
@@ -1740,6 +1751,9 @@ _panel_replay_compute_config(struct intel_dp *intel_dp,
                return false;
        }
 
+       crtc_state->link_off_after_as_sdp_when_pr_active = compute_link_off_after_as_sdp_when_pr_active(intel_dp);
+       crtc_state->disable_as_sdp_when_pr_active = compute_disable_as_sdp_when_pr_active(intel_dp);
+
        if (!intel_dp_is_edp(intel_dp))
                return true;
 
@@ -1847,8 +1861,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
 
        /* Only used for state verification. */
        crtc_state->panel_replay_dsc_support = intel_dp->psr.sink_panel_replay_dsc_support;
-       crtc_state->has_panel_replay = _panel_replay_compute_config(intel_dp,
-                                                                   crtc_state,
+       crtc_state->has_panel_replay = _panel_replay_compute_config(crtc_state,
                                                                    conn_state);
 
        crtc_state->has_psr = crtc_state->has_panel_replay ? true :