drm/radeon/kms/atom: add proper external encoders support

These are external encoder chips connected via DVO or DP.
The actual external encoder programming is handled by the
kms encoder functions for primary encoder.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by Alex Deucher and committed by Dave Airlie 3e4b9982 99999aaa

+184
+183
drivers/gpu/drm/radeon/radeon_encoders.c
··· 229 229 return NULL; 230 230 } 231 231 232 + struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder) 233 + { 234 + struct drm_device *dev = encoder->dev; 235 + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 236 + struct drm_encoder *other_encoder; 237 + struct radeon_encoder *other_radeon_encoder; 238 + 239 + if (radeon_encoder->is_ext_encoder) 240 + return NULL; 241 + 242 + list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) { 243 + if (other_encoder == encoder) 244 + continue; 245 + other_radeon_encoder = to_radeon_encoder(other_encoder); 246 + if (other_radeon_encoder->is_ext_encoder && 247 + (radeon_encoder->devices & other_radeon_encoder->devices)) 248 + return other_encoder; 249 + } 250 + return NULL; 251 + } 252 + 232 253 void radeon_panel_mode_fixup(struct drm_encoder *encoder, 233 254 struct drm_display_mode *adjusted_mode) 234 255 { ··· 1042 1021 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 1043 1022 } 1044 1023 1024 + union external_encoder_control { 1025 + EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; 1026 + }; 1027 + 1028 + static void 1029 + atombios_external_encoder_setup(struct drm_encoder *encoder, 1030 + struct drm_encoder *ext_encoder, 1031 + int action) 1032 + { 1033 + struct drm_device *dev = encoder->dev; 1034 + struct radeon_device *rdev = dev->dev_private; 1035 + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1036 + union external_encoder_control args; 1037 + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 1038 + int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); 1039 + u8 frev, crev; 1040 + int dp_clock = 0; 1041 + int dp_lane_count = 0; 1042 + int connector_object_id = 0; 1043 + 1044 + if (connector) { 1045 + struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1046 + struct radeon_connector_atom_dig *dig_connector = 1047 + radeon_connector->con_priv; 1048 + 1049 + dp_clock = dig_connector->dp_clock; 1050 + dp_lane_count = dig_connector->dp_lane_count; 1051 + connector_object_id = 1052 + (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; 1053 + } 1054 + 1055 + memset(&args, 0, sizeof(args)); 1056 + 1057 + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) 1058 + return; 1059 + 1060 + switch (frev) { 1061 + case 1: 1062 + /* no params on frev 1 */ 1063 + break; 1064 + case 2: 1065 + switch (crev) { 1066 + case 1: 1067 + case 2: 1068 + args.v1.sDigEncoder.ucAction = action; 1069 + args.v1.sDigEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); 1070 + args.v1.sDigEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); 1071 + 1072 + if (args.v1.sDigEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) { 1073 + if (dp_clock == 270000) 1074 + args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; 1075 + args.v1.sDigEncoder.ucLaneNum = dp_lane_count; 1076 + } else if (radeon_encoder->pixel_clock > 165000) 1077 + args.v1.sDigEncoder.ucLaneNum = 8; 1078 + else 1079 + args.v1.sDigEncoder.ucLaneNum = 4; 1080 + break; 1081 + default: 1082 + DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); 1083 + return; 1084 + } 1085 + break; 1086 + default: 1087 + DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); 1088 + return; 1089 + } 1090 + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 1091 + } 1092 + 1045 1093 static void 1046 1094 atombios_yuv_setup(struct drm_encoder *encoder, bool enable) 1047 1095 { ··· 1154 1064 struct drm_device *dev = encoder->dev; 1155 1065 struct radeon_device *rdev = dev->dev_private; 1156 1066 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1067 + struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); 1157 1068 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; 1158 1069 int index = 0; 1159 1070 bool is_dig = false; ··· 1282 1191 break; 1283 1192 } 1284 1193 } 1194 + 1195 + if (ext_encoder) { 1196 + int action; 1197 + 1198 + switch (mode) { 1199 + case DRM_MODE_DPMS_ON: 1200 + default: 1201 + action = ATOM_ENABLE; 1202 + break; 1203 + case DRM_MODE_DPMS_STANDBY: 1204 + case DRM_MODE_DPMS_SUSPEND: 1205 + case DRM_MODE_DPMS_OFF: 1206 + action = ATOM_DISABLE; 1207 + break; 1208 + } 1209 + atombios_external_encoder_setup(encoder, ext_encoder, action); 1210 + } 1211 + 1285 1212 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 1286 1213 1287 1214 } ··· 1547 1438 struct drm_device *dev = encoder->dev; 1548 1439 struct radeon_device *rdev = dev->dev_private; 1549 1440 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1441 + struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); 1550 1442 1551 1443 radeon_encoder->pixel_clock = adjusted_mode->clock; 1552 1444 ··· 1608 1498 } 1609 1499 break; 1610 1500 } 1501 + 1502 + if (ext_encoder) { 1503 + atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); 1504 + } 1505 + 1611 1506 atombios_apply_encoder_quirks(encoder, adjusted_mode); 1612 1507 1613 1508 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { ··· 1813 1698 radeon_encoder->active_device = 0; 1814 1699 } 1815 1700 1701 + /* these are handled by the primary encoders */ 1702 + static void radeon_atom_ext_prepare(struct drm_encoder *encoder) 1703 + { 1704 + 1705 + } 1706 + 1707 + static void radeon_atom_ext_commit(struct drm_encoder *encoder) 1708 + { 1709 + 1710 + } 1711 + 1712 + static void 1713 + radeon_atom_ext_mode_set(struct drm_encoder *encoder, 1714 + struct drm_display_mode *mode, 1715 + struct drm_display_mode *adjusted_mode) 1716 + { 1717 + 1718 + } 1719 + 1720 + static void radeon_atom_ext_disable(struct drm_encoder *encoder) 1721 + { 1722 + 1723 + } 1724 + 1725 + static void 1726 + radeon_atom_ext_dpms(struct drm_encoder *encoder, int mode) 1727 + { 1728 + 1729 + } 1730 + 1731 + static bool radeon_atom_ext_mode_fixup(struct drm_encoder *encoder, 1732 + struct drm_display_mode *mode, 1733 + struct drm_display_mode *adjusted_mode) 1734 + { 1735 + return true; 1736 + } 1737 + 1738 + static const struct drm_encoder_helper_funcs radeon_atom_ext_helper_funcs = { 1739 + .dpms = radeon_atom_ext_dpms, 1740 + .mode_fixup = radeon_atom_ext_mode_fixup, 1741 + .prepare = radeon_atom_ext_prepare, 1742 + .mode_set = radeon_atom_ext_mode_set, 1743 + .commit = radeon_atom_ext_commit, 1744 + .disable = radeon_atom_ext_disable, 1745 + /* no detect for TMDS/LVDS yet */ 1746 + }; 1747 + 1816 1748 static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { 1817 1749 .dpms = radeon_atom_encoder_dpms, 1818 1750 .mode_fixup = radeon_atom_mode_fixup, ··· 1969 1807 radeon_encoder->devices = supported_device; 1970 1808 radeon_encoder->rmx_type = RMX_OFF; 1971 1809 radeon_encoder->underscan_type = UNDERSCAN_OFF; 1810 + radeon_encoder->is_ext_encoder = false; 1972 1811 1973 1812 switch (radeon_encoder->encoder_id) { 1974 1813 case ENCODER_OBJECT_ID_INTERNAL_LVDS: ··· 2011 1848 radeon_encoder->rmx_type = RMX_FULL; 2012 1849 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); 2013 1850 radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); 1851 + } else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) { 1852 + drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); 1853 + radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); 2014 1854 } else { 2015 1855 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); 2016 1856 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); ··· 2021 1855 radeon_encoder->underscan_type = UNDERSCAN_AUTO; 2022 1856 } 2023 1857 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); 1858 + break; 1859 + case ENCODER_OBJECT_ID_SI170B: 1860 + case ENCODER_OBJECT_ID_CH7303: 1861 + case ENCODER_OBJECT_ID_EXTERNAL_SDVOA: 1862 + case ENCODER_OBJECT_ID_EXTERNAL_SDVOB: 1863 + case ENCODER_OBJECT_ID_TITFP513: 1864 + case ENCODER_OBJECT_ID_VT1623: 1865 + case ENCODER_OBJECT_ID_HDMI_SI1930: 1866 + /* these are handled by the primary encoders */ 1867 + radeon_encoder->is_ext_encoder = true; 1868 + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) 1869 + drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); 1870 + else if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) 1871 + drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); 1872 + else 1873 + drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); 1874 + drm_encoder_helper_add(encoder, &radeon_atom_ext_helper_funcs); 2024 1875 break; 2025 1876 } 2026 1877 }
+1
drivers/gpu/drm/radeon/radeon_mode.h
··· 375 375 int hdmi_config_offset; 376 376 int hdmi_audio_workaround; 377 377 int hdmi_buffer_status; 378 + bool is_ext_encoder; 378 379 }; 379 380 380 381 struct radeon_connector_atom_dig {