aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c50
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c35
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c24
-rw-r--r--include/drm/drm_dp_helper.h5
4 files changed, 59 insertions, 55 deletions
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index bb4eaf60117f..1378b789bd10 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -205,3 +205,53 @@ i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
205 return error; 205 return error;
206} 206}
207EXPORT_SYMBOL(i2c_dp_aux_add_bus); 207EXPORT_SYMBOL(i2c_dp_aux_add_bus);
208
209/* Helpers for DP link training */
210static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r)
211{
212 return link_status[r - DP_LANE0_1_STATUS];
213}
214
215static u8 dp_get_lane_status(u8 link_status[DP_LINK_STATUS_SIZE],
216 int lane)
217{
218 int i = DP_LANE0_1_STATUS + (lane >> 1);
219 int s = (lane & 1) * 4;
220 u8 l = dp_link_status(link_status, i);
221 return (l >> s) & 0xf;
222}
223
224bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
225 int lane_count)
226{
227 u8 lane_align;
228 u8 lane_status;
229 int lane;
230
231 lane_align = dp_link_status(link_status,
232 DP_LANE_ALIGN_STATUS_UPDATED);
233 if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
234 return false;
235 for (lane = 0; lane < lane_count; lane++) {
236 lane_status = dp_get_lane_status(link_status, lane);
237 if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
238 return false;
239 }
240 return true;
241}
242EXPORT_SYMBOL(drm_dp_channel_eq_ok);
243
244bool drm_dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
245 int lane_count)
246{
247 int lane;
248 u8 lane_status;
249
250 for (lane = 0; lane < lane_count; lane++) {
251 lane_status = dp_get_lane_status(link_status, lane);
252 if ((lane_status & DP_LANE_CR_DONE) == 0)
253 return false;
254 }
255 return true;
256}
257EXPORT_SYMBOL(drm_dp_clock_recovery_ok);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 38305c93754c..f69044b7f008 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -37,7 +37,6 @@
37#include "i915_drv.h" 37#include "i915_drv.h"
38 38
39#define DP_RECEIVER_CAP_SIZE 0xf 39#define DP_RECEIVER_CAP_SIZE 0xf
40#define DP_LINK_STATUS_SIZE 6
41#define DP_LINK_CHECK_TIMEOUT (10 * 1000) 40#define DP_LINK_CHECK_TIMEOUT (10 * 1000)
42 41
43/** 42/**
@@ -1437,13 +1436,6 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_
1437} 1436}
1438 1437
1439static uint8_t 1438static uint8_t
1440intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
1441 int r)
1442{
1443 return link_status[r - DP_LANE0_1_STATUS];
1444}
1445
1446static uint8_t
1447intel_get_adjust_request_voltage(uint8_t adjust_request[2], 1439intel_get_adjust_request_voltage(uint8_t adjust_request[2],
1448 int lane) 1440 int lane)
1449{ 1441{
@@ -1728,29 +1720,6 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count
1728 return true; 1720 return true;
1729} 1721}
1730 1722
1731/* Check to see if channel eq is done on all channels */
1732#define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\
1733 DP_LANE_CHANNEL_EQ_DONE|\
1734 DP_LANE_SYMBOL_LOCKED)
1735static bool
1736intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE])
1737{
1738 uint8_t lane_align;
1739 uint8_t lane_status;
1740 int lane;
1741
1742 lane_align = intel_dp_link_status(link_status,
1743 DP_LANE_ALIGN_STATUS_UPDATED);
1744 if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
1745 return false;
1746 for (lane = 0; lane < intel_dp->lane_count; lane++) {
1747 lane_status = intel_get_lane_status(link_status, lane);
1748 if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS)
1749 return false;
1750 }
1751 return true;
1752}
1753
1754static bool 1723static bool
1755intel_dp_set_link_train(struct intel_dp *intel_dp, 1724intel_dp_set_link_train(struct intel_dp *intel_dp,
1756 uint32_t dp_reg_value, 1725 uint32_t dp_reg_value,
@@ -2004,7 +1973,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
2004 continue; 1973 continue;
2005 } 1974 }
2006 1975
2007 if (intel_channel_eq_ok(intel_dp, link_status)) { 1976 if (drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
2008 channel_eq = true; 1977 channel_eq = true;
2009 break; 1978 break;
2010 } 1979 }
@@ -2223,7 +2192,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
2223 DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); 2192 DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n");
2224 } 2193 }
2225 2194
2226 if (!intel_channel_eq_ok(intel_dp, link_status)) { 2195 if (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
2227 DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", 2196 DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n",
2228 drm_get_encoder_name(&intel_dp->base.base)); 2197 drm_get_encoder_name(&intel_dp->base.base));
2229 intel_dp_start_link_train(intel_dp); 2198 intel_dp_start_link_train(intel_dp);
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index d5699fe4f1e8..3f46bb1bb987 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -34,7 +34,6 @@
34 34
35/* move these to drm_dp_helper.c/h */ 35/* move these to drm_dp_helper.c/h */
36#define DP_LINK_CONFIGURATION_SIZE 9 36#define DP_LINK_CONFIGURATION_SIZE 9
37#define DP_LINK_STATUS_SIZE 6
38#define DP_DPCD_SIZE 8 37#define DP_DPCD_SIZE 8
39 38
40static char *voltage_names[] = { 39static char *voltage_names[] = {
@@ -318,25 +317,6 @@ static bool dp_clock_recovery_ok(u8 link_status[DP_LINK_STATUS_SIZE],
318 return true; 317 return true;
319} 318}
320 319
321static bool dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
322 int lane_count)
323{
324 u8 lane_align;
325 u8 lane_status;
326 int lane;
327
328 lane_align = dp_link_status(link_status,
329 DP_LANE_ALIGN_STATUS_UPDATED);
330 if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0)
331 return false;
332 for (lane = 0; lane < lane_count; lane++) {
333 lane_status = dp_get_lane_status(link_status, lane);
334 if ((lane_status & DP_CHANNEL_EQ_BITS) != DP_CHANNEL_EQ_BITS)
335 return false;
336 }
337 return true;
338}
339
340static u8 dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE], 320static u8 dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE],
341 int lane) 321 int lane)
342 322
@@ -664,7 +644,7 @@ bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
664 644
665 if (!radeon_dp_get_link_status(radeon_connector, link_status)) 645 if (!radeon_dp_get_link_status(radeon_connector, link_status))
666 return false; 646 return false;
667 if (dp_channel_eq_ok(link_status, dig->dp_lane_count)) 647 if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
668 return false; 648 return false;
669 return true; 649 return true;
670} 650}
@@ -896,7 +876,7 @@ static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info)
896 break; 876 break;
897 } 877 }
898 878
899 if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) { 879 if (drm_dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) {
900 channel_eq = true; 880 channel_eq = true;
901 break; 881 break;
902 } 882 }
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index fe061489f91f..9e1042073f67 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -322,4 +322,9 @@ struct i2c_algo_dp_aux_data {
322int 322int
323i2c_dp_aux_add_bus(struct i2c_adapter *adapter); 323i2c_dp_aux_add_bus(struct i2c_adapter *adapter);
324 324
325
326#define DP_LINK_STATUS_SIZE 6
327bool drm_dp_channel_eq_ok(u8 link_status[DP_LINK_STATUS_SIZE],
328 int lane_count);
329
325#endif /* _DRM_DP_HELPER_H_ */ 330#endif /* _DRM_DP_HELPER_H_ */