From patchwork Thu Feb 4 18:10:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= X-Patchwork-Id: 12068239 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7C7CC433E6 for ; Thu, 4 Feb 2021 18:11:12 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 93A8364F64 for ; Thu, 4 Feb 2021 18:11:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 93A8364F64 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3AD756EE15; Thu, 4 Feb 2021 18:11:12 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1168C6EE15 for ; Thu, 4 Feb 2021 18:11:11 +0000 (UTC) IronPort-SDR: bVR67qoxf1+ILAlyUE+YfoTag6awiXbouJAIeofGAY0D6bfs+UWi5pz7b2QVK4U6wDPiOhPBuz 3Trxdcv58vUA== X-IronPort-AV: E=McAfee;i="6000,8403,9885"; a="180524794" X-IronPort-AV: E=Sophos;i="5.81,153,1610438400"; d="scan'208";a="180524794" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Feb 2021 10:11:09 -0800 IronPort-SDR: HAz2z5lQtkdL1AW608Bp1Kx4+Ixod0mhUY1oyXhXkPNuRmwtFgk8VW7dQ5i0calahDSwxB0fEq QLacLVOdcjVQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.81,153,1610438400"; d="scan'208";a="434053353" Received: from stinkbox.fi.intel.com (HELO stinkbox) ([10.237.72.171]) by orsmga001.jf.intel.com with SMTP; 04 Feb 2021 10:11:07 -0800 Received: by stinkbox (sSMTP sendmail emulation); Thu, 04 Feb 2021 20:11:06 +0200 From: Ville Syrjala To: intel-gfx@lists.freedesktop.org Date: Thu, 4 Feb 2021 20:10:40 +0200 Message-Id: <20210204181048.24202-7-ville.syrjala@linux.intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210204181048.24202-1-ville.syrjala@linux.intel.com> References: <20210204181048.24202-1-ville.syrjala@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v2 06/14] drm/i915: Extract icl+ .{enable, disable}_clock() vfuncs X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lucas De Marchi Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Ville Syrjälä For ICL+ we have several styles of clock routing for DDIs: 1) TC DDI + TC PHY -> needs DDI_CLK_SEL==MG/TBT part form intel_ddi_clk_{select,disable}() and ICL_DPCLKA_CFGCR0_TC_CLK_OFF part form icl_{map,unmap}_plls_to_ports() 2) ICL/TGL combo DDI + combo PHY -> just need the stuff from icl_{map,unmap}_plls_to_ports() 3) JSL/EHL TC DDI + combo PHY -> needs DDI_CLK_SEL==MG part from intel_ddi_clk_{select,disable}() and the full combo style clock selection from icl_{map,unmap}_plls_to_ports() 4) ADLS/RKL -> these use both TC and combo DDIs with combo PHYs, however they always use the full combo style clock selection as per icl_{map,unmap}_plls_to_ports() and do not use DDI_CLK_SEL at all, thus get treated the same as 2) We extract all that from the current mess in the following way: 1) icl_ddi_tc_{enable,disable}_clock() 2) icl_ddi_combo_{enable,disable}_clock() 3) jsl_ddi_tc_{enable,disable}_clock() 4) for now we reuse icl_ddi_combo_{enable,disable}_clock() here v2: s/dev_priv/i915/ (Lucas) Reviewed-by: Lucas De Marchi Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/display/intel_ddi.c | 163 ++++++++++++++--------- 1 file changed, 102 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index cbeb75d00013..d688ef231eeb 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3174,8 +3174,8 @@ static void dg1_ddi_disable_clock(struct intel_encoder *encoder) mutex_unlock(&dev_priv->dpll.lock); } -static void icl_map_plls_to_ports(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_shared_dpll *pll = crtc_state->shared_dpll; @@ -3203,22 +3203,20 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder, drm_WARN_ON(&dev_priv->drm, (val & icl_dpclka_cfgcr0_clk_off(dev_priv, phy)) == 0); - if (intel_phy_is_combo(dev_priv, phy)) { - /* - * Even though this register references DDIs, note that we - * want to pass the PHY rather than the port (DDI). For - * ICL, port=phy in all cases so it doesn't matter, but for - * EHL the bspec notes the following: - * - * "DDID clock tied to DDIA clock, so DPCLKA_CFGCR0 DDIA - * Clock Select chooses the PLL for both DDIA and DDID and - * drives port A in all cases." - */ - val &= ~mask; - val |= sel; - intel_de_write(dev_priv, reg, val); - intel_de_posting_read(dev_priv, reg); - } + /* + * Even though this register references DDIs, note that we + * want to pass the PHY rather than the port (DDI). For + * ICL, port=phy in all cases so it doesn't matter, but for + * EHL the bspec notes the following: + * + * "DDID clock tied to DDIA clock, so DPCLKA_CFGCR0 DDIA + * Clock Select chooses the PLL for both DDIA and DDID and + * drives port A in all cases." + */ + val &= ~mask; + val |= sel; + intel_de_write(dev_priv, reg, val); + intel_de_posting_read(dev_priv, reg); val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, phy); intel_de_write(dev_priv, reg, val); @@ -3226,7 +3224,7 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder, mutex_unlock(&dev_priv->dpll.lock); } -static void icl_unmap_plls_to_ports(struct intel_encoder *encoder) +static void icl_ddi_combo_disable_clock(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum phy phy = intel_port_to_phy(dev_priv, encoder->port); @@ -3375,47 +3373,71 @@ void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) icl_sanitize_port_clk_off(dev_priv, port_mask, ddi_clk_needed); } -static void intel_ddi_clk_select(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state) +static void jsl_ddi_tc_enable_clock(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum port port = encoder->port; - enum phy phy = intel_port_to_phy(dev_priv, port); + + if (drm_WARN_ON(&i915->drm, !pll)) + return; + + /* + * "For DDIC and DDID, program DDI_CLK_SEL to map the MG clock to the port. + * MG does not exist, but the programming is required to ungate DDIC and DDID." + */ + intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_MG); + + icl_ddi_combo_enable_clock(encoder, crtc_state); +} + +static void jsl_ddi_tc_disable_clock(struct intel_encoder *encoder) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + enum port port = encoder->port; + + icl_ddi_combo_disable_clock(encoder); + + intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); +} + +static void icl_ddi_tc_enable_clock(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; + enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); + enum port port = encoder->port; - if (drm_WARN_ON(&dev_priv->drm, !pll)) + if (drm_WARN_ON(&i915->drm, !pll)) return; - mutex_lock(&dev_priv->dpll.lock); - - if (INTEL_GEN(dev_priv) >= 11) { - if (!intel_phy_is_combo(dev_priv, phy)) - intel_de_write(dev_priv, DDI_CLK_SEL(port), - icl_pll_to_ddi_clk_sel(encoder, crtc_state)); - else if (IS_JSL_EHL(dev_priv) && port >= PORT_C) - /* - * MG does not exist but the programming is required - * to ungate DDIC and DDID - */ - intel_de_write(dev_priv, DDI_CLK_SEL(port), - DDI_CLK_SEL_MG); - } - - mutex_unlock(&dev_priv->dpll.lock); + intel_de_write(i915, DDI_CLK_SEL(port), + icl_pll_to_ddi_clk_sel(encoder, crtc_state)); + + mutex_lock(&i915->dpll.lock); + + intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, + ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port), 0); + + mutex_unlock(&i915->dpll.lock); } -static void intel_ddi_clk_disable(struct intel_encoder *encoder) +static void icl_ddi_tc_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); enum port port = encoder->port; - enum phy phy = intel_port_to_phy(dev_priv, port); - - if (INTEL_GEN(dev_priv) >= 11) { - if (!intel_phy_is_combo(dev_priv, phy) || - (IS_JSL_EHL(dev_priv) && port >= PORT_C)) - intel_de_write(dev_priv, DDI_CLK_SEL(port), - DDI_CLK_SEL_NONE); - } + + mutex_lock(&i915->dpll.lock); + + intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, + 0, ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)); + + mutex_unlock(&i915->dpll.lock); + + intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); } static void cnl_ddi_enable_clock(struct intel_encoder *encoder, @@ -3516,16 +3538,12 @@ static void intel_ddi_enable_clock(struct intel_encoder *encoder, { if (encoder->enable_clock) encoder->enable_clock(encoder, crtc_state); - else - intel_ddi_clk_select(encoder, crtc_state); } static void intel_ddi_disable_clock(struct intel_encoder *encoder) { if (encoder->disable_clock) encoder->disable_clock(encoder); - else - intel_ddi_clk_disable(encoder); } static void @@ -4007,9 +4025,6 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder); - if (!IS_DG1(dev_priv) && INTEL_GEN(dev_priv) >= 11) - icl_map_plls_to_ports(encoder, crtc_state); - intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { @@ -4208,9 +4223,6 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, intel_ddi_post_disable_dp(state, encoder, old_crtc_state, old_conn_state); - if (!IS_DG1(dev_priv) && INTEL_GEN(dev_priv) >= 11) - icl_unmap_plls_to_ports(encoder); - if (intel_crtc_has_dp_encoder(old_crtc_state) || is_tc_port) intel_display_power_put(dev_priv, intel_ddi_main_link_aux_domain(dig_port), @@ -5549,6 +5561,16 @@ static enum hpd_pin cnl_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } +static bool intel_ddi_is_tc(struct drm_i915_private *i915, enum port port) +{ + if (INTEL_GEN(i915) >= 12) + return port >= PORT_TC1; + else if (INTEL_GEN(i915) >= 11) + return port >= PORT_C; + else + return false; +} + #define port_tc_name(port) ((port) - PORT_TC1 + '1') #define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1') @@ -5653,9 +5675,28 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) encoder->cloneable = 0; encoder->pipe_mask = ~0; - if (IS_DG1(dev_priv)) { + if (IS_ALDERLAKE_S(dev_priv) || IS_ROCKETLAKE(dev_priv)) { + encoder->enable_clock = icl_ddi_combo_enable_clock; + encoder->disable_clock = icl_ddi_combo_disable_clock; + } else if (IS_DG1(dev_priv)) { encoder->enable_clock = dg1_ddi_enable_clock; encoder->disable_clock = dg1_ddi_disable_clock; + } else if (IS_JSL_EHL(dev_priv)) { + if (intel_ddi_is_tc(dev_priv, port)) { + encoder->enable_clock = jsl_ddi_tc_enable_clock; + encoder->disable_clock = jsl_ddi_tc_disable_clock; + } else { + encoder->enable_clock = icl_ddi_combo_enable_clock; + encoder->disable_clock = icl_ddi_combo_disable_clock; + } + } else if (INTEL_GEN(dev_priv) >= 11) { + if (intel_ddi_is_tc(dev_priv, port)) { + encoder->enable_clock = icl_ddi_tc_enable_clock; + encoder->disable_clock = icl_ddi_tc_disable_clock; + } else { + encoder->enable_clock = icl_ddi_combo_enable_clock; + encoder->disable_clock = icl_ddi_combo_disable_clock; + } } else if (IS_CANNONLAKE(dev_priv)) { encoder->enable_clock = cnl_ddi_enable_clock; encoder->disable_clock = cnl_ddi_disable_clock;