From patchwork Tue Nov 24 10:43:07 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: 1405465 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 4CgLJj51t3z9sRK; Tue, 24 Nov 2020 21:45: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 1khVp0-0004Gt-Kp; Tue, 24 Nov 2020 10:45:18 +0000 Received: from mail-pf1-f182.google.com ([209.85.210.182]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1khVoc-0003pP-JC for kernel-team@lists.ubuntu.com; Tue, 24 Nov 2020 10:44:55 +0000 Received: by mail-pf1-f182.google.com with SMTP id b6so7664388pfp.7 for ; Tue, 24 Nov 2020 02:44:42 -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=GUqjP64QUC9BybyTLafeh8M9TBADQiykBWS8EsdurDo=; b=gXoCCd3p+R2vUDafA4lG2xTYJnpaRX9YD7/WQIuuq0fBEI19bVnrKO+bWtXEKqsUZU QmSpooVUGj2oiXe6J5G0hoMs1/pszi3jF8LOFU7LDGiZTizyF7QyGGrmg4o+iuTz98+7 Q3ziK/T4/lmX++8jDNQvn+uhJwGhn3BBUrbVLRai/qYPhpbX5EvsOjDLCkzo/h5rE4qO bTVTc/hUHHJtcT3kNFI4WyRnCuUSLKhSWC5CuAEOy2dcdflRrDvTFPg/x23iuekl0Ura 4VS/+WTO0PXMEnEniah3Sf0AF9dlB4NxWumAmDVfah34ECxe9WhYUkij6HwRcJ7F+1wt N/iA== X-Gm-Message-State: AOAM5304bCG+UpWoBZ97chtIHnweUbsQV8bsjS3hexQohVIGp/zW9LYX bQmqXkmd+H61r8KvfFVGhMmFB202FT4Ang== X-Google-Smtp-Source: ABdhPJyO+djLLIbij1VJnAq44R34+GyE8rgdmEdAW/ZdIMPRJbf4xBnVSrPI4qiLaa2xSHZaTzAEyg== X-Received: by 2002:aa7:93b7:0:b029:197:f534:87d7 with SMTP id x23-20020aa793b70000b0290197f53487d7mr3553667pff.35.1606214678938; Tue, 24 Nov 2020 02:44:38 -0800 (PST) Received: from localhost (61-220-137-37.HINET-IP.hinet.net. [61.220.137.37]) by smtp.gmail.com with ESMTPSA id e18sm6224160pgr.71.2020.11.24.02.44.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Nov 2020 02:44:38 -0800 (PST) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 32/38][SRU][G/H] UBUNTU SAUCE: drm/i915: Plumb crtc_state to link training Date: Tue, 24 Nov 2020 18:43:07 +0800 Message-Id: <20201124104313.421860-33-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201124104313.421860-1-vicamo.yang@canonical.com> References: <20201124104313.421860-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.182; envelope-from=vicamo@gmail.com; helo=mail-pf1-f182.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 (backported 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 1bc76cd95c5f..acb7f40e4f15 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -1020,7 +1020,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); @@ -1028,7 +1029,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); @@ -1036,12 +1038,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) { @@ -1049,23 +1052,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); @@ -1073,10 +1078,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 { @@ -1086,17 +1092,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); @@ -1104,7 +1112,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); @@ -1112,13 +1121,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 { @@ -1127,23 +1137,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); @@ -1151,12 +1163,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; @@ -1171,13 +1184,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) { @@ -1188,23 +1202,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); @@ -1212,10 +1228,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 { @@ -1225,16 +1242,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; @@ -1242,19 +1261,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); @@ -1567,14 +1582,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, @@ -2245,13 +2261,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); @@ -2260,14 +2277,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; @@ -2290,16 +2305,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); @@ -2316,7 +2332,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); @@ -2326,33 +2343,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); @@ -2379,7 +2391,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; @@ -2387,9 +2400,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); @@ -2443,22 +2456,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, @@ -2466,10 +2473,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 */ @@ -2501,7 +2508,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)); @@ -2510,23 +2517,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; @@ -2537,7 +2542,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; @@ -2585,25 +2590,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, @@ -2611,7 +2607,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; @@ -2646,7 +2642,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)); @@ -2655,23 +2651,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, @@ -2738,7 +2727,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; @@ -2749,7 +2738,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 | @@ -2759,7 +2748,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 | @@ -2785,38 +2774,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; @@ -2852,20 +2833,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; @@ -2882,55 +2863,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); @@ -2947,7 +2931,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)); @@ -3342,8 +3326,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); @@ -3415,8 +3400,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 @@ -3439,7 +3423,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); @@ -3459,11 +3443,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); @@ -3489,8 +3473,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); @@ -3504,12 +3489,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); @@ -3522,16 +3506,16 @@ 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_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); @@ -3571,7 +3555,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &intel_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); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); @@ -3582,20 +3566,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); @@ -3887,12 +3869,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, @@ -3905,7 +3889,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); @@ -4165,7 +4149,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); @@ -4193,9 +4178,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; @@ -4211,6 +4196,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); @@ -4241,7 +4227,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 077e9dbbe367..7a06bb942d21 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.h +++ b/drivers/gpu/drm/i915/display/intel_ddi.h @@ -40,8 +40,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, bool enable); void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 186896b69897..da11ebad19f8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1276,7 +1276,6 @@ struct intel_dp { int link_rate; u8 lane_count; u8 sink_count; - bool link_mst; bool link_trained; bool has_audio; bool reset_link_params; @@ -1368,13 +1367,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 8f88403b7304..07289cc385de 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2664,13 +2664,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, @@ -2682,10 +2680,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: @@ -3656,6 +3653,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); @@ -3686,6 +3684,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); @@ -3721,7 +3720,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 @@ -3774,8 +3774,8 @@ static void intel_enable_dp(struct intel_atomic_state *state, } intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); - 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", @@ -3984,12 +3984,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; } @@ -4004,7 +4006,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, @@ -4084,11 +4087,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; @@ -4165,8 +4170,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) @@ -4207,7 +4213,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]; @@ -4254,7 +4261,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]; @@ -4305,7 +4313,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]; @@ -4323,7 +4332,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]; @@ -4337,11 +4347,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); @@ -4352,13 +4363,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 @@ -5326,14 +5338,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; @@ -5393,7 +5405,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; @@ -5419,7 +5432,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; @@ -5445,7 +5459,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; @@ -5457,15 +5472,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]); @@ -5610,6 +5625,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)) @@ -5743,8 +5762,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 = @@ -5814,6 +5845,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; @@ -5831,7 +5863,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 676914b6f6af..a529a3d2d760 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -43,8 +43,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, @@ -88,10 +87,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 2d435ca9fe9e..e24ecbcd5e79 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]) { u8 v = 0; u8 p = 0; @@ -58,7 +60,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)); } @@ -69,7 +71,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); if (v >= voltage_max) v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; @@ -79,12 +81,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) == @@ -93,8 +97,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, @@ -105,31 +109,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; @@ -139,7 +146,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; @@ -149,9 +157,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) @@ -163,7 +171,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); @@ -180,7 +188,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"); @@ -211,7 +219,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; } @@ -230,8 +238,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; @@ -243,7 +251,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; } @@ -257,7 +265,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; @@ -271,7 +280,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"); @@ -288,7 +297,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"); @@ -301,7 +310,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; @@ -309,13 +319,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; @@ -332,7 +342,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 " @@ -341,7 +351,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"); @@ -349,8 +359,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; @@ -364,35 +374,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: @@ -400,15 +412,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 fb65c7764df5..6fae3feb8a0b 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2748,8 +2748,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, @@ -2826,7 +2827,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,