/*
 * Copyright 2007-8 Advanced Micro Devices, Inc.
 * Copyright 2008 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Dave Airlie
 *          Alex Deucher
 */
#include "drmP.h"
#include "radeon_drm.h"
#include "radeon.h"

#include "atom.h"
#include "atom-bits.h"
#include "drm_dp_helper.h"

/* move these to drm_dp_helper.c/h */
#define DP_LINK_CONFIGURATION_SIZE 9
#define DP_LINK_STATUS_SIZE	   6
#define DP_DPCD_SIZE	           8

static char *voltage_names[] = {
        "0.4V", "0.6V", "0.8V", "1.2V"
};
static char *pre_emph_names[] = {
        "0dB", "3.5dB", "6dB", "9.5dB"
};

static const int dp_clocks[] = {
	54000,  /* 1 lane, 1.62 Ghz */
	90000,  /* 1 lane, 2.70 Ghz */
	108000, /* 2 lane, 1.62 Ghz */
	180000, /* 2 lane, 2.70 Ghz */
	216000, /* 4 lane, 1.62 Ghz */
	360000, /* 4 lane, 2.70 Ghz */
};

static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int);

/* common helper functions */
static int dp_lanes_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
{
	int i;
	u8 max_link_bw;
	u8 max_lane_count;

	if (!dpcd)
		return 0;

	max_link_bw = dpcd[DP_MAX_LINK_RATE];
	max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;

	switch (max_link_bw) {
	case DP_LINK_BW_1_62:
	default:
		for (i = 0; i < num_dp_clocks; i++) {
			if (i % 2)
				continue;
			switch (max_lane_count) {
			case 1:
				if (i > 1)
					return 0;
				break;
			case 2:
				if (i > 3)
					return 0;
				break;
			case 4:
			default:
				break;
			}
			if (dp_clocks[i] > mode_clock) {
				if (i < 2)
					return 1;
				else if (i < 4)
					return 2;
				else
					return 4;
			}
		}
		break;
	case DP_LINK_BW_2_7:
		for (i = 0; i < num_dp_clocks; i++) {
			switch (max_lane_count) {
			case 1:
				if (i > 1)
					return 0;
				break;
			case 2:
				if (i > 3)
					return 0;
				break;
			case 4:
			default:
				break;
			}
			if (dp_clocks[i] > mode_clock) {
				if (i < 2)
					return 1;
				else if (i < 4)
					return 2;
				else
					return 4;
			}
		}
		break;
	}

	return 0;
}

static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
{
	int i;
	u8 max_link_bw;
	u8 max_lane_count;

	if (!dpcd)
		return 0;

	max_link_bw = dpcd[DP_MAX_LINK_RATE];
	max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;

	switch (max_link_bw) {
	case DP_LINK_BW_1_62:
	default:
		for (i = 0; i < num_dp_clocks; i++) {
			if (i % 2)
				continue;
			switch (max_lane_count) {
			case 1:
				if (i > 1)
					return 0;
				break;
			case 2:
				if (i > 3)
					return 0;
				break;
			case 4:
			default:
				break;
			}
			if (dp_clocks[i] > mode_clock)
				return 162000;
		}
		break;
	case DP_LINK_BW_2_7:
		for (i = 0; i < num_dp_clocks; i++) {
			switch (max_lane_count) {
			case 1:
				if (i > 1)
					return 0;
				break;
			case 2:
				if (i > 3)
					return 0;
				break;
			case 4:
			default:
				break;
			}
			if (dp_clocks[i] > mode_clock)
				return (i % 2) ? 270000 : 162000;
		}
	}

	return 0;
}

int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
{
	int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock);
	int dp_clock = dp_link_clock_for_mode_clock(dpcd, mode_clock);

	if ((lanes == 0) || (dp_clock == 0))
		return MODE_CLOCK_HIGH;

	return MODE_OK;
}

static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r)
{
	return link_status[r - DP_LANE0_1_STATUS];
}

