From patchwork Tue Jul 28 16:03:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Tissoires X-Patchwork-Id: 6887501 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 3DAED9F39D for ; Tue, 28 Jul 2015 16:03:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 24764205DC for ; Tue, 28 Jul 2015 16:03:41 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 0B504205E2 for ; Tue, 28 Jul 2015 16:03:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 06DA76EA47; Tue, 28 Jul 2015 09:03:38 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTPS id 59D0C898BE for ; Tue, 28 Jul 2015 09:03:36 -0700 (PDT) Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id EC8CA550CF; Tue, 28 Jul 2015 16:03:35 +0000 (UTC) Received: from plouf.banquise.eu.com (ovpn-113-32.phx2.redhat.com [10.3.113.32]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t6SG3Xvd012447; Tue, 28 Jul 2015 12:03:35 -0400 From: Benjamin Tissoires To: Daniel Vetter Date: Tue, 28 Jul 2015 12:03:27 -0400 Message-Id: <1438099409-25456-2-git-send-email-benjamin.tissoires@redhat.com> In-Reply-To: <1438099409-25456-1-git-send-email-benjamin.tissoires@redhat.com> References: <1438099409-25456-1-git-send-email-benjamin.tissoires@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 Cc: intel-gfx@lists.freedesktop.org, Benjamin Tissoires , Todd Broch , linux-kernel@vger.kernel.org Subject: [Intel-gfx] [PATCH 1/3] drm/i915: add parameters to dp_start_link_train and dp_complete_link_train X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-5.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In order to detect if the Display Port is reversed or not (when connected to a USC type-C connector), we need to probe the training with one lane to check if the polarity is correct. Factor out the code that we need later on. This commit has no functional change Signed-off-by: Benjamin Tissoires --- drivers/gpu/drm/i915/intel_dp.c | 75 ++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f1b9f93..f2352d8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3566,15 +3566,15 @@ static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) } /* Enable corresponding port and start training pattern 1 */ -void -intel_dp_start_link_train(struct intel_dp *intel_dp) +static bool +_intel_dp_start_link_train(struct intel_dp *intel_dp, uint8_t lane_count, + uint32_t *DP) { struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base; struct drm_device *dev = encoder->dev; int i; uint8_t voltage; int voltage_tries, loop_tries; - uint32_t DP = intel_dp->DP; uint8_t link_config[2]; if (HAS_DDI(dev)) @@ -3582,7 +3582,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) /* Write the link configuration data */ link_config[0] = intel_dp->link_bw; - link_config[1] = intel_dp->lane_count; + link_config[1] = lane_count; if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2); @@ -3594,14 +3594,14 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) link_config[1] = DP_SET_ANSI_8B10B; drm_dp_dpcd_write(&intel_dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2); - DP |= DP_PORT_EN; + *DP |= DP_PORT_EN; /* clock recovery */ - if (!intel_dp_reset_link_train(intel_dp, &DP, + if (!intel_dp_reset_link_train(intel_dp, DP, DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE)) { DRM_ERROR("failed to enable link training\n"); - return; + return false; } voltage = 0xff; @@ -3616,7 +3616,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) break; } - if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) { + if (drm_dp_clock_recovery_ok(link_status, lane_count)) { DRM_DEBUG_KMS("clock recovery OK\n"); break; } @@ -3629,26 +3629,26 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) DRM_DEBUG_KMS("clock recovery not ok, reset"); /* clear the flag as we are not reusing train set */ intel_dp->train_set_valid = false; - if (!intel_dp_reset_link_train(intel_dp, &DP, + if (!intel_dp_reset_link_train(intel_dp, DP, DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE)) { DRM_ERROR("failed to enable link training\n"); - return; + return false; } continue; } /* Check to see if we've tried the max voltage */ - for (i = 0; i < intel_dp->lane_count; i++) + for (i = 0; i < lane_count; i++) if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) break; - if (i == intel_dp->lane_count) { + if (i == lane_count) { ++loop_tries; if (loop_tries == 5) { DRM_ERROR("too many full retries, give up\n"); break; } - intel_dp_reset_link_train(intel_dp, &DP, + intel_dp_reset_link_train(intel_dp, DP, DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE); voltage_tries = 0; @@ -3667,21 +3667,31 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; /* Update training set as requested by target */ - if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) { + if (!intel_dp_update_link_train(intel_dp, DP, link_status)) { DRM_ERROR("failed to update link training\n"); break; } } - intel_dp->DP = DP; + return true; } +/* Enable corresponding port and start training pattern 1 */ void -intel_dp_complete_link_train(struct intel_dp *intel_dp) +intel_dp_start_link_train(struct intel_dp *intel_dp) +{ + uint32_t DP = intel_dp->DP; + + if (_intel_dp_start_link_train(intel_dp, intel_dp->lane_count, &DP)) + intel_dp->DP = DP; +} + +static bool +_intel_dp_complete_link_train(struct intel_dp *intel_dp, uint8_t lane_count, + uint32_t *DP) { bool channel_eq = false; int tries, cr_tries; - uint32_t DP = intel_dp->DP; uint32_t training_pattern = DP_TRAINING_PATTERN_2; /* Training Pattern 3 for HBR2 ot 1.2 devices that support it*/ @@ -3689,11 +3699,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) training_pattern = DP_TRAINING_PATTERN_3; /* channel equalization */ - if (!intel_dp_set_link_train(intel_dp, &DP, + if (!intel_dp_set_link_train(intel_dp, DP, training_pattern | DP_LINK_SCRAMBLING_DISABLE)) { DRM_ERROR("failed to start channel equalization\n"); - return; + return false; } tries = 0; @@ -3714,17 +3724,17 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) } /* Make sure clock is still ok */ - if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) { + if (!drm_dp_clock_recovery_ok(link_status, lane_count)) { intel_dp->train_set_valid = false; - intel_dp_start_link_train(intel_dp); - intel_dp_set_link_train(intel_dp, &DP, + _intel_dp_start_link_train(intel_dp, lane_count, DP); + intel_dp_set_link_train(intel_dp, DP, training_pattern | DP_LINK_SCRAMBLING_DISABLE); cr_tries++; continue; } - if (drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) { + if (drm_dp_channel_eq_ok(link_status, lane_count)) { channel_eq = true; break; } @@ -3732,8 +3742,8 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) /* Try 5 times, then try clock recovery if that fails */ if (tries > 5) { intel_dp->train_set_valid = false; - intel_dp_start_link_train(intel_dp); - intel_dp_set_link_train(intel_dp, &DP, + _intel_dp_start_link_train(intel_dp); + intel_dp_set_link_train(intel_dp, DP, training_pattern | DP_LINK_SCRAMBLING_DISABLE); tries = 0; @@ -3742,7 +3752,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) } /* Update training set as requested by target */ - if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) { + if (!intel_dp_update_link_train(intel_dp, DP, link_status)) { DRM_ERROR("failed to update link training\n"); break; } @@ -3751,12 +3761,21 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) intel_dp_set_idle_link_train(intel_dp); - intel_dp->DP = DP; - if (channel_eq) { intel_dp->train_set_valid = true; DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n"); } + + return channel_eq; +} + +void +intel_dp_complete_link_train(struct intel_dp *intel_dp) +{ + uint32_t DP = intel_dp->DP; + + if (_intel_dp_complete_link_train(intel_dp, intel_dp->lane_count, &DP)) + intel_dp->DP = DP; } void intel_dp_stop_link_train(struct intel_dp *intel_dp)