Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Alan Stead" <alan.stead@intel.com>,
	intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org
Subject: Re: [RFC v1 3/3] drm/i915/vrr: Allow VRR on HDMI 2.1 sinks
Date: Fri, 30 Oct 2026 20:58:02 +0000	[thread overview]
Message-ID: <sashiko-outbox-191504@kernel.org> (raw)
In-Reply-To: <20261030203314.1085262-4-alan.stead@intel.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] drm/i915/dip: emp_as_sdp_tl not computed for HDMI VRR due to DP-only call
- [Medium] drm/i915/hdmi: stale vrr_capable property on disconnect in intel_hdmi_detect()
- [Medium] drm/i915/vrr: fallback to monitor_range.max_vfreq fails when vrr_max is 0
- [Medium] drm/i915/vrr: VRR enabled in DVI mode in intel_vrr_compute_config()
- [Low] drm/i915/dip: undeclared HDMI_EMP_DATA() macro in intel_dip_write_hdmi_vtem()
--

commit d2e831520b52e253f435c04bcef565c5c658d639
Author: Alan Stead <alan.stead@intel.com>

drm/i915/vrr: Allow VRR on HDMI 2.1 sinks

This commit enables VRR support on HDMI 2.1 sinks for display version 20+
by using the VRR range from the HDMI Forum VSDB in display_info.hdmi.vrr_cap
and attaching and updating the vrr_capable property on HDMI connectors.

> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index b6fa1a1558b82..4854e86c1762a 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);
>  }

[Severity: Medium]
When an HDMI 2.1 VRR-capable sink is unplugged on display version 20+
platforms, will intel_hdmi_unset_edid() actually be reached to reset the
vrr_capable property to false?

In drivers/gpu/drm/i915/display/intel_hdmi.c, intel_hdmi_detect() checks if
the port is connected before calling intel_hdmi_unset_edid():

	if (DISPLAY_VER(display) >= 11 &&
	    !intel_digital_port_connected(encoder))
		goto out;

	intel_hdmi_unset_edid(&connector->base);

	if (intel_hdmi_set_edid(&connector->base))
		status = connector_status_connected;

out:
	intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref);

	if (status != connector_status_connected)
		cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);

Because DISPLAY_VER(display) >= 11 is true for all display version 20+
hardware, unplugging the sink causes intel_hdmi_detect() to jump directly to
out without calling intel_hdmi_unset_edid(), leaving the connector's
vrr_capable property stuck at true while disconnected.

> diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
> index 142ba2db52fda..c2774fd690473 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;
> +	}
> +}

[Severity: Medium]
Can falling back to info->monitor_range.max_vfreq when vrr_cap->vrr_max is 0
reject valid HDMI 2.1 VRR sinks?

Per the HDMI 2.1 specification and struct drm_hdmi_vrr_cap, vrr_max == 0
indicates that the upper VRR bound is the refresh rate of the active video
timing (and vrr_max == 0 is required for any sink whose maximum VRR rate is
below 100 Hz, since HF-VSDB only encodes 0 or values >= 100).

However, drm_get_monitor_range() in drivers/gpu/drm/drm_edid.c only populates
info->monitor_range.max_vfreq when the EDID revision is >= 4,
DRM_EDID_FEATURE_CONTINUOUS_FREQ is set, and a 0xfd Display Range Limits
descriptor with DRM_EDID_RANGE_LIMITS_ONLY_FLAG is present. On HDMI 2.1 sinks
that advertise vrr_max == 0 in the HF-VSDB without a DisplayPort-style
continuous-frequency Range Limits Only descriptor,
info->monitor_range.max_vfreq remains 0, causing intel_vrr_sink_range() to
set *max_vfreq = 0 and both intel_vrr_is_capable() and
intel_vrr_is_in_range() to 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;

[Severity: High]
When VRR is enabled on an HDMI connector, does crtc_state->dip.emp_as_sdp_tl
ever get computed?

In drivers/gpu/drm/i915/display/intel_dip.c,
intel_dip_get_as_sdp_transmission_line() has an HDMI VRR branch:

	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
	    crtc_state->vrr.in_range) {
		const struct drm_display_mode *mode = &crtc_state->hw.adjusted_mode;
		int max_tl = crtc_state->set_context_latency +
			crtc_state->vrr.guardband - 1;
		int tl = mode->crtc_vtotal - mode->crtc_vdisplay - 1;

		if (max_tl > 0)
			tl = min(tl, max_tl);

		return tl;
	}

