/*
 * 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 bw = dp_lanes_for_mode_clock(dpcd, mode_clock);

	if ((lanes == 0) || (bw == 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("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("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;
}


/* 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;
	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args;
	int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
	unsigned char *base;

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

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

	memcpy(base, req_bytes, num_bytes);

	args.lpAuxRequest = 0;
	args.lpDataOut = 16;
	args.ucDataOutLen = 0;
	args.ucChannelID = chan->rec.i2c_id;
	args.ucDelay = delay / 10;

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

	if (args.ucReplyStatus) {
		DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n",
			  req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
			  chan->rec.i2c_id, args.ucReplyStatus);
		return false;
	}

	if (args.ucDataOutLen && read_byte && read_buf_len) {
		if (read_buf_len < args.ucDataOutLen) {
			DRM_ERROR("Buffer to small for return answer %d %d\n",
				  read_buf_len, args.ucDataOutLen);
			return false;
		}
		{
			int len = min(read_buf_len, args.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("DPCD: ");
			for (i = 0; i < 8; i++)
				DRM_DEBUG("%02x ", msg[i]);
			DRM_DEBUG("\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)
		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("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)
		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 (ASIC_IS_DCE32(rdev)) {
		if (dig->dig_block)
			enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
		else
			enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
		if (dig_connector->linkb)
			enc_id |= ATOM_DP_CONFIG_LINK_B;
		else
			enc_id |= ATOM_DP_CONFIG_LINK_A;
	} else {
		if (dig_connector->linkb)
			enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER | ATOM_DP_CONFIG_LINK_B;
		else
			enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER | 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);
	/* 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("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 */
	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("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);

	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;
}

