> -----Original Message-----
> From: Nautiyal, Ankit K <[email protected]>
> Sent: Monday, October 12, 2026 9:27 AM
> To: [email protected]; [email protected]
> Cc: [email protected]; [email protected]; Shankar, Uma
> <[email protected]>; [email protected]; Kandpal, Suraj
> <[email protected]>
> Subject: [PATCH v2 02/56] drm/i915/hdmi: Add new data members for FRL
> configuration
>
> HDMI supports higher resolutions using Fixed Rate Link.
> Source needs to do FRL link training on the 4 lanes before video stream
> transmission.
>
> Add the members to crtc_state and intel_hdmi for identifying the FRL
> supporting
> HDMI sink and to maintain the FRL training information after successful
> training.
Seems only intel_hdmi is touched here, drop crtc_state from comment.
>
> Signed-off-by: Ankit Nautiyal <[email protected]>
> ---
> .../drm/i915/display/intel_display_types.h | 9 +++++
> drivers/gpu/drm/i915/display/intel_hdmi.c | 36 +++++++++++++++++++
> 2 files changed, 45 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 79f30660c2b6..89333c9ddcc8 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1709,8 +1709,17 @@ struct intel_hdmi {
> enum drm_dp_dual_mode_type type;
> int max_tmds_clock;
> } dp_dual_mode;
> + bool has_sink_hdmi_21;
> + int max_frl_rate;
> + int max_dsc_frl_rate;
> struct intel_connector *attached_connector;
> struct cec_notifier *cec_notifier;
> + struct {
> + bool trained;
> + int lanes;
> + int rate_gbps;
> + int ffe_level;
> + } frl;
> };
>
> struct intel_dp_mst_encoder;
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c
> b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index b6fa1a1558b8..69534eea78a1 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -2485,6 +2485,8 @@ intel_hdmi_unset_edid(struct drm_connector
> *_connector)
> struct intel_connector *connector = to_intel_connector(_connector);
> struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
>
> + intel_hdmi->has_sink_hdmi_21 = false;
but max_frl_rate, max_dsc_frl_rate, and the frl.* training state are left
behind. On unplug,
these carry stale values from the previous sink. unset_edid should also zero
max_frl_rate/max_dsc_frl_rate and call intel_hdmi_reset_frl_config()
> +
> intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
> intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
>
> @@ -2545,6 +2547,38 @@ intel_hdmi_dp_dual_mode_detect(struct
> drm_connector *_connector)
> }
> }
>
> +static void
> +intel_hdmi_reset_frl_config(struct intel_hdmi *intel_hdmi) {
> + intel_hdmi->frl.trained = false;
> + intel_hdmi->frl.lanes = 0;
> + intel_hdmi->frl.rate_gbps = 0;
> + intel_hdmi->frl.ffe_level = 0;
> +}
> +
> +static void
> +intel_hdmi_init_frl_config(struct intel_connector *connector) {
> + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
> + struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
> + int max_src_frl_rate =
> + DIV_ROUND_UP(intel_bios_hdmi_max_frl_rate(encoder-
> >devdata), 1000000) * 4;
We should maybe check the validity of encoder->devdata before going further.
Also define a MACRO for the magic number. For 4 as well you can use
MAX_FRL_LANES.
> + int max_sink_dsc_frl_rate =
> + intel_hdmi_sink_dsc_max_frl_rate(&connector->base);
> + int max_sink_frl_rate =
> + intel_hdmi_sink_max_frl_rate(&connector->base);
> +
> + intel_hdmi->has_sink_hdmi_21 = max_sink_frl_rate > 0;
> +
> + intel_hdmi->max_frl_rate = min(max_sink_frl_rate,
> + max_src_frl_rate);
Per the previous patch, intel_bios_hdmi_max_frl_rate() returns 0 to mean "no
VBT limit / use platform default".
Here src == 0 makes max_src_frl_rate == 0, and min(sink, 0) == 0 - so FRL is
fully disabled even when
the sink supports it. Only MTL escapes this, every very other FRL-capable
platform collapses to 0. Clamp only
when source value is non-zero (e.g. if (max_src_frl_rate) rate = min(rate,
max_src_frl_rate)), same for max_dsc_frl_rate.
> +
> + intel_hdmi->max_dsc_frl_rate = min(max_sink_dsc_frl_rate,
> + max_src_frl_rate);
> +
> + intel_hdmi_reset_frl_config(intel_hdmi);
> +}
> +
> static bool
> intel_hdmi_set_edid(struct drm_connector *_connector) { @@ -2576,6 +2610,8
> @@ intel_hdmi_set_edid(struct drm_connector *_connector)
> if (drm_edid_is_digital(drm_edid)) {
> intel_hdmi_dp_dual_mode_detect(&connector->base);
>
> + intel_hdmi_init_frl_config(connector);
> +
> connected = true;
> }
>
> --
> 2.50.1