From patchwork Tue Nov 24 09:12:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405358 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJFy11dcz9sVT; Tue, 24 Nov 2020 20:12:54 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNV-0005TC-W9; Tue, 24 Nov 2020 09:12:49 +0000 Received: from mail-pf1-f193.google.com ([209.85.210.193]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNJ-0005OD-As for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:12:37 +0000 Received: by mail-pf1-f193.google.com with SMTP id w187so3368061pfd.5 for ; Tue, 24 Nov 2020 01:12:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TOV485rIDl4fSHL/SNDRba+xejeg42V02zB6p9+h9h0=; b=kHqLB4HZ0U1sFmuK6IohMe8WnnPDJHi7SH7QLxRZe+dTscfE2GclmQUA5BZeOXleFl LDc9xANsp2MANwEePvgaHIGmNk+7iyYsiOLofgQWfZoG4vzYMFzf6WgfzyZrHxkqE2Nt UoBMnkcSo2ua6rVjS/yYp47Crjg0u4KTm3v1Pu0D9dkNomoMvcXm29ZaL/BZs8Dh4jyU NPXwh9xX7UFTECnpktFB9WlHaNU8+XjCbpQiE61Ku8gG4aP0eDQ1GlpXFrxQ8dBRbuNh +30gBnl2OLlZWWrj+VWCebSOYfh0NUxvVWnIxbI17Hs+MPMfiWC5Wgj1KT2AMjcmUlPn ZjxA== X-Gm-Message-State: AOAM532W7isU35y4+pCpt8MBzfDBOPyBy2bTjuQ+D1VeC22LNoOArqvg 5rZEdtHgbBfxXfKIp/GtOC+PPSRYUf3vKA== X-Google-Smtp-Source: ABdhPJyGiixGHSXpz44LUTaIdCtOzMyWOja9PmNfaJvYFA7uQoeNnAQ8FNGDkSWlCeigl8bbjZORbQ== X-Received: by 2002:a17:90a:c687:: with SMTP id n7mr3633763pjt.185.1606209155256; Tue, 24 Nov 2020 01:12:35 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id o18sm5077843pfp.16.2020.11.24.01.12.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:34 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 01/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: s/old_crtc_state/crtc_state/ Date: Tue, 24 Nov 2020 17:12:16 +0800 Message-Id: <20201124091230.335132-2-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.193; envelope-from=vicamo@gmail.com; helo=mail-pf1-f193.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ville Syrjälä BugLink: https://bugs.launchpad.net/bugs/1903969 intel_dp_enable_port() is called during the enable sequence, so there is nothing old about the passed in crtc state. Rename it. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200929233449.32323-3-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit 95cef532f22286c810a74e1a067ed050b2e951cf https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index bf1e9cf1c0f3..2e08a33b7957 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3830,7 +3830,7 @@ g4x_set_link_train(struct intel_dp *intel_dp, } static void intel_dp_enable_port(struct intel_dp *intel_dp, - const struct intel_crtc_state *old_crtc_state) + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -3845,7 +3845,7 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp, * fail when the power sequencer is freshly used for this port. */ intel_dp->DP |= DP_PORT_EN; - if (old_crtc_state->has_audio) + if (crtc_state->has_audio) intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; intel_de_write(dev_priv, intel_dp->output_reg, intel_dp->DP); From patchwork Tue Nov 24 09:12:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405353 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJFp6Nckz9sSs; Tue, 24 Nov 2020 20:12:46 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNM-0005Oi-V6; Tue, 24 Nov 2020 09:12:40 +0000 Received: from mail-pf1-f173.google.com ([209.85.210.173]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNL-0005OX-I2 for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:12:39 +0000 Received: by mail-pf1-f173.google.com with SMTP id w202so2066418pff.10 for ; Tue, 24 Nov 2020 01:12:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8PYk7SKj3YEFY4yK6bPaDNmfefyb0eWu2GIkOcS2myE=; b=KliHQrHLtv0F1i7ZHbErqbr9ZxyDDSxbIv3dOrcVfnkVbAdLFaOKHWPFxa8i801OK2 ZySQ1h8PXoksEktx8NeJDb1FCz6UhtKbaFknezoJKhSqJdAQvTNWB2OIeahSPQ+q9eW7 pZnCtp9t02IEnGI0vT8VJeJ/ePZp4ILmO4qU6s7JRWO8MxdshYI2NaWE25GXV3oEQz7h pj+vCdY9Xc69iVqECnIp3HXrWg1X9uUkEgG2CtX0CodbbgdoUyIwavheH8gkTQNPMUOV DXAUmNlT3YUem1xY5LDiTez5ZJIbqSgS21nOp7KjLssKL17Y9bLLyF2VyxQfuItF/N+z AFLQ== X-Gm-Message-State: AOAM530PFWVmrrkhe/Zbh6Z4zC2X+BLQHWZeGGcqUQC5lgX1jxm+IAJt Xbfi3T9fTWvcutOE5RUHELa2Usovta5AGw== X-Google-Smtp-Source: ABdhPJxnPisgSlPveMuuwomwdGxp1gukiBFCV4VwheqH2wKipEIVKVJRfgzCBmbnCkJiztfHR+bOLA== X-Received: by 2002:a63:3309:: with SMTP id z9mr2861729pgz.243.1606209157532; Tue, 24 Nov 2020 01:12:37 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id c203sm7869632pfc.10.2020.11.24.01.12.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:36 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 02/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Make intel_dp_process_phy_request() static Date: Tue, 24 Nov 2020 17:12:17 +0800 Message-Id: <20201124091230.335132-3-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.173; envelope-from=vicamo@gmail.com; helo=mail-pf1-f173.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ville Syrjälä BugLink: https://bugs.launchpad.net/bugs/1903969 intel_dp_process_phy_request() has no business being externally visible. Make it static. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200929233449.32323-4-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit 7ac469a0f7c627e1fd31b8d6f2e5b828b25f0877 https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_dp.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 2e08a33b7957..da650a2f253f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5542,7 +5542,7 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt) trans_ddi_func_ctl_value); } -void intel_dp_process_phy_request(struct intel_dp *intel_dp) +static void intel_dp_process_phy_request(struct intel_dp *intel_dp) { struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 08a1c0aa8b94..58c7360eab13 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -122,7 +122,6 @@ void intel_read_dp_sdp(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, unsigned int type); bool intel_digital_port_connected(struct intel_encoder *encoder); -void intel_dp_process_phy_request(struct intel_dp *intel_dp); static inline unsigned int intel_dp_unused_lane_mask(int lane_count) { From patchwork Tue Nov 24 09:12:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405355 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJFr0lcxz9sVN; Tue, 24 Nov 2020 20:12:48 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNQ-0005Pb-3v; Tue, 24 Nov 2020 09:12:44 +0000 Received: from mail-pf1-f176.google.com ([209.85.210.176]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNO-0005Om-5D for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:12:42 +0000 Received: by mail-pf1-f176.google.com with SMTP id w187so3368207pfd.5 for ; Tue, 24 Nov 2020 01:12:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6E0lY6LHVJZsDNQkhuKkb8inCCjBmeKtKsCrhRnsP44=; b=oF35sVDOMyEnuIsG/YIS0z7MAzdeqwZLfWeOxfzKsE0x3jyxIEj019sY6OZwJjHyoK OL6ucfb7kaJ5OvPpct9ZGL5QQlR3xH9WK3BIyRsKfYdgGl6EaClgbzm25R8mSKMbVWA+ SQS6QEnfWyp6mq4kOKRDudCJR2S/P3/BdcQu/WAgJyWXHDaMGMYmjxMgBzguWKJhC4LW HuwOCB/DeyGZ64Rl/o/UaTJxBLZZw6Kx/3dHu/IYQiNqbXFEtH54/RJULsGEIzfbdvEu +R2oUZC+KYQkFEyQOLL0CGBOK2VR2vgRn/1wn3W7m8IWNRceVckXNCSYK8m6xX/6lYyi RXfA== X-Gm-Message-State: AOAM530kismi/B1tDWEjDOJWPV3Gdi244W2nLBGwPM7xdY1bItWA3Rxp iVGHXigjuySnTKkhdTXXBpw2Wx3hRFGC3Q== X-Google-Smtp-Source: ABdhPJzukgzE40hlJ0BWg8aBbND26fzIX/OKQg+47L3jR/U3P2FwEjYv2RMY0ifVkq1ex4wfA6qRrA== X-Received: by 2002:a17:90b:1057:: with SMTP id gq23mr3754247pjb.179.1606209159797; Tue, 24 Nov 2020 01:12:39 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id c191sm14299371pfc.166.2020.11.24.01.12.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:39 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 03/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Shove the PHY test into the hotplug work Date: Tue, 24 Nov 2020 17:12:18 +0800 Message-Id: <20201124091230.335132-4-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.176; envelope-from=vicamo@gmail.com; helo=mail-pf1-f176.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ville Syrjälä BugLink: https://bugs.launchpad.net/bugs/1903969 Doing any kind modeset stuff from the short hpd handler is verboten. The ad-hoc PHY test modeset code violates this. And by calling various link training related functions it's now blocking further work to plumb the crtc state down into the link training code. Let's hack around that by pushing the PHY test stuff into the hotplug work where it's less of a problem. Still not great but at least acceptable. We take a few pages from the link retraining handbook to handle the locking and whatnot. v2: Fix the intel_dp_hotplug() return value Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200930100412.9313-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit 193af12cd6815ace3bdc93454454f5c7a053d3b6 https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_dp.c | 154 ++++++++++++++++++++---- 1 file changed, 128 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index da650a2f253f..22a46edb4551 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5404,25 +5404,6 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) return test_result; } -static u8 intel_dp_prepare_phytest(struct intel_dp *intel_dp) -{ - struct drm_dp_phy_test_params *data = - &intel_dp->compliance.test_data.phytest; - - if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { - DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n"); - return DP_TEST_NAK; - } - - /* - * link_mst is set to false to avoid executing mst related code - * during compliance testing. - */ - intel_dp->link_mst = false; - - return DP_TEST_ACK; -} - static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = @@ -5570,15 +5551,18 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp) static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) { - u8 test_result; + struct drm_dp_phy_test_params *data = + &intel_dp->compliance.test_data.phytest; - test_result = intel_dp_prepare_phytest(intel_dp); - if (test_result != DP_TEST_ACK) - DRM_ERROR("Phy test preparation failed\n"); + if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { + DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n"); + return DP_TEST_NAK; + } - intel_dp_process_phy_request(intel_dp); + /* Set test active flag here so userspace doesn't interrupt things */ + intel_dp->compliance.test_active = true; - return test_result; + return DP_TEST_ACK; } static void intel_dp_handle_test_request(struct intel_dp *intel_dp) @@ -5867,6 +5851,104 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, return 0; } +static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, + struct drm_modeset_acquire_ctx *ctx, + u32 *crtc_mask) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + struct drm_connector_list_iter conn_iter; + struct intel_connector *connector; + int ret = 0; + + *crtc_mask = 0; + + drm_connector_list_iter_begin(&i915->drm, &conn_iter); + for_each_intel_connector_iter(connector, &conn_iter) { + struct drm_connector_state *conn_state = + connector->base.state; + struct intel_crtc_state *crtc_state; + struct intel_crtc *crtc; + + if (!intel_dp_has_connector(intel_dp, conn_state)) + continue; + + crtc = to_intel_crtc(conn_state->crtc); + if (!crtc) + continue; + + ret = drm_modeset_lock(&crtc->base.mutex, ctx); + if (ret) + break; + + crtc_state = to_intel_crtc_state(crtc->base.state); + + drm_WARN_ON(&i915->drm, !intel_crtc_has_dp_encoder(crtc_state)); + + if (!crtc_state->hw.active) + continue; + + if (conn_state->commit && + !try_wait_for_completion(&conn_state->commit->hw_done)) + continue; + + *crtc_mask |= drm_crtc_mask(&crtc->base); + } + drm_connector_list_iter_end(&conn_iter); + + return ret; +} + +static int intel_dp_do_phy_test(struct intel_encoder *encoder, + struct drm_modeset_acquire_ctx *ctx) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + u32 crtc_mask; + int ret; + + ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, + ctx); + if (ret) + return ret; + + ret = intel_dp_prep_phy_test(intel_dp, ctx, &crtc_mask); + if (ret) + return ret; + + if (crtc_mask == 0) + return 0; + + drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n", + encoder->base.base.id, encoder->base.name); + intel_dp_process_phy_request(intel_dp); + + return 0; +} + +static void intel_dp_phy_test(struct intel_encoder *encoder) +{ + struct drm_modeset_acquire_ctx ctx; + int ret; + + drm_modeset_acquire_init(&ctx, 0); + + for (;;) { + ret = intel_dp_do_phy_test(encoder, &ctx); + + if (ret == -EDEADLK) { + drm_modeset_backoff(&ctx); + continue; + } + + break; + } + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + drm_WARN(encoder->base.dev, ret, + "Acquiring modeset locks failed with %i\n", ret); +} + /* * If display is now connected check links status, * there has been known issues of link loss triggering @@ -5883,10 +5965,18 @@ static enum intel_hotplug_state intel_dp_hotplug(struct intel_encoder *encoder, struct intel_connector *connector) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct drm_modeset_acquire_ctx ctx; enum intel_hotplug_state state; int ret; + if (intel_dp->compliance.test_active && + intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) { + intel_dp_phy_test(encoder); + /* just do the PHY test and nothing else */ + return INTEL_HOTPLUG_UNCHANGED; + } + state = intel_encoder_hotplug(encoder, connector); drm_modeset_acquire_init(&ctx, 0); @@ -5991,11 +6081,23 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) intel_psr_short_pulse(intel_dp); - if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { + switch (intel_dp->compliance.test_type) { + case DP_TEST_LINK_TRAINING: drm_dbg_kms(&dev_priv->drm, "Link Training Compliance Test requested\n"); /* Send a Hotplug Uevent to userspace to start modeset */ drm_kms_helper_hotplug_event(&dev_priv->drm); + break; + case DP_TEST_LINK_PHY_TEST_PATTERN: + drm_dbg_kms(&dev_priv->drm, + "PHY test pattern Compliance Test requested\n"); + /* + * Schedule long hpd to do the test + * + * FIXME get rid of the ad-hoc phy test modeset code + * and properly incorporate it into the normal modeset. + */ + return false; } return true; From patchwork Tue Nov 24 09:12:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405356 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJFv47Nrz9sVK; Tue, 24 Nov 2020 20:12:51 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNT-0005RD-Jw; Tue, 24 Nov 2020 09:12:47 +0000 Received: from mail-pf1-f196.google.com ([209.85.210.196]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNQ-0005PT-Tb for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:12:45 +0000 Received: by mail-pf1-f196.google.com with SMTP id x24so5599182pfn.6 for ; Tue, 24 Nov 2020 01:12:44 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NHVtthk47BmbghwcGqiDWYpJxn0P17ig8J6px+T8obo=; b=VNjTeOhHkha1tv61pDtzCU5wVTjqRCXj0bBiOwKK7XvqKF+i+lJWjEVj6TEQ4bfC2M IYma5so5+jkOucmCwBu/Wp+ezxGnIDDh3kJhADuPNPn54gwUmKheMSSUCB1U5ojMS3rK 335EqZieW5YSpwQVwrC5FNmNB0BdV++KH0sMMVAWBHo/tKMqtDndrLD1YGKPTfcAv/nU g63P5M+VsRHNVPlcnAvpovtS82bTKSz0RSv9oueQwzyyk2IGLKX5T3VPPQfEbhQYaV80 9Of1UT8gQ6rm4ACSQQoR9sc4tYt+ebc3UfGDPTGEu6RSKnRrIUmMoGTOc9R8eoa4DNG0 WFMQ== X-Gm-Message-State: AOAM533hwX2t5QtHCd+QWfmcbqbD2e2rrO7hZUU6tVYwdUg97cm7X0LQ xIWVCplGlX1P8tM+c5bpaQn+EM/+aokd3g== X-Google-Smtp-Source: ABdhPJzJ6e4QYxiWOvRn7WKd0dLUSY6xiIg/Ksvk3D+A3hAIRjIcdIK9MFLKytJc4QEdmErPTDQd+A== X-Received: by 2002:a63:5d51:: with SMTP id o17mr2787760pgm.302.1606209162153; Tue, 24 Nov 2020 01:12:42 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id d22sm2385648pjw.11.2020.11.24.01.12.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:41 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 04/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Split ICL combo PHY buf trans per output type Date: Tue, 24 Nov 2020 17:12:19 +0800 Message-Id: <20201124091230.335132-5-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.196; envelope-from=vicamo@gmail.com; helo=mail-pf1-f196.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ville Syrjälä BugLink: https://bugs.launchpad.net/bugs/1903969 Make the mess inside the buf trans funcs a bit more manageable by splitting along the lines of output type. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200929233449.32323-6-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit 6ed9aefa69fc0085a197c2a32c2e2de87164672d https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_ddi.c | 42 +++++++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index cdcb7b1034ae..5084368c6904 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1034,24 +1034,48 @@ cnl_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries) } static const struct cnl_ddi_buf_trans * -icl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, - int *n_entries) +icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); + return icl_combo_phy_ddi_translations_hdmi; +} + +static const struct cnl_ddi_buf_trans * +icl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2); + return icl_combo_phy_ddi_translations_dp_hbr2; +} + +static const struct cnl_ddi_buf_trans * +icl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, + int *n_entries) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - if (type == INTEL_OUTPUT_HDMI) { - *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); - return icl_combo_phy_ddi_translations_hdmi; - } else if (rate > 540000 && type == INTEL_OUTPUT_EDP) { + if (rate > 540000) { *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); return icl_combo_phy_ddi_translations_edp_hbr3; - } else if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) { + } else if (dev_priv->vbt.edp.low_vswing) { *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2); return icl_combo_phy_ddi_translations_edp_hbr2; } - *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2); - return icl_combo_phy_ddi_translations_dp_hbr2; + return icl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); +} + +static const struct cnl_ddi_buf_trans * +icl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + if (type == INTEL_OUTPUT_HDMI) + return icl_get_combo_buf_trans_hdmi(encoder, type, rate, n_entries); + else if (type == INTEL_OUTPUT_EDP) + return icl_get_combo_buf_trans_edp(encoder, type, rate, n_entries); + else + return icl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); } static const struct icl_mg_phy_ddi_buf_trans * From patchwork Tue Nov 24 09:12:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405357 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJFx550Fz9sVL; Tue, 24 Nov 2020 20:12:53 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNV-0005Sc-18; Tue, 24 Nov 2020 09:12:49 +0000 Received: from mail-pf1-f175.google.com ([209.85.210.175]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNS-0005Qe-Ig for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:12:46 +0000 Received: by mail-pf1-f175.google.com with SMTP id t8so17865458pfg.8 for ; Tue, 24 Nov 2020 01:12:46 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5/2ShJ0WSRhmyXas+4+oid5NzBleEhS5PQJGpGcxFe8=; b=DuT1t6BUiMvm95IkQ9gVjV0pXS79JhRH4+WSpYOxYDWglxOLCCkgSITa/ACPSlk1ms 2EjrJk67O8c475TDko4e/3qdgYH/jZp4BWsyoAQKfNhGzotuV1TIt/Ors44Qulh7EOZf oveJf0Y22p/magjlrnm4ZjJfFPjT4Df8XgqY1Ei7Hssyh9Z+yHrZwr8x7xoK3fKdKhDY 3Dkx+gYNldH+kVP2+5EPxXiIXw6JT5kveSByLKWtFqSm7s8IHYTuSuxifTkqUBOh3BhX jBlr0uTMNmZ3NOJDcjhFQQ4O6T3NS44TYoZh7bs6E3IvGRO6kLxax/Yhez5Sz2z+syeI TmNg== X-Gm-Message-State: AOAM530M080apO1mawT+1wy7ETrgRNErolQMQRwqHy57CmGou4SlRl/j 8kIKvJsRLlKkJ5eX0O0WSzJAGnSMIgSbBw== X-Google-Smtp-Source: ABdhPJyZAwWGLfpDhi/PPjVTt/dEguCK5KNpfB2XRok1WxqyV9n9Y9Mwzcr9xx/sTO5iPv7Jvv2pZQ== X-Received: by 2002:a17:90a:65c9:: with SMTP id i9mr3899440pjs.125.1606209164391; Tue, 24 Nov 2020 01:12:44 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id b13sm10919994pfb.38.2020.11.24.01.12.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:43 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 05/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Split ICL MG PHY buf trans per output type Date: Tue, 24 Nov 2020 17:12:20 +0800 Message-Id: <20201124091230.335132-6-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.175; envelope-from=vicamo@gmail.com; helo=mail-pf1-f175.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ville Syrjälä BugLink: https://bugs.launchpad.net/bugs/1903969 Make the mess inside the buf trans funcs a bit more manageable by splitting along the lines of output type. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200929233449.32323-7-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit 5ee3e1daa8165105346a3b14dfd4917b628d2e9d https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_ddi.c | 31 ++++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 5084368c6904..b68b12f0f290 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1079,19 +1079,34 @@ icl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, } static const struct icl_mg_phy_ddi_buf_trans * -icl_get_mg_buf_trans(struct intel_encoder *encoder, int type, int rate, - int *n_entries) +icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, + int *n_entries) { - if (type == INTEL_OUTPUT_HDMI) { - *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi); - return icl_mg_phy_ddi_translations_hdmi; - } else if (rate > 270000) { + *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi); + return icl_mg_phy_ddi_translations_hdmi; +} + +static const struct icl_mg_phy_ddi_buf_trans * +icl_get_mg_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + if (rate > 270000) { *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hbr2_hbr3); return icl_mg_phy_ddi_translations_hbr2_hbr3; + } else { + *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr); + return icl_mg_phy_ddi_translations_rbr_hbr; } +} - *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr); - return icl_mg_phy_ddi_translations_rbr_hbr; +static const struct icl_mg_phy_ddi_buf_trans * +icl_get_mg_buf_trans(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + if (type == INTEL_OUTPUT_HDMI) + return icl_get_mg_buf_trans_hdmi(encoder, type, rate, n_entries); + else + return icl_get_mg_buf_trans_dp(encoder, type, rate, n_entries); } static const struct cnl_ddi_buf_trans * From patchwork Tue Nov 24 09:12:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405359 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJG16n7jz9sSs; Tue, 24 Nov 2020 20:12:57 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNZ-0005Vi-C0; Tue, 24 Nov 2020 09:12:53 +0000 Received: from mail-pf1-f193.google.com ([209.85.210.193]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNW-0005RB-D6 for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:12:50 +0000 Received: by mail-pf1-f193.google.com with SMTP id c66so17880081pfa.4 for ; Tue, 24 Nov 2020 01:12:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=sM8MLAa7CYFCoi+mFjPNtdTJGL806WbqluD5zOqnoRM=; b=jx8+aawnEc2RHZ88poj+ZpfpFVxiLOBZ51s7DJJFPsu03xB9Va2Sr0fJmtxoMK/sUC iYgEA2TP/DXAw2LWEuQN6kvFYh3hNNZzJXaQeQp3gJqhAFuQ+qpCgOKZi+bQm22Hwdap 6wxHtGIUmbxsetMDCfV3NlgYyh4BdaxyqczwWFADMa6Dz5JG6kYCNr1OpRqGKQM3LNZm UPk3x2J44GmjqrJv0O8ti9ROEG9idH9PBk16Nvn61eXRBkkR9Evcajlf9Q3QdzhXcbVW CmWYdfY9jp9eps3oi/eryl/TIcJlpeyzs12HdC3xAOVsRgAMVv8eN1MzLfGSPQ9J9UoF pqBA== X-Gm-Message-State: AOAM533f0OARdPJ0Jvlkl2J9BeyzWSCh00/mPps8xDVH5D2dnW5rLS0u vizMO0kl+7kAcPz34D/72mQQYjn6nFa2GA== X-Google-Smtp-Source: ABdhPJyW4pzRPRW8/gg4Md2UhAK6OM/LV6gF2XzrjOtZolvFHxgdSXSl2STOa1NGfJ8709CwfGluTg== X-Received: by 2002:a17:90a:2e04:: with SMTP id q4mr3902166pjd.37.1606209166618; Tue, 24 Nov 2020 01:12:46 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id r66sm12997260pfc.114.2020.11.24.01.12.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:45 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 06/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Split EHL combo PHY buf trans per output type Date: Tue, 24 Nov 2020 17:12:21 +0800 Message-Id: <20201124091230.335132-7-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.193; envelope-from=vicamo@gmail.com; helo=mail-pf1-f193.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ville Syrjälä BugLink: https://bugs.launchpad.net/bugs/1903969 Make the mess inside the buf trans funcs a bit more manageable by splitting along the lines of output type. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200929233449.32323-8-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit ba30075d8d84a0e19bffc5040e989f6ad1a89fd4 https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_ddi.c | 59 ++++++++++++++++-------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index b68b12f0f290..0d0ebd31da7e 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1110,31 +1110,50 @@ icl_get_mg_buf_trans(struct intel_encoder *encoder, int type, int rate, } static const struct cnl_ddi_buf_trans * -ehl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, - int *n_entries) +ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); + return icl_combo_phy_ddi_translations_hdmi; +} + +static const struct cnl_ddi_buf_trans * +ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + *n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp); + return ehl_combo_phy_ddi_translations_dp; +} + +static const struct cnl_ddi_buf_trans * +ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, + int *n_entries) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - switch (type) { - case INTEL_OUTPUT_HDMI: - *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); - return icl_combo_phy_ddi_translations_hdmi; - case INTEL_OUTPUT_EDP: - if (dev_priv->vbt.edp.low_vswing) { - if (rate > 540000) { - *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); - return icl_combo_phy_ddi_translations_edp_hbr3; - } else { - *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2); - return icl_combo_phy_ddi_translations_edp_hbr2; - } + if (dev_priv->vbt.edp.low_vswing) { + if (rate > 540000) { + *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); + return icl_combo_phy_ddi_translations_edp_hbr3; + } else { + *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2); + return icl_combo_phy_ddi_translations_edp_hbr2; } - /* fall through */ - default: - /* All combo DP and eDP ports that do not support low_vswing */ - *n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp); - return ehl_combo_phy_ddi_translations_dp; } + + return ehl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); +} + +static const struct cnl_ddi_buf_trans * +ehl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + if (type == INTEL_OUTPUT_HDMI) + return ehl_get_combo_buf_trans_hdmi(encoder, type, rate, n_entries); + else if (type == INTEL_OUTPUT_EDP) + return ehl_get_combo_buf_trans_edp(encoder, type, rate, n_entries); + else + return ehl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); } static const struct cnl_ddi_buf_trans * From patchwork Tue Nov 24 09:12:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405360 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJG31YCVz9sVK; Tue, 24 Nov 2020 20:12:59 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNa-0005Ww-Ri; Tue, 24 Nov 2020 09:12:54 +0000 Received: from mail-pf1-f196.google.com ([209.85.210.196]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNY-0005UA-MJ for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:12:52 +0000 Received: by mail-pf1-f196.google.com with SMTP id t8so17865678pfg.8 for ; Tue, 24 Nov 2020 01:12:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ceyCY4nrnaXmUXpis7NEtyFbNmFZuOyZBfIaSWtx48Q=; b=VlyDUQLo3d48ZKpdTddZQFt6MR6sTnQ/SRl1IeG/pe438x3WQ1PjGAicNcJwUUtrMP uIO1Xh2L5gQYYKa5pZdYmzwPKADmAHjVcBKkHvcUmC8ZQDuS7MH1qOumsvXFDiY1zqHj +OKVZjxjImdcrnwXDgZsQCM3xRbfoJCSpr6F0f5+JZO42DruEfHSSjsF+zx4aHWGybzg 9cC9/Ey92Lm9FriuxTeIMUN2AFQFML+qXHlhe1o/bxlZ8gCiNr+uQ0N49RgpK1dr/5kP z2J6J82HnVNgPLWmx6ji9bYaGK3tVCh0ugpfSgKMSX+nij5dUmkWrHDdjjOSPD0EbZ0f Ny4g== X-Gm-Message-State: AOAM533yDjTsStCzM6eFlmEyGECC+2Nz3iE+BkfbH3YzSxo+dTQL52sy WkQWhy6HPpn14qEHMNFP5mzWOixQS2NV7g== X-Google-Smtp-Source: ABdhPJyFkp26oSt2zyHIhiZZq8dq9Ui2LzDR4cJcDZoYl+0sFhmpNDibS6iWe2Y1S1arBWHDIJeDAw== X-Received: by 2002:a17:90a:aa13:: with SMTP id k19mr3886547pjq.145.1606209169750; Tue, 24 Nov 2020 01:12:49 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id b17sm2538787pgs.61.2020.11.24.01.12.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:49 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 07/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Split TGL combo PHY buf trans per output type Date: Tue, 24 Nov 2020 17:12:22 +0800 Message-Id: <20201124091230.335132-8-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.196; envelope-from=vicamo@gmail.com; helo=mail-pf1-f196.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ville Syrjälä BugLink: https://bugs.launchpad.net/bugs/1903969 Make the mess inside the buf trans funcs a bit more manageable by splitting along the lines of output type. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200929233449.32323-9-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit 4669f5c2b7edb5666d1fcb9be13bdda2a5aec066 https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_ddi.c | 83 ++++++++++++++---------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 0d0ebd31da7e..f99575a26300 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1157,51 +1157,66 @@ ehl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, } static const struct cnl_ddi_buf_trans * -tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, - int *n_entries) +tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, + int *n_entries) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - - switch (type) { - case INTEL_OUTPUT_HDMI: - *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); - return icl_combo_phy_ddi_translations_hdmi; - case INTEL_OUTPUT_EDP: - if (dev_priv->vbt.edp.hobl) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - - if (!intel_dp->hobl_failed && rate <= 540000) { - /* Same table applies to TGL, RKL and DG1 */ - *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_edp_hbr2_hobl); - return tgl_combo_phy_ddi_translations_edp_hbr2_hobl; - } - } + *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); + return icl_combo_phy_ddi_translations_hdmi; +} - if (rate > 540000) { - *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); - return icl_combo_phy_ddi_translations_edp_hbr3; - } else if (dev_priv->vbt.edp.low_vswing) { - *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2); - return icl_combo_phy_ddi_translations_edp_hbr2; - } - /* fall through */ - default: - /* All combo DP and eDP ports that do not support low_vswing */ - if (rate > 270000) { - if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) { - *n_entries = ARRAY_SIZE(tgl_uy_combo_phy_ddi_translations_dp_hbr2); - return tgl_uy_combo_phy_ddi_translations_dp_hbr2; - } +static const struct cnl_ddi_buf_trans * +tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + if (rate > 270000) { + if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) { + *n_entries = ARRAY_SIZE(tgl_uy_combo_phy_ddi_translations_dp_hbr2); + return tgl_uy_combo_phy_ddi_translations_dp_hbr2; + } else { *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr2); return tgl_combo_phy_ddi_translations_dp_hbr2; } - + } else { *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr); return tgl_combo_phy_ddi_translations_dp_hbr; } } +static const struct cnl_ddi_buf_trans * +tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + if (rate > 540000) { + *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); + return icl_combo_phy_ddi_translations_edp_hbr3; + } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) { + *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_edp_hbr2_hobl); + return tgl_combo_phy_ddi_translations_edp_hbr2_hobl; + } else if (dev_priv->vbt.edp.low_vswing) { + *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2); + return icl_combo_phy_ddi_translations_edp_hbr2; + } + + return tgl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); +} + +static const struct cnl_ddi_buf_trans * +tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + if (type == INTEL_OUTPUT_HDMI) + return tgl_get_combo_buf_trans_hdmi(encoder, type, rate, n_entries); + else if (type == INTEL_OUTPUT_EDP) + return tgl_get_combo_buf_trans_edp(encoder, type, rate, n_entries); + else + return tgl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); +} + static const struct tgl_dkl_phy_ddi_buf_trans * tgl_get_dkl_buf_trans(struct intel_encoder *encoder, int type, int rate, int *n_entries) From patchwork Tue Nov 24 09:12:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405361 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJG93Xz4z9s1l; Tue, 24 Nov 2020 20:13:05 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNg-0005bY-7k; Tue, 24 Nov 2020 09:13:00 +0000 Received: from mail-pl1-f196.google.com ([209.85.214.196]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNd-0005Vc-Qf for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:12:57 +0000 Received: by mail-pl1-f196.google.com with SMTP id u2so10370681pls.10 for ; Tue, 24 Nov 2020 01:12:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ohyUxAef6F4rf0khjSAowvArMsXCw4zJS40xMwiyomY=; b=gXQMGKC1SFYXrteBQdVQD4+QH1Rwhuq8fOPwvq/cffQcRxC528L3lrJYrHf6bNx+Wy k1R3uJgth4Pm8c66xTOSDXICgtMsZcg6xLBpxS4YX7f56xzoVahZpzuwBxcmvCSYqBOm k0uxjir15jgPC4t74yJeXmuBdw+87l3P6K3FRiOUiFBFyvPn2VaU38ksEkFpX8xSz4OC r3kSiKvsdUx5Gcf3ATsrTtrfTO6d+MGQ3rYdN0aAaTAogHVfRtGBuTjSecbTL0QtZQMX SIc5UUnLmP6joKCM9xfYoTuuO0BP9atzZxWqxrc8CxjVTqRnkvzAo8uWrNPTYDosnAEO CZ2A== X-Gm-Message-State: AOAM530t0gS+mz/h7Zy/ZZdbiJPTT9N1e6WTj2/d/kbiQ8mMdGO5XbCj wooMRl5ONPnGcBREu1ZSRRKsR4vx94JjzQ== X-Google-Smtp-Source: ABdhPJyXmSkX32AW3mxUfqvPWOOYp+EwiE4eEfMvsIGmifj3EowJ7PvinDnOKWKm2mzvBbQs3UuwhQ== X-Received: by 2002:a17:902:6bc2:b029:d6:e0ba:f2ff with SMTP id m2-20020a1709026bc2b02900d6e0baf2ffmr3367138plt.10.1606209172065; Tue, 24 Nov 2020 01:12:52 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id ne22sm2262230pjb.45.2020.11.24.01.12.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:51 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 08/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Split TGL DKL PHY buf trans per output type Date: Tue, 24 Nov 2020 17:12:23 +0800 Message-Id: <20201124091230.335132-9-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.214.196; envelope-from=vicamo@gmail.com; helo=mail-pl1-f196.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ville Syrjälä BugLink: https://bugs.launchpad.net/bugs/1903969 Make the mess inside the buf trans funcs a bit more manageable by splitting along the lines of output type. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20200929233449.32323-10-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit 6a41121f05501ce6af6a8f8300d27cdacd366201 https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_ddi.c | 31 ++++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index f99575a26300..4c6bd4444585 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1218,19 +1218,34 @@ tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, } static const struct tgl_dkl_phy_ddi_buf_trans * -tgl_get_dkl_buf_trans(struct intel_encoder *encoder, int type, int rate, - int *n_entries) +tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, + int *n_entries) { - if (type == INTEL_OUTPUT_HDMI) { - *n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans); - return tgl_dkl_phy_hdmi_ddi_trans; - } else if (rate > 270000) { + *n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans); + return tgl_dkl_phy_hdmi_ddi_trans; +} + +static const struct tgl_dkl_phy_ddi_buf_trans * +tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + if (rate > 270000) { *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans_hbr2); return tgl_dkl_phy_dp_ddi_trans_hbr2; + } else { + *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans); + return tgl_dkl_phy_dp_ddi_trans; } +} - *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans); - return tgl_dkl_phy_dp_ddi_trans; +static const struct tgl_dkl_phy_ddi_buf_trans * +tgl_get_dkl_buf_trans(struct intel_encoder *encoder, int type, int rate, + int *n_entries) +{ + if (type == INTEL_OUTPUT_HDMI) + return tgl_get_dkl_buf_trans_hdmi(encoder, type, rate, n_entries); + else + return tgl_get_dkl_buf_trans_dp(encoder, type, rate, n_entries); } static int intel_ddi_hdmi_level(struct intel_encoder *encoder) From patchwork Tue Nov 24 09:12:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405362 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJGN39f6z9s1l; Tue, 24 Nov 2020 20:13:16 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNq-0005j7-Fq; Tue, 24 Nov 2020 09:13:10 +0000 Received: from mail-pg1-f178.google.com ([209.85.215.178]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNe-0005YV-Pc for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:12:59 +0000 Received: by mail-pg1-f178.google.com with SMTP id f17so8369495pge.6 for ; Tue, 24 Nov 2020 01:12:57 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8Q3C3loNfMo177xQrhjzVekg/0iRM4gk52DjKXVIqx0=; b=tIdODRFGLNhNh7mHrVthLLVBPoVJmUmJdHhlpZ3/6ixEFL/L8bvBKMty9nhW+0LmJ/ ptfmNIX7ZPgIam1swARX/5oYOZrUpdHrZB5E6eVVIKqoKDqI/AHKDYba8W0+BNtQG4vR OlWY6uqmNywfeDrVTfGE6CQKZv+zKv4R1i4B2Hwq+O3FzImEHxBWFP3JF2DLm3WPDyiN W+clG3MXgwfiSTeScB4sqg4Hhf6m3hACC4fDO26pKID1fDiwgo4bIVzFh4/YN5ObdQwk AiqpEOSTFpVx/DyyVUOzaNYbM+TNPpfUP4KAnE7WwXv1rU9L19wv8byxIi7AJE2zOaWz nS2Q== X-Gm-Message-State: AOAM532BUh91N/NOShjlEqi07XLKNI09qz45R+jpBHnqs93iwkufWkDe lSMAKSirZJ3Z8XRMfOAoy/Rn4QtjsQz48Q== X-Google-Smtp-Source: ABdhPJwhqH5ds/385uE9qEV6G/Tbmf66sATbkzEeKQhsmmaXjpU0q46sr6o5jyGEeamTfGpKQarBng== X-Received: by 2002:a17:90b:234b:: with SMTP id ms11mr3836672pjb.110.1606209174729; Tue, 24 Nov 2020 01:12:54 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id i3sm2323187pjd.33.2020.11.24.01.12.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:53 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 09/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Plumb crtc_state to link training Date: Tue, 24 Nov 2020 17:12:24 +0800 Message-Id: <20201124091230.335132-10-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.215.178; envelope-from=vicamo@gmail.com; helo=mail-pg1-f178.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Ville Syrjälä BugLink: https://bugs.launchpad.net/bugs/1903969 Get rid of mode crtc->config usage, and some ad-hoc intel_dp state usage by plumbing the crtc state all the way down to the link training code. Unfortunately we do have to keep some cached state in intel_dp so that we can do the "does the link need retraining?" checks from the short hpd handler. v2: Add intel_crtc_state forward declaration v3: Don't kill the PHY test code totally since it's now in the hotplug work where we can get at the states v4: Don't resurrect the debug scrambling disable bit (Imre) Use intel_dp_mst_is_master_trans() (Imre) Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20201001111053.24451-1-ville.syrjala@linux.intel.com (cherry picked from commit a621860a5eb82a1b63378aac58c67fd612824013 https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_ddi.c | 413 +++++++++--------- drivers/gpu/drm/i915/display/intel_ddi.h | 6 +- .../drm/i915/display/intel_display_types.h | 17 +- drivers/gpu/drm/i915/display/intel_dp.c | 123 ++++-- drivers/gpu/drm/i915/display/intel_dp.h | 10 +- .../drm/i915/display/intel_dp_link_training.c | 102 +++-- .../drm/i915/display/intel_dp_link_training.h | 8 +- drivers/gpu/drm/i915/display/intel_dpio_phy.c | 23 +- drivers/gpu/drm/i915/display/intel_dpio_phy.h | 2 + drivers/gpu/drm/i915/display/intel_hdmi.c | 7 +- 10 files changed, 386 insertions(+), 325 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 4c6bd4444585..dbf0ffc05c8f 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1034,7 +1034,8 @@ cnl_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries) } static const struct cnl_ddi_buf_trans * -icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, +icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); @@ -1042,7 +1043,8 @@ icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, } static const struct cnl_ddi_buf_trans * -icl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, +icl_get_combo_buf_trans_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2); @@ -1050,12 +1052,13 @@ icl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, } static const struct cnl_ddi_buf_trans * -icl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, +icl_get_combo_buf_trans_edp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - if (rate > 540000) { + if (crtc_state->port_clock > 540000) { *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); return icl_combo_phy_ddi_translations_edp_hbr3; } else if (dev_priv->vbt.edp.low_vswing) { @@ -1063,23 +1066,25 @@ icl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, return icl_combo_phy_ddi_translations_edp_hbr2; } - return icl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); + return icl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries); } static const struct cnl_ddi_buf_trans * -icl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, +icl_get_combo_buf_trans(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { - if (type == INTEL_OUTPUT_HDMI) - return icl_get_combo_buf_trans_hdmi(encoder, type, rate, n_entries); - else if (type == INTEL_OUTPUT_EDP) - return icl_get_combo_buf_trans_edp(encoder, type, rate, n_entries); + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + return icl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries); + else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) + return icl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else - return icl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); + return icl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries); } static const struct icl_mg_phy_ddi_buf_trans * -icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, +icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi); @@ -1087,10 +1092,11 @@ icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, } static const struct icl_mg_phy_ddi_buf_trans * -icl_get_mg_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, +icl_get_mg_buf_trans_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { - if (rate > 270000) { + if (crtc_state->port_clock > 270000) { *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hbr2_hbr3); return icl_mg_phy_ddi_translations_hbr2_hbr3; } else { @@ -1100,17 +1106,19 @@ icl_get_mg_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, } static const struct icl_mg_phy_ddi_buf_trans * -icl_get_mg_buf_trans(struct intel_encoder *encoder, int type, int rate, +icl_get_mg_buf_trans(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { - if (type == INTEL_OUTPUT_HDMI) - return icl_get_mg_buf_trans_hdmi(encoder, type, rate, n_entries); + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + return icl_get_mg_buf_trans_hdmi(encoder, crtc_state, n_entries); else - return icl_get_mg_buf_trans_dp(encoder, type, rate, n_entries); + return icl_get_mg_buf_trans_dp(encoder, crtc_state, n_entries); } static const struct cnl_ddi_buf_trans * -ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, +ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); @@ -1118,7 +1126,8 @@ ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, } static const struct cnl_ddi_buf_trans * -ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, +ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { *n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp); @@ -1126,13 +1135,14 @@ ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, } static const struct cnl_ddi_buf_trans * -ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, +ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); if (dev_priv->vbt.edp.low_vswing) { - if (rate > 540000) { + if (crtc_state->port_clock > 540000) { *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); return icl_combo_phy_ddi_translations_edp_hbr3; } else { @@ -1141,23 +1151,25 @@ ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, } } - return ehl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); + return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries); } static const struct cnl_ddi_buf_trans * -ehl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, +ehl_get_combo_buf_trans(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { - if (type == INTEL_OUTPUT_HDMI) - return ehl_get_combo_buf_trans_hdmi(encoder, type, rate, n_entries); - else if (type == INTEL_OUTPUT_EDP) - return ehl_get_combo_buf_trans_edp(encoder, type, rate, n_entries); + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + return ehl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries); + else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) + return ehl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else - return ehl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); + return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries); } static const struct cnl_ddi_buf_trans * -tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, +tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi); @@ -1165,12 +1177,13 @@ tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, } static const struct cnl_ddi_buf_trans * -tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, +tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - if (rate > 270000) { + if (crtc_state->port_clock > 270000) { if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) { *n_entries = ARRAY_SIZE(tgl_uy_combo_phy_ddi_translations_dp_hbr2); return tgl_uy_combo_phy_ddi_translations_dp_hbr2; @@ -1185,13 +1198,14 @@ tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, } static const struct cnl_ddi_buf_trans * -tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, +tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - if (rate > 540000) { + if (crtc_state->port_clock > 540000) { *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3); return icl_combo_phy_ddi_translations_edp_hbr3; } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) { @@ -1202,23 +1216,25 @@ tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder, int type, int rate, return icl_combo_phy_ddi_translations_edp_hbr2; } - return tgl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); + return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries); } static const struct cnl_ddi_buf_trans * -tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, +tgl_get_combo_buf_trans(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { - if (type == INTEL_OUTPUT_HDMI) - return tgl_get_combo_buf_trans_hdmi(encoder, type, rate, n_entries); - else if (type == INTEL_OUTPUT_EDP) - return tgl_get_combo_buf_trans_edp(encoder, type, rate, n_entries); + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + return tgl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries); + else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) + return tgl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries); else - return tgl_get_combo_buf_trans_dp(encoder, type, rate, n_entries); + return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries); } static const struct tgl_dkl_phy_ddi_buf_trans * -tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, +tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { *n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans); @@ -1226,10 +1242,11 @@ tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder, int type, int rate, } static const struct tgl_dkl_phy_ddi_buf_trans * -tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, +tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { - if (rate > 270000) { + if (crtc_state->port_clock > 270000) { *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans_hbr2); return tgl_dkl_phy_dp_ddi_trans_hbr2; } else { @@ -1239,16 +1256,18 @@ tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder, int type, int rate, } static const struct tgl_dkl_phy_ddi_buf_trans * -tgl_get_dkl_buf_trans(struct intel_encoder *encoder, int type, int rate, +tgl_get_dkl_buf_trans(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int *n_entries) { - if (type == INTEL_OUTPUT_HDMI) - return tgl_get_dkl_buf_trans_hdmi(encoder, type, rate, n_entries); + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) + return tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, n_entries); else - return tgl_get_dkl_buf_trans_dp(encoder, type, rate, n_entries); + return tgl_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries); } -static int intel_ddi_hdmi_level(struct intel_encoder *encoder) +static int intel_ddi_hdmi_level(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int n_entries, level, default_entry; @@ -1256,19 +1275,15 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder) if (INTEL_GEN(dev_priv) >= 12) { if (intel_phy_is_combo(dev_priv, phy)) - tgl_get_combo_buf_trans(encoder, INTEL_OUTPUT_HDMI, - 0, &n_entries); + tgl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries); else - tgl_get_dkl_buf_trans(encoder, INTEL_OUTPUT_HDMI, 0, - &n_entries); + tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, &n_entries); default_entry = n_entries - 1; } else if (INTEL_GEN(dev_priv) == 11) { if (intel_phy_is_combo(dev_priv, phy)) - icl_get_combo_buf_trans(encoder, INTEL_OUTPUT_HDMI, - 0, &n_entries); + icl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries); else - icl_get_mg_buf_trans(encoder, INTEL_OUTPUT_HDMI, 0, - &n_entries); + icl_get_mg_buf_trans_hdmi(encoder, crtc_state, &n_entries); default_entry = n_entries - 1; } else if (IS_CANNONLAKE(dev_priv)) { cnl_get_buf_trans_hdmi(encoder, &n_entries); @@ -1595,14 +1610,15 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, DP_TP_CTL_ENABLE); } -static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder) +static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); intel_dp->DP = dig_port->saved_port_bits | DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0); - intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); + intel_dp->DP |= DDI_PORT_WIDTH(crtc_state->lane_count); } static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv, @@ -2266,13 +2282,14 @@ static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv, } static void skl_ddi_set_iboost(struct intel_encoder *encoder, - int level, enum intel_output_type type) + const struct intel_crtc_state *crtc_state, + int level) { struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u8 iboost; - if (type == INTEL_OUTPUT_HDMI) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) iboost = intel_bios_hdmi_boost_level(encoder); else iboost = intel_bios_dp_boost_level(encoder); @@ -2281,14 +2298,12 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, const struct ddi_buf_trans *ddi_translations; int n_entries; - if (type == INTEL_OUTPUT_HDMI) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) ddi_translations = intel_ddi_get_buf_trans_hdmi(encoder, &n_entries); - else if (type == INTEL_OUTPUT_EDP) - ddi_translations = intel_ddi_get_buf_trans_edp(encoder, - &n_entries); + else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) + ddi_translations = intel_ddi_get_buf_trans_edp(encoder, &n_entries); else - ddi_translations = intel_ddi_get_buf_trans_dp(encoder, - &n_entries); + ddi_translations = intel_ddi_get_buf_trans_dp(encoder, &n_entries); if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations)) return; @@ -2311,16 +2326,17 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, } static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, - int level, enum intel_output_type type) + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); const struct bxt_ddi_buf_trans *ddi_translations; enum port port = encoder->port; int n_entries; - if (type == INTEL_OUTPUT_HDMI) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) ddi_translations = bxt_get_buf_trans_hdmi(encoder, &n_entries); - else if (type == INTEL_OUTPUT_EDP) + else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) ddi_translations = bxt_get_buf_trans_edp(encoder, &n_entries); else ddi_translations = bxt_get_buf_trans_dp(encoder, &n_entries); @@ -2337,7 +2353,8 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder, ddi_translations[level].deemphasis); } -static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp) +static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -2347,33 +2364,28 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp) if (INTEL_GEN(dev_priv) >= 12) { if (intel_phy_is_combo(dev_priv, phy)) - tgl_get_combo_buf_trans(encoder, encoder->type, - intel_dp->link_rate, &n_entries); + tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries); else - tgl_get_dkl_buf_trans(encoder, encoder->type, - intel_dp->link_rate, &n_entries); + tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries); } else if (INTEL_GEN(dev_priv) == 11) { if (IS_ELKHARTLAKE(dev_priv)) - ehl_get_combo_buf_trans(encoder, encoder->type, - intel_dp->link_rate, &n_entries); + ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries); else if (intel_phy_is_combo(dev_priv, phy)) - icl_get_combo_buf_trans(encoder, encoder->type, - intel_dp->link_rate, &n_entries); + icl_get_combo_buf_trans(encoder, crtc_state, &n_entries); else - icl_get_mg_buf_trans(encoder, encoder->type, - intel_dp->link_rate, &n_entries); + icl_get_mg_buf_trans(encoder, crtc_state, &n_entries); } else if (IS_CANNONLAKE(dev_priv)) { - if (encoder->type == INTEL_OUTPUT_EDP) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) cnl_get_buf_trans_edp(encoder, &n_entries); else cnl_get_buf_trans_dp(encoder, &n_entries); } else if (IS_GEN9_LP(dev_priv)) { - if (encoder->type == INTEL_OUTPUT_EDP) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) bxt_get_buf_trans_edp(encoder, &n_entries); else bxt_get_buf_trans_dp(encoder, &n_entries); } else { - if (encoder->type == INTEL_OUTPUT_EDP) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) intel_ddi_get_buf_trans_edp(encoder, &n_entries); else intel_ddi_get_buf_trans_dp(encoder, &n_entries); @@ -2400,7 +2412,8 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp) } static void cnl_ddi_vswing_program(struct intel_encoder *encoder, - int level, enum intel_output_type type) + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); const struct cnl_ddi_buf_trans *ddi_translations; @@ -2408,9 +2421,9 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder, int n_entries, ln; u32 val; - if (type == INTEL_OUTPUT_HDMI) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) ddi_translations = cnl_get_buf_trans_hdmi(encoder, &n_entries); - else if (type == INTEL_OUTPUT_EDP) + else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) ddi_translations = cnl_get_buf_trans_edp(encoder, &n_entries); else ddi_translations = cnl_get_buf_trans_dp(encoder, &n_entries); @@ -2464,22 +2477,16 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder, } static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, - int level, enum intel_output_type type) + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; int width, rate, ln; u32 val; - if (type == INTEL_OUTPUT_HDMI) { - width = 4; - rate = 0; /* Rate is always < than 6GHz for HDMI */ - } else { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - - width = intel_dp->lane_count; - rate = intel_dp->link_rate; - } + width = crtc_state->lane_count; + rate = crtc_state->port_clock; /* * 1. If port type is eDP or DP, @@ -2487,10 +2494,10 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, * else clear to 0b. */ val = intel_de_read(dev_priv, CNL_PORT_PCS_DW1_LN0(port)); - if (type != INTEL_OUTPUT_HDMI) - val |= COMMON_KEEPER_EN; - else + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) val &= ~COMMON_KEEPER_EN; + else + val |= COMMON_KEEPER_EN; intel_de_write(dev_priv, CNL_PORT_PCS_DW1_GRP(port), val); /* 2. Program loadgen select */ @@ -2522,7 +2529,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val); /* 5. Program swing and de-emphasis */ - cnl_ddi_vswing_program(encoder, level, type); + cnl_ddi_vswing_program(encoder, crtc_state, level); /* 6. Set training enable to trigger update */ val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port)); @@ -2531,23 +2538,21 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder, } static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, - u32 level, int type, int rate) + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + const struct cnl_ddi_buf_trans *ddi_translations; enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - const struct cnl_ddi_buf_trans *ddi_translations = NULL; - u32 n_entries, val; - int ln; + int n_entries, ln; + u32 val; if (INTEL_GEN(dev_priv) >= 12) - ddi_translations = tgl_get_combo_buf_trans(encoder, type, rate, - &n_entries); + ddi_translations = tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries); else if (IS_ELKHARTLAKE(dev_priv)) - ddi_translations = ehl_get_combo_buf_trans(encoder, type, rate, - &n_entries); + ddi_translations = ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries); else - ddi_translations = icl_get_combo_buf_trans(encoder, type, rate, - &n_entries); + ddi_translations = icl_get_combo_buf_trans(encoder, crtc_state, &n_entries); if (!ddi_translations) return; @@ -2558,7 +2563,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, level = n_entries - 1; } - if (type == INTEL_OUTPUT_EDP) { + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED; @@ -2606,25 +2611,16 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, } static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, - u32 level, - enum intel_output_type type) + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - int width = 0; - int rate = 0; + int width, rate, ln; u32 val; - int ln = 0; - - if (type == INTEL_OUTPUT_HDMI) { - width = 4; - /* Rate is always < than 6GHz for HDMI */ - } else { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - width = intel_dp->lane_count; - rate = intel_dp->link_rate; - } + width = crtc_state->lane_count; + rate = crtc_state->port_clock; /* * 1. If port type is eDP or DP, @@ -2632,7 +2628,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, * else clear to 0b. */ val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy)); - if (type == INTEL_OUTPUT_HDMI) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) val &= ~COMMON_KEEPER_EN; else val |= COMMON_KEEPER_EN; @@ -2667,7 +2663,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); /* 5. Program swing and de-emphasis */ - icl_ddi_combo_vswing_program(encoder, level, type, rate); + icl_ddi_combo_vswing_program(encoder, crtc_state, level); /* 6. Set training enable to trigger update */ val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)); @@ -2676,23 +2672,16 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, } static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, - int link_clock, u32 level, - enum intel_output_type type) + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); const struct icl_mg_phy_ddi_buf_trans *ddi_translations; - u32 n_entries, val; - int ln, rate = 0; - - if (type != INTEL_OUTPUT_HDMI) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - - rate = intel_dp->link_rate; - } + int n_entries, ln; + u32 val; - ddi_translations = icl_get_mg_buf_trans(encoder, type, rate, - &n_entries); + ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries); /* The table does not have values for level 3 and level 9. */ if (level >= n_entries || level == 3 || level == 9) { drm_dbg_kms(&dev_priv->drm, @@ -2759,7 +2748,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, */ for (ln = 0; ln < 2; ln++) { val = intel_de_read(dev_priv, MG_CLKHUB(ln, tc_port)); - if (link_clock < 300000) + if (crtc_state->port_clock < 300000) val |= CFG_LOW_RATE_LKREN_EN; else val &= ~CFG_LOW_RATE_LKREN_EN; @@ -2770,7 +2759,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, for (ln = 0; ln < 2; ln++) { val = intel_de_read(dev_priv, MG_TX1_DCC(ln, tc_port)); val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK; - if (link_clock <= 500000) { + if (crtc_state->port_clock <= 500000) { val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN; } else { val |= CFG_AMI_CK_DIV_OVERRIDE_EN | @@ -2780,7 +2769,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, val = intel_de_read(dev_priv, MG_TX2_DCC(ln, tc_port)); val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK; - if (link_clock <= 500000) { + if (crtc_state->port_clock <= 500000) { val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN; } else { val |= CFG_AMI_CK_DIV_OVERRIDE_EN | @@ -2806,38 +2795,30 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, } static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, - int link_clock, - u32 level, - enum intel_output_type type) + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum phy phy = intel_port_to_phy(dev_priv, encoder->port); if (intel_phy_is_combo(dev_priv, phy)) - icl_combo_phy_ddi_vswing_sequence(encoder, level, type); + icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level); else - icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level, - type); + icl_mg_phy_ddi_vswing_sequence(encoder, crtc_state, level); } static void -tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock, - u32 level, enum intel_output_type type) +tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port); const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations; - u32 n_entries, val, ln, dpcnt_mask, dpcnt_val; - int rate = 0; - - if (type != INTEL_OUTPUT_HDMI) { - struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - - rate = intel_dp->link_rate; - } + u32 val, dpcnt_mask, dpcnt_val; + int n_entries, ln; - ddi_translations = tgl_get_dkl_buf_trans(encoder, encoder->type, rate, - &n_entries); + ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries); if (level >= n_entries) level = n_entries - 1; @@ -2873,20 +2854,20 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock, } static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder, - int link_clock, - u32 level, - enum intel_output_type type) + const struct intel_crtc_state *crtc_state, + int level) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum phy phy = intel_port_to_phy(dev_priv, encoder->port); if (intel_phy_is_combo(dev_priv, phy)) - icl_combo_phy_ddi_vswing_sequence(encoder, level, type); + icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level); else - tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level, type); + tgl_dkl_phy_ddi_vswing_sequence(encoder, crtc_state, level); } -static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels) +static int translate_signal_level(struct intel_dp *intel_dp, + u8 signal_levels) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); int i; @@ -2903,55 +2884,58 @@ static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels) return 0; } -static u32 intel_ddi_dp_level(struct intel_dp *intel_dp) +static int intel_ddi_dp_level(struct intel_dp *intel_dp) { u8 train_set = intel_dp->train_set[0]; - int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | - DP_TRAIN_PRE_EMPHASIS_MASK); + u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | + DP_TRAIN_PRE_EMPHASIS_MASK); return translate_signal_level(intel_dp, signal_levels); } static void -tgl_set_signal_levels(struct intel_dp *intel_dp) +tgl_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; int level = intel_ddi_dp_level(intel_dp); - tgl_ddi_vswing_sequence(encoder, intel_dp->link_rate, - level, encoder->type); + tgl_ddi_vswing_sequence(encoder, crtc_state, level); } static void -icl_set_signal_levels(struct intel_dp *intel_dp) +icl_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; int level = intel_ddi_dp_level(intel_dp); - icl_ddi_vswing_sequence(encoder, intel_dp->link_rate, - level, encoder->type); + icl_ddi_vswing_sequence(encoder, crtc_state, level); } static void -cnl_set_signal_levels(struct intel_dp *intel_dp) +cnl_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; int level = intel_ddi_dp_level(intel_dp); - cnl_ddi_vswing_sequence(encoder, level, encoder->type); + cnl_ddi_vswing_sequence(encoder, crtc_state, level); } static void -bxt_set_signal_levels(struct intel_dp *intel_dp) +bxt_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; int level = intel_ddi_dp_level(intel_dp); - bxt_ddi_vswing_sequence(encoder, level, encoder->type); + bxt_ddi_vswing_sequence(encoder, crtc_state, level); } static void -hsw_set_signal_levels(struct intel_dp *intel_dp) +hsw_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -2968,7 +2952,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp) intel_dp->DP |= signal_levels; if (IS_GEN9_BC(dev_priv)) - skl_ddi_set_iboost(encoder, level, encoder->type); + skl_ddi_set_iboost(encoder, crtc_state, level); intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); @@ -3375,8 +3359,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, int level = intel_ddi_dp_level(intel_dp); enum transcoder transcoder = crtc_state->cpu_transcoder; - intel_dp_set_link_params(intel_dp, crtc_state->port_clock, - crtc_state->lane_count, is_mst); + intel_dp_set_link_params(intel_dp, + crtc_state->port_clock, + crtc_state->lane_count); intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder); intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder); @@ -3448,8 +3433,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, */ /* 7.e Configure voltage swing and related IO settings */ - tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock, level, - encoder->type); + tgl_ddi_vswing_sequence(encoder, crtc_state, level); /* * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up @@ -3472,7 +3456,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, * We only configure what the register value will be here. Actual * enabling happens during link training farther down. */ - intel_ddi_init_dp_buf_reg(encoder); + intel_ddi_init_dp_buf_reg(encoder, crtc_state); if (!is_mst) intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); @@ -3492,11 +3476,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent) * (timeout after 800 us) */ - intel_dp_start_link_train(intel_dp); + intel_dp_start_link_train(intel_dp, crtc_state); /* 7.k Set DP_TP_CTL link training to Normal */ if (!is_trans_port_sync_mode(crtc_state)) - intel_dp_stop_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp, crtc_state); /* 7.l Configure and enable FEC if needed */ intel_ddi_enable_fec(encoder, crtc_state); @@ -3522,8 +3506,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, else drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A); - intel_dp_set_link_params(intel_dp, crtc_state->port_clock, - crtc_state->lane_count, is_mst); + intel_dp_set_link_params(intel_dp, + crtc_state->port_clock, + crtc_state->lane_count); intel_edp_panel_on(intel_dp); @@ -3537,12 +3522,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, icl_program_mg_dp_mode(dig_port, crtc_state); if (INTEL_GEN(dev_priv) >= 11) - icl_ddi_vswing_sequence(encoder, crtc_state->port_clock, - level, encoder->type); + icl_ddi_vswing_sequence(encoder, crtc_state, level); else if (IS_CANNONLAKE(dev_priv)) - cnl_ddi_vswing_sequence(encoder, level, encoder->type); + cnl_ddi_vswing_sequence(encoder, crtc_state, level); else if (IS_GEN9_LP(dev_priv)) - bxt_ddi_vswing_sequence(encoder, level, encoder->type); + bxt_ddi_vswing_sequence(encoder, crtc_state, level); else intel_prepare_dp_ddi_buffers(encoder, crtc_state); @@ -3555,17 +3539,17 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, lane_reversal); } - intel_ddi_init_dp_buf_reg(encoder); + intel_ddi_init_dp_buf_reg(encoder, crtc_state); if (!is_mst) intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_configure_protocol_converter(intel_dp); intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); intel_dp_sink_set_fec_ready(intel_dp, crtc_state); - intel_dp_start_link_train(intel_dp); + intel_dp_start_link_train(intel_dp, crtc_state); if ((port != PORT_A || INTEL_GEN(dev_priv) >= 9) && !is_trans_port_sync_mode(crtc_state)) - intel_dp_stop_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp, crtc_state); intel_ddi_enable_fec(encoder, crtc_state); @@ -3605,7 +3589,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &dig_port->hdmi; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - int level = intel_ddi_hdmi_level(encoder); + int level = intel_ddi_hdmi_level(encoder, crtc_state); intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); intel_ddi_clk_select(encoder, crtc_state); @@ -3615,20 +3599,18 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, icl_program_mg_dp_mode(dig_port, crtc_state); if (INTEL_GEN(dev_priv) >= 12) - tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock, - level, INTEL_OUTPUT_HDMI); + tgl_ddi_vswing_sequence(encoder, crtc_state, level); else if (INTEL_GEN(dev_priv) == 11) - icl_ddi_vswing_sequence(encoder, crtc_state->port_clock, - level, INTEL_OUTPUT_HDMI); + icl_ddi_vswing_sequence(encoder, crtc_state, level); else if (IS_CANNONLAKE(dev_priv)) - cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); + cnl_ddi_vswing_sequence(encoder, crtc_state, level); else if (IS_GEN9_LP(dev_priv)) - bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI); + bxt_ddi_vswing_sequence(encoder, crtc_state, level); else intel_prepare_hdmi_ddi_buffers(encoder, level); if (IS_GEN9_BC(dev_priv)) - skl_ddi_set_iboost(encoder, level, INTEL_OUTPUT_HDMI); + skl_ddi_set_iboost(encoder, crtc_state, level); intel_ddi_enable_pipe_clock(encoder, crtc_state); @@ -3918,12 +3900,14 @@ static void trans_port_sync_stop_link_train(struct intel_atomic_state *state, crtc_state->cpu_transcoder) continue; - intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder)); + intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder), + slave_crtc_state); } usleep_range(200, 400); - intel_dp_stop_link_train(enc_to_intel_dp(encoder)); + intel_dp_stop_link_train(enc_to_intel_dp(encoder), + crtc_state); } static void intel_enable_ddi_dp(struct intel_atomic_state *state, @@ -3936,7 +3920,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state, enum port port = encoder->port; if (port == PORT_A && INTEL_GEN(dev_priv) < 9) - intel_dp_stop_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp, crtc_state); intel_edp_backlight_on(crtc_state, conn_state); intel_psr_enable(intel_dp, crtc_state, conn_state); @@ -4197,7 +4181,8 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, crtc_state->lane_lat_optim_mask); } -static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) +static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); @@ -4225,9 +4210,9 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) } dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1; - if (intel_dp->link_mst) + if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) { dp_tp_ctl |= DP_TP_CTL_MODE_MST; - else { + } else { dp_tp_ctl |= DP_TP_CTL_MODE_SST; if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; @@ -4243,6 +4228,7 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) } static void intel_ddi_set_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, u8 dp_train_pat) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -4273,7 +4259,8 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp, intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, temp); } -static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp) +static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h index f5fb62fc9400..9a2ac73164f8 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.h +++ b/drivers/gpu/drm/i915/display/intel_ddi.h @@ -41,8 +41,10 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, bool state); void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv, struct intel_crtc_state *crtc_state); -u32 bxt_signal_levels(struct intel_dp *intel_dp); -u32 ddi_signal_levels(struct intel_dp *intel_dp); +u32 bxt_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +u32 ddi_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, enum transcoder cpu_transcoder, bool enable); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 3d4bf9b6a0a2..21e92e0babe5 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1270,7 +1270,6 @@ struct intel_dp { int link_rate; u8 lane_count; u8 sink_count; - bool link_mst; bool link_trained; bool has_hdmi_sink; bool has_audio; @@ -1363,13 +1362,19 @@ struct intel_dp { i915_reg_t (*aux_ch_data_reg)(struct intel_dp *dp, int index); /* This is called before a link training is starterd */ - void (*prepare_link_retrain)(struct intel_dp *intel_dp); - void (*set_link_train)(struct intel_dp *intel_dp, u8 dp_train_pat); - void (*set_idle_link_train)(struct intel_dp *intel_dp); - void (*set_signal_levels)(struct intel_dp *intel_dp); + void (*prepare_link_retrain)(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); + void (*set_link_train)(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + u8 dp_train_pat); + void (*set_idle_link_train)(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); + void (*set_signal_levels)(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); u8 (*preemph_max)(struct intel_dp *intel_dp); - u8 (*voltage_max)(struct intel_dp *intel_dp); + u8 (*voltage_max)(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); /* Displayport compliance testing */ struct intel_dp_compliance compliance; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 22a46edb4551..2fc5d253b6c2 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2779,13 +2779,11 @@ intel_dp_compute_config(struct intel_encoder *encoder, } void intel_dp_set_link_params(struct intel_dp *intel_dp, - int link_rate, u8 lane_count, - bool link_mst) + int link_rate, int lane_count) { intel_dp->link_trained = false; intel_dp->link_rate = link_rate; intel_dp->lane_count = lane_count; - intel_dp->link_mst = link_mst; } static void intel_dp_prepare(struct intel_encoder *encoder, @@ -2797,10 +2795,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder, struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; - intel_dp_set_link_params(intel_dp, pipe_config->port_clock, - pipe_config->lane_count, - intel_crtc_has_type(pipe_config, - INTEL_OUTPUT_DP_MST)); + intel_dp_set_link_params(intel_dp, + pipe_config->port_clock, + pipe_config->lane_count); /* * There are four kinds of DP registers: @@ -3771,6 +3768,7 @@ static void chv_post_disable_dp(struct intel_atomic_state *state, static void cpt_set_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, u8 dp_train_pat) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -3801,6 +3799,7 @@ cpt_set_link_train(struct intel_dp *intel_dp, static void g4x_set_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, u8 dp_train_pat) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -3836,7 +3835,8 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp, /* enable with pattern 1 (as per spec) */ - intel_dp_program_link_training_pattern(intel_dp, DP_TRAINING_PATTERN_1); + intel_dp_program_link_training_pattern(intel_dp, crtc_state, + DP_TRAINING_PATTERN_1); /* * Magic for VLV/CHV. We _must_ first set up the register @@ -3927,8 +3927,8 @@ static void intel_enable_dp(struct intel_atomic_state *state, intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_configure_protocol_converter(intel_dp); - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); + intel_dp_start_link_train(intel_dp, pipe_config); + intel_dp_stop_link_train(intel_dp, pipe_config); if (pipe_config->has_audio) { drm_dbg(&dev_priv->drm, "Enabling DP audio on pipe %c\n", @@ -4137,12 +4137,14 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATU DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE; } -static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp) +static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { return DP_TRAIN_VOLTAGE_SWING_LEVEL_2; } -static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp) +static u8 intel_dp_voltage_max_3(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; } @@ -4157,7 +4159,8 @@ static u8 intel_dp_pre_empemph_max_3(struct intel_dp *intel_dp) return DP_TRAIN_PRE_EMPH_LEVEL_3; } -static void vlv_set_signal_levels(struct intel_dp *intel_dp) +static void vlv_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; unsigned long demph_reg_value, preemph_reg_value, @@ -4237,11 +4240,13 @@ static void vlv_set_signal_levels(struct intel_dp *intel_dp) return; } - vlv_set_phy_signal_level(encoder, demph_reg_value, preemph_reg_value, + vlv_set_phy_signal_level(encoder, crtc_state, + demph_reg_value, preemph_reg_value, uniqtranscale_reg_value, 0); } -static void chv_set_signal_levels(struct intel_dp *intel_dp) +static void chv_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; u32 deemph_reg_value, margin_reg_value; @@ -4318,8 +4323,9 @@ static void chv_set_signal_levels(struct intel_dp *intel_dp) return; } - chv_set_phy_signal_level(encoder, deemph_reg_value, - margin_reg_value, uniq_trans_scale); + chv_set_phy_signal_level(encoder, crtc_state, + deemph_reg_value, margin_reg_value, + uniq_trans_scale); } static u32 g4x_signal_levels(u8 train_set) @@ -4360,7 +4366,8 @@ static u32 g4x_signal_levels(u8 train_set) } static void -g4x_set_signal_levels(struct intel_dp *intel_dp) +g4x_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u8 train_set = intel_dp->train_set[0]; @@ -4407,7 +4414,8 @@ static u32 snb_cpu_edp_signal_levels(u8 train_set) } static void -snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp) +snb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u8 train_set = intel_dp->train_set[0]; @@ -4458,7 +4466,8 @@ static u32 ivb_cpu_edp_signal_levels(u8 train_set) } static void -ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp) +ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u8 train_set = intel_dp->train_set[0]; @@ -4476,7 +4485,8 @@ ivb_cpu_edp_set_signal_levels(struct intel_dp *intel_dp) intel_de_posting_read(dev_priv, intel_dp->output_reg); } -void intel_dp_set_signal_levels(struct intel_dp *intel_dp) +void intel_dp_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u8 train_set = intel_dp->train_set[0]; @@ -4490,11 +4500,12 @@ void intel_dp_set_signal_levels(struct intel_dp *intel_dp) train_set & DP_TRAIN_MAX_PRE_EMPHASIS_REACHED ? " (max)" : ""); - intel_dp->set_signal_levels(intel_dp); + intel_dp->set_signal_levels(intel_dp, crtc_state); } void intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, u8 dp_train_pat) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -4505,13 +4516,14 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, "Using DP training pattern TPS%d\n", dp_train_pat & train_pat_mask); - intel_dp->set_link_train(intel_dp, dp_train_pat); + intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat); } -void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) +void intel_dp_set_idle_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { if (intel_dp->set_idle_link_train) - intel_dp->set_idle_link_train(intel_dp); + intel_dp->set_idle_link_train(intel_dp, crtc_state); } static void @@ -5404,14 +5416,14 @@ static u8 intel_dp_autotest_edid(struct intel_dp *intel_dp) return test_result; } -static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp) +static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(dp_to_dig_port(intel_dp)->base.base.dev); - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; - struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum pipe pipe = crtc->pipe; u32 pattern_val; @@ -5471,7 +5483,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp) } static void -intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp) +intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; @@ -5497,7 +5510,8 @@ intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp) } static void -intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt) +intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_device *dev = dig_port->base.base.dev; @@ -5523,7 +5537,8 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, uint8_t lane_cnt) trans_ddi_func_ctl_value); } -static void intel_dp_process_phy_request(struct intel_dp *intel_dp) +static void intel_dp_process_phy_request(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; @@ -5535,15 +5550,15 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp) } /* retrieve vswing & pre-emphasis setting */ - intel_dp_get_adjust_train(intel_dp, link_status); + intel_dp_get_adjust_train(intel_dp, crtc_state, link_status); - intel_dp_autotest_phy_ddi_disable(intel_dp); + intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state); - intel_dp_set_signal_levels(intel_dp); + intel_dp_set_signal_levels(intel_dp, crtc_state); - intel_dp_phy_pattern_update(intel_dp); + intel_dp_phy_pattern_update(intel_dp, crtc_state); - intel_dp_autotest_phy_ddi_enable(intel_dp, data->num_lanes); + intel_dp_autotest_phy_ddi_enable(intel_dp, crtc_state); drm_dp_set_phy_test_pattern(&intel_dp->aux, data, link_status[DP_DPCD_REV]); @@ -5699,6 +5714,10 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) /* * Validate the cached values of intel_dp->link_rate and * intel_dp->lane_count before attempting to retrain. + * + * FIXME would be nice to user the crtc state here, but since + * we need to call this from the short HPD handler that seems + * a bit hard. */ if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate, intel_dp->lane_count)) @@ -5832,8 +5851,20 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, intel_crtc_pch_transcoder(crtc), false); } - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); + for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) { + const struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + + /* retrain on the MST master transcoder */ + if (INTEL_GEN(dev_priv) >= 12 && + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && + !intel_dp_mst_is_master_trans(crtc_state)) + continue; + + intel_dp_start_link_train(intel_dp, crtc_state); + intel_dp_stop_link_train(intel_dp, crtc_state); + break; + } for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) { const struct intel_crtc_state *crtc_state = @@ -5903,6 +5934,7 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder, { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct intel_crtc *crtc; u32 crtc_mask; int ret; @@ -5920,7 +5952,20 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder, drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n", encoder->base.base.id, encoder->base.name); - intel_dp_process_phy_request(intel_dp); + + for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) { + const struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->base.state); + + /* test on the MST master transcoder */ + if (INTEL_GEN(dev_priv) >= 12 && + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) && + !intel_dp_mst_is_master_trans(crtc_state)) + continue; + + intel_dp_process_phy_request(intel_dp, crtc_state); + break; + } return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 58c7360eab13..22248f4ccae5 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -44,8 +44,7 @@ bool intel_dp_init(struct drm_i915_private *dev_priv, i915_reg_t output_reg, bool intel_dp_init_connector(struct intel_digital_port *dig_port, struct intel_connector *intel_connector); void intel_dp_set_link_params(struct intel_dp *intel_dp, - int link_rate, u8 lane_count, - bool link_mst); + int link_rate, int lane_count); int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, int link_rate, u8 lane_count); int intel_dp_retrain_link(struct intel_encoder *encoder, @@ -92,10 +91,13 @@ void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, void intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, u8 dp_train_pat); void -intel_dp_set_signal_levels(struct intel_dp *intel_dp); -void intel_dp_set_idle_link_train(struct intel_dp *intel_dp); +intel_dp_set_signal_levels(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_dp_set_idle_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, u8 *link_bw, u8 *rate_select); bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index f2c8b56be9ea..51e8d46d9b7f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -49,8 +49,10 @@ static u8 dp_voltage_max(u8 preemph) } } -void intel_dp_get_adjust_train(struct intel_dp *intel_dp, - const u8 link_status[DP_LINK_STATUS_SIZE]) +void +intel_dp_get_adjust_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + const u8 link_status[DP_LINK_STATUS_SIZE]) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); u8 v = 0; @@ -59,7 +61,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp, u8 voltage_max; u8 preemph_max; - for (lane = 0; lane < intel_dp->lane_count; lane++) { + for (lane = 0; lane < crtc_state->lane_count; lane++) { v = max(v, drm_dp_get_adjust_request_voltage(link_status, lane)); p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, lane)); } @@ -74,7 +76,7 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp, v = min(v, dp_voltage_max(p)); - voltage_max = intel_dp->voltage_max(intel_dp); + voltage_max = intel_dp->voltage_max(intel_dp, crtc_state); drm_WARN_ON_ONCE(&i915->drm, voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_2 && voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_3); @@ -88,12 +90,14 @@ void intel_dp_get_adjust_train(struct intel_dp *intel_dp, static bool intel_dp_set_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, u8 dp_train_pat) { u8 buf[sizeof(intel_dp->train_set) + 1]; int ret, len; - intel_dp_program_link_training_pattern(intel_dp, dp_train_pat); + intel_dp_program_link_training_pattern(intel_dp, crtc_state, + dp_train_pat); buf[0] = dp_train_pat; if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) == @@ -102,8 +106,8 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, len = 1; } else { /* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */ - memcpy(buf + 1, intel_dp->train_set, intel_dp->lane_count); - len = intel_dp->lane_count + 1; + memcpy(buf + 1, intel_dp->train_set, crtc_state->lane_count); + len = crtc_state->lane_count + 1; } ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET, @@ -114,31 +118,34 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, static bool intel_dp_reset_link_train(struct intel_dp *intel_dp, - u8 dp_train_pat) + const struct intel_crtc_state *crtc_state, + u8 dp_train_pat) { memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); - intel_dp_set_signal_levels(intel_dp); - return intel_dp_set_link_train(intel_dp, dp_train_pat); + intel_dp_set_signal_levels(intel_dp, crtc_state); + return intel_dp_set_link_train(intel_dp, crtc_state, dp_train_pat); } static bool -intel_dp_update_link_train(struct intel_dp *intel_dp) +intel_dp_update_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { int ret; - intel_dp_set_signal_levels(intel_dp); + intel_dp_set_signal_levels(intel_dp, crtc_state); ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET, - intel_dp->train_set, intel_dp->lane_count); + intel_dp->train_set, crtc_state->lane_count); - return ret == intel_dp->lane_count; + return ret == crtc_state->lane_count; } -static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp) +static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { int lane; - for (lane = 0; lane < intel_dp->lane_count; lane++) + for (lane = 0; lane < crtc_state->lane_count; lane++) if ((intel_dp->train_set[lane] & DP_TRAIN_MAX_SWING_REACHED) == 0) return false; @@ -148,7 +155,8 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp) /* Enable corresponding port and start training pattern 1 */ static bool -intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) +intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); u8 voltage; @@ -158,9 +166,9 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) u8 link_bw, rate_select; if (intel_dp->prepare_link_retrain) - intel_dp->prepare_link_retrain(intel_dp); + intel_dp->prepare_link_retrain(intel_dp, crtc_state); - intel_dp_compute_rate(intel_dp, intel_dp->link_rate, + intel_dp_compute_rate(intel_dp, crtc_state->port_clock, &link_bw, &rate_select); if (link_bw) @@ -172,7 +180,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) /* Write the link configuration data */ link_config[0] = link_bw; - link_config[1] = intel_dp->lane_count; + link_config[1] = crtc_state->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); @@ -189,7 +197,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) intel_dp->DP |= DP_PORT_EN; /* clock recovery */ - if (!intel_dp_reset_link_train(intel_dp, + if (!intel_dp_reset_link_train(intel_dp, crtc_state, DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE)) { drm_err(&i915->drm, "failed to enable link training\n"); @@ -220,7 +228,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) return false; } - if (drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) { + if (drm_dp_clock_recovery_ok(link_status, crtc_state->lane_count)) { drm_dbg_kms(&i915->drm, "clock recovery OK\n"); return true; } @@ -239,8 +247,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; /* Update training set as requested by target */ - intel_dp_get_adjust_train(intel_dp, link_status); - if (!intel_dp_update_link_train(intel_dp)) { + intel_dp_get_adjust_train(intel_dp, crtc_state, link_status); + if (!intel_dp_update_link_train(intel_dp, crtc_state)) { drm_err(&i915->drm, "failed to update link training\n"); return false; @@ -252,7 +260,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) else voltage_tries = 1; - if (intel_dp_link_max_vswing_reached(intel_dp)) + if (intel_dp_link_max_vswing_reached(intel_dp, crtc_state)) max_vswing_reached = true; } @@ -266,7 +274,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) * or for 1.4 devices that support it, training Pattern 3 for HBR2 * or 1.2 devices that support it, Training Pattern 2 otherwise. */ -static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) +static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { bool source_tps3, sink_tps3, source_tps4, sink_tps4; @@ -280,7 +289,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) sink_tps4 = drm_dp_tps4_supported(intel_dp->dpcd); if (source_tps4 && sink_tps4) { return DP_TRAINING_PATTERN_4; - } else if (intel_dp->link_rate == 810000) { + } else if (crtc_state->port_clock == 810000) { if (!source_tps4) drm_dbg_kms(&dp_to_i915(intel_dp)->drm, "8.1 Gbps link rate without source HBR3/TPS4 support\n"); @@ -297,7 +306,7 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) sink_tps3 = drm_dp_tps3_supported(intel_dp->dpcd); if (source_tps3 && sink_tps3) { return DP_TRAINING_PATTERN_3; - } else if (intel_dp->link_rate >= 540000) { + } else if (crtc_state->port_clock >= 540000) { if (!source_tps3) drm_dbg_kms(&dp_to_i915(intel_dp)->drm, ">=5.4/6.48 Gbps link rate without source HBR2/TPS3 support\n"); @@ -310,7 +319,8 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp) } static bool -intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) +intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); int tries; @@ -318,13 +328,13 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) u8 link_status[DP_LINK_STATUS_SIZE]; bool channel_eq = false; - training_pattern = intel_dp_training_pattern(intel_dp); + training_pattern = intel_dp_training_pattern(intel_dp, crtc_state); /* Scrambling is disabled for TPS2/3 and enabled for TPS4 */ if (training_pattern != DP_TRAINING_PATTERN_4) training_pattern |= DP_LINK_SCRAMBLING_DISABLE; /* channel equalization */ - if (!intel_dp_set_link_train(intel_dp, + if (!intel_dp_set_link_train(intel_dp, crtc_state, training_pattern)) { drm_err(&i915->drm, "failed to start channel equalization\n"); return false; @@ -341,7 +351,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) /* Make sure clock is still ok */ if (!drm_dp_clock_recovery_ok(link_status, - intel_dp->lane_count)) { + crtc_state->lane_count)) { intel_dp_dump_link_status(link_status); drm_dbg_kms(&i915->drm, "Clock recovery check failed, cannot " @@ -350,7 +360,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) } if (drm_dp_channel_eq_ok(link_status, - intel_dp->lane_count)) { + crtc_state->lane_count)) { channel_eq = true; drm_dbg_kms(&i915->drm, "Channel EQ done. DP Training " "successful\n"); @@ -358,8 +368,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) } /* Update training set as requested by target */ - intel_dp_get_adjust_train(intel_dp, link_status); - if (!intel_dp_update_link_train(intel_dp)) { + intel_dp_get_adjust_train(intel_dp, crtc_state, link_status); + if (!intel_dp_update_link_train(intel_dp, crtc_state)) { drm_err(&i915->drm, "failed to update link training\n"); break; @@ -373,35 +383,37 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) "Channel equalization failed 5 times\n"); } - intel_dp_set_idle_link_train(intel_dp); + intel_dp_set_idle_link_train(intel_dp, crtc_state); return channel_eq; } -void intel_dp_stop_link_train(struct intel_dp *intel_dp) +void intel_dp_stop_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { intel_dp->link_trained = true; - intel_dp_set_link_train(intel_dp, + intel_dp_set_link_train(intel_dp, crtc_state, DP_TRAINING_PATTERN_DISABLE); } void -intel_dp_start_link_train(struct intel_dp *intel_dp) +intel_dp_start_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_connector *intel_connector = intel_dp->attached_connector; - if (!intel_dp_link_training_clock_recovery(intel_dp)) + if (!intel_dp_link_training_clock_recovery(intel_dp, crtc_state)) goto failure_handling; - if (!intel_dp_link_training_channel_equalization(intel_dp)) + if (!intel_dp_link_training_channel_equalization(intel_dp, crtc_state)) goto failure_handling; drm_dbg_kms(&dp_to_i915(intel_dp)->drm, "[CONNECTOR:%d:%s] Link Training Passed at Link Rate = %d, Lane count = %d", intel_connector->base.base.id, intel_connector->base.name, - intel_dp->link_rate, intel_dp->lane_count); + crtc_state->port_clock, crtc_state->lane_count); return; failure_handling: @@ -409,15 +421,15 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) "[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d", intel_connector->base.base.id, intel_connector->base.name, - intel_dp->link_rate, intel_dp->lane_count); + crtc_state->port_clock, crtc_state->lane_count); if (intel_dp->hobl_active) { drm_dbg_kms(&dp_to_i915(intel_dp)->drm, "Link Training failed with HOBL active, not enabling it from now on"); intel_dp->hobl_failed = true; } else if (intel_dp_get_link_train_fallback_values(intel_dp, - intel_dp->link_rate, - intel_dp->lane_count)) { + crtc_state->port_clock, + crtc_state->lane_count)) { return; } diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h index 01f1dabbb060..648a6d1f9fa2 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h @@ -8,11 +8,15 @@ #include +struct intel_crtc_state; struct intel_dp; void intel_dp_get_adjust_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, const u8 link_status[DP_LINK_STATUS_SIZE]); -void intel_dp_start_link_train(struct intel_dp *intel_dp); -void intel_dp_stop_link_train(struct intel_dp *intel_dp); +void intel_dp_start_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_dp_stop_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); #endif /* __INTEL_DP_LINK_TRAINING_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c index 7910522273b2..514c4a7adffc 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c @@ -644,16 +644,16 @@ bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder) return mask; } - void chv_set_phy_signal_level(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, u32 deemph_reg_value, u32 margin_reg_value, bool uniq_trans_scale) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum dpio_channel ch = vlv_dig_port_to_channel(dig_port); - enum pipe pipe = intel_crtc->pipe; + enum pipe pipe = crtc->pipe; u32 val; int i; @@ -666,7 +666,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val); - if (intel_crtc->config->lane_count > 2) { + if (crtc_state->lane_count > 2) { val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); @@ -679,7 +679,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val); - if (intel_crtc->config->lane_count > 2) { + if (crtc_state->lane_count > 2) { val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch)); val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; @@ -687,7 +687,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, } /* Program swing deemph */ - for (i = 0; i < intel_crtc->config->lane_count; i++) { + for (i = 0; i < crtc_state->lane_count; i++) { val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i)); val &= ~DPIO_SWING_DEEMPH9P5_MASK; val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT; @@ -695,7 +695,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, } /* Program swing margin */ - for (i = 0; i < intel_crtc->config->lane_count; i++) { + for (i = 0; i < crtc_state->lane_count; i++) { val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i)); val &= ~DPIO_SWING_MARGIN000_MASK; @@ -718,7 +718,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, * For now, for this unique transition scale selection, set bit * 27 for ch0 and ch1. */ - for (i = 0; i < intel_crtc->config->lane_count; i++) { + for (i = 0; i < crtc_state->lane_count; i++) { val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i)); if (uniq_trans_scale) val |= DPIO_TX_UNIQ_TRANS_SCALE_EN; @@ -732,7 +732,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val); - if (intel_crtc->config->lane_count > 2) { + if (crtc_state->lane_count > 2) { val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); @@ -992,14 +992,15 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder, } void vlv_set_phy_signal_level(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, u32 demph_reg_value, u32 preemph_reg_value, u32 uniqtranscale_reg_value, u32 tx3_demph) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); enum dpio_channel port = vlv_dig_port_to_channel(dig_port); - enum pipe pipe = intel_crtc->pipe; + enum pipe pipe = crtc->pipe; vlv_dpio_get(dev_priv); diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.h b/drivers/gpu/drm/i915/display/intel_dpio_phy.h index f418aab90b7e..6473440e7457 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.h +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.h @@ -32,6 +32,7 @@ void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder, u8 bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder); void chv_set_phy_signal_level(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, u32 deemph_reg_value, u32 margin_reg_value, bool uniq_trans_scale); void chv_data_lane_soft_reset(struct intel_encoder *encoder, @@ -46,6 +47,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state); void vlv_set_phy_signal_level(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, u32 demph_reg_value, u32 preemph_reg_value, u32 uniqtranscale_reg_value, u32 tx3_demph); void vlv_phy_pre_pll_enable(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index e0eff28af2a5..05a8a1d58bad 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2780,8 +2780,9 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state, vlv_phy_pre_encoder_enable(encoder, pipe_config); /* HDMI 1.0V-2dB */ - vlv_set_phy_signal_level(encoder, 0x2b245f5f, 0x00002000, 0x5578b83a, - 0x2b247878); + vlv_set_phy_signal_level(encoder, pipe_config, + 0x2b245f5f, 0x00002000, + 0x5578b83a, 0x2b247878); dig_port->set_infoframes(encoder, pipe_config->has_infoframe, @@ -2858,7 +2859,7 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state, /* FIXME: Program the support xxx V-dB */ /* Use 800mV-0dB */ - chv_set_phy_signal_level(encoder, 128, 102, false); + chv_set_phy_signal_level(encoder, pipe_config, 128, 102, false); dig_port->set_infoframes(encoder, pipe_config->has_infoframe, From patchwork Tue Nov 24 09:12:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405363 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJGR50x7z9sSf; Tue, 24 Nov 2020 20:13:19 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNu-0005m8-6m; Tue, 24 Nov 2020 09:13:14 +0000 Received: from mail-pf1-f196.google.com ([209.85.210.196]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNp-0005Zm-Th for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:13:10 +0000 Received: by mail-pf1-f196.google.com with SMTP id w187so3368917pfd.5 for ; Tue, 24 Nov 2020 01:12:59 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ITBVdJWpeQkSsG9HHuSNdElvgCORbw5WJkPQDGVPqmY=; b=F023Jc8vPR9JtBB/hRPLY7W5fWtKx7fmLGTlxlxbmRmuj0/yCwYvMMDKju+97li4FV uJYiVC7l1+fnrtww4M1nDJ+eO+yMeBrS+TK4MgNhayHUYpPisEfOxGzcvMr/N8J4U1Ql BmSP+aZJKbDLohiF3Q3ujjVv5VL7Mc8iqfbnU8QIiAKWmla9/gRa02+KysZqWEcq14rJ g4ZiDRi5GTu5x4vvRG1liKPBhP9/JXatmuroa8Kz2nADUvp5ur1Q+umSc6PGlZz6KY8C C/PlaoNbF4jP7QQR/gnW3vk56spWj+lWP6ZjsK6PXXuVC6lfMfqr0+PbI/ud89lVwBxa LsaA== X-Gm-Message-State: AOAM532oqVjd/BaZ/OkznnwiPNci1I2G1aGcG6Bp5g/OsjvNeP4Ce+WQ qR11a2BBhgALS7MHaXAFDnkuyQBEkim+Iw== X-Google-Smtp-Source: ABdhPJwKoUvsvUOTo4BEd07fb9i+S4dzTYYtubi9tOmt9VnhrCXh/yJ3EXsLbR79cqspi/+fRUlJHA== X-Received: by 2002:aa7:8704:0:b029:18a:e2c9:c38 with SMTP id b4-20020aa787040000b029018ae2c90c38mr3163503pfo.79.1606209177166; Tue, 24 Nov 2020 01:12:57 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id m4sm7542197pfd.203.2020.11.24.01.12.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:56 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 10/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Fix DP link training pattern mask Date: Tue, 24 Nov 2020 17:12:25 +0800 Message-Id: <20201124091230.335132-11-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.196; envelope-from=vicamo@gmail.com; helo=mail-pf1-f196.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Imre Deak BugLink: https://bugs.launchpad.net/bugs/1903969 An LTTPR can be trained with training pattern 4 even if the DPCD revision is < 1.4, but drm_dp_training_pattern_mask() would change pattern 4 to pattern 3 on those DPCD revisions. Since intel_dp_training_pattern() makes already sure that the proper training pattern is used, all that needs to be masked out is the scrambling disable flag, which is or'd to the mask later based on the training pattern. v2: - Use a helper instead of open-coding the masking. (Ville) Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20201007170917.1764556-2-imre.deak@intel.com (backported from commit 6777a855d66d27c4082d6316cc0f2a26a004ed62 https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_ddi.c | 3 +-- drivers/gpu/drm/i915/display/intel_dp.c | 10 +++++----- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 2 +- drivers/gpu/drm/i915/display/intel_dp_link_training.h | 6 ++++++ 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index dbf0ffc05c8f..d1e88bb5ff03 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4232,13 +4232,12 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp, u8 dp_train_pat) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u8 train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd); u32 temp; temp = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl); temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; - switch (dp_train_pat & train_pat_mask) { + switch (intel_dp_training_pattern_symbol(dp_train_pat)) { case DP_TRAINING_PATTERN_DISABLE: temp |= DP_TP_CTL_LINK_TRAIN_NORMAL; break; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 2fc5d253b6c2..6f3c5595da34 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -3776,7 +3776,7 @@ cpt_set_link_train(struct intel_dp *intel_dp, *DP &= ~DP_LINK_TRAIN_MASK_CPT; - switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { + switch (intel_dp_training_pattern_symbol(dp_train_pat)) { case DP_TRAINING_PATTERN_DISABLE: *DP |= DP_LINK_TRAIN_OFF_CPT; break; @@ -3807,7 +3807,7 @@ g4x_set_link_train(struct intel_dp *intel_dp, *DP &= ~DP_LINK_TRAIN_MASK; - switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { + switch (intel_dp_training_pattern_symbol(dp_train_pat)) { case DP_TRAINING_PATTERN_DISABLE: *DP |= DP_LINK_TRAIN_OFF; break; @@ -4509,12 +4509,12 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, u8 dp_train_pat) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u8 train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd); - if (dp_train_pat & train_pat_mask) + if ((intel_dp_training_pattern_symbol(dp_train_pat)) != + DP_TRAINING_PATTERN_DISABLE) drm_dbg_kms(&dev_priv->drm, "Using DP training pattern TPS%d\n", - dp_train_pat & train_pat_mask); + intel_dp_training_pattern_symbol(dp_train_pat)); intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat); } diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 51e8d46d9b7f..b2ff88a152cd 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -100,7 +100,7 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, dp_train_pat); buf[0] = dp_train_pat; - if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) == + if (intel_dp_training_pattern_symbol(dp_train_pat) == DP_TRAINING_PATTERN_DISABLE) { /* don't write DP_TRAINING_LANEx_SET on disable */ len = 1; diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h index 648a6d1f9fa2..bf9474e41aed 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h @@ -19,4 +19,10 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp, void intel_dp_stop_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); +/* Get the TPSx symbol type of the value programmed to DP_TRAINING_PATTERN_SET */ +static inline u8 intel_dp_training_pattern_symbol(u8 pattern) +{ + return pattern & ~DP_LINK_SCRAMBLING_DISABLE; +} + #endif /* __INTEL_DP_LINK_TRAINING_H__ */ From patchwork Tue Nov 24 09:12:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405364 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJGV4s1bz9sSs; Tue, 24 Nov 2020 20:13:22 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNx-0005oV-HW; Tue, 24 Nov 2020 09:13:17 +0000 Received: from mail-pl1-f196.google.com ([209.85.214.196]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNs-0005cQ-0j for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:13:12 +0000 Received: by mail-pl1-f196.google.com with SMTP id l11so10393313plt.1 for ; Tue, 24 Nov 2020 01:13:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/TrFRL2WenVOhmCyWSZ816ulTGvu1GXxPOfrwTdFIH0=; b=Oeli/wPBXjIY7dkOhuqKSCVhwuCkqaa02K+/XiLkH5H5SyuCB6yaw/xrsoGJdOqEYI 3KK9kNBgRRzRHfohWcZ5HrDjrWGhtIASTHWCNDNSVruB6PKVW12ivg+N71ZzVxb63QTc RVdbnd84jBNEdsvA7Ty7rwTlOSninZ8nXSR5+yqeukEGX3o1zXhF3ltmqCJig/jCgBhV 2ht9vySNMVeZ1H/cm020ewUkkeIRiKQ5HYse+i/rQyCZmrkqg1udf8y1EhvVrncmvesN RhjFPuO4gCILDHmbSOs89ymlKEW9IjrYSSPVVC4iszRktrNSBwZVHN0SCaNoQgNLMWlq n34Q== X-Gm-Message-State: AOAM533ggsfXzPbqy9T9qvuhHkfEtLUe9HRqrbZSkhCMhZi+qAez9MXV r0NkmVNn/LUkqUU7l1Ksi8MUsX8V5hHhIQ== X-Google-Smtp-Source: ABdhPJx4RkgFfO81nUeFm/Mt1T8KxBG/jrwPVqAwERYhnbcQm8RgibZTeyj+Ku71UzPwGERfcFB5Ow== X-Received: by 2002:a17:902:7594:b029:d5:eda6:fb45 with SMTP id j20-20020a1709027594b02900d5eda6fb45mr3103676pll.5.1606209179901; Tue, 24 Nov 2020 01:12:59 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id y10sm2336600pjm.34.2020.11.24.01.12.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:12:59 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 11/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Simplify the link training functions Date: Tue, 24 Nov 2020 17:12:26 +0800 Message-Id: <20201124091230.335132-12-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.214.196; envelope-from=vicamo@gmail.com; helo=mail-pl1-f196.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Imre Deak BugLink: https://bugs.launchpad.net/bugs/1903969 Split the prepare, link training, fallback-handling steps into their own functions for clarity and as a preparation for the upcoming LTTPR changes. While at it also: - Unexport and inline intel_dp_set_idle_link_train(), which is used at a single place. - Add some documentation to functions that are exported or that can use a better description about which part of the LT sequence they implement. v2: (Ville) - Unexport/inline intel_dp_set_idle_link_train() - Make the documentation of intel_dp_prepare_link_train()/intel_dp_stop_link_train() more accurate wrt. HW specific details. Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20201007170917.1764556-3-imre.deak@intel.com (cherry picked from commit 0a5991f5d022235ba085001e2a3926f83a0aed1b https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/i915/display/intel_dp.c | 7 -- drivers/gpu/drm/i915/display/intel_dp.h | 2 - .../drm/i915/display/intel_dp_link_training.c | 100 ++++++++++++++---- 3 files changed, 79 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 6f3c5595da34..986e992b215f 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4519,13 +4519,6 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, intel_dp->set_link_train(intel_dp, crtc_state, dp_train_pat); } -void intel_dp_set_idle_link_train(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) -{ - if (intel_dp->set_idle_link_train) - intel_dp->set_idle_link_train(intel_dp, crtc_state); -} - static void intel_dp_link_down(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state) diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 22248f4ccae5..65d6b1b7b0f8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -96,8 +96,6 @@ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, void intel_dp_set_signal_levels(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); -void intel_dp_set_idle_link_train(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, u8 *link_bw, u8 *rate_select); bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index b2ff88a152cd..51d1316c37d5 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -153,15 +153,15 @@ static bool intel_dp_link_max_vswing_reached(struct intel_dp *intel_dp, return true; } -/* Enable corresponding port and start training pattern 1 */ +/* + * Prepare link training by configuring the link parameters. On DDI platforms + * also enable the port here. + */ static bool -intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +intel_dp_prepare_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); - u8 voltage; - int voltage_tries, cr_tries, max_cr_tries; - bool max_vswing_reached = false; u8 link_config[2]; u8 link_bw, rate_select; @@ -196,6 +196,19 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, intel_dp->DP |= DP_PORT_EN; + return true; +} + +/* Perform the link training clock recovery phase using training pattern 1. */ +static bool +intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + u8 voltage; + int voltage_tries, cr_tries, max_cr_tries; + bool max_vswing_reached = false; + /* clock recovery */ if (!intel_dp_reset_link_train(intel_dp, crtc_state, DP_TRAINING_PATTERN_1 | @@ -318,6 +331,10 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, return DP_TRAINING_PATTERN_2; } +/* + * Perform the link training channel equalization phase using one of training + * pattern 2, 3 or 4 depending on the source and sink capabilities. + */ static bool intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) @@ -383,12 +400,28 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, "Channel equalization failed 5 times\n"); } - intel_dp_set_idle_link_train(intel_dp, crtc_state); + if (intel_dp->set_idle_link_train) + intel_dp->set_idle_link_train(intel_dp, crtc_state); return channel_eq; - } +/** + * intel_dp_stop_link_train - stop link training + * @intel_dp: DP struct + * @crtc_state: state for CRTC attached to the encoder + * + * Stop the link training of the @intel_dp port, disabling the test pattern + * symbol generation on the port and disabling the training pattern in + * the sink's DPCD. + * + * What symbols are output on the port after this point is + * platform specific: On DDI/VLV/CHV platforms it will be the idle pattern + * with the pipe being disabled, on older platforms it's HW specific if/how an + * idle pattern is generated, as the pipe is already enabled here for those. + * + * This function must be called after intel_dp_start_link_train(). + */ void intel_dp_stop_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { @@ -398,31 +431,39 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp, DP_TRAINING_PATTERN_DISABLE); } -void -intel_dp_start_link_train(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +static bool +intel_dp_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) { struct intel_connector *intel_connector = intel_dp->attached_connector; + bool ret = false; + + intel_dp_prepare_link_train(intel_dp, crtc_state); if (!intel_dp_link_training_clock_recovery(intel_dp, crtc_state)) - goto failure_handling; + goto out; + if (!intel_dp_link_training_channel_equalization(intel_dp, crtc_state)) - goto failure_handling; + goto out; - drm_dbg_kms(&dp_to_i915(intel_dp)->drm, - "[CONNECTOR:%d:%s] Link Training Passed at Link Rate = %d, Lane count = %d", - intel_connector->base.base.id, - intel_connector->base.name, - crtc_state->port_clock, crtc_state->lane_count); - return; + ret = true; - failure_handling: +out: drm_dbg_kms(&dp_to_i915(intel_dp)->drm, - "[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d", + "[CONNECTOR:%d:%s] Link Training %s at link rate = %d, lane count = %d", intel_connector->base.base.id, intel_connector->base.name, + ret ? "passed" : "failed", crtc_state->port_clock, crtc_state->lane_count); + return ret; +} + +static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct intel_connector *intel_connector = intel_dp->attached_connector; + if (intel_dp->hobl_active) { drm_dbg_kms(&dp_to_i915(intel_dp)->drm, "Link Training failed with HOBL active, not enabling it from now on"); @@ -436,3 +477,20 @@ intel_dp_start_link_train(struct intel_dp *intel_dp, /* Schedule a Hotplug Uevent to userspace to start modeset */ schedule_work(&intel_connector->modeset_retry_work); } + +/** + * intel_dp_start_link_train - start link training + * @intel_dp: DP struct + * @crtc_state: state for CRTC attached to the encoder + * + * Start the link training of the @intel_dp port, scheduling a fallback + * retraining with reduced link rate/lane parameters if the link training + * fails. + * After calling this function intel_dp_stop_link_train() must be called. + */ +void intel_dp_start_link_train(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + if (!intel_dp_link_train(intel_dp, crtc_state)) + intel_dp_schedule_fallback_link_training(intel_dp, crtc_state); +} From patchwork Tue Nov 24 09:12:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405365 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJGX0QPXz9sT6; Tue, 24 Nov 2020 20:13:24 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNz-0005pe-5H; Tue, 24 Nov 2020 09:13:19 +0000 Received: from mail-pg1-f194.google.com ([209.85.215.194]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNt-0005fP-Tl for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:13:14 +0000 Received: by mail-pg1-f194.google.com with SMTP id t3so3058770pgi.11 for ; Tue, 24 Nov 2020 01:13:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OpXtfXM9u4n7OS0lWf3Ez8at9CD4WWhZY0sMKSse5/g=; b=kKijX4fIPgOLyrmOfYzbuUS+rf3Vuqs2N/tK56mhb01AQxl4dL9c73WsMrKkOoP+Yf IFP3+sE6HU9or9A2YuZjwiC0imxSrVu3IYuSIwXEVjvbMNyNYrGA3kX72NOHK7hshRzg gu8ESwWgQjtXszPaOFTxAt/tSqSltPMag6xta2jdy2J8twKWA8+SbBOOq7dvDG79jkxI 68tW5oeHhEhMOfslsw6mFA8GEH2ykxaEYrs/ApTizDWk0lWtiwYAv3oXS/JkY/rvev6b 4tFRphCX0uQZNqq/qP3KBWnMX5FyM+qu/YpnEdrkh6fMSVfEWM01WDWyOHCKa1+5CeCh qx+A== X-Gm-Message-State: AOAM533vVsTLw/UrCHiQoXE+xODQCVt8Czxm5DUU4LEqnbR7TZtsuLk1 G1+hAT4VnkAh6dO0hEUhp9TH9w/NHiBJCA== X-Google-Smtp-Source: ABdhPJx7DnD2lI2o9RjrS4vaowM6m7AVd0wPompUp1px5T4mDGXPM5di6daQWoPNw6aRan5s5UANWg== X-Received: by 2002:a62:8685:0:b029:197:f766:b135 with SMTP id x127-20020a6286850000b0290197f766b135mr3388186pfd.0.1606209182592; Tue, 24 Nov 2020 01:13:02 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id h18sm9694679pfk.17.2020.11.24.01.13.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:13:01 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 12/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Factor out a helper to disable the DPCD training pattern Date: Tue, 24 Nov 2020 17:12:27 +0800 Message-Id: <20201124091230.335132-13-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.215.194; envelope-from=vicamo@gmail.com; helo=mail-pg1-f194.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Imre Deak BugLink: https://bugs.launchpad.net/bugs/1903969 To prepare for a follow-up LTTPR change factor out a helper to disable the training pattern in DPCD. We'll need to do this for each LTTPR (without programming the port to output the idle pattern) when training in LTTPR non-transparent mode. While at it also move the disable-link-training logic from intel_dp_set_link_train() to intel_dp_stop_link_train(), since the latter is the only user of this. v2: - Move the disable-link-training logic to intel_dp_stop_link_train() (Ville) Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20201007170917.1764556-4-imre.deak@intel.com (cherry picked from commit c43027a9a37541dbdc54e9dca647602175ff27a2 https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- .../drm/i915/display/intel_dp_link_training.c | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 51d1316c37d5..71a8c9a546a3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -94,26 +94,18 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, u8 dp_train_pat) { u8 buf[sizeof(intel_dp->train_set) + 1]; - int ret, len; + int len; intel_dp_program_link_training_pattern(intel_dp, crtc_state, dp_train_pat); buf[0] = dp_train_pat; - if (intel_dp_training_pattern_symbol(dp_train_pat) == - DP_TRAINING_PATTERN_DISABLE) { - /* don't write DP_TRAINING_LANEx_SET on disable */ - len = 1; - } else { - /* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */ - memcpy(buf + 1, intel_dp->train_set, crtc_state->lane_count); - len = crtc_state->lane_count + 1; - } - - ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET, - buf, len); + /* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */ + memcpy(buf + 1, intel_dp->train_set, crtc_state->lane_count); + len = crtc_state->lane_count + 1; - return ret == len; + return drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET, + buf, len) == len; } static bool @@ -406,6 +398,13 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, return channel_eq; } +static bool intel_dp_disable_dpcd_training_pattern(struct intel_dp *intel_dp) +{ + u8 val = DP_TRAINING_PATTERN_DISABLE; + + return drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET, &val, 1) == 1; +} + /** * intel_dp_stop_link_train - stop link training * @intel_dp: DP struct @@ -427,8 +426,10 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp, { intel_dp->link_trained = true; - intel_dp_set_link_train(intel_dp, crtc_state, - DP_TRAINING_PATTERN_DISABLE); + intel_dp_program_link_training_pattern(intel_dp, + crtc_state, + DP_TRAINING_PATTERN_DISABLE); + intel_dp_disable_dpcd_training_pattern(intel_dp); } static bool From patchwork Tue Nov 24 09:12:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405367 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJGc5LZ5z9sSs; Tue, 24 Nov 2020 20:13:28 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUO2-0005sL-Hz; Tue, 24 Nov 2020 09:13:22 +0000 Received: from mail-pl1-f173.google.com ([209.85.214.173]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNv-0005gl-53 for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:13:15 +0000 Received: by mail-pl1-f173.google.com with SMTP id bj5so9566326plb.4 for ; Tue, 24 Nov 2020 01:13:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qzDsRjF4DGA6qQJNonL0RgffL69R5x1OcuZnoFZmc9w=; b=lKOqQ644vzCSSb1khVNWB6F79LhYJjBbBdzN+veQyLlgIB8kyFlfzN/wJK5JWTfLow xkEhil7+9lfKWOZJVsLsMmaYnWz3oogkxZTTmWpFBTzRKudJngsxUbMNtnXHScIldU+U WP78fPNfe/3ZbZl0/O95VltNEcK9wJkKIJOZunVIyO72R3CRdkwwuUKQQ4zc1xUa/E0r wgnPU7xpSpRDyEbig5T6x9ifQ1xGsUE0zWcoKv9FwVl3m+egvElcGCDe2i2/w7uyqksG 3QqrdJJtHUyCtw81t0Vu1hbL9oQsXvl558X8Z9f4hZc5w0gZuF19/rAWnABPjijj4u4a GwQg== X-Gm-Message-State: AOAM532+qlTAxOS3DGwcOjxFf5cqAOD4Dyi7s0MO1GKjEXViF1G4/y9Z y5ceGw6J7YwyVUJUrHZb5vQYYNtOGS70CA== X-Google-Smtp-Source: ABdhPJwGGZPsgUWxABAbP4G18VXSaUcjRCl0LSjTfd/2u1hwVgMZzHjO3aV17nPmic/d+FSl2RU7og== X-Received: by 2002:a17:902:7b83:b029:da:beb:b81a with SMTP id w3-20020a1709027b83b02900da0bebb81amr3032674pll.62.1606209184893; Tue, 24 Nov 2020 01:13:04 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id p6sm1690724pjt.13.2020.11.24.01.13.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:13:04 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 13/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/dp: Add LTTPR helpers Date: Tue, 24 Nov 2020 17:12:28 +0800 Message-Id: <20201124091230.335132-14-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.214.173; envelope-from=vicamo@gmail.com; helo=mail-pl1-f173.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Imre Deak BugLink: https://bugs.launchpad.net/bugs/1903969 Add the helpers and register definitions needed to read out the common and per-PHY LTTPR capabilities and perform link training in the LTTPR non-transparent mode. v2: - Add drm_dp_dpcd_read_phy_link_status() and DP_PHY_LTTPR() here instead of adding these to i915. (Ville) v3: - Use memmove() to convert LTTPR to DPRX link status format. (Ville) Cc: dri-devel@lists.freedesktop.org Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Acked-by: Lyude Paul Acked-by: Daniel Vetter Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20201007170917.1764556-5-imre.deak@intel.com (cherry picked from commit 9782f52ab5d65a667074beda11b12490935d608b https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/drm_dp_helper.c | 232 +++++++++++++++++++++++++++++++- include/drm/drm_dp_helper.h | 62 +++++++++ 2 files changed, 290 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index e1db953bc431..ac9d594e5d43 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -150,11 +150,8 @@ void drm_dp_link_train_clock_recovery_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) } EXPORT_SYMBOL(drm_dp_link_train_clock_recovery_delay); -void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) +static void __drm_dp_link_train_channel_eq_delay(unsigned long rd_interval) { - 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); @@ -166,8 +163,35 @@ void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) usleep_range(rd_interval, rd_interval * 2); } + +void drm_dp_link_train_channel_eq_delay(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) +{ + __drm_dp_link_train_channel_eq_delay(dpcd[DP_TRAINING_AUX_RD_INTERVAL] & + DP_TRAINING_AUX_RD_MASK); +} EXPORT_SYMBOL(drm_dp_link_train_channel_eq_delay); +void drm_dp_lttpr_link_train_clock_recovery_delay(void) +{ + usleep_range(100, 200); +} +EXPORT_SYMBOL(drm_dp_lttpr_link_train_clock_recovery_delay); + +static u8 dp_lttpr_phy_cap(const u8 phy_cap[DP_LTTPR_PHY_CAP_SIZE], int r) +{ + return phy_cap[r - DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1]; +} + +void drm_dp_lttpr_link_train_channel_eq_delay(const u8 phy_cap[DP_LTTPR_PHY_CAP_SIZE]) +{ + u8 interval = dp_lttpr_phy_cap(phy_cap, + DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1) & + DP_TRAINING_AUX_RD_MASK; + + __drm_dp_link_train_channel_eq_delay(interval); +} +EXPORT_SYMBOL(drm_dp_lttpr_link_train_channel_eq_delay); + u8 drm_dp_link_rate_to_bw_code(int link_rate) { /* Spec says link_bw = link_rate / 0.27Gbps */ @@ -363,6 +387,59 @@ int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux, } EXPORT_SYMBOL(drm_dp_dpcd_read_link_status); +/** + * drm_dp_dpcd_read_phy_link_status - get the link status information for a DP PHY + * @aux: DisplayPort AUX channel + * @dp_phy: the DP PHY to get the link status for + * @link_status: buffer to return the status in + * + * Fetch the AUX DPCD registers for the DPRX or an LTTPR PHY link status. The + * layout of the returned @link_status matches the DPCD register layout of the + * DPRX PHY link status. + * + * Returns 0 if the information was read successfully or a negative error code + * on failure. + */ +int drm_dp_dpcd_read_phy_link_status(struct drm_dp_aux *aux, + enum drm_dp_phy dp_phy, + u8 link_status[DP_LINK_STATUS_SIZE]) +{ + int ret; + + if (dp_phy == DP_PHY_DPRX) { + ret = drm_dp_dpcd_read(aux, + DP_LANE0_1_STATUS, + link_status, + DP_LINK_STATUS_SIZE); + + if (ret < 0) + return ret; + + WARN_ON(ret != DP_LINK_STATUS_SIZE); + + return 0; + } + + ret = drm_dp_dpcd_read(aux, + DP_LANE0_1_STATUS_PHY_REPEATER(dp_phy), + link_status, + DP_LINK_STATUS_SIZE - 1); + + if (ret < 0) + return ret; + + WARN_ON(ret != DP_LINK_STATUS_SIZE - 1); + + /* Convert the LTTPR to the sink PHY link status layout */ + memmove(&link_status[DP_SINK_STATUS - DP_LANE0_1_STATUS + 1], + &link_status[DP_SINK_STATUS - DP_LANE0_1_STATUS], + DP_LINK_STATUS_SIZE - (DP_SINK_STATUS - DP_LANE0_1_STATUS) - 1); + link_status[DP_SINK_STATUS - DP_LANE0_1_STATUS] = 0; + + return 0; +} +EXPORT_SYMBOL(drm_dp_dpcd_read_phy_link_status); + static bool is_edid_digital_input_dp(const struct edid *edid) { return edid && edid->revision >= 4 && @@ -2113,6 +2190,153 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_S } EXPORT_SYMBOL(drm_dp_dsc_sink_supported_input_bpcs); +/** + * drm_dp_read_lttpr_common_caps - read the LTTPR common capabilities + * @aux: DisplayPort AUX channel + * @caps: buffer to return the capability info in + * + * Read capabilities common to all LTTPRs. + * + * Returns 0 on success or a negative error code on failure. + */ +int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux, + u8 caps[DP_LTTPR_COMMON_CAP_SIZE]) +{ + int ret; + + ret = drm_dp_dpcd_read(aux, + DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV, + caps, DP_LTTPR_COMMON_CAP_SIZE); + if (ret < 0) + return ret; + + WARN_ON(ret != DP_LTTPR_COMMON_CAP_SIZE); + + return 0; +} +EXPORT_SYMBOL(drm_dp_read_lttpr_common_caps); + +/** + * drm_dp_read_lttpr_phy_caps - read the capabilities for a given LTTPR PHY + * @aux: DisplayPort AUX channel + * @dp_phy: LTTPR PHY to read the capabilities for + * @caps: buffer to return the capability info in + * + * Read the capabilities for the given LTTPR PHY. + * + * Returns 0 on success or a negative error code on failure. + */ +int drm_dp_read_lttpr_phy_caps(struct drm_dp_aux *aux, + enum drm_dp_phy dp_phy, + u8 caps[DP_LTTPR_PHY_CAP_SIZE]) +{ + int ret; + + ret = drm_dp_dpcd_read(aux, + DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER(dp_phy), + caps, DP_LTTPR_PHY_CAP_SIZE); + if (ret < 0) + return ret; + + WARN_ON(ret != DP_LTTPR_PHY_CAP_SIZE); + + return 0; +} +EXPORT_SYMBOL(drm_dp_read_lttpr_phy_caps); + +static u8 dp_lttpr_common_cap(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE], int r) +{ + return caps[r - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; +} + +/** + * drm_dp_lttpr_count - get the number of detected LTTPRs + * @caps: LTTPR common capabilities + * + * Get the number of detected LTTPRs from the LTTPR common capabilities info. + * + * Returns: + * -ERANGE if more than supported number (8) of LTTPRs are detected + * -EINVAL if the DP_PHY_REPEATER_CNT register contains an invalid value + * otherwise the number of detected LTTPRs + */ +int drm_dp_lttpr_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]) +{ + u8 count = dp_lttpr_common_cap(caps, DP_PHY_REPEATER_CNT); + + switch (hweight8(count)) { + case 0: + return 0; + case 1: + return 8 - ilog2(count); + case 8: + return -ERANGE; + default: + return -EINVAL; + } +} +EXPORT_SYMBOL(drm_dp_lttpr_count); + +/** + * drm_dp_lttpr_max_link_rate - get the maximum link rate supported by all LTTPRs + * @caps: LTTPR common capabilities + * + * Returns the maximum link rate supported by all detected LTTPRs. + */ +int drm_dp_lttpr_max_link_rate(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]) +{ + u8 rate = dp_lttpr_common_cap(caps, DP_MAX_LINK_RATE_PHY_REPEATER); + + return drm_dp_bw_code_to_link_rate(rate); +} +EXPORT_SYMBOL(drm_dp_lttpr_max_link_rate); + +/** + * drm_dp_lttpr_max_lane_count - get the maximum lane count supported by all LTTPRs + * @caps: LTTPR common capabilities + * + * Returns the maximum lane count supported by all detected LTTPRs. + */ +int drm_dp_lttpr_max_lane_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]) +{ + u8 max_lanes = dp_lttpr_common_cap(caps, DP_MAX_LANE_COUNT_PHY_REPEATER); + + return max_lanes & DP_MAX_LANE_COUNT_MASK; +} +EXPORT_SYMBOL(drm_dp_lttpr_max_lane_count); + +/** + * drm_dp_lttpr_voltage_swing_level_3_supported - check for LTTPR vswing3 support + * @caps: LTTPR PHY capabilities + * + * Returns true if the @caps for an LTTPR TX PHY indicate support for + * voltage swing level 3. + */ +bool +drm_dp_lttpr_voltage_swing_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]) +{ + u8 txcap = dp_lttpr_phy_cap(caps, DP_TRANSMITTER_CAPABILITY_PHY_REPEATER1); + + return txcap & DP_VOLTAGE_SWING_LEVEL_3_SUPPORTED; +} +EXPORT_SYMBOL(drm_dp_lttpr_voltage_swing_level_3_supported); + +/** + * drm_dp_lttpr_pre_emphasis_level_3_supported - check for LTTPR preemph3 support + * @caps: LTTPR PHY capabilities + * + * Returns true if the @caps for an LTTPR TX PHY indicate support for + * pre-emphasis level 3. + */ +bool +drm_dp_lttpr_pre_emphasis_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]) +{ + u8 txcap = dp_lttpr_phy_cap(caps, DP_TRANSMITTER_CAPABILITY_PHY_REPEATER1); + + return txcap & DP_PRE_EMPHASIS_LEVEL_3_SUPPORTED; +} +EXPORT_SYMBOL(drm_dp_lttpr_pre_emphasis_level_3_supported); + /** * drm_dp_get_phy_test_pattern() - get the requested pattern from the sink. * @aux: DisplayPort AUX channel diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 75500bfc7aa1..dd60dd9a8865 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1066,15 +1066,58 @@ struct drm_device; #define DP_MAX_LANE_COUNT_PHY_REPEATER 0xf0004 /* 1.4a */ #define DP_Repeater_FEC_CAPABILITY 0xf0004 /* 1.4 */ #define DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT 0xf0005 /* 1.4a */ + +enum drm_dp_phy { + DP_PHY_DPRX, + + DP_PHY_LTTPR1, + DP_PHY_LTTPR2, + DP_PHY_LTTPR3, + DP_PHY_LTTPR4, + DP_PHY_LTTPR5, + DP_PHY_LTTPR6, + DP_PHY_LTTPR7, + DP_PHY_LTTPR8, + + DP_MAX_LTTPR_COUNT = DP_PHY_LTTPR8, +}; + +#define DP_PHY_LTTPR(i) (DP_PHY_LTTPR1 + (i)) + +#define __DP_LTTPR1_BASE 0xf0010 /* 1.3 */ +#define __DP_LTTPR2_BASE 0xf0060 /* 1.3 */ +#define DP_LTTPR_BASE(dp_phy) \ + (__DP_LTTPR1_BASE + (__DP_LTTPR2_BASE - __DP_LTTPR1_BASE) * \ + ((dp_phy) - DP_PHY_LTTPR1)) + +#define DP_LTTPR_REG(dp_phy, lttpr1_reg) \ + (DP_LTTPR_BASE(dp_phy) - DP_LTTPR_BASE(DP_PHY_LTTPR1) + (lttpr1_reg)) + #define DP_TRAINING_PATTERN_SET_PHY_REPEATER1 0xf0010 /* 1.3 */ +#define DP_TRAINING_PATTERN_SET_PHY_REPEATER(dp_phy) \ + DP_LTTPR_REG(dp_phy, DP_TRAINING_PATTERN_SET_PHY_REPEATER1) + #define DP_TRAINING_LANE0_SET_PHY_REPEATER1 0xf0011 /* 1.3 */ +#define DP_TRAINING_LANE0_SET_PHY_REPEATER(dp_phy) \ + DP_LTTPR_REG(dp_phy, DP_TRAINING_LANE0_SET_PHY_REPEATER1) + #define DP_TRAINING_LANE1_SET_PHY_REPEATER1 0xf0012 /* 1.3 */ #define DP_TRAINING_LANE2_SET_PHY_REPEATER1 0xf0013 /* 1.3 */ #define DP_TRAINING_LANE3_SET_PHY_REPEATER1 0xf0014 /* 1.3 */ #define DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 0xf0020 /* 1.4a */ +#define DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER(dp_phy) \ + DP_LTTPR_REG(dp_phy, DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1) + #define DP_TRANSMITTER_CAPABILITY_PHY_REPEATER1 0xf0021 /* 1.4a */ +# define DP_VOLTAGE_SWING_LEVEL_3_SUPPORTED BIT(0) +# define DP_PRE_EMPHASIS_LEVEL_3_SUPPORTED BIT(1) + #define DP_LANE0_1_STATUS_PHY_REPEATER1 0xf0030 /* 1.3 */ +#define DP_LANE0_1_STATUS_PHY_REPEATER(dp_phy) \ + DP_LTTPR_REG(dp_phy, DP_LANE0_1_STATUS_PHY_REPEATER1) + #define DP_LANE2_3_STATUS_PHY_REPEATER1 0xf0031 /* 1.3 */ + #define DP_LANE_ALIGN_STATUS_UPDATED_PHY_REPEATER1 0xf0032 /* 1.3 */ #define DP_ADJUST_REQUEST_LANE0_1_PHY_REPEATER1 0xf0033 /* 1.3 */ #define DP_ADJUST_REQUEST_LANE2_3_PHY_REPEATER1 0xf0034 /* 1.3 */ @@ -1185,9 +1228,13 @@ u8 drm_dp_get_adjust_request_post_cursor(const u8 link_status[DP_LINK_STATUS_SIZ #define DP_DSC_RECEIVER_CAP_SIZE 0xf #define EDP_PSR_RECEIVER_CAP_SIZE 2 #define EDP_DISPLAY_CTL_CAP_SIZE 3 +#define DP_LTTPR_COMMON_CAP_SIZE 8 +#define DP_LTTPR_PHY_CAP_SIZE 3 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]); +void drm_dp_lttpr_link_train_channel_eq_delay(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]); u8 drm_dp_link_rate_to_bw_code(int link_rate); int drm_dp_bw_code_to_link_rate(u8 link_bw); @@ -1646,6 +1693,10 @@ int drm_dp_read_dpcd_caps(struct drm_dp_aux *aux, int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux, u8 status[DP_LINK_STATUS_SIZE]); +int drm_dp_dpcd_read_phy_link_status(struct drm_dp_aux *aux, + enum drm_dp_phy dp_phy, + u8 link_status[DP_LINK_STATUS_SIZE]); + bool drm_dp_send_real_edid_checksum(struct drm_dp_aux *aux, u8 real_edid_checksum); @@ -1695,6 +1746,17 @@ bool drm_dp_read_sink_count_cap(struct drm_connector *connector, const struct drm_dp_desc *desc); int drm_dp_read_sink_count(struct drm_dp_aux *aux); +int drm_dp_read_lttpr_common_caps(struct drm_dp_aux *aux, + u8 caps[DP_LTTPR_COMMON_CAP_SIZE]); +int drm_dp_read_lttpr_phy_caps(struct drm_dp_aux *aux, + enum drm_dp_phy dp_phy, + u8 caps[DP_LTTPR_PHY_CAP_SIZE]); +int drm_dp_lttpr_count(const u8 cap[DP_LTTPR_COMMON_CAP_SIZE]); +int drm_dp_lttpr_max_link_rate(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]); +int drm_dp_lttpr_max_lane_count(const u8 caps[DP_LTTPR_COMMON_CAP_SIZE]); +bool drm_dp_lttpr_voltage_swing_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]); +bool drm_dp_lttpr_pre_emphasis_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]); + void drm_dp_remote_aux_init(struct drm_dp_aux *aux); void drm_dp_aux_init(struct drm_dp_aux *aux); int drm_dp_aux_register(struct drm_dp_aux *aux); From patchwork Tue Nov 24 09:12:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405366 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJGY5RhVz9s1l; Tue, 24 Nov 2020 20:13:25 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUNz-0005qQ-Ux; Tue, 24 Nov 2020 09:13:19 +0000 Received: from mail-pl1-f196.google.com ([209.85.214.196]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNw-0005hz-9P for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:13:16 +0000 Received: by mail-pl1-f196.google.com with SMTP id l1so2133818pld.5 for ; Tue, 24 Nov 2020 01:13:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cbIiDNyq+zXYPtRi4zSU9OWKsPtyJ9PGRZaDsF2IST4=; b=H+n4feeNylhhyTo7MMyryyOO4hQW8ek98Zo1UlQ0vcebex7CJwcbJaKyosFUwTnf1j rGZcXUJ1YU+unzskO5/ZaSedBQ8WTOy2FWrUj3p0jr9YqqNS2qxvzK8iKQoc4xTDNdGH zjN7oxc6FxRJRg3k0FMal3OvrGL8HchnAt0hsXHi53S9mtStNf36mkTPkF4b2mt4AyPf YQedyHVzutxPoBYLcw+Ar4skx3GTWMiMMbKP6qLp8clAHuPySREMBK7nwgE+RFkuuuhW pQC4Yb59xcTdhFWyhdAGLMsoeCWRSHXPng3UP8qX/yOzKwWfd5HU/uBpnnQBRILq6E4M GF/w== X-Gm-Message-State: AOAM532jgDOO6xv/691SvCrY+Nr7+cWDXiYOadfnr/vQbTS0EQtieCNz sxyzZ+PJ668+TDck0Hf55k4PJC9Eq956ag== X-Google-Smtp-Source: ABdhPJwiTIUbYvKpNoMe1yWCbcVAKISVioISWeXAOSouTmDnq0SNbZpstyX0makS3HrrFlEnVYGN9Q== X-Received: by 2002:a17:902:8e87:b029:d8:e26a:77ea with SMTP id bg7-20020a1709028e87b02900d8e26a77eamr3129261plb.18.1606209187170; Tue, 24 Nov 2020 01:13:07 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id u1sm7041910pfn.181.2020.11.24.01.13.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:13:06 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 14/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Switch to LTTPR transparent mode link training Date: Tue, 24 Nov 2020 17:12:29 +0800 Message-Id: <20201124091230.335132-15-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.214.196; envelope-from=vicamo@gmail.com; helo=mail-pl1-f196.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Imre Deak BugLink: https://bugs.launchpad.net/bugs/1903969 By default LTTPRs should be in transparent link training mode, nevertheless in this patch we switch to this default mode explicitly. The DP Standard recommends this, supposedly because an LTTPR may be left in the non-transparent mode (by BIOS, previous kernel, or after reset due to a firmware bug). I haven't seen this happening, but let's follow the DP Standard. v2: - Add a code comment about the explicit disabling of non-transparent mode. v3: - Move check to prevent initing LTTPRs on eDP to init_dp_lttpr_init(). Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20201007170917.1764556-6-imre.deak@intel.com (cherry picked from commit 7b2a4ab8b0ef2a6dbec0b15d2cabf5a9e7acdf4c https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- .../drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 2 + .../drm/i915/display/intel_dp_link_training.c | 55 +++++++++++++++++++ .../drm/i915/display/intel_dp_link_training.h | 2 + 4 files changed, 60 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 21e92e0babe5..3943ed87d6a1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1279,6 +1279,7 @@ struct intel_dp { u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS]; u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]; + u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE]; u8 fec_capable; /* source rates */ int num_source_rates; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 986e992b215f..be4781c9d617 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4737,6 +4737,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) { int ret; + intel_dp_lttpr_init(intel_dp); + if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) return false; diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 71a8c9a546a3..a19f0fd50c69 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -34,6 +34,55 @@ intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE]) link_status[3], link_status[4], link_status[5]); } +static bool intel_dp_read_lttpr_common_caps(struct intel_dp *intel_dp) +{ + if (drm_dp_read_lttpr_common_caps(&intel_dp->aux, + intel_dp->lttpr_common_caps) < 0) { + memset(intel_dp->lttpr_common_caps, 0, + sizeof(intel_dp->lttpr_common_caps)); + return false; + } + + drm_dbg_kms(&dp_to_i915(intel_dp)->drm, + "LTTPR common capabilities: %*ph\n", + (int)sizeof(intel_dp->lttpr_common_caps), + intel_dp->lttpr_common_caps); + + return true; +} + +static bool +intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable) +{ + u8 val = enable ? DP_PHY_REPEATER_MODE_TRANSPARENT : + DP_PHY_REPEATER_MODE_NON_TRANSPARENT; + + return drm_dp_dpcd_write(&intel_dp->aux, DP_PHY_REPEATER_MODE, &val, 1) == 1; +} + +/** + * intel_dp_lttpr_init - detect LTTPRs and init the LTTPR link training mode + * @intel_dp: Intel DP struct + * + * Read the LTTPR common capabilities and switch to transparent link training + * mode. + */ +int intel_dp_lttpr_init(struct intel_dp *intel_dp) +{ + if (intel_dp_is_edp(intel_dp)) + return 0; + + intel_dp_read_lttpr_common_caps(intel_dp); + + /* + * See DP Standard v2.0 3.6.6.1. about the explicit disabling of + * non-transparent mode. + */ + intel_dp_set_lttpr_transparent_mode(intel_dp, true); + + return 0; +} + static u8 dp_voltage_max(u8 preemph) { switch (preemph & DP_TRAIN_PRE_EMPHASIS_MASK) { @@ -492,6 +541,12 @@ static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp, void intel_dp_start_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + /* + * 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_train(intel_dp, crtc_state)) intel_dp_schedule_fallback_link_training(intel_dp, crtc_state); } diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h index bf9474e41aed..b3fb1d125b9b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h @@ -11,6 +11,8 @@ struct intel_crtc_state; struct intel_dp; +int intel_dp_lttpr_init(struct intel_dp *intel_dp); + void intel_dp_get_adjust_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, const u8 link_status[DP_LINK_STATUS_SIZE]); From patchwork Tue Nov 24 09:12:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1405368 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CgJGk1l2sz9s1l; Tue, 24 Nov 2020 20:13:34 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1khUO9-0005xE-GH; Tue, 24 Nov 2020 09:13:29 +0000 Received: from mail-pf1-f195.google.com ([209.85.210.195]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khUNx-0005ji-An for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 09:13:17 +0000 Received: by mail-pf1-f195.google.com with SMTP id w202so2067763pff.10 for ; Tue, 24 Nov 2020 01:13:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=323EMtq5WXyOncXV1vm8z576rVmPWv8RDgF1TTsawqA=; b=tJY3lzh391A221D/KsOGnAcLTBdTm/s6v0LHbf6DStDHOM32IE2lWoTWJy7I8niekm FgtG1V+vFb14KPK4NvyUjb+ycJowz+QEOs0/ZJ+Gdyt0cJG0NrRoOTQki4MrXo8K084j XzitSV3syscYlW/PCjVGx6ybiiaA0HnHmLRZ31NVKv77RT8zJqaxcaxej3g2YuAorPa5 03e/P40rLL9MWu88fVlBw40Vh2D65SY/RfuC6L67KjrXQ2NN2dqoK4EfDFM6IM0nTMIm zmoNFYz6mkxrczdFzthRg6JGkAUa9RU9xyedFg1CQjSoy8nXFhjlNRzqPbLOO1ulVAVw Xu5g== X-Gm-Message-State: AOAM532omeagne0AFL6QP+OsLKKsBI7z+8QrTlWe/3mQ3XszNxRhxaCU XRpF8KC+XZ5IQly5dNt2/uaS9Foy4zrWTA== X-Google-Smtp-Source: ABdhPJyJWhcRlqJ6R5IUcXilKXvtzkUTo7lwIkSHLV5jIU4qo3zNB3waLjZLqo+mkUyBpL4br6OrhA== X-Received: by 2002:a63:ad4a:: with SMTP id y10mr2940264pgo.176.1606209189587; Tue, 24 Nov 2020 01:13:09 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id k4sm14829015pfg.130.2020.11.24.01.13.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 01:13:08 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 15/15][SRU][U/OEM-5.10] UBUNTU: SAUCE: drm/i915: Switch to LTTPR non-transparent mode link training Date: Tue, 24 Nov 2020 17:12:30 +0800 Message-Id: <20201124091230.335132-16-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124091230.335132-1-vicamo.yang@canonical.com> References: <20201124091230.335132-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.195; envelope-from=vicamo@gmail.com; helo=mail-pf1-f195.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Imre Deak BugLink: https://bugs.launchpad.net/bugs/1903969 The DP Standard's recommendation is to use the LTTPR non-transparent mode link training if LTTPRs are detected, so let's do this. Besides power-saving, the advantages of this are that the maximum number of LTTPRs can only be used in non-transparent mode (the limit is 5-8 in transparent mode), and it provides a way to narrow down the reason for a link training failure to a given link segment. Non-transparent mode is probably also the mode that was tested the most by the industry. The changes in this patchset: - Pass the DP PHY that is currently link trained to all LT helpers, so that these can access the correct LTTPR/DPRX DPCD registers. - During LT take into account the LTTPR common lane rate/count and the per LTTPR-PHY vswing/pre-emph limits. - Switch to LTTPR non-transparent LT mode and train each link segment according to the sequence in DP Standard v2.0 (complete CR/EQ for each segment before continuing with the next segment). v2: - Switch to non-transparent mode during connector detection, which is required before reading the per-PHY LTTPR capabilities. - Move the DP_PHY_LTTPR() macro to drm_dp_helper.h (Ville) - Use the new drm_dp_dpcd_read_phy_link_status() instead of adding the same logic to intel_dp_get_link_status(). (Ville) - Make intel_dp_lttpr_phy_caps() return a pointer to the whole array instead of a pointer to its first element. (Ville) - Add the intel_dp_phy_is_downstream_of_source() helper. (Ville) - Add a code comment about the disable->enable quirk of non-transparent mode. - Add the intel_dp_training_pattern_set_reg() helper. - Fix checkpatch/sparse warns. Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20201007170917.1764556-7-imre.deak@intel.com (cherry picked from commit b30edfd8d0b4b22f9c17c208064b39a3d93e6971 https://anongit.freedesktop.org/git/drm-tip.git) Signed-off-by: You-Sheng Yang --- .../drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 28 +- drivers/gpu/drm/i915/display/intel_dp.h | 2 - .../drm/i915/display/intel_dp_link_training.c | 362 +++++++++++++++--- .../drm/i915/display/intel_dp_link_training.h | 1 + 5 files changed, 321 insertions(+), 73 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 3943ed87d6a1..5a804a9b06ae 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1280,6 +1280,7 @@ struct intel_dp { u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE]; u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]; u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE]; + u8 lttpr_phy_caps[DP_MAX_LTTPR_COUNT][DP_LTTPR_PHY_CAP_SIZE]; u8 fec_capable; /* source rates */ int num_source_rates; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index be4781c9d617..a31ba5e1c71b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -161,6 +161,7 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) 162000, 270000, 540000, 810000 }; int i, max_rate; + int max_lttpr_rate; if (drm_dp_has_quirk(&intel_dp->desc, 0, DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS)) { @@ -174,6 +175,9 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) } max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]); + max_lttpr_rate = drm_dp_lttpr_max_link_rate(intel_dp->lttpr_common_caps); + if (max_lttpr_rate) + max_rate = min(max_rate, max_lttpr_rate); for (i = 0; i < ARRAY_SIZE(dp_rates); i++) { if (dp_rates[i] > max_rate) @@ -219,6 +223,10 @@ static int intel_dp_max_common_lane_count(struct intel_dp *intel_dp) int source_max = dig_port->max_lanes; int sink_max = drm_dp_max_lane_count(intel_dp->dpcd); int fia_max = intel_tc_port_fia_max_lane_count(dig_port); + int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps); + + if (lttpr_max) + sink_max = min(sink_max, lttpr_max); return min3(source_max, sink_max, fia_max); } @@ -4126,17 +4134,6 @@ static void chv_dp_post_pll_disable(struct intel_atomic_state *state, chv_phy_post_pll_disable(encoder, old_crtc_state); } -/* - * Fetch AUX CH registers 0x202 - 0x207 which contain - * link status information - */ -bool -intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATUS_SIZE]) -{ - return drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS, link_status, - DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE; -} - static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { @@ -5539,13 +5536,15 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp, &intel_dp->compliance.test_data.phytest; u8 link_status[DP_LINK_STATUS_SIZE]; - if (!intel_dp_get_link_status(intel_dp, link_status)) { + if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, + link_status) < 0) { DRM_DEBUG_KMS("failed to get link status\n"); return; } /* retrieve vswing & pre-emphasis setting */ - intel_dp_get_adjust_train(intel_dp, crtc_state, link_status); + intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, + link_status); intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state); @@ -5703,7 +5702,8 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) if (intel_psr_enabled(intel_dp)) return false; - if (!intel_dp_get_link_status(intel_dp, link_status)) + if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, + link_status) < 0) return false; /* diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 65d6b1b7b0f8..e8511234c693 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -100,8 +100,6 @@ void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, u8 *link_bw, u8 *rate_select); bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp); -bool -intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status); bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp); int intel_dp_link_required(int pixel_clock, int bpp); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index a19f0fd50c69..91d3979902d0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -34,6 +34,63 @@ intel_dp_dump_link_status(const u8 link_status[DP_LINK_STATUS_SIZE]) link_status[3], link_status[4], link_status[5]); } +static int intel_dp_lttpr_count(struct intel_dp *intel_dp) +{ + int count = drm_dp_lttpr_count(intel_dp->lttpr_common_caps); + + /* + * Pretend no LTTPRs in case of LTTPR detection error, or + * if too many (>8) LTTPRs are detected. This translates to link + * training in transparent mode. + */ + return count <= 0 ? 0 : count; +} + +static void intel_dp_reset_lttpr_count(struct intel_dp *intel_dp) +{ + intel_dp->lttpr_common_caps[DP_PHY_REPEATER_CNT - + DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV] = 0; +} + +static const char *intel_dp_phy_name(enum drm_dp_phy dp_phy, + char *buf, size_t buf_size) +{ + if (dp_phy == DP_PHY_DPRX) + snprintf(buf, buf_size, "DPRX"); + else + snprintf(buf, buf_size, "LTTPR %d", dp_phy - DP_PHY_LTTPR1 + 1); + + return buf; +} + +static u8 *intel_dp_lttpr_phy_caps(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + return intel_dp->lttpr_phy_caps[dp_phy - DP_PHY_LTTPR1]; +} + +static void intel_dp_read_lttpr_phy_caps(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + u8 *phy_caps = intel_dp_lttpr_phy_caps(intel_dp, dp_phy); + char phy_name[10]; + + intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name)); + + if (drm_dp_read_lttpr_phy_caps(&intel_dp->aux, dp_phy, phy_caps) < 0) { + drm_dbg_kms(&dp_to_i915(intel_dp)->drm, + "failed to read the PHY caps for %s\n", + phy_name); + return; + } + + drm_dbg_kms(&dp_to_i915(intel_dp)->drm, + "%s PHY capabilities: %*ph\n", + phy_name, + (int)sizeof(intel_dp->lttpr_phy_caps[0]), + phy_caps); +} + static bool intel_dp_read_lttpr_common_caps(struct intel_dp *intel_dp) { if (drm_dp_read_lttpr_common_caps(&intel_dp->aux, @@ -64,24 +121,64 @@ intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable) * intel_dp_lttpr_init - detect LTTPRs and init the LTTPR link training mode * @intel_dp: Intel DP struct * - * Read the LTTPR common capabilities and switch to transparent link training - * mode. + * Read the LTTPR common capabilities, switch to non-transparent link training + * mode if any is detected and read the PHY capabilities for all detected + * LTTPRs. In case of an LTTPR detection error or if the number of + * LTTPRs is more than is supported (8), fall back to the no-LTTPR, + * transparent mode link training mode. + * + * Returns: + * >0 if LTTPRs were detected and the non-transparent LT mode was set + * 0 if no LTTPRs or more than 8 LTTPRs were detected or in case of a + * detection failure and the transparent LT mode was set */ int intel_dp_lttpr_init(struct intel_dp *intel_dp) { + int lttpr_count; + bool ret; + int i; + if (intel_dp_is_edp(intel_dp)) return 0; - intel_dp_read_lttpr_common_caps(intel_dp); + ret = intel_dp_read_lttpr_common_caps(intel_dp); /* * See DP Standard v2.0 3.6.6.1. about the explicit disabling of - * non-transparent mode. + * non-transparent mode and the disable->enable non-transparent mode + * sequence. */ intel_dp_set_lttpr_transparent_mode(intel_dp, true); - return 0; + if (!ret) + return 0; + + lttpr_count = intel_dp_lttpr_count(intel_dp); + + /* + * In case of unsupported number of LTTPRs or failing to switch to + * non-transparent mode fall-back to transparent link training mode, + * still taking into account any LTTPR common lane- rate/count limits. + */ + if (lttpr_count == 0) + return 0; + + if (!intel_dp_set_lttpr_transparent_mode(intel_dp, false)) { + drm_dbg_kms(&dp_to_i915(intel_dp)->drm, + "Switching to LTTPR non-transparent LT mode failed, fall-back to transparent mode\n"); + + intel_dp_set_lttpr_transparent_mode(intel_dp, true); + intel_dp_reset_lttpr_count(intel_dp); + + return 0; + } + + for (i = 0; i < lttpr_count; i++) + intel_dp_read_lttpr_phy_caps(intel_dp, DP_PHY_LTTPR(i)); + + return lttpr_count; } +EXPORT_SYMBOL(intel_dp_lttpr_init); static u8 dp_voltage_max(u8 preemph) { @@ -98,12 +195,91 @@ static u8 dp_voltage_max(u8 preemph) } } +static u8 intel_dp_lttpr_voltage_max(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + const u8 *phy_caps = intel_dp_lttpr_phy_caps(intel_dp, dp_phy); + + if (drm_dp_lttpr_voltage_swing_level_3_supported(phy_caps)) + return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; + else + return DP_TRAIN_VOLTAGE_SWING_LEVEL_2; +} + +static u8 intel_dp_lttpr_preemph_max(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + const u8 *phy_caps = intel_dp_lttpr_phy_caps(intel_dp, dp_phy); + + if (drm_dp_lttpr_pre_emphasis_level_3_supported(phy_caps)) + return DP_TRAIN_PRE_EMPH_LEVEL_3; + else + return DP_TRAIN_PRE_EMPH_LEVEL_2; +} + +static bool +intel_dp_phy_is_downstream_of_source(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + int lttpr_count = intel_dp_lttpr_count(intel_dp); + + drm_WARN_ON_ONCE(&i915->drm, lttpr_count == 0 && dp_phy != DP_PHY_DPRX); + + return lttpr_count == 0 || dp_phy == DP_PHY_LTTPR(lttpr_count - 1); +} + +static u8 intel_dp_phy_voltage_max(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + u8 voltage_max; + + /* + * Get voltage_max from the DPTX_PHY (source or LTTPR) upstream from + * the DPRX_PHY we train. + */ + if (intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy)) + voltage_max = intel_dp->voltage_max(intel_dp, crtc_state); + else + voltage_max = intel_dp_lttpr_voltage_max(intel_dp, dp_phy + 1); + + drm_WARN_ON_ONCE(&i915->drm, + voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_2 && + voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_3); + + return voltage_max; +} + +static u8 intel_dp_phy_preemph_max(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + u8 preemph_max; + + /* + * Get preemph_max from the DPTX_PHY (source or LTTPR) upstream from + * the DPRX_PHY we train. + */ + if (intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy)) + preemph_max = intel_dp->preemph_max(intel_dp); + else + preemph_max = intel_dp_lttpr_preemph_max(intel_dp, dp_phy + 1); + + drm_WARN_ON_ONCE(&i915->drm, + preemph_max != DP_TRAIN_PRE_EMPH_LEVEL_2 && + preemph_max != DP_TRAIN_PRE_EMPH_LEVEL_3); + + return preemph_max; +} + void intel_dp_get_adjust_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy, const u8 link_status[DP_LINK_STATUS_SIZE]) { - struct drm_i915_private *i915 = dp_to_i915(intel_dp); u8 v = 0; u8 p = 0; int lane; @@ -115,21 +291,13 @@ intel_dp_get_adjust_train(struct intel_dp *intel_dp, p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status, lane)); } - preemph_max = intel_dp->preemph_max(intel_dp); - drm_WARN_ON_ONCE(&i915->drm, - preemph_max != DP_TRAIN_PRE_EMPH_LEVEL_2 && - preemph_max != DP_TRAIN_PRE_EMPH_LEVEL_3); - + preemph_max = intel_dp_phy_preemph_max(intel_dp, dp_phy); if (p >= preemph_max) p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; v = min(v, dp_voltage_max(p)); - voltage_max = intel_dp->voltage_max(intel_dp, crtc_state); - drm_WARN_ON_ONCE(&i915->drm, - voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_2 && - voltage_max != DP_TRAIN_VOLTAGE_SWING_LEVEL_3); - + voltage_max = intel_dp_phy_voltage_max(intel_dp, crtc_state, dp_phy); if (v >= voltage_max) v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; @@ -137,11 +305,21 @@ intel_dp_get_adjust_train(struct intel_dp *intel_dp, intel_dp->train_set[lane] = v | p; } +static int intel_dp_training_pattern_set_reg(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + return dp_phy == DP_PHY_DPRX ? + DP_TRAINING_PATTERN_SET : + DP_TRAINING_PATTERN_SET_PHY_REPEATER(dp_phy); +} + static bool intel_dp_set_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy, u8 dp_train_pat) { + int reg = intel_dp_training_pattern_set_reg(intel_dp, dp_phy); u8 buf[sizeof(intel_dp->train_set) + 1]; int len; @@ -153,29 +331,33 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, memcpy(buf + 1, intel_dp->train_set, crtc_state->lane_count); len = crtc_state->lane_count + 1; - return drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET, - buf, len) == len; + return drm_dp_dpcd_write(&intel_dp->aux, reg, buf, len) == len; } static bool intel_dp_reset_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy, u8 dp_train_pat) { memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); intel_dp_set_signal_levels(intel_dp, crtc_state); - return intel_dp_set_link_train(intel_dp, crtc_state, dp_train_pat); + return intel_dp_set_link_train(intel_dp, crtc_state, dp_phy, dp_train_pat); } static bool intel_dp_update_link_train(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy) { + int reg = dp_phy == DP_PHY_DPRX ? + DP_TRAINING_LANE0_SET : + DP_TRAINING_LANE0_SET_PHY_REPEATER(dp_phy); int ret; intel_dp_set_signal_levels(intel_dp, crtc_state); - ret = drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET, + ret = drm_dp_dpcd_write(&intel_dp->aux, reg, intel_dp->train_set, crtc_state->lane_count); return ret == crtc_state->lane_count; @@ -240,10 +422,23 @@ intel_dp_prepare_link_train(struct intel_dp *intel_dp, return true; } -/* Perform the link training clock recovery phase using training pattern 1. */ +static void intel_dp_link_training_clock_recovery_delay(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + if (dp_phy == DP_PHY_DPRX) + drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd); + else + drm_dp_lttpr_link_train_clock_recovery_delay(); +} + +/* + * Perform the link training clock recovery phase on the given DP PHY using + * training pattern 1. + */ static bool intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); u8 voltage; @@ -251,7 +446,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, bool max_vswing_reached = false; /* clock recovery */ - if (!intel_dp_reset_link_train(intel_dp, crtc_state, + if (!intel_dp_reset_link_train(intel_dp, crtc_state, dp_phy, DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE)) { drm_err(&i915->drm, "failed to enable link training\n"); @@ -275,9 +470,10 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, 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); + intel_dp_link_training_clock_recovery_delay(intel_dp, dp_phy); - if (!intel_dp_get_link_status(intel_dp, link_status)) { + if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, dp_phy, + link_status) < 0) { drm_err(&i915->drm, "failed to get link status\n"); return false; } @@ -301,8 +497,9 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; /* Update training set as requested by target */ - intel_dp_get_adjust_train(intel_dp, crtc_state, link_status); - if (!intel_dp_update_link_train(intel_dp, crtc_state)) { + intel_dp_get_adjust_train(intel_dp, crtc_state, dp_phy, + link_status); + if (!intel_dp_update_link_train(intel_dp, crtc_state, dp_phy)) { drm_err(&i915->drm, "failed to update link training\n"); return false; @@ -329,7 +526,8 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, * or 1.2 devices that support it, Training Pattern 2 otherwise. */ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy) { bool source_tps3, sink_tps3, source_tps4, sink_tps4; @@ -338,9 +536,11 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, * for all downstream devices that support HBR3. There are no known eDP * panels that support TPS4 as of Feb 2018 as per VESA eDP_v1.4b_E1 * specification. + * LTTPRs must support TPS4. */ source_tps4 = intel_dp_source_supports_hbr3(intel_dp); - sink_tps4 = drm_dp_tps4_supported(intel_dp->dpcd); + sink_tps4 = dp_phy != DP_PHY_DPRX || + drm_dp_tps4_supported(intel_dp->dpcd); if (source_tps4 && sink_tps4) { return DP_TRAINING_PATTERN_4; } else if (crtc_state->port_clock == 810000) { @@ -357,7 +557,8 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, * all sinks follow the spec. */ source_tps3 = intel_dp_source_supports_hbr2(intel_dp); - sink_tps3 = drm_dp_tps3_supported(intel_dp->dpcd); + sink_tps3 = dp_phy != DP_PHY_DPRX || + drm_dp_tps3_supported(intel_dp->dpcd); if (source_tps3 && sink_tps3) { return DP_TRAINING_PATTERN_3; } else if (crtc_state->port_clock >= 540000) { @@ -372,13 +573,28 @@ static u32 intel_dp_training_pattern(struct intel_dp *intel_dp, return DP_TRAINING_PATTERN_2; } +static void +intel_dp_link_training_channel_equalization_delay(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) +{ + if (dp_phy == DP_PHY_DPRX) { + drm_dp_link_train_channel_eq_delay(intel_dp->dpcd); + } else { + const u8 *phy_caps = intel_dp_lttpr_phy_caps(intel_dp, dp_phy); + + drm_dp_lttpr_link_train_channel_eq_delay(phy_caps); + } +} + /* - * Perform the link training channel equalization phase using one of training - * pattern 2, 3 or 4 depending on the source and sink capabilities. + * Perform the link training channel equalization phase on the given DP PHY + * using one of training pattern 2, 3 or 4 depending on the source and + * sink capabilities. */ static bool intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); int tries; @@ -386,22 +602,23 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATUS_SIZE]; bool channel_eq = false; - training_pattern = intel_dp_training_pattern(intel_dp, crtc_state); + training_pattern = intel_dp_training_pattern(intel_dp, crtc_state, dp_phy); /* Scrambling is disabled for TPS2/3 and enabled for TPS4 */ if (training_pattern != DP_TRAINING_PATTERN_4) training_pattern |= DP_LINK_SCRAMBLING_DISABLE; /* channel equalization */ - if (!intel_dp_set_link_train(intel_dp, crtc_state, + if (!intel_dp_set_link_train(intel_dp, crtc_state, dp_phy, training_pattern)) { drm_err(&i915->drm, "failed to start channel equalization\n"); return false; } for (tries = 0; tries < 5; tries++) { - - drm_dp_link_train_channel_eq_delay(intel_dp->dpcd); - if (!intel_dp_get_link_status(intel_dp, link_status)) { + intel_dp_link_training_channel_equalization_delay(intel_dp, + dp_phy); + if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, dp_phy, + link_status) < 0) { drm_err(&i915->drm, "failed to get link status\n"); break; @@ -426,8 +643,9 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, } /* Update training set as requested by target */ - intel_dp_get_adjust_train(intel_dp, crtc_state, link_status); - if (!intel_dp_update_link_train(intel_dp, crtc_state)) { + intel_dp_get_adjust_train(intel_dp, crtc_state, dp_phy, + link_status); + if (!intel_dp_update_link_train(intel_dp, crtc_state, dp_phy)) { drm_err(&i915->drm, "failed to update link training\n"); break; @@ -441,17 +659,16 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, "Channel equalization failed 5 times\n"); } - if (intel_dp->set_idle_link_train) - intel_dp->set_idle_link_train(intel_dp, crtc_state); - return channel_eq; } -static bool intel_dp_disable_dpcd_training_pattern(struct intel_dp *intel_dp) +static bool intel_dp_disable_dpcd_training_pattern(struct intel_dp *intel_dp, + enum drm_dp_phy dp_phy) { + int reg = intel_dp_training_pattern_set_reg(intel_dp, dp_phy); u8 val = DP_TRAINING_PATTERN_DISABLE; - return drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_PATTERN_SET, &val, 1) == 1; + return drm_dp_dpcd_write(&intel_dp->aux, reg, &val, 1) == 1; } /** @@ -478,33 +695,34 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp, intel_dp_program_link_training_pattern(intel_dp, crtc_state, DP_TRAINING_PATTERN_DISABLE); - intel_dp_disable_dpcd_training_pattern(intel_dp); + intel_dp_disable_dpcd_training_pattern(intel_dp, DP_PHY_DPRX); } static bool -intel_dp_link_train(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) +intel_dp_link_train_phy(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy) { struct intel_connector *intel_connector = intel_dp->attached_connector; + char phy_name[10]; bool ret = false; - intel_dp_prepare_link_train(intel_dp, crtc_state); - - if (!intel_dp_link_training_clock_recovery(intel_dp, crtc_state)) + if (!intel_dp_link_training_clock_recovery(intel_dp, crtc_state, dp_phy)) goto out; - if (!intel_dp_link_training_channel_equalization(intel_dp, crtc_state)) + if (!intel_dp_link_training_channel_equalization(intel_dp, crtc_state, dp_phy)) goto out; ret = true; out: drm_dbg_kms(&dp_to_i915(intel_dp)->drm, - "[CONNECTOR:%d:%s] Link Training %s at link rate = %d, lane count = %d", + "[CONNECTOR:%d:%s] Link Training %s at link rate = %d, lane count = %d, at %s", intel_connector->base.base.id, intel_connector->base.name, ret ? "passed" : "failed", - crtc_state->port_clock, crtc_state->lane_count); + crtc_state->port_clock, crtc_state->lane_count, + intel_dp_phy_name(dp_phy, phy_name, sizeof(phy_name))); return ret; } @@ -528,6 +746,36 @@ static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp, schedule_work(&intel_connector->modeset_retry_work); } +/* Perform the link training on all LTTPRs and the DPRX on a link. */ +static bool +intel_dp_link_train_all_phys(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + int lttpr_count) +{ + bool ret = true; + int i; + + intel_dp_prepare_link_train(intel_dp, crtc_state); + + for (i = lttpr_count - 1; i >= 0; i--) { + enum drm_dp_phy dp_phy = DP_PHY_LTTPR(i); + + ret = intel_dp_link_train_phy(intel_dp, crtc_state, dp_phy); + intel_dp_disable_dpcd_training_pattern(intel_dp, dp_phy); + + if (!ret) + break; + } + + if (ret) + intel_dp_link_train_phy(intel_dp, crtc_state, DP_PHY_DPRX); + + if (intel_dp->set_idle_link_train) + intel_dp->set_idle_link_train(intel_dp, crtc_state); + + return ret; +} + /** * intel_dp_start_link_train - start link training * @intel_dp: DP struct @@ -545,8 +793,8 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp, * TODO: Reiniting LTTPRs here won't be needed once proper connector * HW state readout is added. */ - intel_dp_lttpr_init(intel_dp); + int lttpr_count = intel_dp_lttpr_init(intel_dp); - if (!intel_dp_link_train(intel_dp, crtc_state)) + if (!intel_dp_link_train_all_phys(intel_dp, crtc_state, lttpr_count)) intel_dp_schedule_fallback_link_training(intel_dp, crtc_state); } diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.h b/drivers/gpu/drm/i915/display/intel_dp_link_training.h index b3fb1d125b9b..86905aa24db7 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.h +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.h @@ -15,6 +15,7 @@ int intel_dp_lttpr_init(struct intel_dp *intel_dp); void intel_dp_get_adjust_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, + enum drm_dp_phy dp_phy, const u8 link_status[DP_LINK_STATUS_SIZE]); void intel_dp_start_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state);