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 return NULL; 230 } 231 232 void radeon_panel_mode_fixup(struct drm_encoder *encoder, 233 struct drm_display_mode *adjusted_mode) 234 { ··· 1042 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 1043 } 1044 1045 static void 1046 atombios_yuv_setup(struct drm_encoder *encoder, bool enable) 1047 { ··· 1154 struct drm_device *dev = encoder->dev; 1155 struct radeon_device *rdev = dev->dev_private; 1156 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1157 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; 1158 int index = 0; 1159 bool is_dig = false; ··· 1282 break; 1283 } 1284 } 1285 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 1286 1287 } ··· 1547 struct drm_device *dev = encoder->dev; 1548 struct radeon_device *rdev = dev->dev_private; 1549 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1550 1551 radeon_encoder->pixel_clock = adjusted_mode->clock; 1552 ··· 1608 } 1609 break; 1610 } 1611 atombios_apply_encoder_quirks(encoder, adjusted_mode); 1612 1613 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { ··· 1813 radeon_encoder->active_device = 0; 1814 } 1815 1816 static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { 1817 .dpms = radeon_atom_encoder_dpms, 1818 .mode_fixup = radeon_atom_mode_fixup, ··· 1969 radeon_encoder->devices = supported_device; 1970 radeon_encoder->rmx_type = RMX_OFF; 1971 radeon_encoder->underscan_type = UNDERSCAN_OFF; 1972 1973 switch (radeon_encoder->encoder_id) { 1974 case ENCODER_OBJECT_ID_INTERNAL_LVDS: ··· 2011 radeon_encoder->rmx_type = RMX_FULL; 2012 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); 2013 radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); 2014 } else { 2015 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); 2016 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); ··· 2021 radeon_encoder->underscan_type = UNDERSCAN_AUTO; 2022 } 2023 drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); 2024 break; 2025 } 2026 }
··· 229 return NULL; 230 } 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 + 253 void radeon_panel_mode_fixup(struct drm_encoder *encoder, 254 struct drm_display_mode *adjusted_mode) 255 { ··· 1021 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 1022 } 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 + 1093 static void 1094 atombios_yuv_setup(struct drm_encoder *encoder, bool enable) 1095 { ··· 1064 struct drm_device *dev = encoder->dev; 1065 struct radeon_device *rdev = dev->dev_private; 1066 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1067 + struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); 1068 DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; 1069 int index = 0; 1070 bool is_dig = false; ··· 1191 break; 1192 } 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 + 1212 radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); 1213 1214 } ··· 1438 struct drm_device *dev = encoder->dev; 1439 struct radeon_device *rdev = dev->dev_private; 1440 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 1441 + struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); 1442 1443 radeon_encoder->pixel_clock = adjusted_mode->clock; 1444 ··· 1498 } 1499 break; 1500 } 1501 + 1502 + if (ext_encoder) { 1503 + atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); 1504 + } 1505 + 1506 atombios_apply_encoder_quirks(encoder, adjusted_mode); 1507 1508 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { ··· 1698 radeon_encoder->active_device = 0; 1699 } 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 + 1748 static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { 1749 .dpms = radeon_atom_encoder_dpms, 1750 .mode_fixup = radeon_atom_mode_fixup, ··· 1807 radeon_encoder->devices = supported_device; 1808 radeon_encoder->rmx_type = RMX_OFF; 1809 radeon_encoder->underscan_type = UNDERSCAN_OFF; 1810 + radeon_encoder->is_ext_encoder = false; 1811 1812 switch (radeon_encoder->encoder_id) { 1813 case ENCODER_OBJECT_ID_INTERNAL_LVDS: ··· 1848 radeon_encoder->rmx_type = RMX_FULL; 1849 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); 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); 1854 } else { 1855 drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); 1856 radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); ··· 1855 radeon_encoder->underscan_type = UNDERSCAN_AUTO; 1856 } 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); 1875 break; 1876 } 1877 }
+1
drivers/gpu/drm/radeon/radeon_mode.h
··· 375 int hdmi_config_offset; 376 int hdmi_audio_workaround; 377 int hdmi_buffer_status; 378 }; 379 380 struct radeon_connector_atom_dig {
··· 375 int hdmi_config_offset; 376 int hdmi_audio_workaround; 377 int hdmi_buffer_status; 378 + bool is_ext_encoder; 379 }; 380 381 struct radeon_connector_atom_dig {