162143Sarchie/*
262143Sarchie * Copyright 2007-8 Advanced Micro Devices, Inc.
362143Sarchie * Copyright 2008 Red Hat Inc.
4139823Simp *
5139823Simp * Permission is hereby granted, free of charge, to any person obtaining a
6139823Simp * copy of this software and associated documentation files (the "Software"),
762143Sarchie * to deal in the Software without restriction, including without limitation
862143Sarchie * the rights to use, copy, modify, merge, publish, distribute, sublicense,
962143Sarchie * and/or sell copies of the Software, and to permit persons to whom the
1062143Sarchie * Software is furnished to do so, subject to the following conditions:
1162143Sarchie *
1262143Sarchie * The above copyright notice and this permission notice shall be included in
1362143Sarchie * all copies or substantial portions of the Software.
1462143Sarchie *
1562143Sarchie * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1662143Sarchie * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1762143Sarchie * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1862143Sarchie * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1962143Sarchie * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2062143Sarchie * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2162143Sarchie * OTHER DEALINGS IN THE SOFTWARE.
2262143Sarchie *
2362143Sarchie * Authors: Dave Airlie
2462143Sarchie *          Alex Deucher
2562143Sarchie *          Jerome Glisse
2662143Sarchie */
2762143Sarchie
2862143Sarchie#include <sys/cdefs.h>
2962143Sarchie__FBSDID("$FreeBSD: releng/10.3/sys/dev/drm2/radeon/atombios_dp.c 282199 2015-04-28 19:35:05Z dumbbell $");
3062143Sarchie
3162143Sarchie#include <dev/drm2/drmP.h>
3262143Sarchie#include <dev/drm2/radeon/radeon_drm.h>
3362143Sarchie#include "radeon.h"
3462143Sarchie
3562143Sarchie#include "atom.h"
3662143Sarchie#include "atom-bits.h"
3762143Sarchie#include <dev/drm2/drm_dp_helper.h>
3862143Sarchie
3962143Sarchie/* move these to drm_dp_helper.c/h */
4062143Sarchie#define DP_LINK_CONFIGURATION_SIZE 9
4162143Sarchie#define DP_DPCD_SIZE DP_RECEIVER_CAP_SIZE
4262143Sarchie
4362143Sarchiestatic char *voltage_names[] = {
4462143Sarchie        "0.4V", "0.6V", "0.8V", "1.2V"
4562143Sarchie};
4662143Sarchiestatic char *pre_emph_names[] = {
4762143Sarchie        "0dB", "3.5dB", "6dB", "9.5dB"
4862143Sarchie};
4962143Sarchie
5062143Sarchie/***** radeon AUX functions *****/
5162143Sarchieunion aux_channel_transaction {
5262143Sarchie	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
5362143Sarchie	PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
5462143Sarchie};
5562143Sarchie
5662143Sarchiestatic int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
5762143Sarchie				 u8 *send, int send_bytes,
58136428Sglebius				 u8 *recv, int recv_size,
5962143Sarchie				 u8 delay, u8 *ack)
60141721Sglebius{
6162143Sarchie	struct drm_device *dev = chan->dev;
6262143Sarchie	struct radeon_device *rdev = dev->dev_private;
6362143Sarchie	union aux_channel_transaction args;
6462143Sarchie	int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
6562143Sarchie	unsigned char *base;
6662143Sarchie	int recv_bytes;
6762143Sarchie
6862143Sarchie	memset(&args, 0, sizeof(args));
6962143Sarchie
7062143Sarchie	base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
71147256Sbrooks
72147256Sbrooks	memcpy(base, send, send_bytes);
7362143Sarchie
74126035Spjd	args.v1.lpAuxRequest = 0 + 4;
75126035Spjd	args.v1.lpDataOut = 16 + 4;
76126035Spjd	args.v1.ucDataOutLen = 0;
77126035Spjd	args.v1.ucChannelID = chan->rec.i2c_id;
78129281Sarchie	args.v1.ucDelay = delay / 10;
79129281Sarchie	if (ASIC_IS_DCE4(rdev))
80126035Spjd		args.v2.ucHPD_ID = chan->rec.hpd;
81126035Spjd
82126035Spjd	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
83126035Spjd
84126035Spjd	*ack = args.v1.ucReplyStatus;
85126035Spjd
8662143Sarchie	/* timeout */
87106933Ssam	if (args.v1.ucReplyStatus == 1) {
88106933Ssam		DRM_DEBUG_KMS("dp_aux_ch timeout\n");
89106933Ssam		return -ETIMEDOUT;
90106933Ssam	}
91106933Ssam
92106933Ssam	/* flags not zero */
93139903Sglebius	if (args.v1.ucReplyStatus == 2) {
94106933Ssam		DRM_DEBUG_KMS("dp_aux_ch flags not zero\n");
9562143Sarchie		return -EBUSY;
96106933Ssam	}
97106933Ssam
9862143Sarchie	/* error */
9962143Sarchie	if (args.v1.ucReplyStatus == 3) {
10062143Sarchie		DRM_DEBUG_KMS("dp_aux_ch error\n");
101139903Sglebius		return -EIO;
10262143Sarchie	}
10362143Sarchie
104131155Sjulian	recv_bytes = args.v1.ucDataOutLen;
105131155Sjulian	if (recv_bytes > recv_size)
10662143Sarchie		recv_bytes = recv_size;
10762143Sarchie
10862143Sarchie	if (recv && recv_size)
10962143Sarchie		memcpy(recv, base + 16, recv_bytes);
11070700Sjulian
11162143Sarchie	return recv_bytes;
11269922Sjulian}
11362143Sarchie
11462143Sarchiestatic int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,
11562143Sarchie				      u16 address, u8 *send, u8 send_bytes, u8 delay)
11662143Sarchie{
11762143Sarchie	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
11862143Sarchie	int ret;
11962143Sarchie	u8 msg[20];
12062143Sarchie	int msg_bytes = send_bytes + 4;
12162143Sarchie	u8 ack;
12262143Sarchie	unsigned retry;
12362143Sarchie
12462143Sarchie	if (send_bytes > 16)
12562143Sarchie		return -1;
12662143Sarchie
12762143Sarchie	msg[0] = address;
12862143Sarchie	msg[1] = address >> 8;
12962143Sarchie	msg[2] = AUX_NATIVE_WRITE << 4;
13062143Sarchie	msg[3] = (msg_bytes << 4) | (send_bytes - 1);
13162143Sarchie	memcpy(&msg[4], send, send_bytes);
13262143Sarchie
13364358Sarchie	for (retry = 0; retry < 4; retry++) {
13464358Sarchie		ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
13564358Sarchie					    msg, msg_bytes, NULL, 0, delay, &ack);
13664358Sarchie		if (ret == -EBUSY)
13764358Sarchie			continue;
138123600Sru		else if (ret < 0)
13964358Sarchie			return ret;
14064358Sarchie		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
14164358Sarchie			return send_bytes;
14264653Sarchie		else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
14364653Sarchie			udelay(400);
144123600Sru		else
14564653Sarchie			return -EIO;
14664653Sarchie	}
14764653Sarchie
14864653Sarchie	return -EIO;
14964653Sarchie}
15064653Sarchie
15164653Sarchiestatic int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
15264653Sarchie				     u16 address, u8 *recv, int recv_bytes, u8 delay)
15364653Sarchie{
15464653Sarchie	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
15564653Sarchie	u8 msg[4];
15664358Sarchie	int msg_bytes = 4;
15764358Sarchie	u8 ack;
15864358Sarchie	int ret;
15964358Sarchie	unsigned retry;
16064358Sarchie
16164358Sarchie	msg[0] = address;
16264358Sarchie	msg[1] = address >> 8;
16364653Sarchie	msg[2] = AUX_NATIVE_READ << 4;
16464653Sarchie	msg[3] = (msg_bytes << 4) | (recv_bytes - 1);
16564653Sarchie
16664653Sarchie	for (retry = 0; retry < 4; retry++) {
16764653Sarchie		ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
16864653Sarchie					    msg, msg_bytes, recv, recv_bytes, delay, &ack);
16964653Sarchie		if (ret == -EBUSY)
17064358Sarchie			continue;
17164358Sarchie		else if (ret < 0)
17264358Sarchie			return ret;
17364358Sarchie		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
17464358Sarchie			return ret;
175141721Sglebius		else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
176141721Sglebius			udelay(400);
177141721Sglebius		else if (ret == 0)
178141721Sglebius			return -EPROTO;
179141721Sglebius		else
180141721Sglebius			return -EIO;
181141721Sglebius	}
182141721Sglebius
183141721Sglebius	return -EIO;
184141721Sglebius}
185141721Sglebius
186141721Sglebiusstatic void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector,
187141721Sglebius				 u16 reg, u8 val)
188141721Sglebius{
189141910Sglebius	radeon_dp_aux_native_write(radeon_connector, reg, &val, 1, 0);
190141910Sglebius}
191141910Sglebius
192141910Sglebiusstatic u8 radeon_read_dpcd_reg(struct radeon_connector *radeon_connector,
193141910Sglebius			       u16 reg)
194141910Sglebius{
195141910Sglebius	u8 val = 0;
19662143Sarchie
19762143Sarchie	radeon_dp_aux_native_read(radeon_connector, reg, &val, 1, 0);
19862143Sarchie
19962143Sarchie	return val;
200129823Sjulian}
201129823Sjulian
202129823Sjulianint radeon_dp_i2c_aux_ch(device_t dev, int mode, u8 write_byte, u8 *read_byte)
203129823Sjulian{
204129823Sjulian	struct iic_dp_aux_data *algo_data = device_get_softc(dev);
205129823Sjulian	struct radeon_i2c_chan *auxch = algo_data->priv;
206129823Sjulian	u16 address = algo_data->address;
207129823Sjulian	u8 msg[5];
208129823Sjulian	u8 reply[2];
209129823Sjulian	unsigned retry;
210129823Sjulian	int msg_bytes;
21162143Sarchie	int reply_bytes = 1;
21262143Sarchie	int ret;
21362143Sarchie	u8 ack;
21462143Sarchie
21562143Sarchie	/* Set up the command byte */
21662143Sarchie	if (mode & MODE_I2C_READ)
21762143Sarchie		msg[2] = AUX_I2C_READ << 4;
21862143Sarchie	else
21962143Sarchie		msg[2] = AUX_I2C_WRITE << 4;
22062143Sarchie
22162143Sarchie	if (!(mode & MODE_I2C_STOP))
22262143Sarchie		msg[2] |= AUX_I2C_MOT << 4;
22362143Sarchie
22462143Sarchie	msg[0] = address;
225106933Ssam	msg[1] = address >> 8;
22662143Sarchie
22762143Sarchie	switch (mode) {
22870784Sjulian	case MODE_I2C_WRITE:
229129281Sarchie		msg_bytes = 5;
23062143Sarchie		msg[3] = msg_bytes << 4;
23162143Sarchie		msg[4] = write_byte;
232129281Sarchie		break;
23362143Sarchie	case MODE_I2C_READ:
234129281Sarchie		msg_bytes = 4;
23562143Sarchie		msg[3] = msg_bytes << 4;
23662143Sarchie		break;
23762143Sarchie	default:
23862143Sarchie		msg_bytes = 4;
23962143Sarchie		msg[3] = 3 << 4;
24062143Sarchie		break;
24162143Sarchie	}
24262143Sarchie
24362143Sarchie	for (retry = 0; retry < 4; retry++) {
244106933Ssam		ret = radeon_process_aux_ch(auxch,
24562143Sarchie					    msg, msg_bytes, reply, reply_bytes, 0, &ack);
24662143Sarchie		if (ret == -EBUSY)
24770784Sjulian			continue;
248129281Sarchie		else if (ret < 0) {
24962143Sarchie			DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
250129281Sarchie			return ret;
251129281Sarchie		}
25262143Sarchie
25362143Sarchie		switch (ack & AUX_NATIVE_REPLY_MASK) {
25462143Sarchie		case AUX_NATIVE_REPLY_ACK:
255129281Sarchie			/* I2C-over-AUX Reply field is only valid
25662143Sarchie			 * when paired with AUX ACK.
25762143Sarchie			 */
25862143Sarchie			break;
25962143Sarchie		case AUX_NATIVE_REPLY_NACK:
26062143Sarchie			DRM_DEBUG_KMS("aux_ch native nack\n");
26162143Sarchie			return -EREMOTEIO;
26262143Sarchie		case AUX_NATIVE_REPLY_DEFER:
26362143Sarchie			DRM_DEBUG_KMS("aux_ch native defer\n");
26462143Sarchie			udelay(400);
26562143Sarchie			continue;
26670784Sjulian		default:
26762143Sarchie			DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack);
26862143Sarchie			return -EREMOTEIO;
26962143Sarchie		}
27062143Sarchie
27162143Sarchie		switch (ack & AUX_I2C_REPLY_MASK) {
27262143Sarchie		case AUX_I2C_REPLY_ACK:
27362143Sarchie			if (mode == MODE_I2C_READ)
27470700Sjulian				*read_byte = reply[0];
27562143Sarchie			return ret;
27662143Sarchie		case AUX_I2C_REPLY_NACK:
27762143Sarchie			DRM_DEBUG_KMS("aux_i2c nack\n");
27862143Sarchie			return -EREMOTEIO;
27962143Sarchie		case AUX_I2C_REPLY_DEFER:
28062143Sarchie			DRM_DEBUG_KMS("aux_i2c defer\n");
28162143Sarchie			udelay(400);
28262143Sarchie			break;
28362143Sarchie		default:
28462143Sarchie			DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack);
28562143Sarchie			return -EREMOTEIO;
28662143Sarchie		}
28762143Sarchie	}
28862143Sarchie
28987599Sobrien	DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
29062143Sarchie	return -EREMOTEIO;
29162143Sarchie}
292121816Sbrooks
29362143Sarchie/***** general DP utility functions *****/
29462143Sarchie
29562143Sarchie#define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
29662143Sarchie#define DP_PRE_EMPHASIS_MAX    DP_TRAIN_PRE_EMPHASIS_9_5
29768876Sdwmalone
29862143Sarchiestatic void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
29962143Sarchie				int lane_count,
300121816Sbrooks				u8 train_set[4])
30170784Sjulian{
30262143Sarchie	u8 v = 0;
30362143Sarchie	u8 p = 0;
30470784Sjulian	int lane;
30562143Sarchie
306132780Skan	for (lane = 0; lane < lane_count; lane++) {
30764358Sarchie		u8 this_v = drm_dp_get_adjust_request_voltage(link_status, lane);
30890249Sarchie		u8 this_p = drm_dp_get_adjust_request_pre_emphasis(link_status, lane);
30962143Sarchie
31062143Sarchie		DRM_DEBUG_KMS("requested signal parameters: lane %d voltage %s pre_emph %s\n",
311121816Sbrooks			  lane,
31262143Sarchie			  voltage_names[this_v >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
313121816Sbrooks			  pre_emph_names[this_p >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
31462143Sarchie
31562143Sarchie		if (this_v > v)
31662143Sarchie			v = this_v;
31762143Sarchie		if (this_p > p)
31862143Sarchie			p = this_p;
31971849Sjulian	}
32062143Sarchie
32162143Sarchie	if (v >= DP_VOLTAGE_MAX)
32262143Sarchie		v |= DP_TRAIN_MAX_SWING_REACHED;
32362143Sarchie
32462143Sarchie	if (p >= DP_PRE_EMPHASIS_MAX)
32571849Sjulian		p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
32662143Sarchie
32771849Sjulian	DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n",
32871849Sjulian		  voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
32971849Sjulian		  pre_emph_names[(p & DP_TRAIN_PRE_EMPHASIS_MASK) >> DP_TRAIN_PRE_EMPHASIS_SHIFT]);
33071849Sjulian
33171849Sjulian	for (lane = 0; lane < 4; lane++)
33271849Sjulian		train_set[lane] = v | p;
333132780Skan}
33471849Sjulian
33571849Sjulian/* convert bits per color to bits per pixel */
33662143Sarchie/* get bpc from the EDID */
33762143Sarchiestatic int convert_bpc_to_bpp(int bpc)
338139903Sglebius{
339139903Sglebius	if (bpc == 0)
340139903Sglebius		return 24;
341139903Sglebius	else
342139903Sglebius		return bpc * 3;
343139903Sglebius}
344139903Sglebius
345139903Sglebius/* get the max pix clock supported by the link rate and lane num */
346139903Sglebiusstatic int dp_get_max_dp_pix_clock(int link_rate,
347139903Sglebius				   int lane_num,
348139903Sglebius				   int bpp)
349139903Sglebius{
350139903Sglebius	return (link_rate * lane_num * 8) / bpp;
351139903Sglebius}
352139903Sglebius
353139903Sglebius/***** radeon specific DP functions *****/
354139903Sglebius
355139903Sglebius/* First get the min lane# when low rate is used according to pixel clock
356139903Sglebius * (prefer low rate), second check max lane# supported by DP panel,
357139903Sglebius * if the max lane# < low rate lane# then use max lane# instead.
358139903Sglebius */
359139903Sglebiusstatic int radeon_dp_get_dp_lane_number(struct drm_connector *connector,
360139903Sglebius					u8 dpcd[DP_DPCD_SIZE],
361139903Sglebius					int pix_clock)
362139903Sglebius{
363139903Sglebius	int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
364139903Sglebius	int max_link_rate = drm_dp_max_link_rate(dpcd);
36562143Sarchie	int max_lane_num = drm_dp_max_lane_count(dpcd);
36662143Sarchie	int lane_num;
36762143Sarchie	int max_dp_pix_clock;
36862143Sarchie
36962143Sarchie	for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) {
37062143Sarchie		max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp);
37162143Sarchie		if (pix_clock <= max_dp_pix_clock)
37262143Sarchie			break;
37362143Sarchie	}
37462143Sarchie
37570700Sjulian	return lane_num;
37662143Sarchie}
37762143Sarchie
37862143Sarchiestatic int radeon_dp_get_dp_link_clock(struct drm_connector *connector,
37962143Sarchie				       u8 dpcd[DP_DPCD_SIZE],
38062143Sarchie				       int pix_clock)
38162143Sarchie{
38262143Sarchie	int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
38362143Sarchie	int lane_num, max_pix_clock;
38462143Sarchie
38562143Sarchie	if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
38670784Sjulian	    ENCODER_OBJECT_ID_NUTMEG)
38762143Sarchie		return 270000;
38862143Sarchie
38962143Sarchie	lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock);
39062143Sarchie	max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp);
39162143Sarchie	if (pix_clock <= max_pix_clock)
39262143Sarchie		return 162000;
39362143Sarchie	max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp);
39462143Sarchie	if (pix_clock <= max_pix_clock)
39562143Sarchie		return 270000;
396129281Sarchie	if (radeon_connector_is_dp12_capable(connector)) {
39762143Sarchie		max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp);
398129281Sarchie		if (pix_clock <= max_pix_clock)
399129281Sarchie			return 540000;
400129281Sarchie	}
40162143Sarchie
40262143Sarchie	return drm_dp_max_link_rate(dpcd);
40362143Sarchie}
40462143Sarchie
40562143Sarchiestatic u8 radeon_dp_encoder_service(struct radeon_device *rdev,
40662143Sarchie				    int action, int dp_clock,
40790249Sarchie				    u8 ucconfig, u8 lane_num)
40890249Sarchie{
40990249Sarchie	DP_ENCODER_SERVICE_PARAMETERS args;
41090249Sarchie	int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
41162143Sarchie
41262143Sarchie	memset(&args, 0, sizeof(args));
41362143Sarchie	args.ucLinkClock = dp_clock / 10;
41462143Sarchie	args.ucConfig = ucconfig;
41562143Sarchie	args.ucAction = action;
41662143Sarchie	args.ucLaneNum = lane_num;
41769922Sjulian	args.ucStatus = 0;
41869922Sjulian
41969922Sjulian	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
42069922Sjulian	return args.ucStatus;
42169922Sjulian}
42269922Sjulian
42369922Sjulianu8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
42470784Sjulian{
42569922Sjulian	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
42669922Sjulian	struct drm_device *dev = radeon_connector->base.dev;
42769922Sjulian	struct radeon_device *rdev = dev->dev_private;
42869922Sjulian
42962143Sarchie	return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
43062143Sarchie					 dig_connector->dp_i2c_bus->rec.i2c_id, 0);
43162143Sarchie}
43270700Sjulian
43362143Sarchiestatic void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
43470784Sjulian{
43562143Sarchie	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
43662143Sarchie	u8 buf[3];
43770700Sjulian
43862143Sarchie	if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
43970700Sjulian		return;
44062143Sarchie
44162143Sarchie	if (radeon_dp_aux_native_read(radeon_connector, DP_SINK_OUI, buf, 3, 0))
44262143Sarchie		DRM_DEBUG_KMS("Sink OUI: %02hhx%02hhx%02hhx\n",
44362143Sarchie			      buf[0], buf[1], buf[2]);
444141195Sru
44562143Sarchie	if (radeon_dp_aux_native_read(radeon_connector, DP_BRANCH_OUI, buf, 3, 0))
44662143Sarchie		DRM_DEBUG_KMS("Branch OUI: %02hhx%02hhx%02hhx\n",
44762143Sarchie			      buf[0], buf[1], buf[2]);
44862143Sarchie}
449141195Sru
45062143Sarchiebool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
45162143Sarchie{
45262143Sarchie	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
45362143Sarchie	u8 msg[DP_DPCD_SIZE];
45462143Sarchie	int ret, i;
45562143Sarchie
45662143Sarchie	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg,
45762143Sarchie					DP_DPCD_SIZE, 0);
45862143Sarchie	if (ret > 0) {
45964358Sarchie		memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE);
46064358Sarchie		DRM_DEBUG_KMS("DPCD: ");
46164358Sarchie		for (i = 0; i < DP_DPCD_SIZE; i++)
46264358Sarchie			DRM_DEBUG_KMS("%02x ", msg[i]);
46364358Sarchie		DRM_DEBUG_KMS("\n");
46464358Sarchie
465147256Sbrooks		radeon_dp_probe_oui(radeon_connector);
46664358Sarchie
46764358Sarchie		return true;
46864653Sarchie	}
46964653Sarchie	dig_connector->dpcd[0] = 0;
47064653Sarchie	return false;
47164653Sarchie}
47264653Sarchie
47364653Sarchieint radeon_dp_get_panel_mode(struct drm_encoder *encoder,
47464653Sarchie			     struct drm_connector *connector)
47564653Sarchie{
47664653Sarchie	struct drm_device *dev = encoder->dev;
47764653Sarchie	struct radeon_device *rdev = dev->dev_private;
47864653Sarchie	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
47964653Sarchie	int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
48064653Sarchie	u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector);
48164653Sarchie	u8 tmp;
48264653Sarchie
48364653Sarchie	if (!ASIC_IS_DCE4(rdev))
48464653Sarchie		return panel_mode;
48564653Sarchie
48664358Sarchie	if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
48764358Sarchie		/* DP bridge chips */
48864358Sarchie		tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
48964358Sarchie		if (tmp & 1)
49064358Sarchie			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
49164358Sarchie		else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
49264358Sarchie			 (dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
49364358Sarchie			panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
49464358Sarchie		else
49564358Sarchie			panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
49664358Sarchie	} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
49764358Sarchie		/* eDP */
49864358Sarchie		tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP);
49964358Sarchie		if (tmp & 1)
50064358Sarchie			panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
50164358Sarchie	}
50264653Sarchie
50364653Sarchie	return panel_mode;
50464653Sarchie}
50564653Sarchie
50664653Sarchievoid radeon_dp_set_link_config(struct drm_connector *connector,
50764653Sarchie			       const struct drm_display_mode *mode)
50864653Sarchie{
50964653Sarchie	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
51064358Sarchie	struct radeon_connector_atom_dig *dig_connector;
51164358Sarchie
51264358Sarchie	if (!radeon_connector->con_priv)
51364358Sarchie		return;
51464358Sarchie	dig_connector = radeon_connector->con_priv;
51564358Sarchie
51664358Sarchie	if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
517141721Sglebius	    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
518141721Sglebius		dig_connector->dp_clock =
519141721Sglebius			radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
520141721Sglebius		dig_connector->dp_lane_count =
521141721Sglebius			radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock);
522141721Sglebius	}
523141721Sglebius}
524141721Sglebius
525141721Sglebiusint radeon_dp_mode_valid_helper(struct drm_connector *connector,
526141755Sglebius				struct drm_display_mode *mode)
527141721Sglebius{
528141721Sglebius	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
529141755Sglebius	struct radeon_connector_atom_dig *dig_connector;
530141721Sglebius	int dp_clock;
531141721Sglebius
532141721Sglebius	if (!radeon_connector->con_priv)
533141721Sglebius		return MODE_CLOCK_HIGH;
534141721Sglebius	dig_connector = radeon_connector->con_priv;
535141721Sglebius
536141721Sglebius	dp_clock =
537141721Sglebius		radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
538141721Sglebius
539141721Sglebius	if ((dp_clock == 540000) &&
540141721Sglebius	    (!radeon_connector_is_dp12_capable(connector)))
541141721Sglebius		return MODE_CLOCK_HIGH;
542141721Sglebius
543141721Sglebius	return MODE_OK;
544141755Sglebius}
545141721Sglebius
546141721Sglebiusstatic bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector,
547141755Sglebius				      u8 link_status[DP_LINK_STATUS_SIZE])
548141721Sglebius{
549141721Sglebius	int ret;
550141721Sglebius	ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS,
551141721Sglebius					link_status, DP_LINK_STATUS_SIZE, 100);
552141721Sglebius	if (ret <= 0) {
553141721Sglebius		return false;
554141910Sglebius	}
555141910Sglebius
556141910Sglebius	DRM_DEBUG_KMS("link status %*ph\n", 6, link_status);
55762143Sarchie	return true;
55862143Sarchie}
55962143Sarchie
56062143Sarchiebool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
56162143Sarchie{
56262143Sarchie	u8 link_status[DP_LINK_STATUS_SIZE];
56362143Sarchie	struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
56462143Sarchie
56562143Sarchie	if (!radeon_dp_get_link_status(radeon_connector, link_status))
56670700Sjulian		return false;
56770700Sjulian	if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
56862143Sarchie		return false;
56962143Sarchie	return true;
57062143Sarchie}
57162143Sarchie
57262143Sarchiestruct radeon_dp_link_train_info {
57362143Sarchie	struct radeon_device *rdev;
57462143Sarchie	struct drm_encoder *encoder;
57570700Sjulian	struct drm_connector *connector;
57662143Sarchie	struct radeon_connector *radeon_connector;
57770784Sjulian	int enc_id;
57870784Sjulian	int dp_clock;
57970700Sjulian	int dp_lane_count;
58062143Sarchie	bool tp3_supported;
58170700Sjulian	u8 dpcd[DP_RECEIVER_CAP_SIZE];
58270700Sjulian	u8 train_set[4];
583131155Sjulian	u8 link_status[DP_LINK_STATUS_SIZE];
584129281Sarchie	u8 tries;
585131155Sjulian	bool use_dpencoder;
58662143Sarchie};
587131155Sjulian
58887599Sobrienstatic void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info)
589129281Sarchie{
590136312Sdes	/* set the initial vs/emph on the source */
59183366Sjulian	atombios_dig_transmitter_setup(dp_info->encoder,
59262143Sarchie				       ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH,
59362143Sarchie				       0, dp_info->train_set[0]); /* sets all lanes at once */
59462143Sarchie
595129281Sarchie	/* set the vs/emph on the sink */
59662143Sarchie	radeon_dp_aux_native_write(dp_info->radeon_connector, DP_TRAINING_LANE0_SET,
59762143Sarchie				   dp_info->train_set, dp_info->dp_lane_count, 0);
598131155Sjulian}
59962143Sarchie
60070784Sjulianstatic void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp)
60196265Sarchie{
60262143Sarchie	int rtp = 0;
60396265Sarchie
604148887Srwatson	/* set training pattern on the source */
605148887Srwatson	if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) {
60696265Sarchie		switch (tp) {
60796265Sarchie		case DP_TRAINING_PATTERN_1:
60896265Sarchie			rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1;
60996265Sarchie			break;
61062143Sarchie		case DP_TRAINING_PATTERN_2:
61162143Sarchie			rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2;
61270700Sjulian			break;
61362143Sarchie		case DP_TRAINING_PATTERN_3:
61462143Sarchie			rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3;
61562143Sarchie			break;
61697896Sarchie		}
61762143Sarchie		atombios_dig_encoder_setup(dp_info->encoder, rtp, 0);
61862143Sarchie	} else {
61964358Sarchie		switch (tp) {
62064358Sarchie		case DP_TRAINING_PATTERN_1:
62197896Sarchie			rtp = 0;
62297896Sarchie			break;
62397896Sarchie		case DP_TRAINING_PATTERN_2:
62497896Sarchie			rtp = 1;
62597896Sarchie			break;
62697896Sarchie		}
62797896Sarchie		radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
628147256Sbrooks					  dp_info->dp_clock, dp_info->enc_id, rtp);
62964358Sarchie	}
63064358Sarchie
63164358Sarchie	/* enable training pattern on the sink */
63262678Sjulian	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_TRAINING_PATTERN_SET, tp);
63362143Sarchie}
63496265Sarchie
63562143Sarchiestatic int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
63662143Sarchie{
63762143Sarchie	struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder);
63862143Sarchie	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
63962143Sarchie	u8 tmp;
64062143Sarchie
641131155Sjulian	/* power up the sink */
64262143Sarchie	if (dp_info->dpcd[0] >= 0x11)
64370784Sjulian		radeon_write_dpcd_reg(dp_info->radeon_connector,
64462143Sarchie				      DP_SET_POWER, DP_SET_POWER_D0);
64566061Sjulian
64662143Sarchie	/* possibly enable downspread on the sink */
647136428Sglebius	if (dp_info->dpcd[3] & 0x1)
648136428Sglebius		radeon_write_dpcd_reg(dp_info->radeon_connector,
649136428Sglebius				      DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5);
650136428Sglebius	else
65162143Sarchie		radeon_write_dpcd_reg(dp_info->radeon_connector,
652106933Ssam				      DP_DOWNSPREAD_CTRL, 0);
65362143Sarchie
65462143Sarchie	if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
65562143Sarchie	    (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
65662143Sarchie		radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1);
65771849Sjulian	}
65871849Sjulian
65962143Sarchie	/* set the lane count on the sink */
66062143Sarchie	tmp = dp_info->dp_lane_count;
66170700Sjulian	if (dp_info->dpcd[DP_DPCD_REV] >= 0x11 &&
66262143Sarchie	    dp_info->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)
66370784Sjulian		tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
66464358Sarchie	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LANE_COUNT_SET, tmp);
665132464Sjulian
66671849Sjulian	/* set the link rate on the sink */
66771849Sjulian	tmp = drm_dp_link_rate_to_bw_code(dp_info->dp_clock);
66871849Sjulian	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp);
66971849Sjulian
67071849Sjulian	/* start training on the source */
67171849Sjulian	if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
67271849Sjulian		atombios_dig_encoder_setup(dp_info->encoder,
67371849Sjulian					   ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0);
67471849Sjulian	else
67571849Sjulian		radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_START,
67670700Sjulian					  dp_info->dp_clock, dp_info->enc_id, 0);
677124269Sgreen
678124269Sgreen	/* disable the training pattern on the sink */
679124269Sgreen	radeon_write_dpcd_reg(dp_info->radeon_connector,
680124269Sgreen			      DP_TRAINING_PATTERN_SET,
68164358Sarchie			      DP_TRAINING_PATTERN_DISABLE);
682132464Sjulian
683132464Sjulian	return 0;
68462143Sarchie}
68562143Sarchie
68662143Sarchiestatic int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info)
68762143Sarchie{
68862143Sarchie	udelay(400);
68962143Sarchie
69062143Sarchie	/* disable the training pattern on the sink */
69162143Sarchie	radeon_write_dpcd_reg(dp_info->radeon_connector,
69262143Sarchie			      DP_TRAINING_PATTERN_SET,
69370784Sjulian			      DP_TRAINING_PATTERN_DISABLE);
69462143Sarchie
69590249Sarchie	/* disable the training pattern on the source */
69662143Sarchie	if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
697124270Sgreen		atombios_dig_encoder_setup(dp_info->encoder,
698124270Sgreen					   ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0);
699129281Sarchie	else
70062143Sarchie		radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
701129281Sarchie					  dp_info->dp_clock, dp_info->enc_id, 0);
702129281Sarchie
703129281Sarchie	return 0;
70487599Sobrien}
70570784Sjulian
70670784Sjulianstatic int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info)
70770784Sjulian{
70862143Sarchie	bool clock_recovery;
70962143Sarchie 	u8 voltage;
71062143Sarchie	int i;
71162143Sarchie
71262143Sarchie	radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_1);
71362143Sarchie	memset(dp_info->train_set, 0, 4);
71462143Sarchie	radeon_dp_update_vs_emph(dp_info);
71562143Sarchie
71662143Sarchie	udelay(400);
71762143Sarchie
71862143Sarchie	/* clock recovery loop */
71962143Sarchie	clock_recovery = false;
72062143Sarchie	dp_info->tries = 0;
72162143Sarchie	voltage = 0xff;
72262143Sarchie	while (1) {
72362143Sarchie		drm_dp_link_train_clock_recovery_delay(dp_info->dpcd);
72462143Sarchie
72562143Sarchie		if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
72662143Sarchie			DRM_ERROR("displayport link status failed\n");
72762143Sarchie			break;
72862143Sarchie		}
72962143Sarchie
73062143Sarchie		if (drm_dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) {
73162143Sarchie			clock_recovery = true;
73262143Sarchie			break;
73362143Sarchie		}
73462143Sarchie
73562143Sarchie		for (i = 0; i < dp_info->dp_lane_count; i++) {
73662143Sarchie			if ((dp_info->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
73762143Sarchie				break;
73862143Sarchie		}
739139903Sglebius		if (i == dp_info->dp_lane_count) {
74062143Sarchie			DRM_ERROR("clock recovery reached max voltage\n");
74162143Sarchie			break;
742108172Shsu		}
74362143Sarchie
74482586Sarchie		if ((dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
74582586Sarchie			++dp_info->tries;
74662143Sarchie			if (dp_info->tries == 5) {
74762143Sarchie				DRM_ERROR("clock recovery tried 5 times\n");
748108172Shsu				break;
74962143Sarchie			}
75062143Sarchie		} else
75162143Sarchie			dp_info->tries = 0;
75262143Sarchie
75362143Sarchie		voltage = dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
75462143Sarchie
75562143Sarchie		/* Compute new train_set as requested by sink */
75662143Sarchie		dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set);
75762143Sarchie
75862143Sarchie		radeon_dp_update_vs_emph(dp_info);
75962143Sarchie	}
76062143Sarchie	if (!clock_recovery) {
76162143Sarchie		DRM_ERROR("clock recovery failed\n");
76262143Sarchie		return -1;
76362143Sarchie	} else {
76462143Sarchie		DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n",
76562143Sarchie			  dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
76662143Sarchie			  (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
767139903Sglebius			  DP_TRAIN_PRE_EMPHASIS_SHIFT);
76862143Sarchie		return 0;
76962143Sarchie	}
77062143Sarchie}
77162143Sarchie
77262143Sarchiestatic int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info)
77362143Sarchie{
77462143Sarchie	bool channel_eq;
77562143Sarchie
77662143Sarchie	if (dp_info->tp3_supported)
77762143Sarchie		radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_3);
778	else
779		radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_2);
780
781	/* channel equalization loop */
782	dp_info->tries = 0;
783	channel_eq = false;
784	while (1) {
785		drm_dp_link_train_channel_eq_delay(dp_info->dpcd);
786
787		if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status)) {
788			DRM_ERROR("displayport link status failed\n");
789			break;
790		}
791
792		if (drm_dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) {
793			channel_eq = true;
794			break;
795		}
796
797		/* Try 5 times */
798		if (dp_info->tries > 5) {
799			DRM_ERROR("channel eq failed: 5 tries\n");
800			break;
801		}
802
803		/* Compute new train_set as requested by sink */
804		dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set);
805
806		radeon_dp_update_vs_emph(dp_info);
807		dp_info->tries++;
808	}
809
810	if (!channel_eq) {
811		DRM_ERROR("channel eq failed\n");
812		return -1;
813	} else {
814		DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n",
815			  dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
816			  (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
817			  >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
818		return 0;
819	}
820}
821
822void radeon_dp_link_train(struct drm_encoder *encoder,
823			  struct drm_connector *connector)
824{
825	struct drm_device *dev = encoder->dev;
826	struct radeon_device *rdev = dev->dev_private;
827	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
828	struct radeon_encoder_atom_dig *dig;
829	struct radeon_connector *radeon_connector;
830	struct radeon_connector_atom_dig *dig_connector;
831	struct radeon_dp_link_train_info dp_info;
832	int index;
833	u8 tmp, frev, crev;
834
835	if (!radeon_encoder->enc_priv)
836		return;
837	dig = radeon_encoder->enc_priv;
838
839	radeon_connector = to_radeon_connector(connector);
840	if (!radeon_connector->con_priv)
841		return;
842	dig_connector = radeon_connector->con_priv;
843
844	if ((dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) &&
845	    (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP))
846		return;
847
848	/* DPEncoderService newer than 1.1 can't program properly the
849	 * training pattern. When facing such version use the
850	 * DIGXEncoderControl (X== 1 | 2)
851	 */
852	dp_info.use_dpencoder = true;
853	index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
854	if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) {
855		if (crev > 1) {
856			dp_info.use_dpencoder = false;
857		}
858	}
859
860	dp_info.enc_id = 0;
861	if (dig->dig_encoder)
862		dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
863	else
864		dp_info.enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
865	if (dig->linkb)
866		dp_info.enc_id |= ATOM_DP_CONFIG_LINK_B;
867	else
868		dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
869
870	tmp = radeon_read_dpcd_reg(radeon_connector, DP_MAX_LANE_COUNT);
871	if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
872		dp_info.tp3_supported = true;
873	else
874		dp_info.tp3_supported = false;
875
876	memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE);
877	dp_info.rdev = rdev;
878	dp_info.encoder = encoder;
879	dp_info.connector = connector;
880	dp_info.radeon_connector = radeon_connector;
881	dp_info.dp_lane_count = dig_connector->dp_lane_count;
882	dp_info.dp_clock = dig_connector->dp_clock;
883
884	if (radeon_dp_link_train_init(&dp_info))
885		goto done;
886	if (radeon_dp_link_train_cr(&dp_info))
887		goto done;
888	if (radeon_dp_link_train_ce(&dp_info))
889		goto done;
890done:
891	if (radeon_dp_link_train_finish(&dp_info))
892		return;
893}
894