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>
This commit is contained in:

committed by
Dave Airlie

parent
d629a3ceb4
commit
591a10e16c
@@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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
|
|||||||
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);
|
|||||||
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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user