Commit 591a10e1 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

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: default avatarAlex Deucher <alexdeucher@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent d629a3ce
...@@ -44,6 +44,8 @@ extern void ...@@ -44,6 +44,8 @@ extern void
radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
struct drm_connector *drm_connector); struct drm_connector *drm_connector);
bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);
void radeon_connector_hotplug(struct drm_connector *connector) void radeon_connector_hotplug(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
...@@ -1070,10 +1072,10 @@ static int radeon_dp_get_modes(struct drm_connector *connector) ...@@ -1070,10 +1072,10 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
{ {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
int ret; int ret;
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
struct drm_encoder *encoder;
struct drm_display_mode *mode; struct drm_display_mode *mode;
if (!radeon_dig_connector->edp_on) if (!radeon_dig_connector->edp_on)
...@@ -1085,7 +1087,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector) ...@@ -1085,7 +1087,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
ATOM_TRANSMITTER_ACTION_POWER_OFF); ATOM_TRANSMITTER_ACTION_POWER_OFF);
if (ret > 0) { if (ret > 0) {
encoder = radeon_best_single_encoder(connector);
if (encoder) { if (encoder) {
radeon_fixup_lvds_native_mode(encoder, connector); radeon_fixup_lvds_native_mode(encoder, connector);
/* add scaled modes */ /* add scaled modes */
...@@ -1109,8 +1110,14 @@ static int radeon_dp_get_modes(struct drm_connector *connector) ...@@ -1109,8 +1110,14 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
/* add scaled modes */ /* add scaled modes */
radeon_add_common_modes(encoder, connector); radeon_add_common_modes(encoder, connector);
} }
} else } else {
/* need to setup ddc on the bridge */
if (radeon_connector_encoder_is_dp_bridge(connector)) {
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
}
ret = radeon_ddc_get_modes(radeon_connector); ret = radeon_ddc_get_modes(radeon_connector);
}
return ret; return ret;
} }
...@@ -1194,6 +1201,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) ...@@ -1194,6 +1201,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
enum drm_connector_status ret = connector_status_disconnected; enum drm_connector_status ret = connector_status_disconnected;
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
if (radeon_connector->edid) { if (radeon_connector->edid) {
kfree(radeon_connector->edid); kfree(radeon_connector->edid);
...@@ -1201,7 +1209,6 @@ radeon_dp_detect(struct drm_connector *connector, bool force) ...@@ -1201,7 +1209,6 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
} }
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
if (encoder) { if (encoder) {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_display_mode *native_mode = &radeon_encoder->native_mode; struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
...@@ -1221,6 +1228,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force) ...@@ -1221,6 +1228,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
atombios_set_edp_panel_power(connector, atombios_set_edp_panel_power(connector,
ATOM_TRANSMITTER_ACTION_POWER_OFF); ATOM_TRANSMITTER_ACTION_POWER_OFF);
} else { } else {
/* need to setup ddc on the bridge */
if (radeon_connector_encoder_is_dp_bridge(connector)) {
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
}
radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
ret = connector_status_connected; ret = connector_status_connected;
......
...@@ -2046,6 +2046,18 @@ radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connec ...@@ -2046,6 +2046,18 @@ radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connec
return connector_status_disconnected; return connector_status_disconnected;
} }
void
radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder)
{
struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
if (ext_encoder)
/* ddc_setup on the dp bridge */
atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
}
static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
{ {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
......
...@@ -483,6 +483,7 @@ extern void radeon_atom_encoder_init(struct radeon_device *rdev); ...@@ -483,6 +483,7 @@ extern void radeon_atom_encoder_init(struct radeon_device *rdev);
extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
int action, uint8_t lane_num, int action, uint8_t lane_num,
uint8_t lane_set); uint8_t lane_set);
extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder);
extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
u8 write_byte, u8 *read_byte); u8 write_byte, u8 *read_byte);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment