xref: /dflybsd-src/sys/dev/drm/drm_dp_helper.c (revision 9edbd4a07c3138f5c4f076f77de5d722fcc606cc)
16f486c69SFrançois Tigeot /*
26f486c69SFrançois Tigeot  * Copyright © 2009 Keith Packard
36f486c69SFrançois Tigeot  *
46f486c69SFrançois Tigeot  * Permission to use, copy, modify, distribute, and sell this software and its
56f486c69SFrançois Tigeot  * documentation for any purpose is hereby granted without fee, provided that
66f486c69SFrançois Tigeot  * the above copyright notice appear in all copies and that both that copyright
76f486c69SFrançois Tigeot  * notice and this permission notice appear in supporting documentation, and
86f486c69SFrançois Tigeot  * that the name of the copyright holders not be used in advertising or
96f486c69SFrançois Tigeot  * publicity pertaining to distribution of the software without specific,
106f486c69SFrançois Tigeot  * written prior permission.  The copyright holders make no representations
116f486c69SFrançois Tigeot  * about the suitability of this software for any purpose.  It is provided "as
126f486c69SFrançois Tigeot  * is" without express or implied warranty.
136f486c69SFrançois Tigeot  *
146f486c69SFrançois Tigeot  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
156f486c69SFrançois Tigeot  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
166f486c69SFrançois Tigeot  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
176f486c69SFrançois Tigeot  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
186f486c69SFrançois Tigeot  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
196f486c69SFrançois Tigeot  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
206f486c69SFrançois Tigeot  * OF THIS SOFTWARE.
216f486c69SFrançois Tigeot  */
226f486c69SFrançois Tigeot 
2319df918dSFrançois Tigeot #include <linux/export.h>
2418e26a6dSFrançois Tigeot #include <drm/drmP.h>
2518e26a6dSFrançois Tigeot #include <drm/drm_dp_helper.h>
266f486c69SFrançois Tigeot 
276f486c69SFrançois Tigeot 
2819df918dSFrançois Tigeot /* Helpers for DP link training */
29*9edbd4a0SFrançois Tigeot static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
306f486c69SFrançois Tigeot {
316f486c69SFrançois Tigeot 	return link_status[r - DP_LANE0_1_STATUS];
326f486c69SFrançois Tigeot }
336f486c69SFrançois Tigeot 
34*9edbd4a0SFrançois Tigeot static u8 dp_get_lane_status(const u8 link_status[DP_LINK_STATUS_SIZE],
356f486c69SFrançois Tigeot 			     int lane)
366f486c69SFrançois Tigeot {
376f486c69SFrançois Tigeot 	int i = DP_LANE0_1_STATUS + (lane >> 1);
386f486c69SFrançois Tigeot 	int s = (lane & 1) * 4;
396f486c69SFrançois Tigeot 	u8 l = dp_link_status(link_status, i);
406f486c69SFrançois Tigeot 	return (l >> s) & 0xf;
416f486c69SFrançois Tigeot }
426f486c69SFrançois Tigeot 
43*9edbd4a0SFrançois Tigeot bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
446f486c69SFrançois Tigeot 			  int lane_count)
456f486c69SFrançois Tigeot {
466f486c69SFrançois Tigeot 	u8 lane_align;
476f486c69SFrançois Tigeot 	u8 lane_status;
486f486c69SFrançois Tigeot 	int lane;
496f486c69SFrançois Tigeot 
506f486c69SFrançois Tigeot 	lane_align = dp_link_status(link_status,
516f486c69SFrançois Tigeot 				    DP_LANE_ALIGN_STATUS_UPDATED);
526f486c69SFrançois Tigeot 	if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
536f486c69SFrançois Tigeot 		return false;
546f486c69SFrançois Tigeot 	for (lane = 0; lane < lane_count; lane++) {
556f486c69SFrançois Tigeot 		lane_status = dp_get_lane_status(link_status, lane);
566f486c69SFrançois Tigeot 		if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
576f486c69SFrançois Tigeot 			return false;
586f486c69SFrançois Tigeot 	}
596f486c69SFrançois Tigeot 	return true;
606f486c69SFrançois Tigeot }
6119df918dSFrançois Tigeot EXPORT_SYMBOL(drm_dp_channel_eq_ok);
626f486c69SFrançois Tigeot 
63*9edbd4a0SFrançois Tigeot bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
646f486c69SFrançois Tigeot 			      int lane_count)
656f486c69SFrançois Tigeot {
666f486c69SFrançois Tigeot 	int lane;
676f486c69SFrançois Tigeot 	u8 lane_status;
686f486c69SFrançois Tigeot 
696f486c69SFrançois Tigeot 	for (lane = 0; lane < lane_count; lane++) {
706f486c69SFrançois Tigeot 		lane_status = dp_get_lane_status(link_status, lane);
716f486c69SFrançois Tigeot 		if ((lane_status & DP_LANE_CR_DONE) == 0)
726f486c69SFrançois Tigeot 			return false;
736f486c69SFrançois Tigeot 	}
746f486c69SFrançois Tigeot 	return true;
756f486c69SFrançois Tigeot }
7619df918dSFrançois Tigeot EXPORT_SYMBOL(drm_dp_clock_recovery_ok);
776f486c69SFrançois Tigeot 
78*9edbd4a0SFrançois Tigeot u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE],
796f486c69SFrançois Tigeot 				     int lane)
806f486c69SFrançois Tigeot {
816f486c69SFrançois Tigeot 	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
826f486c69SFrançois Tigeot 	int s = ((lane & 1) ?
836f486c69SFrançois Tigeot 		 DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
846f486c69SFrançois Tigeot 		 DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
856f486c69SFrançois Tigeot 	u8 l = dp_link_status(link_status, i);
866f486c69SFrançois Tigeot 
876f486c69SFrançois Tigeot 	return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
886f486c69SFrançois Tigeot }
8919df918dSFrançois Tigeot EXPORT_SYMBOL(drm_dp_get_adjust_request_voltage);
906f486c69SFrançois Tigeot 
91*9edbd4a0SFrançois Tigeot u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE],
926f486c69SFrançois Tigeot 					  int lane)
936f486c69SFrançois Tigeot {
946f486c69SFrançois Tigeot 	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
956f486c69SFrançois Tigeot 	int s = ((lane & 1) ?
966f486c69SFrançois Tigeot 		 DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
976f486c69SFrançois Tigeot 		 DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
986f486c69SFrançois Tigeot 	u8 l = dp_link_status(link_status, i);
996f486c69SFrançois Tigeot 
1006f486c69SFrançois Tigeot 	return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
1016f486c69SFrançois Tigeot }
10219df918dSFrançois Tigeot EXPORT_SYMBOL(drm_dp_get_adjust_request_pre_emphasis);
1036f486c69SFrançois Tigeot 
104*9edbd4a0SFrançois Tigeot void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
1056f486c69SFrançois Tigeot 	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
10619df918dSFrançois Tigeot 		udelay(100);
1076f486c69SFrançois Tigeot 	else
10819df918dSFrançois Tigeot 		mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
1096f486c69SFrançois Tigeot }
11019df918dSFrançois Tigeot EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay);
1116f486c69SFrançois Tigeot 
112*9edbd4a0SFrançois Tigeot void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) {
1136f486c69SFrançois Tigeot 	if (dpcd[DP_TRAINING_AUX_RD_INTERVAL] == 0)
11419df918dSFrançois Tigeot 		udelay(400);
1156f486c69SFrançois Tigeot 	else
11619df918dSFrançois Tigeot 		mdelay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] * 4);
1176f486c69SFrançois Tigeot }
11819df918dSFrançois Tigeot EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay);
1196f486c69SFrançois Tigeot 
1206f486c69SFrançois Tigeot u8 drm_dp_link_rate_to_bw_code(int link_rate)
1216f486c69SFrançois Tigeot {
1226f486c69SFrançois Tigeot 	switch (link_rate) {
1236f486c69SFrançois Tigeot 	case 162000:
1246f486c69SFrançois Tigeot 	default:
1256f486c69SFrançois Tigeot 		return DP_LINK_BW_1_62;
1266f486c69SFrançois Tigeot 	case 270000:
1276f486c69SFrançois Tigeot 		return DP_LINK_BW_2_7;
1286f486c69SFrançois Tigeot 	case 540000:
1296f486c69SFrançois Tigeot 		return DP_LINK_BW_5_4;
1306f486c69SFrançois Tigeot 	}
1316f486c69SFrançois Tigeot }
13219df918dSFrançois Tigeot EXPORT_SYMBOL(drm_dp_link_rate_to_bw_code);
1336f486c69SFrançois Tigeot 
1346f486c69SFrançois Tigeot int drm_dp_bw_code_to_link_rate(u8 link_bw)
1356f486c69SFrançois Tigeot {
1366f486c69SFrançois Tigeot 	switch (link_bw) {
1376f486c69SFrançois Tigeot 	case DP_LINK_BW_1_62:
1386f486c69SFrançois Tigeot 	default:
1396f486c69SFrançois Tigeot 		return 162000;
1406f486c69SFrançois Tigeot 	case DP_LINK_BW_2_7:
1416f486c69SFrançois Tigeot 		return 270000;
1426f486c69SFrançois Tigeot 	case DP_LINK_BW_5_4:
1436f486c69SFrançois Tigeot 		return 540000;
1446f486c69SFrançois Tigeot 	}
1456f486c69SFrançois Tigeot }
14619df918dSFrançois Tigeot EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate);
147