]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/i915: Reworkd DP DFP clock handling
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 4 Sep 2020 11:53:45 +0000 (14:53 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 17 Sep 2020 15:26:46 +0000 (18:26 +0300)
Move the downstream facing port dotclock check into a new function
(intel_dp_mode_valid_downstream()) so that we have a nice future
place where we can collect other related checks.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200904115354.25336-10-ville.syrjala@linux.intel.com
Reviewed-by: Lyude Paul <lyude@redhat.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_dp.c

index 5f1a6696d0a85871026296e83faeff8fac94aaa7..f9647809452be3fd33cdc7bf9262a49825e92394 100644 (file)
@@ -1383,6 +1383,7 @@ struct intel_dp {
 
        /* Downstream facing port caps */
        struct {
+               int max_dotclock;
                u8 max_bpc;
        } dfp;
 
index c664e8e1bf34660708cb80a58140c6ad154cb4ec..b68a27ab05f8f0f5739775fec153e187e287343d 100644 (file)
@@ -247,29 +247,6 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
        return max_link_clock * max_lanes;
 }
 
-static int
-intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
-{
-       struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-       struct intel_encoder *encoder = &dig_port->base;
-       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-       int max_dotclk = dev_priv->max_dotclk_freq;
-       int ds_max_dotclk;
-
-       int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
-
-       if (type != DP_DS_PORT_TYPE_VGA)
-               return max_dotclk;
-
-       ds_max_dotclk = drm_dp_downstream_max_dotclock(intel_dp->dpcd,
-                                                      intel_dp->downstream_ports);
-
-       if (ds_max_dotclk != 0)
-               max_dotclk = min(max_dotclk, ds_max_dotclk);
-
-       return max_dotclk;
-}
-
 static int cnl_max_source_rate(struct intel_dp *intel_dp)
 {
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@ -634,6 +611,19 @@ static bool intel_dp_hdisplay_bad(struct drm_i915_private *dev_priv,
        return hdisplay == 4096 && !HAS_DDI(dev_priv);
 }
 
+static enum drm_mode_status
+intel_dp_mode_valid_downstream(struct intel_connector *connector,
+                              int target_clock)
+{
+       struct intel_dp *intel_dp = intel_attached_dp(connector);
+
+       if (intel_dp->dfp.max_dotclock &&
+           target_clock > intel_dp->dfp.max_dotclock)
+               return MODE_CLOCK_HIGH;
+
+       return MODE_OK;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
@@ -644,15 +634,14 @@ intel_dp_mode_valid(struct drm_connector *connector,
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
        int target_clock = mode->clock;
        int max_rate, mode_rate, max_lanes, max_link_clock;
-       int max_dotclk;
+       int max_dotclk = dev_priv->max_dotclk_freq;
        u16 dsc_max_output_bpp = 0;
        u8 dsc_slice_count = 0;
+       enum drm_mode_status status;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
 
-       max_dotclk = intel_dp_downstream_max_dotclock(intel_dp);
-
        if (intel_dp_is_edp(intel_dp) && fixed_mode) {
                if (mode->hdisplay > fixed_mode->hdisplay)
                        return MODE_PANEL;
@@ -708,6 +697,10 @@ intel_dp_mode_valid(struct drm_connector *connector,
        if (mode->flags & DRM_MODE_FLAG_DBLCLK)
                return MODE_H_ILLEGAL;
 
+       status = intel_dp_mode_valid_downstream(intel_connector, target_clock);
+       if (status != MODE_OK)
+               return status;
+
        return intel_mode_valid_max_plane_size(dev_priv, mode);
 }
 
@@ -6073,9 +6066,14 @@ intel_dp_set_edid(struct intel_dp *intel_dp)
                drm_dp_downstream_max_bpc(intel_dp->dpcd,
                                          intel_dp->downstream_ports, edid);
 
-       drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] DFP max bpc %d\n",
+       intel_dp->dfp.max_dotclock =
+               drm_dp_downstream_max_dotclock(intel_dp->dpcd,
+                                              intel_dp->downstream_ports);
+
+       drm_dbg_kms(&i915->drm,
+                   "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d\n",
                    connector->base.base.id, connector->base.name,
-                   intel_dp->dfp.max_bpc);
+                   intel_dp->dfp.max_bpc, intel_dp->dfp.max_dotclock);
 
        if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
                intel_dp->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
@@ -6100,6 +6098,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
        intel_dp->edid_quirks = 0;
 
        intel_dp->dfp.max_bpc = 0;
+       intel_dp->dfp.max_dotclock = 0;
 }
 
 static int