That helper is only called from intel_dip_sdp_tl_compute_config_late(), which
in turn is only called via intel_ddi_compute_config_late() ->
intel_dp_compute_config_late() -> intel_dp_sdp_compute_config_late(). In
drivers/gpu/drm/i915/display/intel_ddi.c, intel_ddi_compute_config_late()
guards that call behind intel_crtc_has_dp_encoder():

	if (intel_crtc_has_dp_encoder(crtc_state))
		ret = intel_dp_compute_config_late(encoder, crtc_state, conn_state);

For INTEL_OUTPUT_HDMI, intel_dip_sdp_tl_compute_config_late() is never
called, so crtc_state->dip.emp_as_sdp_tl stays 0 and
intel_vrr_set_transcoder_timings() -> intel_dip_write_emp_as_sdp_tl()
programs EMP_AS_SDP_TL to 0 instead of the calculated transmission line.

[Severity: Low]
Also in the HDMI VTEM support enabled by this path, does
intel_dip_write_hdmi_vtem() in drivers/gpu/drm/i915/display/intel_dip.c build
when CONFIG_DRM_I915 or CONFIG_DRM_XE is enabled?

intel_dip_write_hdmi_vtem() writes the packet body using HDMI_EMP_DATA():

	for (i = 0; i < ARRAY_SIZE(pb); i += 4)
		intel_de_write(display, HDMI_EMP_DATA(display, cpu_transcoder),
			       pb[i] | pb[i + 1] << 8 | pb[i + 2] << 16 |
			       pb[i + 3] << 24);

However, drivers/gpu/drm/i915/display/intel_dip_regs.h only defines
HDMI_EMP_CTL and HDMI_EMP_HEADER:

/* HDMI 2.1 Extended Metadata Packet (EMP) control/header; payload is HDMI_EMP_DATA */
#define _HDMI_EMP_CTL_A				0x600d0
#define HDMI_EMP_CTL(display, trans)		_MMIO_TRANS2((display), (trans), _HDMI_EMP_CTL_A)
...
#define _HDMI_EMP_HEADER_A			0x600d4
#define HDMI_EMP_HEADER(display, trans)		_MMIO_TRANS2((display), (trans), _HDMI_EMP_HEADER_A)

HDMI_EMP_DATA is not defined in intel_dip_regs.h or anywhere else in the
tree, resulting in an implicit declaration build failure in
intel_dip_write_hdmi_vtem().

>  	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;
>  }

[Severity: Medium]
Should intel_vrr_compute_config() also verify that crtc_state->has_hdmi_sink
(or crtc_state->has_infoframe) is true before enabling VRR on an HDMI
connector?

If userspace forces DVI mode via the connector audio property (setting
force_audio to HDMI_AUDIO_OFF_DVI) while an HDMI 2.1 VRR sink is connected,
intel_hdmi_compute_config() leaves pipe_config->has_hdmi_sink and
pipe_config->has_infoframe as false, and intel_ddi_enable_transcoder_func()
programs TRANS_DDI_MODE_SELECT_DVI:

	if (crtc_state->has_hdmi_sink)
		temp |= TRANS_DDI_MODE_SELECT_HDMI;
	else
		temp |= TRANS_DDI_MODE_SELECT_DVI;

Because intel_vrr_compute_config() only checks intel_vrr_is_in_range()
against connector->base.display_info, it still sets crtc_state->vrr.in_range
and crtc_state->vrr.enable to true in DVI mode, even though the AVI InfoFrame
is not computed and the transcoder cannot transmit HDMI data island packets
such as the VTEM.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261030203314.1085262-1-alan.stead@intel.com?part=3

  reply	other threads:[~2026-10-30 20:58 UTC|newest]

Thread overview: 9+ 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:46   ` sashiko-bot
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:59   ` sashiko-bot
2026-10-30 20:32 ` [RFC v1 3/3] drm/i915/vrr: Allow VRR on HDMI 2.1 sinks Alan Stead
2026-10-30 20:58   ` sashiko-bot [this message]
2026-10-30 21:09 ` ✓ CI.KUnit: success for drm/i915/vrr: HDMI 2.1 VRR support Patchwork
2026-10-30 21:45 ` ✓ Xe.CI.BAT: " Patchwork

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=sashiko-outbox-191504@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=alan.stead@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox