*
* Authors: Dave Airlie
* Alex Deucher
- * Jerome Glisse
*/
#include "drmP.h"
#include "radeon_drm.h"
u8 msg[20];
int msg_bytes = send_bytes + 4;
u8 ack;
- unsigned retry;
if (send_bytes > 16)
return -1;
msg[3] = (msg_bytes << 4) | (send_bytes - 1);
memcpy(&msg[4], send, send_bytes);
- for (retry = 0; retry < 4; retry++) {
+ while (1) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, NULL, 0, delay, &ack);
- if (ret == -EBUSY)
- continue;
- else if (ret < 0)
+ if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
- return send_bytes;
+ break;
else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
udelay(400);
else
return -EIO;
}
- return -EIO;
+ return send_bytes;
}
static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
int msg_bytes = 4;
u8 ack;
int ret;
- unsigned retry;
msg[0] = address;
msg[1] = address >> 8;
msg[2] = AUX_NATIVE_READ << 4;
msg[3] = (msg_bytes << 4) | (recv_bytes - 1);
- for (retry = 0; retry < 4; retry++) {
+ while (1) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, recv, recv_bytes, delay, &ack);
- if (ret == -EBUSY)
- continue;
- else if (ret < 0)
+ if (ret == 0)
+ return -EPROTO;
+ if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
return ret;
else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
udelay(400);
- else if (ret == 0)
- return -EPROTO;
else
return -EIO;
}
-
- return -EIO;
}
static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector,
for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(auxch,
msg, msg_bytes, reply, reply_bytes, 0, &ack);
- if (ret == -EBUSY)
- continue;
- else if (ret < 0) {
+ if (ret < 0) {
DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
return ret;
}
}
}
- DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
+ DRM_ERROR("aux i2c too many retries, giving up\n");
return -EREMOTEIO;
}
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
if (!ASIC_IS_DCE4(rdev))
if (radeon_connector_encoder_is_dp_bridge(connector))
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
- else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
- u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
- if (tmp & 1)
- panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
- }
atombios_dig_encoder_setup(encoder,
ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
panel_mode);
-
- if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
- (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
- radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1);
- }
}
void radeon_dp_set_link_config(struct drm_connector *connector,
ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS,
link_status, DP_LINK_STATUS_SIZE, 100);
if (ret <= 0) {
+ DRM_ERROR("displayport link status failed\n");
return false;
}
return true;
}
-bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
-{
- u8 link_status[DP_LINK_STATUS_SIZE];
- struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
-
- if (!radeon_dp_get_link_status(radeon_connector, link_status))
- return false;
- if (dp_channel_eq_ok(link_status, dig->dp_lane_count))
- return false;
- return true;
-}
-
struct radeon_dp_link_train_info {
struct radeon_device *rdev;
struct drm_encoder *encoder;
u8 train_set[4];
u8 link_status[DP_LINK_STATUS_SIZE];
u8 tries;
- bool use_dpencoder;
};
static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info)
int rtp = 0;
/* set training pattern on the source */
- if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) {
+ if (ASIC_IS_DCE4(dp_info->rdev)) {
switch (tp) {
case DP_TRAINING_PATTERN_1:
rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1;
radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp);
/* start training on the source */
- if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
+ if (ASIC_IS_DCE4(dp_info->rdev))
atombios_dig_encoder_setup(dp_info->encoder,
ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0);
else
DP_TRAINING_PATTERN_DISABLE);
/* disable the training pattern on the source */
- if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
+ if (ASIC_IS_DCE4(dp_info->rdev))
atombios_dig_encoder_setup(dp_info->encoder,
ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0);
else
else
mdelay(dp_info->rd_interval * 4);
- if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
- DRM_ERROR("displayport link status failed\n");
+ if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status))
break;
- }
if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) {
clock_recovery = true;
else
mdelay(dp_info->rd_interval * 4);
- if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
- DRM_ERROR("displayport link status failed\n");
+ if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status))
break;
- }
if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) {
channel_eq = true;
struct radeon_connector *radeon_connector;
struct radeon_connector_atom_dig *dig_connector;
struct radeon_dp_link_train_info dp_info;
- int index;
- u8 tmp, frev, crev;
+ u8 tmp;
if (!radeon_encoder->enc_priv)
return;
(dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP))
return;
- /* DPEncoderService newer than 1.1 can't program properly the
- * training pattern. When facing such version use the
- * DIGXEncoderControl (X== 1 | 2)
- */
- dp_info.use_dpencoder = true;
- index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
- if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) {
- if (crev > 1) {
- dp_info.use_dpencoder = false;
- }
- }
-
dp_info.enc_id = 0;
if (dig->dig_encoder)
dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;