aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-11-17 02:54:42 -0500
committerDave Airlie <airlied@redhat.com>2010-11-17 23:56:25 -0500
commit8b834852d705af75ba942b040ca28533329ff13c (patch)
tree87ea766b680fd1dc1b40da17e203a3a6b6bb56bd /drivers/gpu/drm
parentc7a71fc761551dc8be8543f14a90d08cda4e77f9 (diff)
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>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c50
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h2
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)
1008static int radeon_dp_get_modes(struct drm_connector *connector) 1008static 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
993void
994atombios_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
993static void 1023static void
994atombios_yuv_setup(struct drm_encoder *encoder, bool enable) 1024atombios_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
390struct radeon_gpio_rec { 391struct radeon_gpio_rec {
@@ -526,6 +527,7 @@ struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, i
526extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); 527extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
527extern void atombios_digital_setup(struct drm_encoder *encoder, int action); 528extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
528extern int atombios_get_encoder_mode(struct drm_encoder *encoder); 529extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
530extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action);
529extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); 531extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
530 532
531extern void radeon_crtc_load_lut(struct drm_crtc *crtc); 533extern void radeon_crtc_load_lut(struct drm_crtc *crtc);