static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE],
			     int lane)
{
	int i = DP_LANE0_1_STATUS + (lane >> 1);
	int s = (lane & 1) * 4;
	u8 l = dp_link_status(link_status, i);
	return (l >> s) & 0xf;
}

static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
				 int lane_count)
{
	int lane;
	u8 lane_status;

	for (lane = 0; lane < lane_count; lane++) {
		lane_status = dp_get_lane_status(link_status, lane);
		if ((lane_status & DP_LANE_CR_DONE) == 0)
			return false;
	}
	return true;
}

static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
			     int lane_count)
{
	u8 lane_align;
	u8 lane_status;
	int lane;

	lane_align = dp_link_status(link_status,
				    DP_LANE_ALIGN_STATUS_UPDATED);
	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
		return false;
	for (lane = 0; lane < lane_count; lane++) {
		lane_status = dp_get_lane_status(link_status, lane);
		if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
			return false;
	}
	return true;
}

static u8 dp_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
					int lane)

{
	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
	int s = ((lane & 1) ?
		 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
		 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
	u8 l = dp_link_status(link_status, i);

	return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
}

static u8 dp_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
					     int lane)
{
	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
	int s = ((lane & 1) ?
		 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
		 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
	u8 l = dp_link_status(link_status, i);

	return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
}

/* XXX fix me -- chip specific */
#define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
static u8 dp_pre_emphasis_max(u8 voltage_swing)
{
	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
	case DP_TRAIN_VOLTAGE_SWING_400:
		return DP_TRAIN_PRE_EMPHASIS_6;
	case DP_TRAIN_VOLTAGE_SWING_600:
		return DP_TRAIN_PRE_EMPHASIS_6;
	case DP_TRAIN_VOLTAGE_SWING_800:
		return DP_TRAIN_PRE_EMPHASIS_3_5;
	case DP_TRAIN_VOLTAGE_SWING_1200:
	default:
		return DP_TRAIN_PRE_EMPHASIS_0;
	}
}

static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
				int lane_count,
				u8 train_set[4])
{
	u8 v = 0;
	u8 p = 0;
	int lane;

	for (lane = 0; lane < lane_count; lane++) {
		u8 this_v = dp_get_adjust_request_voltage(link_status, lane);
		u8 this_p = dp_get_adjust_request_pre_emphasis(link_status, lane);

		DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n",
			  lane,
			  voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
			  pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);

		if (this_v > v)
			v = this_v;
		if (this_p > p)
			p = this_p;
	}

	if (v >= DP_VOLTAGE_MAX)
		v = DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;

	if (p >= dp_pre_emphasis_max(v))
		p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;

	DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n",
		  voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
		  pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);

	for (lane = 0; lane < 4; lane++)
		train_set[lane] = v | p;
}

union aux_channel_transaction {
	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
	PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
};

/* radeon aux chan functions */
bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
			   int num_bytes, u8 *read_byte,
			   u8 read_buf_len, u8 delay)
{
	struct drm_device *dev = chan->dev;
	struct radeon_device *rdev = dev->dev_private;
	union aux_channel_transaction args;
	int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
	unsigned char *base;
	int retry_count = 0;

	memset(&args, 0, sizeof(args));

	base = (unsigned char *)rdev->mode_info.atom_context->scratch;

retry:
	memcpy(base, req_bytes, num_bytes);

	args.v1.lpAuxRequest = 0;
	args.v1.lpDataOut = 16;
	args.v1.ucDataOutLen = 0;
	args.v1.ucChannelID = chan->rec.i2c_id;
	args.v1.ucDelay = delay / 10;
	if (ASIC_IS_DCE4(rdev))
		args.v2.ucHPD_ID = chan->rec.hpd;

	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);

	if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) {
		if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10)
			goto retry;
		DRM_DEBUG_KMS("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n",
			  req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
			  chan->rec.i2c_id, args.v1.ucReplyStatus, retry_count);
		return false;
	}

	if (args.v1.ucDataOutLen && read_byte && read_buf_len) {
		if (read_buf_len < args.v1.ucDataOutLen) {
			DRM_ERROR("Buffer to small for return answer %d %d\n",
				  read_buf_len, args.v1.ucDataOutLen);
			return false;
		}
		{
			int len = min(read_buf_len, args.v1.ucDataOutLen);
			memcpy(read_byte, base + 16, len);
		}
	}
	return true;
}

bool radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, uint16_t address,
				uint8_t send_bytes, uint8_t *send)
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
	u8 msg[20];
	u8 msg_len, dp_msg_len;
	bool ret;

	dp_msg_len = 4;
	msg[0] = address;
	msg[1] = address >> 8;
	msg[2] = AUX_NATIVE_WRITE << 4;
	dp_msg_len += send_bytes;
	msg[3] = (dp_msg_len << 4) | (send_bytes - 1);

	if (send_bytes > 16)
		return false;

	memcpy(&msg[4], send, send_bytes);
	msg_len = 4 + send_bytes;
	ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, NULL, 0, 0);
	return ret;
}

bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16_t address,
			       uint8_t delay, uint8_t expected_bytes,
			       uint8_t *read_p)
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
	u8 msg[20];
	u8 msg_len, dp_msg_len;
	bool ret = false;
	msg_len = 4;
	dp_msg_len = 4;
	msg[0] = address;
	msg[1] = address >> 8;
	msg[2] = AUX_NATIVE_READ << 4;
	msg[3] = (dp_msg_len) << 4;
	msg[3] |= expected_bytes - 1;

	ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, read_p, expected_bytes, delay);
	return ret;
}

/* radeon dp functions */
static u8 radeon_dp_encoder_service(struct radeon_device *rdev, int action, int dp_clock,
				    uint8_t ucconfig, uint8_t lane_num)
{
	DP_ENCODER_SERVICE_PARAMETERS args;
	int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);

	memset(&args, 0, sizeof(args));
	args.ucLinkClock = dp_clock / 10;
	args.ucConfig = ucconfig;
	args.ucAction = action;
	args.ucLaneNum = lane_num;
	args.ucStatus = 0;

	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
	return args.ucStatus;
}

u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
	struct drm_device *dev = radeon_connector->base.dev;
	struct radeon_device *rdev = dev->dev_private;

	return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
					 dig_connector->dp_i2c_bus->rec.i2c_id, 0);
}

bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
	u8 msg[25];
	int ret;

	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg);
	if (ret) {
		memcpy(dig_connector->dpcd, msg, 8);
		{
			int i;
			DRM_DEBUG_KMS("DPCD: ");
			for (i = 0; i < 8; i++)
				DRM_DEBUG_KMS("%02x ", msg[i]);
			DRM_DEBUG_KMS("\n");
		}
		return true;
	}
	dig_connector->dpcd[0] = 0;
	return false;
}

void radeon_dp_set_link_config(struct drm_connector *connector,
			       struct drm_display_mode *mode)
{
	struct radeon_connector *radeon_connector;
	struct radeon_connector_atom_dig *dig_connector;

	if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
	    (connector->connector_type != DRM_MODE_CONNECTOR_eDP))
		return;

	radeon_connector = to_radeon_connector(connector);
	if (!radeon_connector->con_priv)
		return;
	dig_connector = radeon_connector->con_priv;

	dig_connector->dp_clock =
		dp_link_clock_for_mode_clock(dig_connector->dpcd, mode->clock);
	dig_connector->dp_lane_count =
		dp_lanes_for_mode_clock(dig_connector->dpcd, mode->clock);
}

int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
				struct drm_display_mode *mode)
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;

	return dp_mode_valid(dig_connector->dpcd, mode->clock);
}

