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 <imirkin@xxxxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel