diff mbox series

[RFC,05/15] drm/i915/hdmi21/mtl: Add new data members for FRL configuration

Message ID 20221107072045.628895-6-ankit.k.nautiyal@intel.com (mailing list archive)
State New, archived
Headers show
Series Add support for HDMI2.1 FRL | expand

Commit Message

Nautiyal, Ankit K Nov. 7, 2022, 7:20 a.m. UTC
HDMI2.1 supports higher resolutions using Fixed Rate Link.
Source need to do FRL link training on the 4 lanes before video
stream transmission.

This patch adds 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.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  9 ++++++++
 drivers/gpu/drm/i915/display/intel_hdmi.c     | 22 +++++++++++++++++++
 2 files changed, 31 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index c6abaaa46e17..e57fac00e945 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1517,8 +1517,17 @@  struct intel_hdmi {
 	} dp_dual_mode;
 	bool has_hdmi_sink;
 	bool has_audio;
+	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 02f8374ea51f..1dd0b0f2e2f1 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2346,6 +2346,7 @@  intel_hdmi_unset_edid(struct drm_connector *connector)
 
 	intel_hdmi->has_hdmi_sink = false;
 	intel_hdmi->has_audio = false;
+	intel_hdmi->has_sink_hdmi_21 = false;
 
 	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
 	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
@@ -2405,11 +2406,21 @@  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 bool
 intel_hdmi_set_edid(struct drm_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
+	struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
 	intel_wakeref_t wakeref;
 	struct edid *edid;
 	bool connected = false;
@@ -2431,10 +2442,21 @@  intel_hdmi_set_edid(struct drm_connector *connector)
 
 	to_intel_connector(connector)->detect_edid = edid;
 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
+		int src_rate_lane_gbps = DIV_ROUND_UP(intel_bios_hdmi_max_frl_rate(encoder),
+						      1000000);
+		int max_src_rate = src_rate_lane_gbps * 4;
+
 		intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
 		intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
 
 		intel_hdmi_dp_dual_mode_detect(connector);
+		intel_hdmi->has_sink_hdmi_21 =
+			drm_hdmi_sink_max_frl_rate(connector) > 0 ? true : false;
+		intel_hdmi->max_frl_rate = min(drm_hdmi_sink_max_frl_rate(connector),
+					       max_src_rate);
+		intel_hdmi->max_dsc_frl_rate = min(drm_hdmi_sink_dsc_max_frl_rate(connector),
+						   max_src_rate);
+		intel_hdmi_reset_frl_config(intel_hdmi);
 
 		connected = true;
 	}