drm/radeon/kms: properly power up/down the eDP panel as needed (v4)

The eDP panel must be powered up for aux transactions, so power it
up for detect and mode probe functions, otherwise power it up or
down based on dpms.

v2:
- only mess with eDP panel on DCE4+
- only mess with eDP panel on eDP connectors, not all DP connectors
v3:
- be extra careful to only mess with eDP panels on eDP connectors
v4:
- avoid possible null derefernce if a connector has not been
assigned to the 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 8b834852 c7a71fc7

+70
+18
drivers/gpu/drm/radeon/radeon_connectors.c
··· 1008 static int radeon_dp_get_modes(struct drm_connector *connector) 1009 { 1010 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1011 int ret; 1012 1013 ret = radeon_ddc_get_modes(radeon_connector); 1014 return ret; 1015 } 1016 ··· 1041 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1042 /* eDP is always DP */ 1043 radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; 1044 if (radeon_dp_getdpcd(radeon_connector)) 1045 ret = connector_status_connected; 1046 } else { 1047 radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); 1048 if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
··· 1008 static int radeon_dp_get_modes(struct drm_connector *connector) 1009 { 1010 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1011 + struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; 1012 int ret; 1013 1014 + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1015 + if (!radeon_dig_connector->edp_on) 1016 + atombios_set_edp_panel_power(connector, 1017 + ATOM_TRANSMITTER_ACTION_POWER_ON); 1018 + } 1019 ret = radeon_ddc_get_modes(radeon_connector); 1020 + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1021 + if (!radeon_dig_connector->edp_on) 1022 + atombios_set_edp_panel_power(connector, 1023 + ATOM_TRANSMITTER_ACTION_POWER_OFF); 1024 + } 1025 + 1026 return ret; 1027 } 1028 ··· 1029 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1030 /* eDP is always DP */ 1031 radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; 1032 + if (!radeon_dig_connector->edp_on) 1033 + atombios_set_edp_panel_power(connector, 1034 + ATOM_TRANSMITTER_ACTION_POWER_ON); 1035 if (radeon_dp_getdpcd(radeon_connector)) 1036 ret = connector_status_connected; 1037 + if (!radeon_dig_connector->edp_on) 1038 + atombios_set_edp_panel_power(connector, 1039 + ATOM_TRANSMITTER_ACTION_POWER_OFF); 1040 } else { 1041 radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); 1042 if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
+50
drivers/gpu/drm/radeon/radeon_encoders.c
··· 990 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 991 } 992 993 static void 994 atombios_yuv_setup(struct drm_encoder *encoder, bool enable) 995 { ··· 1124 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { 1125 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 1126 1127 dp_link_train(encoder, connector); 1128 if (ASIC_IS_DCE4(rdev)) 1129 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); ··· 1145 case DRM_MODE_DPMS_OFF: 1146 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); 1147 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { 1148 if (ASIC_IS_DCE4(rdev)) 1149 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); 1150 } 1151 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) 1152 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
··· 990 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 991 } 992 993 + void 994 + atombios_set_edp_panel_power(struct drm_connector *connector, int action) 995 + { 996 + struct radeon_connector *radeon_connector = to_radeon_connector(connector); 997 + struct drm_device *dev = radeon_connector->base.dev; 998 + struct radeon_device *rdev = dev->dev_private; 999 + union dig_transmitter_control args; 1000 + int index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); 1001 + uint8_t frev, crev; 1002 + 1003 + if (connector->connector_type != DRM_MODE_CONNECTOR_eDP) 1004 + return; 1005 + 1006 + if (!ASIC_IS_DCE4(rdev)) 1007 + return; 1008 + 1009 + if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) || 1010 + (action != ATOM_TRANSMITTER_ACTION_POWER_OFF)) 1011 + return; 1012 + 1013 + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) 1014 + return; 1015 + 1016 + memset(&args, 0, sizeof(args)); 1017 + 1018 + args.v1.ucAction = action; 1019 + 1020 + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 1021 + } 1022 + 1023 static void 1024 atombios_yuv_setup(struct drm_encoder *encoder, bool enable) 1025 { ··· 1094 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { 1095 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 1096 1097 + if (connector && 1098 + (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { 1099 + struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1100 + struct radeon_connector_atom_dig *radeon_dig_connector = 1101 + radeon_connector->con_priv; 1102 + atombios_set_edp_panel_power(connector, 1103 + ATOM_TRANSMITTER_ACTION_POWER_ON); 1104 + radeon_dig_connector->edp_on = true; 1105 + } 1106 dp_link_train(encoder, connector); 1107 if (ASIC_IS_DCE4(rdev)) 1108 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); ··· 1106 case DRM_MODE_DPMS_OFF: 1107 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); 1108 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { 1109 + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 1110 + 1111 if (ASIC_IS_DCE4(rdev)) 1112 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); 1113 + if (connector && 1114 + (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { 1115 + struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1116 + struct radeon_connector_atom_dig *radeon_dig_connector = 1117 + radeon_connector->con_priv; 1118 + atombios_set_edp_panel_power(connector, 1119 + ATOM_TRANSMITTER_ACTION_POWER_OFF); 1120 + radeon_dig_connector->edp_on = false; 1121 + } 1122 } 1123 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) 1124 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
+2
drivers/gpu/drm/radeon/radeon_mode.h
··· 385 u8 dp_sink_type; 386 int dp_clock; 387 int dp_lane_count; 388 }; 389 390 struct radeon_gpio_rec { ··· 527 extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); 528 extern void atombios_digital_setup(struct drm_encoder *encoder, int action); 529 extern int atombios_get_encoder_mode(struct drm_encoder *encoder); 530 extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); 531 532 extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
··· 385 u8 dp_sink_type; 386 int dp_clock; 387 int dp_lane_count; 388 + bool edp_on; 389 }; 390 391 struct radeon_gpio_rec { ··· 526 extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); 527 extern void atombios_digital_setup(struct drm_encoder *encoder, int action); 528 extern int atombios_get_encoder_mode(struct drm_encoder *encoder); 529 + extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action); 530 extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); 531 532 extern void radeon_crtc_load_lut(struct drm_crtc *crtc);