diff options
| author | Alex Deucher <alexander.deucher@amd.com> | 2012-01-20 15:03:30 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2012-01-24 12:35:52 -0500 |
| commit | 9aa59993e226af94088adaee993eb8cfd33ae295 (patch) | |
| tree | c779fd613a1ce2adbf2b6fa7350a8fdb5ffe76a7 | |
| parent | 27d9cc8428367e0fec2fc0fc6385e9241b079c3a (diff) | |
drm/radeon/kms: refine TMDS dual link checks
HDMI 1.3 defines single link clocks up to 340 Mhz.
Refine the current dual link checks to only enable
dual link for DVI > 165 Mhz or HDMI > 340 Mhz if the
hw supports HDMI 1.3 (DCE3+).
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=44755
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_encoders.c | 57 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 77 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 4 |
4 files changed, 105 insertions, 37 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 807b89b4933f..891935271d34 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -518,6 +518,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 518 | int encoder_mode = 0; | 518 | int encoder_mode = 0; |
| 519 | u32 dp_clock = mode->clock; | 519 | u32 dp_clock = mode->clock; |
| 520 | int bpc = 8; | 520 | int bpc = 8; |
| 521 | bool is_duallink = false; | ||
| 521 | 522 | ||
| 522 | /* reset the pll flags */ | 523 | /* reset the pll flags */ |
| 523 | pll->flags = 0; | 524 | pll->flags = 0; |
| @@ -552,6 +553,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 552 | if (connector && connector->display_info.bpc) | 553 | if (connector && connector->display_info.bpc) |
| 553 | bpc = connector->display_info.bpc; | 554 | bpc = connector->display_info.bpc; |
| 554 | encoder_mode = atombios_get_encoder_mode(encoder); | 555 | encoder_mode = atombios_get_encoder_mode(encoder); |
| 556 | is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); | ||
| 555 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || | 557 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
| 556 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { | 558 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { |
| 557 | if (connector) { | 559 | if (connector) { |
| @@ -647,7 +649,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 647 | if (dig->coherent_mode) | 649 | if (dig->coherent_mode) |
| 648 | args.v3.sInput.ucDispPllConfig |= | 650 | args.v3.sInput.ucDispPllConfig |= |
| 649 | DISPPLL_CONFIG_COHERENT_MODE; | 651 | DISPPLL_CONFIG_COHERENT_MODE; |
| 650 | if (mode->clock > 165000) | 652 | if (is_duallink) |
| 651 | args.v3.sInput.ucDispPllConfig |= | 653 | args.v3.sInput.ucDispPllConfig |= |
| 652 | DISPPLL_CONFIG_DUAL_LINK; | 654 | DISPPLL_CONFIG_DUAL_LINK; |
| 653 | } | 655 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index f2f14a20a493..b88c4608731b 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -57,22 +57,6 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | |||
| 57 | } | 57 | } |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | static struct drm_connector * | ||
| 61 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
| 62 | { | ||
| 63 | struct drm_device *dev = encoder->dev; | ||
| 64 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 65 | struct drm_connector *connector; | ||
| 66 | struct radeon_connector *radeon_connector; | ||
| 67 | |||
| 68 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 69 | radeon_connector = to_radeon_connector(connector); | ||
| 70 | if (radeon_encoder->devices & radeon_connector->devices) | ||
| 71 | return connector; | ||
| 72 | } | ||
| 73 | return NULL; | ||
| 74 | } | ||
| 75 | |||
| 76 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | 60 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, |
| 77 | struct drm_display_mode *mode, | 61 | struct drm_display_mode *mode, |
| 78 | struct drm_display_mode *adjusted_mode) | 62 | struct drm_display_mode *adjusted_mode) |
| @@ -253,7 +237,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) | |||
| 253 | /* R4xx, R5xx */ | 237 | /* R4xx, R5xx */ |
| 254 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; | 238 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; |
| 255 | 239 | ||
| 256 | if (radeon_encoder->pixel_clock > 165000) | 240 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 257 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 241 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
| 258 | 242 | ||
| 259 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; | 243 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; |
| @@ -265,7 +249,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) | |||
| 265 | /* DFP1, CRT1, TV1 depending on the type of port */ | 249 | /* DFP1, CRT1, TV1 depending on the type of port */ |
| 266 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; | 250 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; |
| 267 | 251 | ||
| 268 | if (radeon_encoder->pixel_clock > 165000) | 252 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 269 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; | 253 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; |
| 270 | break; | 254 | break; |
| 271 | case 3: | 255 | case 3: |
| @@ -349,7 +333,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
| 349 | } else { | 333 | } else { |
| 350 | if (dig->linkb) | 334 | if (dig->linkb) |
| 351 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 335 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
| 352 | if (radeon_encoder->pixel_clock > 165000) | 336 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 353 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 337 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
| 354 | /*if (pScrn->rgbBits == 8) */ | 338 | /*if (pScrn->rgbBits == 8) */ |
| 355 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | 339 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; |
| @@ -388,7 +372,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
| 388 | } else { | 372 | } else { |
| 389 | if (dig->linkb) | 373 | if (dig->linkb) |
| 390 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 374 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
| 391 | if (radeon_encoder->pixel_clock > 165000) | 375 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 392 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 376 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
| 393 | } | 377 | } |
| 394 | break; | 378 | break; |
| @@ -587,7 +571,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
| 587 | 571 | ||
| 588 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 572 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) |
| 589 | args.v1.ucLaneNum = dp_lane_count; | 573 | args.v1.ucLaneNum = dp_lane_count; |
| 590 | else if (radeon_encoder->pixel_clock > 165000) | 574 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 591 | args.v1.ucLaneNum = 8; | 575 | args.v1.ucLaneNum = 8; |
| 592 | else | 576 | else |
| 593 | args.v1.ucLaneNum = 4; | 577 | args.v1.ucLaneNum = 4; |
| @@ -622,7 +606,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
| 622 | 606 | ||
| 623 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 607 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) |
| 624 | args.v3.ucLaneNum = dp_lane_count; | 608 | args.v3.ucLaneNum = dp_lane_count; |
| 625 | else if (radeon_encoder->pixel_clock > 165000) | 609 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 626 | args.v3.ucLaneNum = 8; | 610 | args.v3.ucLaneNum = 8; |
| 627 | else | 611 | else |
| 628 | args.v3.ucLaneNum = 4; | 612 | args.v3.ucLaneNum = 4; |
| @@ -662,7 +646,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
| 662 | 646 | ||
| 663 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 647 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) |
| 664 | args.v4.ucLaneNum = dp_lane_count; | 648 | args.v4.ucLaneNum = dp_lane_count; |
| 665 | else if (radeon_encoder->pixel_clock > 165000) | 649 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 666 | args.v4.ucLaneNum = 8; | 650 | args.v4.ucLaneNum = 8; |
| 667 | else | 651 | else |
| 668 | args.v4.ucLaneNum = 4; | 652 | args.v4.ucLaneNum = 4; |
| @@ -806,7 +790,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 806 | if (is_dp) | 790 | if (is_dp) |
| 807 | args.v1.usPixelClock = | 791 | args.v1.usPixelClock = |
| 808 | cpu_to_le16(dp_clock / 10); | 792 | cpu_to_le16(dp_clock / 10); |
| 809 | else if (radeon_encoder->pixel_clock > 165000) | 793 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 810 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 794 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 811 | else | 795 | else |
| 812 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 796 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| @@ -821,7 +805,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 821 | 805 | ||
| 822 | if ((rdev->flags & RADEON_IS_IGP) && | 806 | if ((rdev->flags & RADEON_IS_IGP) && |
| 823 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | 807 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { |
| 824 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | 808 | if (is_dp || |
| 809 | !radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) { | ||
| 825 | if (igp_lane_info & 0x1) | 810 | if (igp_lane_info & 0x1) |
| 826 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 811 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
| 827 | else if (igp_lane_info & 0x2) | 812 | else if (igp_lane_info & 0x2) |
| @@ -848,7 +833,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 848 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 833 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
| 849 | if (dig->coherent_mode) | 834 | if (dig->coherent_mode) |
| 850 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | 835 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; |
| 851 | if (radeon_encoder->pixel_clock > 165000) | 836 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 852 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | 837 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; |
| 853 | } | 838 | } |
| 854 | break; | 839 | break; |
| @@ -863,7 +848,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 863 | if (is_dp) | 848 | if (is_dp) |
| 864 | args.v2.usPixelClock = | 849 | args.v2.usPixelClock = |
| 865 | cpu_to_le16(dp_clock / 10); | 850 | cpu_to_le16(dp_clock / 10); |
| 866 | else if (radeon_encoder->pixel_clock > 165000) | 851 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 867 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 852 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 868 | else | 853 | else |
| 869 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 854 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| @@ -891,7 +876,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 891 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 876 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
| 892 | if (dig->coherent_mode) | 877 | if (dig->coherent_mode) |
| 893 | args.v2.acConfig.fCoherentMode = 1; | 878 | args.v2.acConfig.fCoherentMode = 1; |
| 894 | if (radeon_encoder->pixel_clock > 165000) | 879 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 895 | args.v2.acConfig.fDualLinkConnector = 1; | 880 | args.v2.acConfig.fDualLinkConnector = 1; |
| 896 | } | 881 | } |
| 897 | break; | 882 | break; |
| @@ -906,7 +891,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 906 | if (is_dp) | 891 | if (is_dp) |
| 907 | args.v3.usPixelClock = | 892 | args.v3.usPixelClock = |
| 908 | cpu_to_le16(dp_clock / 10); | 893 | cpu_to_le16(dp_clock / 10); |
| 909 | else if (radeon_encoder->pixel_clock > 165000) | 894 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 910 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 895 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 911 | else | 896 | else |
| 912 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 897 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| @@ -914,7 +899,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 914 | 899 | ||
| 915 | if (is_dp) | 900 | if (is_dp) |
| 916 | args.v3.ucLaneNum = dp_lane_count; | 901 | args.v3.ucLaneNum = dp_lane_count; |
| 917 | else if (radeon_encoder->pixel_clock > 165000) | 902 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 918 | args.v3.ucLaneNum = 8; | 903 | args.v3.ucLaneNum = 8; |
| 919 | else | 904 | else |
| 920 | args.v3.ucLaneNum = 4; | 905 | args.v3.ucLaneNum = 4; |
| @@ -951,7 +936,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 951 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 936 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
| 952 | if (dig->coherent_mode) | 937 | if (dig->coherent_mode) |
| 953 | args.v3.acConfig.fCoherentMode = 1; | 938 | args.v3.acConfig.fCoherentMode = 1; |
| 954 | if (radeon_encoder->pixel_clock > 165000) | 939 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 955 | args.v3.acConfig.fDualLinkConnector = 1; | 940 | args.v3.acConfig.fDualLinkConnector = 1; |
| 956 | } | 941 | } |
| 957 | break; | 942 | break; |
| @@ -966,7 +951,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 966 | if (is_dp) | 951 | if (is_dp) |
| 967 | args.v4.usPixelClock = | 952 | args.v4.usPixelClock = |
| 968 | cpu_to_le16(dp_clock / 10); | 953 | cpu_to_le16(dp_clock / 10); |
| 969 | else if (radeon_encoder->pixel_clock > 165000) | 954 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 970 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 955 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 971 | else | 956 | else |
| 972 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 957 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| @@ -974,7 +959,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 974 | 959 | ||
| 975 | if (is_dp) | 960 | if (is_dp) |
| 976 | args.v4.ucLaneNum = dp_lane_count; | 961 | args.v4.ucLaneNum = dp_lane_count; |
| 977 | else if (radeon_encoder->pixel_clock > 165000) | 962 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 978 | args.v4.ucLaneNum = 8; | 963 | args.v4.ucLaneNum = 8; |
| 979 | else | 964 | else |
| 980 | args.v4.ucLaneNum = 4; | 965 | args.v4.ucLaneNum = 4; |
| @@ -1014,7 +999,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 1014 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 999 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
| 1015 | if (dig->coherent_mode) | 1000 | if (dig->coherent_mode) |
| 1016 | args.v4.acConfig.fCoherentMode = 1; | 1001 | args.v4.acConfig.fCoherentMode = 1; |
| 1017 | if (radeon_encoder->pixel_clock > 165000) | 1002 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 1018 | args.v4.acConfig.fDualLinkConnector = 1; | 1003 | args.v4.acConfig.fDualLinkConnector = 1; |
| 1019 | } | 1004 | } |
| 1020 | break; | 1005 | break; |
| @@ -1137,7 +1122,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
| 1137 | if (dp_clock == 270000) | 1122 | if (dp_clock == 270000) |
| 1138 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | 1123 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
| 1139 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; | 1124 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; |
| 1140 | } else if (radeon_encoder->pixel_clock > 165000) | 1125 | } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 1141 | args.v1.sDigEncoder.ucLaneNum = 8; | 1126 | args.v1.sDigEncoder.ucLaneNum = 8; |
| 1142 | else | 1127 | else |
| 1143 | args.v1.sDigEncoder.ucLaneNum = 4; | 1128 | args.v1.sDigEncoder.ucLaneNum = 4; |
| @@ -1156,7 +1141,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
| 1156 | else if (dp_clock == 540000) | 1141 | else if (dp_clock == 540000) |
| 1157 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; | 1142 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; |
| 1158 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; | 1143 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; |
| 1159 | } else if (radeon_encoder->pixel_clock > 165000) | 1144 | } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 1160 | args.v3.sExtEncoder.ucLaneNum = 8; | 1145 | args.v3.sExtEncoder.ucLaneNum = 8; |
| 1161 | else | 1146 | else |
| 1162 | args.v3.sExtEncoder.ucLaneNum = 4; | 1147 | args.v3.sExtEncoder.ucLaneNum = 4; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 4b27efa4405b..9419c51bcf50 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -202,6 +202,22 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
| 202 | return NULL; | 202 | return NULL; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | struct drm_connector * | ||
| 206 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
| 207 | { | ||
| 208 | struct drm_device *dev = encoder->dev; | ||
| 209 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 210 | struct drm_connector *connector; | ||
| 211 | struct radeon_connector *radeon_connector; | ||
| 212 | |||
| 213 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 214 | radeon_connector = to_radeon_connector(connector); | ||
| 215 | if (radeon_encoder->devices & radeon_connector->devices) | ||
| 216 | return connector; | ||
| 217 | } | ||
| 218 | return NULL; | ||
| 219 | } | ||
| 220 | |||
| 205 | struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) | 221 | struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) |
| 206 | { | 222 | { |
| 207 | struct drm_device *dev = encoder->dev; | 223 | struct drm_device *dev = encoder->dev; |
| @@ -288,3 +304,64 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder, | |||
| 288 | 304 | ||
| 289 | } | 305 | } |
| 290 | 306 | ||
| 307 | bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | ||
| 308 | u32 pixel_clock) | ||
| 309 | { | ||
| 310 | struct drm_device *dev = encoder->dev; | ||
| 311 | struct radeon_device *rdev = dev->dev_private; | ||
| 312 | struct drm_connector *connector; | ||
| 313 | struct radeon_connector *radeon_connector; | ||
| 314 | struct radeon_connector_atom_dig *dig_connector; | ||
| 315 | |||
| 316 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 317 | /* if we don't have an active device yet, just use one of | ||
| 318 | * the connectors tied to the encoder. | ||
| 319 | */ | ||
| 320 | if (!connector) | ||
| 321 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
| 322 | radeon_connector = to_radeon_connector(connector); | ||
| 323 | |||
| 324 | switch (connector->connector_type) { | ||
| 325 | case DRM_MODE_CONNECTOR_DVII: | ||
| 326 | case DRM_MODE_CONNECTOR_HDMIB: | ||
| 327 | if (radeon_connector->use_digital) { | ||
| 328 | /* HDMI 1.3 supports up to 340 Mhz over single link */ | ||
| 329 | if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
| 330 | if (pixel_clock > 340000) | ||
| 331 | return true; | ||
| 332 | else | ||
| 333 | return false; | ||
| 334 | } else { | ||
| 335 | if (pixel_clock > 165000) | ||
| 336 | return true; | ||
| 337 | else | ||
| 338 | return false; | ||
| 339 | } | ||
| 340 | } else | ||
| 341 | return false; | ||
| 342 | case DRM_MODE_CONNECTOR_DVID: | ||
| 343 | case DRM_MODE_CONNECTOR_HDMIA: | ||
| 344 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
| 345 | dig_connector = radeon_connector->con_priv; | ||
| 346 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | ||
| 347 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | ||
| 348 | return false; | ||
| 349 | else { | ||
| 350 | /* HDMI 1.3 supports up to 340 Mhz over single link */ | ||
| 351 | if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
| 352 | if (pixel_clock > 340000) | ||
| 353 | return true; | ||
| 354 | else | ||
| 355 | return false; | ||
| 356 | } else { | ||
| 357 | if (pixel_clock > 165000) | ||
| 358 | return true; | ||
| 359 | else | ||
| 360 | return false; | ||
| 361 | } | ||
| 362 | } | ||
| 363 | default: | ||
| 364 | return false; | ||
| 365 | } | ||
| 366 | } | ||
| 367 | |||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index d34dcb6ac384..4330e3253573 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -467,6 +467,10 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev); | |||
| 467 | 467 | ||
| 468 | extern struct drm_connector * | 468 | extern struct drm_connector * |
| 469 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); | 469 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); |
| 470 | extern struct drm_connector * | ||
| 471 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder); | ||
| 472 | extern bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | ||
| 473 | u32 pixel_clock); | ||
| 470 | 474 | ||
| 471 | extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); | 475 | extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); |
| 472 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); | 476 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); |
