Scrambling is required for supporting any mode over 340MHz. If it's not
supported, reject any modes that would require it.

Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu>
---
 drivers/gpu/drm/nouveau/nouveau_connector.c | 34 +++++++++++++++++++----------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c 
b/drivers/gpu/drm/nouveau/nouveau_connector.c
index af68eae4c626..64228cc1412c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -977,18 +977,33 @@ nouveau_connector_get_modes(struct drm_connector 
*connector)
 }
 
 static unsigned
-get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi)
+get_tmds_link_bandwidth(struct drm_connector *connector)
 {
        struct nouveau_connector *nv_connector = nouveau_connector(connector);
+       struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
        struct nouveau_drm *drm = nouveau_drm(connector->dev);
        struct dcb_output *dcb = nv_connector->detected_encoder->dcb;
+       struct drm_display_info *info = NULL;
+       const unsigned duallink_scale =
+               nouveau_duallink && nv_encoder->dcb->duallink_possible ? 2 : 1;
+
+       if (drm_detect_hdmi_monitor(nv_connector->edid))
+               info = &nv_connector->base.display_info;
 
-       if (hdmi) {
+       if (info) {
                if (nouveau_hdmimhz > 0)
                        return nouveau_hdmimhz * 1000;
                /* Note: these limits are conservative, some Fermi's
                 * can do 297 MHz. Unclear how this can be determined.
                 */
+               if (drm->client.device.info.chipset >= 0x120) {
+                       const int max_tmds_clock =
+                               info->hdmi.scdc.scrambling.supported ?
+                               594000 : 340000;
+                       return info->max_tmds_clock ?
+                               min(info->max_tmds_clock, max_tmds_clock) :
+                               max_tmds_clock;
+               }
                if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_KEPLER)
                        return 297000;
                if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI)
@@ -996,13 +1011,13 @@ get_tmds_link_bandwidth(struct drm_connector *connector, 
bool hdmi)
        }
        if (dcb->location != DCB_LOC_ON_CHIP ||
            drm->client.device.info.chipset >= 0x46)
-               return 165000;
+               return 165000 * duallink_scale;
        else if (drm->client.device.info.chipset >= 0x40)
-               return 155000;
+               return 155000 * duallink_scale;
        else if (drm->client.device.info.chipset >= 0x18)
-               return 135000;
+               return 135000 * duallink_scale;
        else
-               return 112000;
+               return 112000 * duallink_scale;
 }
 
 static enum drm_mode_status
@@ -1014,7 +1029,6 @@ nouveau_connector_mode_valid(struct drm_connector 
*connector,
        struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
        unsigned min_clock = 25000, max_clock = min_clock;
        unsigned clock = mode->clock;
-       bool hdmi;
 
        switch (nv_encoder->dcb->type) {
        case DCB_OUTPUT_LVDS:
@@ -1027,11 +1041,7 @@ nouveau_connector_mode_valid(struct drm_connector 
*connector,
                max_clock = 400000;
                break;
        case DCB_OUTPUT_TMDS:
-               hdmi = drm_detect_hdmi_monitor(nv_connector->edid);
-               max_clock = get_tmds_link_bandwidth(connector, hdmi);
-               if (!hdmi && nouveau_duallink &&
-                   nv_encoder->dcb->duallink_possible)
-                       max_clock *= 2;
+               max_clock = get_tmds_link_bandwidth(connector);
                break;
        case DCB_OUTPUT_ANALOG:
                max_clock = nv_encoder->dcb->crtconf.maxfreq;
-- 
2.16.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to