From: Alan Stead <alan.stead@intel.com>
To: rodrigo.vivi@intel.com, jani.nikula@linux.intel.com,
intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
vivek.kasireddy@intel.com, dongwon.kim@intel.com,
james.xiong@intel.com
Subject: [RFC v1 3/3] drm/i915/vrr: Allow VRR on HDMI 2.1 sinks
Date: Fri, 30 Oct 2026 13:32:22 -0700 [thread overview]
Message-ID: <20261030203314.1085262-4-alan.stead@intel.com> (raw)
In-Reply-To: <20261030203314.1085262-1-alan.stead@intel.com>
Let intel_vrr_is_capable() accept HDMI sinks that advertise a VRR range
in the HDMI Forum VSDB (parsed by the DRM core into
display_info.hdmi.vrr_cap), and use that range instead of the EDID range
descriptor for the in-range check and for vmax. A VRRmax of 0 means the
refresh rate of the video timing, in which case the maximum comes from
the EDID range descriptor.
Attach the vrr_capable connector property to HDMI connectors and update
it whenever the EDID is read or dropped, as is done for DP.
HDMI 2.1 VRR is signalled to the sink with the VTEM, which needs the
HDMI EMP hardware of display version 20+, so restrict it to those.
Signed-off-by: Alan Stead <alan.stead@intel.com>
Assisted-by: LLM
---
drivers/gpu/drm/i915/display/intel_hdmi.c | 8 ++++
drivers/gpu/drm/i915/display/intel_vrr.c | 54 +++++++++++++++++++----
2 files changed, 53 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index b6fa1a1558b8..4854e86c1762 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2490,6 +2490,8 @@ intel_hdmi_unset_edid(struct drm_connector *_connector)
drm_edid_free(connector->detect_edid);
connector->detect_edid = NULL;
+
+ drm_connector_set_vrr_capable_property(&connector->base, false);
}
static void
@@ -2573,6 +2575,9 @@ intel_hdmi_set_edid(struct drm_connector *_connector)
connector->detect_edid = drm_edid;
+ drm_connector_set_vrr_capable_property(&connector->base,
+ intel_vrr_is_capable(connector));
+
if (drm_edid_is_digital(drm_edid)) {
intel_hdmi_dp_dual_mode_detect(&connector->base);
@@ -2726,6 +2731,9 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *_
if (!HAS_GMCH(display))
drm_connector_attach_max_bpc_property(&connector->base, 8, 12);
+
+ if (HAS_VRR(display) && DISPLAY_VER(display) >= 20)
+ drm_connector_attach_vrr_capable_property(&connector->base);
}
/*
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
index f4cc4148d3a1..ae3863c523b6 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -39,11 +39,33 @@
#define DCB_CORRECTION_AGGRESSIVENESS 1000 /* ms × 100; 10 ms */
#define DCB_BLANK_TARGET 50
+/*
+ * The refresh rate range the sink supports VRR in. HDMI 2.1 sinks advertise
+ * it in the HDMI Forum VSDB, where VRRmax = 0 means "the refresh rate of the
+ * video timing" (fall back to the EDID range descriptor for the maximum).
+ */
+static void intel_vrr_sink_range(struct intel_connector *connector,
+ int *min_vfreq, int *max_vfreq)
+{
+ const struct drm_display_info *info = &connector->base.display_info;
+ const struct drm_hdmi_vrr_cap *vrr_cap = &info->hdmi.vrr_cap;
+
+ *min_vfreq = info->monitor_range.min_vfreq;
+ *max_vfreq = info->monitor_range.max_vfreq;
+
+ if (connector->base.connector_type == DRM_MODE_CONNECTOR_HDMIA &&
+ vrr_cap->supported) {
+ *min_vfreq = vrr_cap->vrr_min;
+ if (vrr_cap->vrr_max)
+ *max_vfreq = vrr_cap->vrr_max;
+ }
+}
+
bool intel_vrr_is_capable(struct intel_connector *connector)
{
struct intel_display *display = to_intel_display(connector);
- const struct drm_display_info *info = &connector->base.display_info;
struct intel_dp *intel_dp;
+ int min_vfreq, max_vfreq;
if (!HAS_VRR(display))
return false;
@@ -78,24 +100,36 @@ bool intel_vrr_is_capable(struct intel_connector *connector)
return false;
break;
+ case DRM_MODE_CONNECTOR_HDMIA:
+ /*
+ * HDMI 2.1 VRR is signalled to the sink with the VTEM, which
+ * is sent using the EMP hardware of display version 20+.
+ */
+ if (DISPLAY_VER(display) < 20 ||
+ !connector->base.display_info.hdmi.vrr_cap.supported)
+ return false;
+ break;
default:
return false;
}
- if (!info->monitor_range.min_vfreq || !info->monitor_range.max_vfreq ||
- info->monitor_range.min_vfreq > info->monitor_range.max_vfreq)
+ intel_vrr_sink_range(connector, &min_vfreq, &max_vfreq);
+
+ if (!min_vfreq || !max_vfreq || min_vfreq > max_vfreq)
return false;
- return info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10;
+ return max_vfreq - min_vfreq > 10;
}
bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh)
{
- const struct drm_display_info *info = &connector->base.display_info;
+ int min_vfreq, max_vfreq;
+
+ intel_vrr_sink_range(connector, &min_vfreq, &max_vfreq);
return intel_vrr_is_capable(connector) &&
- vrefresh >= info->monitor_range.min_vfreq &&
- vrefresh <= info->monitor_range.max_vfreq;
+ vrefresh >= min_vfreq &&
+ vrefresh <= max_vfreq;
}
bool intel_vrr_possible(const struct intel_crtc_state *crtc_state)
@@ -413,11 +447,13 @@ static
int intel_vrr_compute_vmax(struct intel_connector *connector,
const struct drm_display_mode *adjusted_mode)
{
- const struct drm_display_info *info = &connector->base.display_info;
+ int min_vfreq, max_vfreq;
int vmax;
+ intel_vrr_sink_range(connector, &min_vfreq, &max_vfreq);
+
vmax = adjusted_mode->crtc_clock * 1000 /
- (adjusted_mode->crtc_htotal * info->monitor_range.min_vfreq);
+ (adjusted_mode->crtc_htotal * min_vfreq);
vmax = max_t(int, vmax, adjusted_mode->crtc_vtotal);
return vmax;
--
2.53.0
prev parent reply other threads:[~2026-10-30 20:34 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 20:32 [RFC v1 0/3] drm/i915/vrr: HDMI 2.1 VRR support Alan Stead
2026-10-30 20:32 ` [RFC v1 1/3] drm/i915/dip: Send HDMI EMPs early in V. Blank when VRR is in range Alan Stead
2026-10-30 20:32 ` [RFC v1 2/3] drm/i915/dip: Send the HDMI 2.1 VTEM when VRR is enabled Alan Stead
2026-10-30 20:32 ` Alan Stead [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261030203314.1085262-4-alan.stead@intel.com \
--to=alan.stead@intel.com \
--cc=dongwon.kim@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=james.xiong@intel.com \
--cc=jani.nikula@linux.intel.com \
--cc=rodrigo.vivi@intel.com \
--cc=vivek.kasireddy@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.