summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAnkit Nautiyal <ankit.k.nautiyal@intel.com>2026-05-27 07:10:47 +0300
committerAnkit Nautiyal <ankit.k.nautiyal@intel.com>2026-05-28 14:18:08 +0300
commit186113b419a2e5086b2148ea02646b1e2c74c6bd (patch)
treefdb719c2daeca85855a0a823e118b9dd9cdde6ba /drivers/gpu
parent1f41dd467333e5d6e8ee1163dd35f7086624b200 (diff)
downloadlinux-186113b419a2e5086b2148ea02646b1e2c74c6bd.tar.xz
drm/i915/dp: Compute and include coasting vtotal for AS SDP
DP v2.1 allows the source to temporarily suspend Adaptive-Sync SDP transmission while Panel Replay is active when the sink supports asynchronous video timing. In such cases, the sink relies on the last transmitted AS SDP timing information to maintain the refresh rate. To support this behavior, compute and populate the coasting vtotal field in the AS SDP payload. Include coasting vtotal in AS SDP packing, unpacking, and comparison, and set it during late AS SDP configuration for PR with Aux-less ALPM when asynchronous video timing is supported. Note: The coasting vtotal value is fully under driver control i.e. the HW does not overwrite these payload bytes. HW only samples the PR_ALPM_CTL[AS SDP Transmission in Active Disable] bit during PR active state and reflects it in the AS SDP payload at the appropriate time. Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patch.msgid.link/20260527041050.601735-10-ankit.k.nautiyal@intel.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c20
2 files changed, 22 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 3d91495905e8..8e269b71f18e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4911,7 +4911,8 @@ intel_compare_dp_as_sdp(const struct drm_dp_as_sdp *a,
a->duration_incr_ms == b->duration_incr_ms &&
a->duration_decr_ms == b->duration_decr_ms &&
a->target_rr_divider == b->target_rr_divider &&
- a->mode == b->mode;
+ a->mode == b->mode &&
+ a->coasting_vtotal == b->coasting_vtotal;
}
static bool
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 959e1575dffb..9adf426ea110 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3254,6 +3254,22 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,
} else {
as_sdp->mode = DP_AS_SDP_AVT_FIXED_VTOTAL;
}
+
+ /*
+ * For Panel Replay with Async Video Timing support, the source can
+ * disable sending the AS SDP during PR Active state. In that case,
+ * the sink needs the coasting vtotal value to maintain the refresh
+ * rate. The HW only samples this on PR_ALPM_CTL[AS SDP Transmission
+ * in Active Disable], which we never program, so providing the value
+ * unconditionally when the sink advertises the capability is safe.
+ *
+ * #TODO:
+ * If we ever advertise support for coasting at other refresh targets,
+ * this logic could be revisited. For now, use the minimum refresh rate
+ * as the only safe coasting value.
+ */
+ if (intel_psr_pr_async_video_timing_supported(intel_dp))
+ as_sdp->coasting_vtotal = crtc_state->vrr.vmax;
}
static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
@@ -5245,6 +5261,9 @@ static ssize_t intel_dp_as_sdp_pack(const struct drm_dp_as_sdp *as_sdp,
if (as_sdp->target_rr_divider)
sdp->db[4] |= 0x20;
+ sdp->db[7] = as_sdp->coasting_vtotal & 0xFF;
+ sdp->db[8] = (as_sdp->coasting_vtotal >> 8) & 0xFF;
+
return length;
}
@@ -5429,6 +5448,7 @@ int intel_dp_as_sdp_unpack(struct drm_dp_as_sdp *as_sdp,
as_sdp->vtotal = (sdp->db[2] << 8) | sdp->db[1];
as_sdp->target_rr = ((sdp->db[4] & 0x3) << 8) | sdp->db[3];
as_sdp->target_rr_divider = sdp->db[4] & 0x20 ? true : false;
+ as_sdp->coasting_vtotal = (sdp->db[8] << 8) | sdp->db[7];
return 0;
}