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 1008 static int radeon_dp_get_modes(struct drm_connector *connector) 1009 1009 { 1010 1010 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1011 + struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; 1011 1012 int ret; 1012 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 + } 1013 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 + 1014 1026 return ret; 1015 1027 } 1016 1028 ··· 1041 1029 if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { 1042 1030 /* eDP is always DP */ 1043 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); 1044 1035 if (radeon_dp_getdpcd(radeon_connector)) 1045 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); 1046 1040 } else { 1047 1041 radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); 1048 1042 if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
+50
drivers/gpu/drm/radeon/radeon_encoders.c
··· 990 990 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 991 991 } 992 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 + 993 1023 static void 994 1024 atombios_yuv_setup(struct drm_encoder *encoder, bool enable) 995 1025 { ··· 1124 1094 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { 1125 1095 struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 1126 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 + } 1127 1106 dp_link_train(encoder, connector); 1128 1107 if (ASIC_IS_DCE4(rdev)) 1129 1108 atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); ··· 1145 1106 case DRM_MODE_DPMS_OFF: 1146 1107 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); 1147 1108 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { 1109 + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 1110 + 1148 1111 if (ASIC_IS_DCE4(rdev)) 1149 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 + } 1150 1122 } 1151 1123 if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) 1152 1124 atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0);
+2
drivers/gpu/drm/radeon/radeon_mode.h
··· 385 385 u8 dp_sink_type; 386 386 int dp_clock; 387 387 int dp_lane_count; 388 + bool edp_on; 388 389 }; 389 390 390 391 struct radeon_gpio_rec { ··· 527 526 extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); 528 527 extern void atombios_digital_setup(struct drm_encoder *encoder, int action); 529 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 530 extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); 531 531 532 532 extern void radeon_crtc_load_lut(struct drm_crtc *crtc);