From: Ilia Mirkin Date: Tue, 4 Sep 2018 00:57:37 +0000 (-0400) Subject: drm/nouveau/disp: take sink support into account for exposing 594mhz X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=9340d77f5327ea673a7f95f58139123d7a278243;p=openwrt%2Fstaging%2Fblogic.git drm/nouveau/disp: take sink support into account for exposing 594mhz 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 Signed-off-by: Ben Skeggs --- diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index a22f4fd03a06..fd80661dff92 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -969,18 +969,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) @@ -988,13 +1003,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 @@ -1006,7 +1021,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: @@ -1019,11 +1033,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;