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.nauti...@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 --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;
        }
-- 
2.25.1

Reply via email to