diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_encoders.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 252 |
1 files changed, 207 insertions, 45 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index b4274883227f..1b557554696e 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -229,6 +229,22 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
229 | return NULL; | 229 | return NULL; |
230 | } | 230 | } |
231 | 231 | ||
232 | static struct drm_connector * | ||
233 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
234 | { | ||
235 | struct drm_device *dev = encoder->dev; | ||
236 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
237 | struct drm_connector *connector; | ||
238 | struct radeon_connector *radeon_connector; | ||
239 | |||
240 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
241 | radeon_connector = to_radeon_connector(connector); | ||
242 | if (radeon_encoder->devices & radeon_connector->devices) | ||
243 | return connector; | ||
244 | } | ||
245 | return NULL; | ||
246 | } | ||
247 | |||
232 | struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder) | 248 | struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder) |
233 | { | 249 | { |
234 | struct drm_device *dev = encoder->dev; | 250 | struct drm_device *dev = encoder->dev; |
@@ -250,6 +266,25 @@ struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder | |||
250 | return NULL; | 266 | return NULL; |
251 | } | 267 | } |
252 | 268 | ||
269 | bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder) | ||
270 | { | ||
271 | struct drm_encoder *other_encoder = radeon_atom_get_external_encoder(encoder); | ||
272 | |||
273 | if (other_encoder) { | ||
274 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder); | ||
275 | |||
276 | switch (radeon_encoder->encoder_id) { | ||
277 | case ENCODER_OBJECT_ID_TRAVIS: | ||
278 | case ENCODER_OBJECT_ID_NUTMEG: | ||
279 | return true; | ||
280 | default: | ||
281 | return false; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | return false; | ||
286 | } | ||
287 | |||
253 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | 288 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, |
254 | struct drm_display_mode *adjusted_mode) | 289 | struct drm_display_mode *adjusted_mode) |
255 | { | 290 | { |
@@ -621,6 +656,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
621 | struct radeon_connector *radeon_connector; | 656 | struct radeon_connector *radeon_connector; |
622 | struct radeon_connector_atom_dig *dig_connector; | 657 | struct radeon_connector_atom_dig *dig_connector; |
623 | 658 | ||
659 | /* dp bridges are always DP */ | ||
660 | if (radeon_encoder_is_dp_bridge(encoder)) | ||
661 | return ATOM_ENCODER_MODE_DP; | ||
662 | |||
624 | connector = radeon_get_connector_for_encoder(encoder); | 663 | connector = radeon_get_connector_for_encoder(encoder); |
625 | if (!connector) { | 664 | if (!connector) { |
626 | switch (radeon_encoder->encoder_id) { | 665 | switch (radeon_encoder->encoder_id) { |
@@ -668,7 +707,6 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
668 | return ATOM_ENCODER_MODE_LVDS; | 707 | return ATOM_ENCODER_MODE_LVDS; |
669 | break; | 708 | break; |
670 | case DRM_MODE_CONNECTOR_DisplayPort: | 709 | case DRM_MODE_CONNECTOR_DisplayPort: |
671 | case DRM_MODE_CONNECTOR_eDP: | ||
672 | dig_connector = radeon_connector->con_priv; | 710 | dig_connector = radeon_connector->con_priv; |
673 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 711 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
674 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 712 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
@@ -682,6 +720,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
682 | } else | 720 | } else |
683 | return ATOM_ENCODER_MODE_DVI; | 721 | return ATOM_ENCODER_MODE_DVI; |
684 | break; | 722 | break; |
723 | case DRM_MODE_CONNECTOR_eDP: | ||
724 | return ATOM_ENCODER_MODE_DP; | ||
685 | case DRM_MODE_CONNECTOR_DVIA: | 725 | case DRM_MODE_CONNECTOR_DVIA: |
686 | case DRM_MODE_CONNECTOR_VGA: | 726 | case DRM_MODE_CONNECTOR_VGA: |
687 | return ATOM_ENCODER_MODE_CRT; | 727 | return ATOM_ENCODER_MODE_CRT; |
@@ -747,7 +787,7 @@ union dig_encoder_control { | |||
747 | }; | 787 | }; |
748 | 788 | ||
749 | void | 789 | void |
750 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | 790 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode) |
751 | { | 791 | { |
752 | struct drm_device *dev = encoder->dev; | 792 | struct drm_device *dev = encoder->dev; |
753 | struct radeon_device *rdev = dev->dev_private; | 793 | struct radeon_device *rdev = dev->dev_private; |
@@ -760,6 +800,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
760 | int dp_clock = 0; | 800 | int dp_clock = 0; |
761 | int dp_lane_count = 0; | 801 | int dp_lane_count = 0; |
762 | int hpd_id = RADEON_HPD_NONE; | 802 | int hpd_id = RADEON_HPD_NONE; |
803 | int bpc = 8; | ||
763 | 804 | ||
764 | if (connector) { | 805 | if (connector) { |
765 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 806 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -769,6 +810,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
769 | dp_clock = dig_connector->dp_clock; | 810 | dp_clock = dig_connector->dp_clock; |
770 | dp_lane_count = dig_connector->dp_lane_count; | 811 | dp_lane_count = dig_connector->dp_lane_count; |
771 | hpd_id = radeon_connector->hpd.hpd; | 812 | hpd_id = radeon_connector->hpd.hpd; |
813 | bpc = connector->display_info.bpc; | ||
772 | } | 814 | } |
773 | 815 | ||
774 | /* no dig encoder assigned */ | 816 | /* no dig encoder assigned */ |
@@ -791,7 +833,10 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
791 | 833 | ||
792 | args.v1.ucAction = action; | 834 | args.v1.ucAction = action; |
793 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 835 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
794 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | 836 | if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE) |
837 | args.v3.ucPanelMode = panel_mode; | ||
838 | else | ||
839 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
795 | 840 | ||
796 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) || | 841 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) || |
797 | (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) | 842 | (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST)) |
@@ -810,7 +855,27 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
810 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; | 855 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ; |
811 | } | 856 | } |
812 | args.v4.acConfig.ucDigSel = dig->dig_encoder; | 857 | args.v4.acConfig.ucDigSel = dig->dig_encoder; |
813 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | 858 | switch (bpc) { |
859 | case 0: | ||
860 | args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
861 | break; | ||
862 | case 6: | ||
863 | args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
864 | break; | ||
865 | case 8: | ||
866 | default: | ||
867 | args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
868 | break; | ||
869 | case 10: | ||
870 | args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
871 | break; | ||
872 | case 12: | ||
873 | args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
874 | break; | ||
875 | case 16: | ||
876 | args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
877 | break; | ||
878 | } | ||
814 | if (hpd_id == RADEON_HPD_NONE) | 879 | if (hpd_id == RADEON_HPD_NONE) |
815 | args.v4.ucHPD_ID = 0; | 880 | args.v4.ucHPD_ID = 0; |
816 | else | 881 | else |
@@ -819,7 +884,27 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
819 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | 884 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) |
820 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; | 885 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; |
821 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | 886 | args.v3.acConfig.ucDigSel = dig->dig_encoder; |
822 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | 887 | switch (bpc) { |
888 | case 0: | ||
889 | args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
890 | break; | ||
891 | case 6: | ||
892 | args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
893 | break; | ||
894 | case 8: | ||
895 | default: | ||
896 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
897 | break; | ||
898 | case 10: | ||
899 | args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
900 | break; | ||
901 | case 12: | ||
902 | args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
903 | break; | ||
904 | case 16: | ||
905 | args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
906 | break; | ||
907 | } | ||
823 | } else { | 908 | } else { |
824 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) | 909 | if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000)) |
825 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | 910 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
@@ -859,7 +944,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
859 | struct radeon_device *rdev = dev->dev_private; | 944 | struct radeon_device *rdev = dev->dev_private; |
860 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 945 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
861 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 946 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
862 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 947 | struct drm_connector *connector; |
863 | union dig_transmitter_control args; | 948 | union dig_transmitter_control args; |
864 | int index = 0; | 949 | int index = 0; |
865 | uint8_t frev, crev; | 950 | uint8_t frev, crev; |
@@ -870,6 +955,11 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
870 | int connector_object_id = 0; | 955 | int connector_object_id = 0; |
871 | int igp_lane_info = 0; | 956 | int igp_lane_info = 0; |
872 | 957 | ||
958 | if (action == ATOM_TRANSMITTER_ACTION_INIT) | ||
959 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
960 | else | ||
961 | connector = radeon_get_connector_for_encoder(encoder); | ||
962 | |||
873 | if (connector) { | 963 | if (connector) { |
874 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 964 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
875 | struct radeon_connector_atom_dig *dig_connector = | 965 | struct radeon_connector_atom_dig *dig_connector = |
@@ -931,10 +1021,10 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
931 | else | 1021 | else |
932 | args.v3.ucLaneNum = 4; | 1022 | args.v3.ucLaneNum = 4; |
933 | 1023 | ||
934 | if (dig->linkb) { | 1024 | if (dig->linkb) |
935 | args.v3.acConfig.ucLinkSel = 1; | 1025 | args.v3.acConfig.ucLinkSel = 1; |
1026 | if (dig->dig_encoder & 1) | ||
936 | args.v3.acConfig.ucEncoderSel = 1; | 1027 | args.v3.acConfig.ucEncoderSel = 1; |
937 | } | ||
938 | 1028 | ||
939 | /* Select the PLL for the PHY | 1029 | /* Select the PLL for the PHY |
940 | * DP PHY should be clocked from external src if there is | 1030 | * DP PHY should be clocked from external src if there is |
@@ -946,11 +1036,16 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
946 | } | 1036 | } |
947 | 1037 | ||
948 | if (ASIC_IS_DCE5(rdev)) { | 1038 | if (ASIC_IS_DCE5(rdev)) { |
949 | if (is_dp && rdev->clock.dp_extclk) | 1039 | /* On DCE5 DCPLL usually generates the DP ref clock */ |
950 | args.v4.acConfig.ucRefClkSource = 3; /* external src */ | 1040 | if (is_dp) { |
951 | else | 1041 | if (rdev->clock.dp_extclk) |
1042 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK; | ||
1043 | else | ||
1044 | args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL; | ||
1045 | } else | ||
952 | args.v4.acConfig.ucRefClkSource = pll_id; | 1046 | args.v4.acConfig.ucRefClkSource = pll_id; |
953 | } else { | 1047 | } else { |
1048 | /* On DCE4, if there is an external clock, it generates the DP ref clock */ | ||
954 | if (is_dp && rdev->clock.dp_extclk) | 1049 | if (is_dp && rdev->clock.dp_extclk) |
955 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | 1050 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ |
956 | else | 1051 | else |
@@ -1047,7 +1142,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
1047 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 1142 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1048 | } | 1143 | } |
1049 | 1144 | ||
1050 | void | 1145 | bool |
1051 | atombios_set_edp_panel_power(struct drm_connector *connector, int action) | 1146 | atombios_set_edp_panel_power(struct drm_connector *connector, int action) |
1052 | { | 1147 | { |
1053 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 1148 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -1058,23 +1153,37 @@ atombios_set_edp_panel_power(struct drm_connector *connector, int action) | |||
1058 | uint8_t frev, crev; | 1153 | uint8_t frev, crev; |
1059 | 1154 | ||
1060 | if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) | 1155 | if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) |
1061 | return; | 1156 | goto done; |
1062 | 1157 | ||
1063 | if (!ASIC_IS_DCE4(rdev)) | 1158 | if (!ASIC_IS_DCE4(rdev)) |
1064 | return; | 1159 | goto done; |
1065 | 1160 | ||
1066 | if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) && | 1161 | if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) && |
1067 | (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) | 1162 | (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) |
1068 | return; | 1163 | goto done; |
1069 | 1164 | ||
1070 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 1165 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
1071 | return; | 1166 | goto done; |
1072 | 1167 | ||
1073 | memset(&args, 0, sizeof(args)); | 1168 | memset(&args, 0, sizeof(args)); |
1074 | 1169 | ||
1075 | args.v1.ucAction = action; | 1170 | args.v1.ucAction = action; |
1076 | 1171 | ||
1077 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 1172 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1173 | |||
1174 | /* wait for the panel to power up */ | ||
1175 | if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) { | ||
1176 | int i; | ||
1177 | |||
1178 | for (i = 0; i < 300; i++) { | ||
1179 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) | ||
1180 | return true; | ||
1181 | mdelay(1); | ||
1182 | } | ||
1183 | return false; | ||
1184 | } | ||
1185 | done: | ||
1186 | return true; | ||
1078 | } | 1187 | } |
1079 | 1188 | ||
1080 | union external_encoder_control { | 1189 | union external_encoder_control { |
@@ -1092,13 +1201,19 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1092 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1201 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1093 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); | 1202 | struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); |
1094 | union external_encoder_control args; | 1203 | union external_encoder_control args; |
1095 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1204 | struct drm_connector *connector; |
1096 | int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); | 1205 | int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); |
1097 | u8 frev, crev; | 1206 | u8 frev, crev; |
1098 | int dp_clock = 0; | 1207 | int dp_clock = 0; |
1099 | int dp_lane_count = 0; | 1208 | int dp_lane_count = 0; |
1100 | int connector_object_id = 0; | 1209 | int connector_object_id = 0; |
1101 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | 1210 | u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; |
1211 | int bpc = 8; | ||
1212 | |||
1213 | if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) | ||
1214 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
1215 | else | ||
1216 | connector = radeon_get_connector_for_encoder(encoder); | ||
1102 | 1217 | ||
1103 | if (connector) { | 1218 | if (connector) { |
1104 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 1219 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -1109,6 +1224,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1109 | dp_lane_count = dig_connector->dp_lane_count; | 1224 | dp_lane_count = dig_connector->dp_lane_count; |
1110 | connector_object_id = | 1225 | connector_object_id = |
1111 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | 1226 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; |
1227 | bpc = connector->display_info.bpc; | ||
1112 | } | 1228 | } |
1113 | 1229 | ||
1114 | memset(&args, 0, sizeof(args)); | 1230 | memset(&args, 0, sizeof(args)); |
@@ -1166,7 +1282,27 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1166 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; | 1282 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; |
1167 | break; | 1283 | break; |
1168 | } | 1284 | } |
1169 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | 1285 | switch (bpc) { |
1286 | case 0: | ||
1287 | args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE; | ||
1288 | break; | ||
1289 | case 6: | ||
1290 | args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR; | ||
1291 | break; | ||
1292 | case 8: | ||
1293 | default: | ||
1294 | args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
1295 | break; | ||
1296 | case 10: | ||
1297 | args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR; | ||
1298 | break; | ||
1299 | case 12: | ||
1300 | args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR; | ||
1301 | break; | ||
1302 | case 16: | ||
1303 | args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR; | ||
1304 | break; | ||
1305 | } | ||
1170 | break; | 1306 | break; |
1171 | default: | 1307 | default: |
1172 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); | 1308 | DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); |
@@ -1307,9 +1443,11 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1307 | ATOM_TRANSMITTER_ACTION_POWER_ON); | 1443 | ATOM_TRANSMITTER_ACTION_POWER_ON); |
1308 | radeon_dig_connector->edp_on = true; | 1444 | radeon_dig_connector->edp_on = true; |
1309 | } | 1445 | } |
1310 | dp_link_train(encoder, connector); | ||
1311 | if (ASIC_IS_DCE4(rdev)) | 1446 | if (ASIC_IS_DCE4(rdev)) |
1312 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); | 1447 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
1448 | radeon_dp_link_train(encoder, connector); | ||
1449 | if (ASIC_IS_DCE4(rdev)) | ||
1450 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); | ||
1313 | } | 1451 | } |
1314 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | 1452 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) |
1315 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); | 1453 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); |
@@ -1322,7 +1460,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1322 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1460 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
1323 | 1461 | ||
1324 | if (ASIC_IS_DCE4(rdev)) | 1462 | if (ASIC_IS_DCE4(rdev)) |
1325 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); | 1463 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
1326 | if (connector && | 1464 | if (connector && |
1327 | (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { | 1465 | (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { |
1328 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 1466 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -1601,12 +1739,9 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
1601 | /* DCE4/5 */ | 1739 | /* DCE4/5 */ |
1602 | if (ASIC_IS_DCE4(rdev)) { | 1740 | if (ASIC_IS_DCE4(rdev)) { |
1603 | dig = radeon_encoder->enc_priv; | 1741 | dig = radeon_encoder->enc_priv; |
1604 | if (ASIC_IS_DCE41(rdev)) { | 1742 | if (ASIC_IS_DCE41(rdev)) |
1605 | if (dig->linkb) | 1743 | return radeon_crtc->crtc_id; |
1606 | return 1; | 1744 | else { |
1607 | else | ||
1608 | return 0; | ||
1609 | } else { | ||
1610 | switch (radeon_encoder->encoder_id) { | 1745 | switch (radeon_encoder->encoder_id) { |
1611 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 1746 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
1612 | if (dig->linkb) | 1747 | if (dig->linkb) |
@@ -1662,6 +1797,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
1662 | return 1; | 1797 | return 1; |
1663 | } | 1798 | } |
1664 | 1799 | ||
1800 | /* This only needs to be called once at startup */ | ||
1801 | void | ||
1802 | radeon_atom_encoder_init(struct radeon_device *rdev) | ||
1803 | { | ||
1804 | struct drm_device *dev = rdev->ddev; | ||
1805 | struct drm_encoder *encoder; | ||
1806 | |||
1807 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
1808 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
1809 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
1810 | |||
1811 | switch (radeon_encoder->encoder_id) { | ||
1812 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1813 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1814 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1815 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
1816 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
1817 | break; | ||
1818 | default: | ||
1819 | break; | ||
1820 | } | ||
1821 | |||
1822 | if (ext_encoder && ASIC_IS_DCE41(rdev)) | ||
1823 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1824 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT); | ||
1825 | } | ||
1826 | } | ||
1827 | |||
1665 | static void | 1828 | static void |
1666 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | 1829 | radeon_atom_encoder_mode_set(struct drm_encoder *encoder, |
1667 | struct drm_display_mode *mode, | 1830 | struct drm_display_mode *mode, |
@@ -1696,19 +1859,17 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1696 | /* disable the transmitter */ | 1859 | /* disable the transmitter */ |
1697 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1860 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1698 | /* setup and enable the encoder */ | 1861 | /* setup and enable the encoder */ |
1699 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP); | 1862 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); |
1700 | 1863 | ||
1701 | /* init and enable the transmitter */ | 1864 | /* enable the transmitter */ |
1702 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
1703 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1865 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1704 | } else { | 1866 | } else { |
1705 | /* disable the encoder and transmitter */ | 1867 | /* disable the encoder and transmitter */ |
1706 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1868 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1707 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | 1869 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); |
1708 | 1870 | ||
1709 | /* setup and enable the encoder and transmitter */ | 1871 | /* setup and enable the encoder and transmitter */ |
1710 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | 1872 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); |
1711 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
1712 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | 1873 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); |
1713 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1874 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1714 | } | 1875 | } |
@@ -1733,12 +1894,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1733 | } | 1894 | } |
1734 | 1895 | ||
1735 | if (ext_encoder) { | 1896 | if (ext_encoder) { |
1736 | if (ASIC_IS_DCE41(rdev)) { | 1897 | if (ASIC_IS_DCE41(rdev)) |
1737 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1738 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT); | ||
1739 | atombios_external_encoder_setup(encoder, ext_encoder, | 1898 | atombios_external_encoder_setup(encoder, ext_encoder, |
1740 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | 1899 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); |
1741 | } else | 1900 | else |
1742 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | 1901 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); |
1743 | } | 1902 | } |
1744 | 1903 | ||
@@ -1845,8 +2004,9 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
1845 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 2004 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1846 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 2005 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
1847 | 2006 | ||
1848 | if (radeon_encoder->active_device & | 2007 | if ((radeon_encoder->active_device & |
1849 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { | 2008 | (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || |
2009 | radeon_encoder_is_dp_bridge(encoder)) { | ||
1850 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 2010 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
1851 | if (dig) | 2011 | if (dig) |
1852 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); | 2012 | dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); |
@@ -1855,11 +2015,17 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
1855 | radeon_atom_output_lock(encoder, true); | 2015 | radeon_atom_output_lock(encoder, true); |
1856 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 2016 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); |
1857 | 2017 | ||
1858 | /* select the clock/data port if it uses a router */ | ||
1859 | if (connector) { | 2018 | if (connector) { |
1860 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 2019 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
2020 | |||
2021 | /* select the clock/data port if it uses a router */ | ||
1861 | if (radeon_connector->router.cd_valid) | 2022 | if (radeon_connector->router.cd_valid) |
1862 | radeon_router_select_cd_port(radeon_connector); | 2023 | radeon_router_select_cd_port(radeon_connector); |
2024 | |||
2025 | /* turn eDP panel on for mode set */ | ||
2026 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) | ||
2027 | atombios_set_edp_panel_power(connector, | ||
2028 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
1863 | } | 2029 | } |
1864 | 2030 | ||
1865 | /* this is needed for the pll/ss setup to work correctly in some cases */ | 2031 | /* this is needed for the pll/ss setup to work correctly in some cases */ |
@@ -1914,7 +2080,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | |||
1914 | else { | 2080 | else { |
1915 | /* disable the encoder and transmitter */ | 2081 | /* disable the encoder and transmitter */ |
1916 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 2082 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1917 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | 2083 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); |
1918 | } | 2084 | } |
1919 | break; | 2085 | break; |
1920 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 2086 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
@@ -2116,8 +2282,6 @@ radeon_add_atom_encoder(struct drm_device *dev, | |||
2116 | } else { | 2282 | } else { |
2117 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | 2283 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); |
2118 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | 2284 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); |
2119 | if (ASIC_IS_AVIVO(rdev)) | ||
2120 | radeon_encoder->underscan_type = UNDERSCAN_AUTO; | ||
2121 | } | 2285 | } |
2122 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | 2286 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); |
2123 | break; | 2287 | break; |
@@ -2150,8 +2314,6 @@ radeon_add_atom_encoder(struct drm_device *dev, | |||
2150 | } else { | 2314 | } else { |
2151 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); | 2315 | drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); |
2152 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); | 2316 | radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); |
2153 | if (ASIC_IS_AVIVO(rdev)) | ||
2154 | radeon_encoder->underscan_type = UNDERSCAN_AUTO; | ||
2155 | } | 2317 | } |
2156 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); | 2318 | drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); |
2157 | break; | 2319 | break; |