Minor code cleanup.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/atombios_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 4ad7643..c79ba8a 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -236,7 +236,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, u8 write_byte, u8 *read_byte) { struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter; + struct radeon_i2c_chan *auxch = i2c_get_adapdata(adapter); u16 address = algo_data->address; u8 msg[5]; u8 reply[2];
This will be used elsewhere.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/atombios_dp.c | 26 +++++++++++++++++++++----- drivers/gpu/drm/radeon/radeon_mode.h | 2 ++ 2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index c79ba8a..88d399c 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -603,6 +603,26 @@ bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) return true; }
+void radeon_dp_set_rx_power_state(struct drm_connector *connector, + u8 power_state) +{ + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *dig_connector; + + if (!radeon_connector->con_priv) + return; + + dig_connector = radeon_connector->con_priv; + + /* power up/down the sink */ + if (dig_connector->dpcd[0] >= 0x11) { + radeon_write_dpcd_reg(radeon_connector, + DP_SET_POWER, power_state); + usleep_range(1000, 2000); + } +} + + struct radeon_dp_link_train_info { struct radeon_device *rdev; struct drm_encoder *encoder; @@ -673,11 +693,7 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) u8 tmp;
/* power up the sink */ - if (dp_info->dpcd[0] >= 0x11) { - radeon_write_dpcd_reg(dp_info->radeon_connector, - DP_SET_POWER, DP_SET_POWER_D0); - usleep_range(1000, 2000); - } + radeon_dp_set_rx_power_state(dp_info->connector, DP_SET_POWER_D0);
/* possibly enable downspread on the sink */ if (dp_info->dpcd[3] & 0x1) diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 402dbe32..e390f55 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -690,6 +690,8 @@ extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, struct drm_connector *connector); +extern void radeon_dp_set_rx_power_state(struct drm_connector *connector, + u8 power_state); extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); extern void radeon_atom_encoder_init(struct radeon_device *rdev); extern void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev);
This more closely matches what the vbios does and also adds a quirk for travis lvds displays and powers down the sink on DP displays which saves some power and may fix display issues in some cases.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/atombios_encoders.c | 82 +++++++++++++----------------- 1 file changed, 34 insertions(+), 48 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 607dc14..e6eb509 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1633,10 +1633,16 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); struct radeon_connector *radeon_connector = NULL; struct radeon_connector_atom_dig *radeon_dig_connector = NULL; + bool travis_quirk = false;
if (connector) { radeon_connector = to_radeon_connector(connector); radeon_dig_connector = radeon_connector->con_priv; + if ((radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == + ENCODER_OBJECT_ID_TRAVIS) && + (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) && + !ASIC_IS_DCE5(rdev)) + travis_quirk = true; }
switch (mode) { @@ -1657,17 +1663,13 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) atombios_external_encoder_setup(encoder, ext_encoder, EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); } - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); } else if (ASIC_IS_DCE4(rdev)) { /* setup and enable the encoder */ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); - /* enable the transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); } else { /* setup and enable the encoder and transmitter */ atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); } if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { @@ -1675,68 +1677,56 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) ATOM_TRANSMITTER_ACTION_POWER_ON); radeon_dig_connector->edp_on = true; } + } + /* enable the transmitter */ + atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { + /* DP_SET_POWER_D0 is set in radeon_dp_link_train */ radeon_dp_link_train(encoder, connector); if (ASIC_IS_DCE4(rdev)) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); } if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); + atombios_dig_transmitter_setup(encoder, + ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); + if (ext_encoder) + atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: if (ASIC_IS_DCE4(rdev)) { + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) + atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); + } + if (ext_encoder) + atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE); + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + atombios_dig_transmitter_setup(encoder, + ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); + + if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && + connector && !travis_quirk) + radeon_dp_set_rx_power_state(connector, DP_SET_POWER_D3); + if (ASIC_IS_DCE4(rdev)) { /* disable the transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); + atombios_dig_transmitter_setup(encoder, + ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); } else { /* disable the encoder and transmitter */ - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); + atombios_dig_transmitter_setup(encoder, + ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); } if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { - if (ASIC_IS_DCE4(rdev)) - atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); + if (travis_quirk) + radeon_dp_set_rx_power_state(connector, DP_SET_POWER_D3); if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { atombios_set_edp_panel_power(connector, ATOM_TRANSMITTER_ACTION_POWER_OFF); radeon_dig_connector->edp_on = false; } } - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLOFF, 0, 0); - break; - } -} - -static void -radeon_atom_encoder_dpms_ext(struct drm_encoder *encoder, - struct drm_encoder *ext_encoder, - int mode) -{ - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - - switch (mode) { - case DRM_MODE_DPMS_ON: - default: - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) { - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT); - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF); - } else - atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) { - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING); - atombios_external_encoder_setup(encoder, ext_encoder, - EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT); - } else - atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE); break; } } @@ -1747,7 +1737,6 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder);
DRM_DEBUG_KMS("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", radeon_encoder->encoder_id, mode, radeon_encoder->devices, @@ -1807,9 +1796,6 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) return; }
- if (ext_encoder) - radeon_atom_encoder_dpms_ext(encoder, ext_encoder, mode); - radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
}
We need a special packet for the start and end of the transaction.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/atombios_dp.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 88d399c..23189b7 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -246,34 +246,30 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, int ret; u8 ack;
- /* Set up the command byte */ - if (mode & MODE_I2C_READ) - msg[2] = DP_AUX_I2C_READ << 4; - else - msg[2] = DP_AUX_I2C_WRITE << 4; - - if (!(mode & MODE_I2C_STOP)) - msg[2] |= DP_AUX_I2C_MOT << 4; - + /* Set up the address */ msg[0] = address; msg[1] = address >> 8;
- switch (mode) { - case MODE_I2C_WRITE: + /* Set up the command byte */ + if (mode & MODE_I2C_READ) { + msg[2] = DP_AUX_I2C_READ << 4; + msg_bytes = 4; + msg[3] = msg_bytes << 4; + } else { + msg[2] = DP_AUX_I2C_WRITE << 4; msg_bytes = 5; msg[3] = msg_bytes << 4; msg[4] = write_byte; - break; - case MODE_I2C_READ: - msg_bytes = 4; - msg[3] = msg_bytes << 4; - break; - default: - msg_bytes = 4; - msg[3] = 3 << 4; - break; }
+ /* special handling for start/stop */ + if (mode & (MODE_I2C_START | MODE_I2C_STOP)) + msg[3] = 3 << 4; + + /* Set MOT bit for all but stop */ + if ((mode & MODE_I2C_STOP) == 0) + msg[2] |= DP_AUX_I2C_MOT << 4; + for (retry = 0; retry < 7; retry++) { ret = radeon_process_aux_ch(auxch, msg, msg_bytes, reply, reply_bytes, 0, &ack);
Am 18.03.2014 04:48, schrieb Alex Deucher:
Minor code cleanup.
Signed-off-by: Alex Deucher alexander.deucher@amd.com
Added to my 3.15 queue (http://cgit.freedesktop.org/~deathsimple/linux/log/?h=drm-next-3.15-wip).
Thanks, Christian.
drivers/gpu/drm/radeon/atombios_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 4ad7643..c79ba8a 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -236,7 +236,7 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, u8 write_byte, u8 *read_byte) { struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
- struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter;
- struct radeon_i2c_chan *auxch = i2c_get_adapdata(adapter); u16 address = algo_data->address; u8 msg[5]; u8 reply[2];
dri-devel@lists.freedesktop.org