aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_encoders.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_encoders.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c205
1 files changed, 165 insertions, 40 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 041943df966b..8fd184286c0b 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -641,7 +641,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
641 switch (connector->connector_type) { 641 switch (connector->connector_type) {
642 case DRM_MODE_CONNECTOR_DVII: 642 case DRM_MODE_CONNECTOR_DVII:
643 case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ 643 case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
644 if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 644 if (drm_detect_monitor_audio(radeon_connector->edid)) {
645 /* fix me */ 645 /* fix me */
646 if (ASIC_IS_DCE4(rdev)) 646 if (ASIC_IS_DCE4(rdev))
647 return ATOM_ENCODER_MODE_DVI; 647 return ATOM_ENCODER_MODE_DVI;
@@ -655,7 +655,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
655 case DRM_MODE_CONNECTOR_DVID: 655 case DRM_MODE_CONNECTOR_DVID:
656 case DRM_MODE_CONNECTOR_HDMIA: 656 case DRM_MODE_CONNECTOR_HDMIA:
657 default: 657 default:
658 if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 658 if (drm_detect_monitor_audio(radeon_connector->edid)) {
659 /* fix me */ 659 /* fix me */
660 if (ASIC_IS_DCE4(rdev)) 660 if (ASIC_IS_DCE4(rdev))
661 return ATOM_ENCODER_MODE_DVI; 661 return ATOM_ENCODER_MODE_DVI;
@@ -673,7 +673,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
673 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 673 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
674 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) 674 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
675 return ATOM_ENCODER_MODE_DP; 675 return ATOM_ENCODER_MODE_DP;
676 else if (drm_detect_hdmi_monitor(radeon_connector->edid)) { 676 else if (drm_detect_monitor_audio(radeon_connector->edid)) {
677 /* fix me */ 677 /* fix me */
678 if (ASIC_IS_DCE4(rdev)) 678 if (ASIC_IS_DCE4(rdev))
679 return ATOM_ENCODER_MODE_DVI; 679 return ATOM_ENCODER_MODE_DVI;
@@ -712,8 +712,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
712 * - 2 DIG encoder blocks. 712 * - 2 DIG encoder blocks.
713 * DIG1/2 can drive UNIPHY0/1/2 link A or link B 713 * DIG1/2 can drive UNIPHY0/1/2 link A or link B
714 * 714 *
715 * DCE 4.0 715 * DCE 4.0/5.0
716 * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B). 716 * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
717 * Supports up to 6 digital outputs 717 * Supports up to 6 digital outputs
718 * - 6 DIG encoder blocks. 718 * - 6 DIG encoder blocks.
719 * - DIG to PHY mapping is hardcoded 719 * - DIG to PHY mapping is hardcoded
@@ -724,6 +724,12 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
724 * DIG5 drives UNIPHY2 link A, A+B 724 * DIG5 drives UNIPHY2 link A, A+B
725 * DIG6 drives UNIPHY2 link B 725 * DIG6 drives UNIPHY2 link B
726 * 726 *
727 * DCE 4.1
728 * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B).
729 * Supports up to 6 digital outputs
730 * - 2 DIG encoder blocks.
731 * DIG1/2 can drive UNIPHY0/1/2 link A or link B
732 *
727 * Routing 733 * Routing
728 * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) 734 * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links)
729 * Examples: 735 * Examples:
@@ -737,6 +743,7 @@ union dig_encoder_control {
737 DIG_ENCODER_CONTROL_PS_ALLOCATION v1; 743 DIG_ENCODER_CONTROL_PS_ALLOCATION v1;
738 DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; 744 DIG_ENCODER_CONTROL_PARAMETERS_V2 v2;
739 DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; 745 DIG_ENCODER_CONTROL_PARAMETERS_V3 v3;
746 DIG_ENCODER_CONTROL_PARAMETERS_V4 v4;
740}; 747};
741 748
742void 749void
@@ -752,6 +759,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
752 uint8_t frev, crev; 759 uint8_t frev, crev;
753 int dp_clock = 0; 760 int dp_clock = 0;
754 int dp_lane_count = 0; 761 int dp_lane_count = 0;
762 int hpd_id = RADEON_HPD_NONE;
755 763
756 if (connector) { 764 if (connector) {
757 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 765 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -760,6 +768,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
760 768
761 dp_clock = dig_connector->dp_clock; 769 dp_clock = dig_connector->dp_clock;
762 dp_lane_count = dig_connector->dp_lane_count; 770 dp_lane_count = dig_connector->dp_lane_count;
771 hpd_id = radeon_connector->hpd.hpd;
763 } 772 }
764 773
765 /* no dig encoder assigned */ 774 /* no dig encoder assigned */
@@ -784,19 +793,36 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
784 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); 793 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
785 args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); 794 args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
786 795
787 if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { 796 if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) ||
788 if (dp_clock == 270000) 797 (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST))
789 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
790 args.v1.ucLaneNum = dp_lane_count; 798 args.v1.ucLaneNum = dp_lane_count;
791 } else if (radeon_encoder->pixel_clock > 165000) 799 else if (radeon_encoder->pixel_clock > 165000)
792 args.v1.ucLaneNum = 8; 800 args.v1.ucLaneNum = 8;
793 else 801 else
794 args.v1.ucLaneNum = 4; 802 args.v1.ucLaneNum = 4;
795 803
796 if (ASIC_IS_DCE4(rdev)) { 804 if (ASIC_IS_DCE5(rdev)) {
805 if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) ||
806 (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) {
807 if (dp_clock == 270000)
808 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
809 else if (dp_clock == 540000)
810 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
811 }
812 args.v4.acConfig.ucDigSel = dig->dig_encoder;
813 args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
814 if (hpd_id == RADEON_HPD_NONE)
815 args.v4.ucHPD_ID = 0;
816 else
817 args.v4.ucHPD_ID = hpd_id + 1;
818 } else if (ASIC_IS_DCE4(rdev)) {
819 if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
820 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
797 args.v3.acConfig.ucDigSel = dig->dig_encoder; 821 args.v3.acConfig.ucDigSel = dig->dig_encoder;
798 args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; 822 args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
799 } else { 823 } else {
824 if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
825 args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
800 switch (radeon_encoder->encoder_id) { 826 switch (radeon_encoder->encoder_id) {
801 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 827 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
802 args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; 828 args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
@@ -823,6 +849,7 @@ union dig_transmitter_control {
823 DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; 849 DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1;
824 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; 850 DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2;
825 DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; 851 DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3;
852 DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 v4;
826}; 853};
827 854
828void 855void
@@ -917,10 +944,18 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
917 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); 944 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
918 pll_id = radeon_crtc->pll_id; 945 pll_id = radeon_crtc->pll_id;
919 } 946 }
920 if (is_dp && rdev->clock.dp_extclk) 947
921 args.v3.acConfig.ucRefClkSource = 2; /* external src */ 948 if (ASIC_IS_DCE5(rdev)) {
922 else 949 if (is_dp && rdev->clock.dp_extclk)
923 args.v3.acConfig.ucRefClkSource = pll_id; 950 args.v4.acConfig.ucRefClkSource = 3; /* external src */
951 else
952 args.v4.acConfig.ucRefClkSource = pll_id;
953 } else {
954 if (is_dp && rdev->clock.dp_extclk)
955 args.v3.acConfig.ucRefClkSource = 2; /* external src */
956 else
957 args.v3.acConfig.ucRefClkSource = pll_id;
958 }
924 959
925 switch (radeon_encoder->encoder_id) { 960 switch (radeon_encoder->encoder_id) {
926 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: 961 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
@@ -1044,6 +1079,7 @@ atombios_set_edp_panel_power(struct drm_connector *connector, int action)
1044 1079
1045union external_encoder_control { 1080union external_encoder_control {
1046 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; 1081 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1;
1082 EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3;
1047}; 1083};
1048 1084
1049static void 1085static void
@@ -1054,6 +1090,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
1054 struct drm_device *dev = encoder->dev; 1090 struct drm_device *dev = encoder->dev;
1055 struct radeon_device *rdev = dev->dev_private; 1091 struct radeon_device *rdev = dev->dev_private;
1056 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1092 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1093 struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
1057 union external_encoder_control args; 1094 union external_encoder_control args;
1058 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 1095 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
1059 int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); 1096 int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
@@ -1061,6 +1098,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
1061 int dp_clock = 0; 1098 int dp_clock = 0;
1062 int dp_lane_count = 0; 1099 int dp_lane_count = 0;
1063 int connector_object_id = 0; 1100 int connector_object_id = 0;
1101 u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
1064 1102
1065 if (connector) { 1103 if (connector) {
1066 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1104 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -1099,6 +1137,37 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
1099 else 1137 else
1100 args.v1.sDigEncoder.ucLaneNum = 4; 1138 args.v1.sDigEncoder.ucLaneNum = 4;
1101 break; 1139 break;
1140 case 3:
1141 args.v3.sExtEncoder.ucAction = action;
1142 if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
1143 args.v3.sExtEncoder.usConnectorId = connector_object_id;
1144 else
1145 args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
1146 args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder);
1147
1148 if (args.v3.sExtEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
1149 if (dp_clock == 270000)
1150 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
1151 else if (dp_clock == 540000)
1152 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;
1153 args.v3.sExtEncoder.ucLaneNum = dp_lane_count;
1154 } else if (radeon_encoder->pixel_clock > 165000)
1155 args.v3.sExtEncoder.ucLaneNum = 8;
1156 else
1157 args.v3.sExtEncoder.ucLaneNum = 4;
1158 switch (ext_enum) {
1159 case GRAPH_OBJECT_ENUM_ID1:
1160 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1;
1161 break;
1162 case GRAPH_OBJECT_ENUM_ID2:
1163 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2;
1164 break;
1165 case GRAPH_OBJECT_ENUM_ID3:
1166 args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;
1167 break;
1168 }
1169 args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR;
1170 break;
1102 default: 1171 default:
1103 DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); 1172 DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
1104 return; 1173 return;
@@ -1158,6 +1227,8 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
1158 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; 1227 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
1159 int index = 0; 1228 int index = 0;
1160 bool is_dig = false; 1229 bool is_dig = false;
1230 bool is_dce5_dac = false;
1231 bool is_dce5_dvo = false;
1161 1232
1162 memset(&args, 0, sizeof(args)); 1233 memset(&args, 0, sizeof(args));
1163 1234
@@ -1180,7 +1251,9 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
1180 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); 1251 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
1181 break; 1252 break;
1182 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: 1253 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
1183 if (ASIC_IS_DCE3(rdev)) 1254 if (ASIC_IS_DCE5(rdev))
1255 is_dce5_dvo = true;
1256 else if (ASIC_IS_DCE3(rdev))
1184 is_dig = true; 1257 is_dig = true;
1185 else 1258 else
1186 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); 1259 index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
@@ -1196,12 +1269,16 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
1196 break; 1269 break;
1197 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 1270 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1198 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: 1271 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
1199 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) 1272 if (ASIC_IS_DCE5(rdev))
1200 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); 1273 is_dce5_dac = true;
1201 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) 1274 else {
1202 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); 1275 if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
1203 else 1276 index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
1204 index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); 1277 else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
1278 index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
1279 else
1280 index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
1281 }
1205 break; 1282 break;
1206 case ENCODER_OBJECT_ID_INTERNAL_DAC2: 1283 case ENCODER_OBJECT_ID_INTERNAL_DAC2:
1207 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: 1284 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
@@ -1260,6 +1337,28 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
1260 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); 1337 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
1261 break; 1338 break;
1262 } 1339 }
1340 } else if (is_dce5_dac) {
1341 switch (mode) {
1342 case DRM_MODE_DPMS_ON:
1343 atombios_dac_setup(encoder, ATOM_ENABLE);
1344 break;
1345 case DRM_MODE_DPMS_STANDBY:
1346 case DRM_MODE_DPMS_SUSPEND:
1347 case DRM_MODE_DPMS_OFF:
1348 atombios_dac_setup(encoder, ATOM_DISABLE);
1349 break;
1350 }
1351 } else if (is_dce5_dvo) {
1352 switch (mode) {
1353 case DRM_MODE_DPMS_ON:
1354 atombios_dvo_setup(encoder, ATOM_ENABLE);
1355 break;
1356 case DRM_MODE_DPMS_STANDBY:
1357 case DRM_MODE_DPMS_SUSPEND:
1358 case DRM_MODE_DPMS_OFF:
1359 atombios_dvo_setup(encoder, ATOM_DISABLE);
1360 break;
1361 }
1263 } else { 1362 } else {
1264 switch (mode) { 1363 switch (mode) {
1265 case DRM_MODE_DPMS_ON: 1364 case DRM_MODE_DPMS_ON:
@@ -1289,12 +1388,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
1289 switch (mode) { 1388 switch (mode) {
1290 case DRM_MODE_DPMS_ON: 1389 case DRM_MODE_DPMS_ON:
1291 default: 1390 default:
1292 action = ATOM_ENABLE; 1391 if (ASIC_IS_DCE41(rdev))
1392 action = EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT;
1393 else
1394 action = ATOM_ENABLE;
1293 break; 1395 break;
1294 case DRM_MODE_DPMS_STANDBY: 1396 case DRM_MODE_DPMS_STANDBY:
1295 case DRM_MODE_DPMS_SUSPEND: 1397 case DRM_MODE_DPMS_SUSPEND:
1296 case DRM_MODE_DPMS_OFF: 1398 case DRM_MODE_DPMS_OFF:
1297 action = ATOM_DISABLE; 1399 if (ASIC_IS_DCE41(rdev))
1400 action = EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT;
1401 else
1402 action = ATOM_DISABLE;
1298 break; 1403 break;
1299 } 1404 }
1300 atombios_external_encoder_setup(encoder, ext_encoder, action); 1405 atombios_external_encoder_setup(encoder, ext_encoder, action);
@@ -1483,27 +1588,35 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
1483 struct radeon_encoder_atom_dig *dig; 1588 struct radeon_encoder_atom_dig *dig;
1484 uint32_t dig_enc_in_use = 0; 1589 uint32_t dig_enc_in_use = 0;
1485 1590
1591 /* DCE4/5 */
1486 if (ASIC_IS_DCE4(rdev)) { 1592 if (ASIC_IS_DCE4(rdev)) {
1487 dig = radeon_encoder->enc_priv; 1593 dig = radeon_encoder->enc_priv;
1488 switch (radeon_encoder->encoder_id) { 1594 if (ASIC_IS_DCE41(rdev)) {
1489 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1490 if (dig->linkb) 1595 if (dig->linkb)
1491 return 1; 1596 return 1;
1492 else 1597 else
1493 return 0; 1598 return 0;
1494 break; 1599 } else {
1495 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: 1600 switch (radeon_encoder->encoder_id) {
1496 if (dig->linkb) 1601 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
1497 return 3; 1602 if (dig->linkb)
1498 else 1603 return 1;
1499 return 2; 1604 else
1500 break; 1605 return 0;
1501 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: 1606 break;
1502 if (dig->linkb) 1607 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
1503 return 5; 1608 if (dig->linkb)
1504 else 1609 return 3;
1505 return 4; 1610 else
1506 break; 1611 return 2;
1612 break;
1613 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
1614 if (dig->linkb)
1615 return 5;
1616 else
1617 return 4;
1618 break;
1619 }
1507 } 1620 }
1508 } 1621 }
1509 1622
@@ -1610,7 +1723,13 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
1610 } 1723 }
1611 1724
1612 if (ext_encoder) { 1725 if (ext_encoder) {
1613 atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); 1726 if (ASIC_IS_DCE41(rdev)) {
1727 atombios_external_encoder_setup(encoder, ext_encoder,
1728 EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
1729 atombios_external_encoder_setup(encoder, ext_encoder,
1730 EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
1731 } else
1732 atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
1614 } 1733 }
1615 1734
1616 atombios_apply_encoder_quirks(encoder, adjusted_mode); 1735 atombios_apply_encoder_quirks(encoder, adjusted_mode);
@@ -1927,7 +2046,10 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
1927} 2046}
1928 2047
1929void 2048void
1930radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) 2049radeon_add_atom_encoder(struct drm_device *dev,
2050 uint32_t encoder_enum,
2051 uint32_t supported_device,
2052 u16 caps)
1931{ 2053{
1932 struct radeon_device *rdev = dev->dev_private; 2054 struct radeon_device *rdev = dev->dev_private;
1933 struct drm_encoder *encoder; 2055 struct drm_encoder *encoder;
@@ -1970,6 +2092,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
1970 radeon_encoder->rmx_type = RMX_OFF; 2092 radeon_encoder->rmx_type = RMX_OFF;
1971 radeon_encoder->underscan_type = UNDERSCAN_OFF; 2093 radeon_encoder->underscan_type = UNDERSCAN_OFF;
1972 radeon_encoder->is_ext_encoder = false; 2094 radeon_encoder->is_ext_encoder = false;
2095 radeon_encoder->caps = caps;
1973 2096
1974 switch (radeon_encoder->encoder_id) { 2097 switch (radeon_encoder->encoder_id) {
1975 case ENCODER_OBJECT_ID_INTERNAL_LVDS: 2098 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
@@ -2029,6 +2152,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t
2029 case ENCODER_OBJECT_ID_TITFP513: 2152 case ENCODER_OBJECT_ID_TITFP513:
2030 case ENCODER_OBJECT_ID_VT1623: 2153 case ENCODER_OBJECT_ID_VT1623:
2031 case ENCODER_OBJECT_ID_HDMI_SI1930: 2154 case ENCODER_OBJECT_ID_HDMI_SI1930:
2155 case ENCODER_OBJECT_ID_TRAVIS:
2156 case ENCODER_OBJECT_ID_NUTMEG:
2032 /* these are handled by the primary encoders */ 2157 /* these are handled by the primary encoders */
2033 radeon_encoder->is_ext_encoder = true; 2158 radeon_encoder->is_ext_encoder = true;
2034 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) 2159 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))