static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
				    u8 link_status[DP_LINK_STATUS_SIZE])
{
	int ret;
	ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, 100,
					DP_LINK_STATUS_SIZE, link_status);
	if (!ret) {
		DRM_ERROR("displayport link status failed\n");
		return false;
	}

	DRM_DEBUG_KMS("link status %02x %02x %02x %02x %02x %02x\n",
		  link_status[0], link_status[1], link_status[2],
		  link_status[3], link_status[4], link_status[5]);
	return true;
}

bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
	u8 link_status[DP_LINK_STATUS_SIZE];

	if (!atom_dp_get_link_status(radeon_connector, link_status))
		return false;
	if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count))
		return false;
	return true;
}

static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;

	if (dig_connector->dpcd[0] >= 0x11) {
		radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1,
					   &power_state);
	}
}

static void dp_set_downspread(struct radeon_connector *radeon_connector, u8 downspread)
{
	radeon_dp_aux_native_write(radeon_connector, DP_DOWNSPREAD_CTRL, 1,
				   &downspread);
}

static void dp_set_link_bw_lanes(struct radeon_connector *radeon_connector,
				 u8 link_configuration[DP_LINK_CONFIGURATION_SIZE])
{
	radeon_dp_aux_native_write(radeon_connector, DP_LINK_BW_SET, 2,
				   link_configuration);
}

static void dp_update_dpvs_emph(struct radeon_connector *radeon_connector,
				struct drm_encoder *encoder,
				u8 train_set[4])
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
	int i;

	for (i = 0; i < dig_connector->dp_lane_count; i++)
		atombios_dig_transmitter_setup(encoder,
					       ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH,
					       i, train_set[i]);

	radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_LANE0_SET,
				   dig_connector->dp_lane_count, train_set);
}

static void dp_set_training(struct radeon_connector *radeon_connector,
			    u8 training)
{
	radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_PATTERN_SET,
				   1, &training);
}

void dp_link_train(struct drm_encoder *encoder,
		   struct drm_connector *connector)
{
	struct drm_device *dev = encoder->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct radeon_encoder_atom_dig *dig;
	struct radeon_connector *radeon_connector;
	struct radeon_connector_atom_dig *dig_connector;
	int enc_id = 0;
	bool clock_recovery, channel_eq;
	u8 link_status[DP_LINK_STATUS_SIZE];
	u8 link_configuration[DP_LINK_CONFIGURATION_SIZE];
	u8 tries, voltage;
	u8 train_set[4];
	int i;

