drm/i915: Capture max frl rate for PCON in dfp cap structure
authorAnkit Nautiyal <ankit.k.nautiyal@intel.com>
Fri, 18 Dec 2020 10:37:16 +0000 (16:07 +0530)
committerJani Nikula <jani.nikula@intel.com>
Tue, 22 Dec 2020 15:53:03 +0000 (17:53 +0200)
HDMI2.1 PCON advertises Max FRL bandwidth supported by the PCON.

This patch captures this in dfp cap structure in intel_dp and uses
this to prune connector modes that cannot be supported by the PCON
and FRL bandwidth.

v2: Addressed review comments from Uma Shankar:
-tweaked the comparison of target bw and pcon frl bw to avoid roundup errors.
-minor modification of field names and comments.

Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201218103723.30844-9-ankit.k.nautiyal@intel.com
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_dp.c

index ce82d654d0f24056bb624efdab8c456add83c1c8..3149a4ed8bf26d2c0d115a3ea9440c0460ac1bca 100644 (file)
@@ -1432,6 +1432,7 @@ struct intel_dp {
        struct {
                int min_tmds_clock, max_tmds_clock;
                int max_dotclock;
+               int pcon_max_frl_bw;
                u8 max_bpc;
                bool ycbcr_444_to_420;
        } dfp;
index 3896d08c41779b430eb9f9c4c21afb6127a6e02c..57f598b896abe030f760bc3cdd18de13a18d56fb 100644 (file)
@@ -716,6 +716,25 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
        const struct drm_display_info *info = &connector->base.display_info;
        int tmds_clock;
 
+       /* If PCON supports FRL MODE, check FRL bandwidth constraints */
+       if (intel_dp->dfp.pcon_max_frl_bw) {
+               int target_bw;
+               int max_frl_bw;
+               int bpp = intel_dp_mode_min_output_bpp(&connector->base, mode);
+
+               target_bw = bpp * target_clock;
+
+               max_frl_bw = intel_dp->dfp.pcon_max_frl_bw;
+
+               /* converting bw from Gbps to Kbps*/
+               max_frl_bw = max_frl_bw * 1000000;
+
+               if (target_bw > max_frl_bw)
+                       return MODE_CLOCK_HIGH;
+
+               return MODE_OK;
+       }
+
        if (intel_dp->dfp.max_dotclock &&
            target_clock > intel_dp->dfp.max_dotclock)
                return MODE_CLOCK_HIGH;
@@ -6480,13 +6499,18 @@ intel_dp_update_dfp(struct intel_dp *intel_dp,
                                                 intel_dp->downstream_ports,
                                                 edid);
 
+       intel_dp->dfp.pcon_max_frl_bw =
+               drm_dp_get_pcon_max_frl_bw(intel_dp->dpcd,
+                                          intel_dp->downstream_ports);
+
        drm_dbg_kms(&i915->drm,
-                   "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d\n",
+                   "[CONNECTOR:%d:%s] DFP max bpc %d, max dotclock %d, TMDS clock %d-%d, PCON Max FRL BW %dGbps\n",
                    connector->base.base.id, connector->base.name,
                    intel_dp->dfp.max_bpc,
                    intel_dp->dfp.max_dotclock,
                    intel_dp->dfp.min_tmds_clock,
-                   intel_dp->dfp.max_tmds_clock);
+                   intel_dp->dfp.max_tmds_clock,
+                   intel_dp->dfp.pcon_max_frl_bw);
 }
 
 static void
@@ -6578,6 +6602,8 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
        intel_dp->dfp.min_tmds_clock = 0;
        intel_dp->dfp.max_tmds_clock = 0;
 
+       intel_dp->dfp.pcon_max_frl_bw = 0;
+
        intel_dp->dfp.ycbcr_444_to_420 = false;
        connector->base.ycbcr_420_allowed = false;
 }