diff options
author | Ilia Mirkin <imirkin@alum.mit.edu> | 2018-09-03 20:57:37 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2018-10-10 19:54:10 -0400 |
commit | 9340d77f5327ea673a7f95f58139123d7a278243 (patch) | |
tree | 8a33e156d5646257aee9557f2b0094be12910383 /drivers/gpu | |
parent | 7a406f8a62ff0a3647f96f0cfdb518a99a01bf3f (diff) |
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 <imirkin@alum.mit.edu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_connector.c | 34 |
1 files changed, 22 insertions, 12 deletions
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) | |||
969 | } | 969 | } |
970 | 970 | ||
971 | static unsigned | 971 | static unsigned |
972 | get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi) | 972 | get_tmds_link_bandwidth(struct drm_connector *connector) |
973 | { | 973 | { |
974 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 974 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
975 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; | ||
975 | struct nouveau_drm *drm = nouveau_drm(connector->dev); | 976 | struct nouveau_drm *drm = nouveau_drm(connector->dev); |
976 | struct dcb_output *dcb = nv_connector->detected_encoder->dcb; | 977 | struct dcb_output *dcb = nv_connector->detected_encoder->dcb; |
978 | struct drm_display_info *info = NULL; | ||
979 | const unsigned duallink_scale = | ||
980 | nouveau_duallink && nv_encoder->dcb->duallink_possible ? 2 : 1; | ||
981 | |||
982 | if (drm_detect_hdmi_monitor(nv_connector->edid)) | ||
983 | info = &nv_connector->base.display_info; | ||
977 | 984 | ||
978 | if (hdmi) { | 985 | if (info) { |
979 | if (nouveau_hdmimhz > 0) | 986 | if (nouveau_hdmimhz > 0) |
980 | return nouveau_hdmimhz * 1000; | 987 | return nouveau_hdmimhz * 1000; |
981 | /* Note: these limits are conservative, some Fermi's | 988 | /* Note: these limits are conservative, some Fermi's |
982 | * can do 297 MHz. Unclear how this can be determined. | 989 | * can do 297 MHz. Unclear how this can be determined. |
983 | */ | 990 | */ |
991 | if (drm->client.device.info.chipset >= 0x120) { | ||
992 | const int max_tmds_clock = | ||
993 | info->hdmi.scdc.scrambling.supported ? | ||
994 | 594000 : 340000; | ||
995 | return info->max_tmds_clock ? | ||
996 | min(info->max_tmds_clock, max_tmds_clock) : | ||
997 | max_tmds_clock; | ||
998 | } | ||
984 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_KEPLER) | 999 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_KEPLER) |
985 | return 297000; | 1000 | return 297000; |
986 | if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI) | 1001 | 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) | |||
988 | } | 1003 | } |
989 | if (dcb->location != DCB_LOC_ON_CHIP || | 1004 | if (dcb->location != DCB_LOC_ON_CHIP || |
990 | drm->client.device.info.chipset >= 0x46) | 1005 | drm->client.device.info.chipset >= 0x46) |
991 | return 165000; | 1006 | return 165000 * duallink_scale; |
992 | else if (drm->client.device.info.chipset >= 0x40) | 1007 | else if (drm->client.device.info.chipset >= 0x40) |
993 | return 155000; | 1008 | return 155000 * duallink_scale; |
994 | else if (drm->client.device.info.chipset >= 0x18) | 1009 | else if (drm->client.device.info.chipset >= 0x18) |
995 | return 135000; | 1010 | return 135000 * duallink_scale; |
996 | else | 1011 | else |
997 | return 112000; | 1012 | return 112000 * duallink_scale; |
998 | } | 1013 | } |
999 | 1014 | ||
1000 | static enum drm_mode_status | 1015 | static enum drm_mode_status |
@@ -1006,7 +1021,6 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
1006 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); | 1021 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); |
1007 | unsigned min_clock = 25000, max_clock = min_clock; | 1022 | unsigned min_clock = 25000, max_clock = min_clock; |
1008 | unsigned clock = mode->clock; | 1023 | unsigned clock = mode->clock; |
1009 | bool hdmi; | ||
1010 | 1024 | ||
1011 | switch (nv_encoder->dcb->type) { | 1025 | switch (nv_encoder->dcb->type) { |
1012 | case DCB_OUTPUT_LVDS: | 1026 | case DCB_OUTPUT_LVDS: |
@@ -1019,11 +1033,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
1019 | max_clock = 400000; | 1033 | max_clock = 400000; |
1020 | break; | 1034 | break; |
1021 | case DCB_OUTPUT_TMDS: | 1035 | case DCB_OUTPUT_TMDS: |
1022 | hdmi = drm_detect_hdmi_monitor(nv_connector->edid); | 1036 | max_clock = get_tmds_link_bandwidth(connector); |
1023 | max_clock = get_tmds_link_bandwidth(connector, hdmi); | ||
1024 | if (!hdmi && nouveau_duallink && | ||
1025 | nv_encoder->dcb->duallink_possible) | ||
1026 | max_clock *= 2; | ||
1027 | break; | 1037 | break; |
1028 | case DCB_OUTPUT_ANALOG: | 1038 | case DCB_OUTPUT_ANALOG: |
1029 | max_clock = nv_encoder->dcb->crtconf.maxfreq; | 1039 | max_clock = nv_encoder->dcb->crtconf.maxfreq; |