	if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
	    (connector->connector_type != DRM_MODE_CONNECTOR_eDP))
		return;

	if (!radeon_encoder->enc_priv)
		return;
	dig = radeon_encoder->enc_priv;

	radeon_connector = to_radeon_connector(connector);
	if (!radeon_connector->con_priv)
		return;
	dig_connector = radeon_connector->con_priv;

	if (dig->dig_encoder)
		enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
	else
		enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
	if (dig->linkb)
		enc_id |= ATOM_DP_CONFIG_LINK_B;
	else
		enc_id |= ATOM_DP_CONFIG_LINK_A;

	memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
	if (dig_connector->dp_clock == 270000)
		link_configuration[0] = DP_LINK_BW_2_7;
	else
		link_configuration[0] = DP_LINK_BW_1_62;
	link_configuration[1] = dig_connector->dp_lane_count;
	if (dig_connector->dpcd[0] >= 0x11)
		link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;

	/* power up the sink */
	dp_set_power(radeon_connector, DP_SET_POWER_D0);
	/* disable the training pattern on the sink */
	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
	/* set link bw and lanes on the sink */
	dp_set_link_bw_lanes(radeon_connector, link_configuration);
	/* disable downspread on the sink */
	dp_set_downspread(radeon_connector, 0);
	if (ASIC_IS_DCE4(rdev)) {
		/* start training on the source */
		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_START);
		/* set training pattern 1 on the source */
		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1);
	} else {
		/* start training on the source */
		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_START,
					  dig_connector->dp_clock, enc_id, 0);
		/* set training pattern 1 on the source */
		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
					  dig_connector->dp_clock, enc_id, 0);
	}

	/* set initial vs/emph */
	memset(train_set, 0, 4);
	udelay(400);
	/* set training pattern 1 on the sink */
	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_1);

	dp_update_dpvs_emph(radeon_connector, encoder, train_set);

	/* clock recovery loop */
	clock_recovery = false;
	tries = 0;
	voltage = 0xff;
	for (;;) {
		udelay(100);
		if (!atom_dp_get_link_status(radeon_connector, link_status))
			break;

		if (dp_clock_recovery_ok(link_status, dig_connector->dp_lane_count)) {
			clock_recovery = true;
			break;
		}

		for (i = 0; i < dig_connector->dp_lane_count; i++) {
			if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
				break;
		}
		if (i == dig_connector->dp_lane_count) {
			DRM_ERROR("clock recovery reached max voltage\n");
			break;
		}

		if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
			++tries;
			if (tries == 5) {
				DRM_ERROR("clock recovery tried 5 times\n");
				break;
			}
		} else
			tries = 0;

		voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;

		/* Compute new train_set as requested by sink */
		dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
		dp_update_dpvs_emph(radeon_connector, encoder, train_set);
	}
	if (!clock_recovery)
		DRM_ERROR("clock recovery failed\n");
	else
		DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n",
			  train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
			  (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
			  DP_TRAIN_PRE_EMPHASIS_SHIFT);


	/* set training pattern 2 on the sink */
	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2);
	/* set training pattern 2 on the source */
	if (ASIC_IS_DCE4(rdev))
		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2);
	else
		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
					  dig_connector->dp_clock, enc_id, 1);

	/* channel equalization loop */
	tries = 0;
	channel_eq = false;
	for (;;) {
		udelay(400);
		if (!atom_dp_get_link_status(radeon_connector, link_status))
			break;

		if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) {
			channel_eq = true;
			break;
		}

		/* Try 5 times */
		if (tries > 5) {
			DRM_ERROR("channel eq failed: 5 tries\n");
			break;
		}

		/* Compute new train_set as requested by sink */
		dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
		dp_update_dpvs_emph(radeon_connector, encoder, train_set);

		tries++;
	}

	if (!channel_eq)
		DRM_ERROR("channel eq failed\n");
	else
		DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n",
			  train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
			  (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
			  >> DP_TRAIN_PRE_EMPHASIS_SHIFT);

	/* disable the training pattern on the sink */
	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);

	/* disable the training pattern on the source */
	if (ASIC_IS_DCE4(rdev))
		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
	else
		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
					  dig_connector->dp_clock, enc_id, 0);
}

int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
			 uint8_t write_byte, uint8_t *read_byte)
{
	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
	struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter;
	int ret = 0;
	uint16_t address = algo_data->address;
	uint8_t msg[5];
	uint8_t reply[2];
	int msg_len, dp_msg_len;
	int reply_bytes;

	/* Set up the command byte */
	if (mode & MODE_I2C_READ)
		msg[2] = AUX_I2C_READ << 4;
	else
		msg[2] = AUX_I2C_WRITE << 4;

	if (!(mode & MODE_I2C_STOP))
		msg[2] |= AUX_I2C_MOT << 4;

	msg[0] = address;
	msg[1] = address >> 8;

	reply_bytes = 1;

	msg_len = 4;
	dp_msg_len = 3;
	switch (mode) {
	case MODE_I2C_WRITE:
		msg[4] = write_byte;
		msg_len++;
		dp_msg_len += 2;
		break;
	case MODE_I2C_READ:
		dp_msg_len += 1;
		break;
	default:
		break;
	}

	msg[3] = (dp_msg_len) << 4;
	ret = radeon_process_aux_ch(auxch, msg, msg_len, reply, reply_bytes, 0);

	if (ret) {
		if (read_byte)
			*read_byte = reply[0];
		return reply_bytes;
	}
	return -EREMOTEIO;
}

