diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_encoders.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 205 |
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 | ||
742 | void | 749 | void |
@@ -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 | ||
828 | void | 855 | void |
@@ -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 | ||
1045 | union external_encoder_control { | 1080 | union 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 | ||
1049 | static void | 1085 | static 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 | ||
1929 | void | 2048 | void |
1930 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) | 2049 | radeon_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)) |