diff options
| author | Alex Deucher <alexdeucher@gmail.com> | 2011-06-13 17:13:34 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2011-06-16 19:28:03 -0400 |
| commit | 591a10e16c2a43f6f2ea5f307ab2a5afecfb9ed9 (patch) | |
| tree | f4d86a8693ccb2f799598a86370e7d6346768e50 | |
| parent | d629a3ceb4fc1ab5aab737b964100d114aba1173 (diff) | |
drm/radeon/kms: fix support for DDC on dp bridges
Need to set up the bridge for DDC prior to the
i2c over aux transaction.
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_connectors.c | 20 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 1 |
3 files changed, 29 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index dc7852b3c5ca..613e36f83b71 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -44,6 +44,8 @@ extern void | |||
| 44 | radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, | 44 | radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, |
| 45 | struct drm_connector *drm_connector); | 45 | struct drm_connector *drm_connector); |
| 46 | 46 | ||
| 47 | bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector); | ||
| 48 | |||
| 47 | void radeon_connector_hotplug(struct drm_connector *connector) | 49 | void radeon_connector_hotplug(struct drm_connector *connector) |
| 48 | { | 50 | { |
| 49 | struct drm_device *dev = connector->dev; | 51 | struct drm_device *dev = connector->dev; |
| @@ -1070,10 +1072,10 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
| 1070 | { | 1072 | { |
| 1071 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 1073 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 1072 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | 1074 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; |
| 1075 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | ||
| 1073 | int ret; | 1076 | int ret; |
| 1074 | 1077 | ||
| 1075 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 1078 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
| 1076 | struct drm_encoder *encoder; | ||
| 1077 | struct drm_display_mode *mode; | 1079 | struct drm_display_mode *mode; |
| 1078 | 1080 | ||
| 1079 | if (!radeon_dig_connector->edp_on) | 1081 | if (!radeon_dig_connector->edp_on) |
| @@ -1085,7 +1087,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
| 1085 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | 1087 | ATOM_TRANSMITTER_ACTION_POWER_OFF); |
| 1086 | 1088 | ||
| 1087 | if (ret > 0) { | 1089 | if (ret > 0) { |
| 1088 | encoder = radeon_best_single_encoder(connector); | ||
| 1089 | if (encoder) { | 1090 | if (encoder) { |
| 1090 | radeon_fixup_lvds_native_mode(encoder, connector); | 1091 | radeon_fixup_lvds_native_mode(encoder, connector); |
| 1091 | /* add scaled modes */ | 1092 | /* add scaled modes */ |
| @@ -1109,8 +1110,14 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
| 1109 | /* add scaled modes */ | 1110 | /* add scaled modes */ |
| 1110 | radeon_add_common_modes(encoder, connector); | 1111 | radeon_add_common_modes(encoder, connector); |
| 1111 | } | 1112 | } |
| 1112 | } else | 1113 | } else { |
| 1114 | /* need to setup ddc on the bridge */ | ||
| 1115 | if (radeon_connector_encoder_is_dp_bridge(connector)) { | ||
| 1116 | if (encoder) | ||
| 1117 | radeon_atom_ext_encoder_setup_ddc(encoder); | ||
| 1118 | } | ||
| 1113 | ret = radeon_ddc_get_modes(radeon_connector); | 1119 | ret = radeon_ddc_get_modes(radeon_connector); |
| 1120 | } | ||
| 1114 | 1121 | ||
| 1115 | return ret; | 1122 | return ret; |
| 1116 | } | 1123 | } |
| @@ -1194,6 +1201,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
| 1194 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 1201 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
| 1195 | enum drm_connector_status ret = connector_status_disconnected; | 1202 | enum drm_connector_status ret = connector_status_disconnected; |
| 1196 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | 1203 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; |
| 1204 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | ||
| 1197 | 1205 | ||
| 1198 | if (radeon_connector->edid) { | 1206 | if (radeon_connector->edid) { |
| 1199 | kfree(radeon_connector->edid); | 1207 | kfree(radeon_connector->edid); |
| @@ -1201,7 +1209,6 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
| 1201 | } | 1209 | } |
| 1202 | 1210 | ||
| 1203 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 1211 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
| 1204 | struct drm_encoder *encoder = radeon_best_single_encoder(connector); | ||
| 1205 | if (encoder) { | 1212 | if (encoder) { |
| 1206 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1213 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1207 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; | 1214 | struct drm_display_mode *native_mode = &radeon_encoder->native_mode; |
| @@ -1221,6 +1228,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
| 1221 | atombios_set_edp_panel_power(connector, | 1228 | atombios_set_edp_panel_power(connector, |
| 1222 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | 1229 | ATOM_TRANSMITTER_ACTION_POWER_OFF); |
| 1223 | } else { | 1230 | } else { |
| 1231 | /* need to setup ddc on the bridge */ | ||
| 1232 | if (radeon_connector_encoder_is_dp_bridge(connector)) { | ||
| 1233 | if (encoder) | ||
| 1234 | radeon_atom_ext_encoder_setup_ddc(encoder); | ||
| 1235 | } | ||
| 1224 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); | 1236 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); |
| 1225 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { | 1237 | if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { |
| 1226 | ret = connector_status_connected; | 1238 | ret = connector_status_connected; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index d3449443aa1f..8e058f1f46d6 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -2046,6 +2046,18 @@ radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connec | |||
| 2046 | return connector_status_disconnected; | 2046 | return connector_status_disconnected; |
| 2047 | } | 2047 | } |
| 2048 | 2048 | ||
| 2049 | void | ||
| 2050 | radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder) | ||
| 2051 | { | ||
| 2052 | struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); | ||
| 2053 | |||
| 2054 | if (ext_encoder) | ||
| 2055 | /* ddc_setup on the dp bridge */ | ||
| 2056 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
| 2057 | EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP); | ||
| 2058 | |||
| 2059 | } | ||
| 2060 | |||
| 2049 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | 2061 | static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) |
| 2050 | { | 2062 | { |
| 2051 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 2063 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 977a341266b6..f734b3737dce 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -483,6 +483,7 @@ extern void radeon_atom_encoder_init(struct radeon_device *rdev); | |||
| 483 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, | 483 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, |
| 484 | int action, uint8_t lane_num, | 484 | int action, uint8_t lane_num, |
| 485 | uint8_t lane_set); | 485 | uint8_t lane_set); |
| 486 | extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder); | ||
| 486 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | 487 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, |
| 487 | u8 write_byte, u8 *read_byte); | 488 | u8 write_byte, u8 *read_byte); |
| 488 | 489 | ||
