@@ -131,6 +131,24 @@ u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZ
}
EXPORT_SYMBOL(drm_dp_get_adjust_request_post_cursor);
+void drm_dp_link_train_clock_recovery_larger_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+ unsigned long rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
+ DP_TRAINING_AUX_RD_MASK;
+
+ if (rd_interval > 4)
+ DRM_DEBUG_KMS("AUX interval %lu, out of range (max 4)\n",
+ rd_interval);
+
+ if (rd_interval == 0 || dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14)
+ rd_interval = 100;
+ else
+ rd_interval *= 4 * USEC_PER_MSEC;
+
+ usleep_range(rd_interval, rd_interval * 4);
+}
+EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_larger_delay);
+
void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
{
unsigned long rd_interval = dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
@@ -180,12 +180,17 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp)
static bool
intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
{
+ struct drm_i915_private *dev_priv;
u8 voltage;
int voltage_tries, cr_tries, max_cr_tries;
bool max_vswing_reached = false;
u8 link_config[2];
u8 link_bw, rate_select;
+ if (intel_dp->attached_connector) {
+ dev_priv = to_i915(intel_dp->attached_connector->base.dev);
+ }
+
if (intel_dp->prepare_link_retrain)
intel_dp->prepare_link_retrain(intel_dp);
@@ -237,10 +242,15 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
max_cr_tries = 80;
voltage_tries = 1;
+
for (cr_tries = 0; cr_tries < max_cr_tries; ++cr_tries) {
u8 link_status[DP_LINK_STATUS_SIZE];
- drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
+ if (dev_priv && IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0)) {
+ drm_dp_link_train_clock_recovery_larger_delay(intel_dp->dpcd);
+ } else {
+ drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
+ }
if (!intel_dp_get_link_status(intel_dp, link_status)) {
DRM_ERROR("failed to get link status\n");
@@ -407,12 +417,6 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
{
struct intel_connector *intel_connector = intel_dp->attached_connector;
- /*
- * TODO: Reiniting LTTPRs here won't be needed once proper connector
- * HW state readout is added.
- */
- intel_dp_lttpr_init(intel_dp);
-
if (!intel_dp_link_training_clock_recovery(intel_dp))
goto failure_handling;
if (!intel_dp_link_training_channel_equalization(intel_dp))
@@ -1188,6 +1188,7 @@ u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZ
#define DP_LTTPR_COMMON_CAP_SIZE 8
#define DP_LTTPR_PHY_CAP_SIZE 3
+void drm_dp_link_train_clock_recovery_larger_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
void drm_dp_lttpr_link_train_clock_recovery_delay(void);
void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]);
BugLink: https://bugs.launchpad.net/bugs/1902861 For TGL platform, Connect with the MST hub, it always failed to recovery the clock for the dispaly port during the boot-up. Wait longer during the clock recovery and check the display port's status. Signed-off-by: Koba Ko <koba.ko@canonical.com> --- drivers/gpu/drm/drm_dp_helper.c | 18 ++++++++++++++++++ .../drm/i915/display/intel_dp_link_training.c | 18 +++++++++++------- include/drm/drm_dp_helper.h | 1 + 3 files changed, 30 insertions(+), 7 deletions(-)