diff options
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 50 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 2 |
3 files changed, 70 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index fe6c74780f18..3bef9f6d66fd 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -1008,9 +1008,21 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector) | |||
| 1008 | static int radeon_dp_get_modes(struct drm_connector *connector) | 1008 | static int radeon_dp_get_modes(struct drm_connector *connector) |
| 1009 | { | 1009 | { |
| 1010 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 1010 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 1011 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | ||
| 1011 | int ret; | 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 | ret = radeon_ddc_get_modes(radeon_connector); | 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 | return ret; | 1026 | return ret; |
| 1015 | } | 1027 | } |
| 1016 | 1028 | ||
| @@ -1029,8 +1041,14 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
| 1029 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 1041 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
| 1030 | /* eDP is always DP */ | 1042 | /* eDP is always DP */ |
| 1031 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; | 1043 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
| 1044 | if (!radeon_dig_connector->edp_on) | ||
| 1045 | atombios_set_edp_panel_power(connector, | ||
| 1046 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
| 1032 | if (radeon_dp_getdpcd(radeon_connector)) | 1047 | if (radeon_dp_getdpcd(radeon_connector)) |
| 1033 | ret = connector_status_connected; | 1048 | ret = connector_status_connected; |
| 1049 | if (!radeon_dig_connector->edp_on) | ||
| 1050 | atombios_set_edp_panel_power(connector, | ||
| 1051 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | ||
| 1034 | } else { | 1052 | } else { |
| 1035 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); | 1053 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); |
| 1036 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { | 1054 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index c6981dfd9156..63f4964e8d2d 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -990,6 +990,36 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 990 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 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 | static void | 1023 | static void |
| 994 | atombios_yuv_setup(struct drm_encoder *encoder, bool enable) | 1024 | atombios_yuv_setup(struct drm_encoder *encoder, bool enable) |
| 995 | { | 1025 | { |
| @@ -1094,6 +1124,15 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 1094 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1124 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
| 1095 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1125 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
| 1096 | 1126 | ||
| 1127 | if (connector && | ||
| 1128 | (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { | ||
| 1129 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1130 | struct radeon_connector_atom_dig *radeon_dig_connector = | ||
| 1131 | radeon_connector->con_priv; | ||
| 1132 | atombios_set_edp_panel_power(connector, | ||
| 1133 | ATOM_TRANSMITTER_ACTION_POWER_ON); | ||
| 1134 | radeon_dig_connector->edp_on = true; | ||
| 1135 | } | ||
| 1097 | dp_link_train(encoder, connector); | 1136 | dp_link_train(encoder, connector); |
| 1098 | if (ASIC_IS_DCE4(rdev)) | 1137 | if (ASIC_IS_DCE4(rdev)) |
| 1099 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); | 1138 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON); |
| @@ -1106,8 +1145,19 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
| 1106 | case DRM_MODE_DPMS_OFF: | 1145 | case DRM_MODE_DPMS_OFF: |
| 1107 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | 1146 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
| 1108 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1147 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
| 1148 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1149 | |||
| 1109 | if (ASIC_IS_DCE4(rdev)) | 1150 | if (ASIC_IS_DCE4(rdev)) |
| 1110 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); | 1151 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); |
| 1152 | if (connector && | ||
| 1153 | (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) { | ||
| 1154 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 1155 | struct radeon_connector_atom_dig *radeon_dig_connector = | ||
| 1156 | radeon_connector->con_priv; | ||
| 1157 | atombios_set_edp_panel_power(connector, | ||
| 1158 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | ||
| 1159 | radeon_dig_connector->edp_on = false; | ||
| 1160 | } | ||
| 1111 | } | 1161 | } |
| 1112 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) | 1162 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) |
| 1113 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); | 1163 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 680f57644e86..ef588835201f 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -385,6 +385,7 @@ struct radeon_connector_atom_dig { | |||
| 385 | u8 dp_sink_type; | 385 | u8 dp_sink_type; |
| 386 | int dp_clock; | 386 | int dp_clock; |
| 387 | int dp_lane_count; | 387 | int dp_lane_count; |
| 388 | bool edp_on; | ||
| 388 | }; | 389 | }; |
| 389 | 390 | ||
| 390 | struct radeon_gpio_rec { | 391 | struct radeon_gpio_rec { |
| @@ -526,6 +527,7 @@ struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, i | |||
| 526 | extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); | 527 | 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 void atombios_digital_setup(struct drm_encoder *encoder, int action); |
| 528 | extern int atombios_get_encoder_mode(struct drm_encoder *encoder); | 529 | extern int atombios_get_encoder_mode(struct drm_encoder *encoder); |
| 530 | extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action); | ||
| 529 | extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); | 531 | extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); |
| 530 | 532 | ||
| 531 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); | 533 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); |
