From patchwork Tue Oct 4 12:32:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ander Conselvan de Oliveira X-Patchwork-Id: 9361735 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5BD0F60752 for ; Tue, 4 Oct 2016 12:32:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4CB6D287E8 for ; Tue, 4 Oct 2016 12:32:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3FAE1287FE; Tue, 4 Oct 2016 12:32:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 568A9287E8 for ; Tue, 4 Oct 2016 12:32:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C37746E637; Tue, 4 Oct 2016 12:32:39 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id C93B36E63A for ; Tue, 4 Oct 2016 12:32:38 +0000 (UTC) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga104.jf.intel.com with ESMTP; 04 Oct 2016 05:32:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.31,295,1473145200"; d="scan'208"; a="1040126002" Received: from linux.intel.com ([10.54.29.200]) by orsmga001.jf.intel.com with ESMTP; 04 Oct 2016 05:32:38 -0700 Received: from localhost (aconselv-mobl3.fi.intel.com [10.237.66.176]) by linux.intel.com (Postfix) with ESMTP id 0F8816A4082; Tue, 4 Oct 2016 05:32:08 -0700 (PDT) From: Ander Conselvan de Oliveira To: intel-gfx@lists.freedesktop.org Date: Tue, 4 Oct 2016 15:32:17 +0300 Message-Id: <1475584337-8900-8-git-send-email-ander.conselvan.de.oliveira@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1475584337-8900-1-git-send-email-ander.conselvan.de.oliveira@intel.com> References: <1475584337-8900-1-git-send-email-ander.conselvan.de.oliveira@intel.com> Cc: Ander Conselvan de Oliveira Subject: [Intel-gfx] [PATCH 7/7] drm/i915: Add entrypoints for mapping dplls to encoders and crtcs X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Abstract the platform specific bits of mapping the dplls under a platform independ entrypoints so the differences between platforms are contained in the dpll code. I.e., it removes IS_PLATFORM() macros from other parts of the code. Signed-off-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/intel_ddi.c | 51 ++---- drivers/gpu/drm/i915/intel_display.c | 124 +------------- drivers/gpu/drm/i915/intel_dp_mst.c | 4 +- drivers/gpu/drm/i915/intel_dpll_mgr.c | 299 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dpll_mgr.h | 7 + drivers/gpu/drm/i915/intel_drv.h | 4 +- 6 files changed, 334 insertions(+), 155 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 4077205..144fe5c 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -319,6 +319,19 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder) } } +struct intel_encoder * +intel_ddi_get_port_encoder(struct drm_i915_private *dev_priv, enum port port) +{ + struct intel_encoder *encoder; + + for_each_intel_encoder(&dev_priv->drm, encoder) { + if (port == intel_ddi_get_encoder_port(encoder)) + return encoder; + } + + return NULL; +} + static const struct ddi_buf_trans * bdw_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries) { @@ -582,11 +595,12 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; - u32 temp, i, rx_ctl_val, ddi_pll_sel; + u32 temp, i, rx_ctl_val; for_each_encoder_on_crtc(dev, crtc, encoder) { WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG); intel_prepare_dp_ddi_buffers(encoder); + break; } /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the @@ -613,9 +627,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val); /* Configure Port Clock Select */ - ddi_pll_sel = hsw_pll_to_ddi_pll_sel(intel_crtc->config->shared_dpll); - I915_WRITE(PORT_CLK_SEL(PORT_E), ddi_pll_sel); - WARN_ON(ddi_pll_sel != PORT_CLK_SEL_SPLL); + intel_dpll_map_to_encoder(intel_crtc->config->shared_dpll, encoder); /* Start the training iterating through available voltages and emphasis, * testing each value twice. */ @@ -1607,33 +1619,6 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp) return DDI_BUF_TRANS_SELECT(level); } -void intel_ddi_clk_select(struct intel_encoder *encoder, - struct intel_shared_dpll *pll) -{ - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - enum port port = intel_ddi_get_encoder_port(encoder); - - if (WARN_ON(!pll)) - return; - - if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { - uint32_t val; - - /* DDI -> PLL mapping */ - val = I915_READ(DPLL_CTRL2); - - val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) | - DPLL_CTRL2_DDI_CLK_SEL_MASK(port)); - val |= (DPLL_CTRL2_DDI_CLK_SEL(pll->id, port) | - DPLL_CTRL2_DDI_SEL_OVERRIDE(port)); - - I915_WRITE(DPLL_CTRL2, val); - - } else if (INTEL_INFO(dev_priv)->gen < 9) { - I915_WRITE(PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); - } -} - static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, int link_rate, uint32_t lane_count, struct intel_shared_dpll *pll, @@ -1648,7 +1633,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder, if (encoder->type == INTEL_OUTPUT_EDP) intel_edp_panel_on(intel_dp); - intel_ddi_clk_select(encoder, pll); + intel_dpll_map_to_encoder(pll, encoder); intel_prepare_dp_ddi_buffers(encoder); intel_ddi_init_dp_buf_reg(encoder); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); @@ -1669,7 +1654,7 @@ static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder, int level = intel_ddi_hdmi_level(dev_priv, port); intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); - intel_ddi_clk_select(encoder, pll); + intel_dpll_map_to_encoder(pll, encoder); intel_prepare_hdmi_ddi_buffers(encoder); if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) skl_ddi_set_iboost(encoder, level); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8ecaf18..22e3c46 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4555,19 +4555,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) /* We need to program the right clock selection before writing the pixel * mutliplier into the DPLL. */ - if (HAS_PCH_CPT(dev)) { - u32 sel; - - temp = I915_READ(PCH_DPLL_SEL); - temp |= TRANS_DPLL_ENABLE(pipe); - sel = TRANS_DPLLB_SEL(pipe); - if (intel_crtc->config->shared_dpll == - intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B)) - temp |= sel; - else - temp &= ~sel; - I915_WRITE(PCH_DPLL_SEL, temp); - } + intel_dpll_map_to_crtc(intel_crtc->config->shared_dpll, intel_crtc); /* XXX: pch pll's can be enabled any time before we enable the PCH * transcoder, and we actually should do this to not upset any PCH @@ -5574,9 +5562,7 @@ static void ironlake_crtc_disable(struct intel_crtc_state *old_crtc_state, I915_WRITE(reg, temp); /* disable DPLL_SEL */ - temp = I915_READ(PCH_DPLL_SEL); - temp &= ~(TRANS_DPLL_ENABLE(pipe) | TRANS_DPLLB_SEL(pipe)); - I915_WRITE(PCH_DPLL_SEL, temp); + intel_dpll_map_to_crtc(NULL, intel_crtc); } ironlake_fdi_pll_disable(intel_crtc); @@ -9952,7 +9938,6 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, if (I915_READ(PCH_TRANSCONF(crtc->pipe)) & TRANS_ENABLE) { struct intel_shared_dpll *pll; - enum intel_dpll_id pll_id; pipe_config->has_pch_encoder = true; @@ -9962,23 +9947,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, ironlake_get_fdi_m_n_config(crtc, pipe_config); - if (HAS_PCH_IBX(dev_priv)) { - /* - * The pipe->pch transcoder and pch transcoder->pll - * mapping is fixed. - */ - pll_id = (enum intel_dpll_id) crtc->pipe; - } else { - tmp = I915_READ(PCH_DPLL_SEL); - if (tmp & TRANS_DPLLB_SEL(crtc->pipe)) - pll_id = DPLL_ID_PCH_PLL_B; - else - pll_id= DPLL_ID_PCH_PLL_A; - } - - pipe_config->shared_dpll = - intel_get_shared_dpll_by_id(dev_priv, pll_id); - pll = pipe_config->shared_dpll; + pipe_config->shared_dpll = pll = intel_get_crtc_dpll(crtc); WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll, &pipe_config->dpll_hw_state)); @@ -10458,82 +10427,6 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc, return 0; } -static void bxt_get_ddi_pll(struct drm_i915_private *dev_priv, - enum port port, - struct intel_crtc_state *pipe_config) -{ - enum intel_dpll_id id; - - switch (port) { - case PORT_A: - id = DPLL_ID_SKL_DPLL0; - break; - case PORT_B: - id = DPLL_ID_SKL_DPLL1; - break; - case PORT_C: - id = DPLL_ID_SKL_DPLL2; - break; - default: - DRM_ERROR("Incorrect port type\n"); - return; - } - - pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); -} - -static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv, - enum port port, - struct intel_crtc_state *pipe_config) -{ - enum intel_dpll_id id; - u32 temp; - - temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port); - id = temp >> (port * 3 + 1); - - if (WARN_ON(id < SKL_DPLL0 || id > SKL_DPLL3)) - return; - - pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); -} - -static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv, - enum port port, - struct intel_crtc_state *pipe_config) -{ - enum intel_dpll_id id; - uint32_t ddi_pll_sel = I915_READ(PORT_CLK_SEL(port)); - - switch (ddi_pll_sel) { - case PORT_CLK_SEL_WRPLL1: - id = DPLL_ID_WRPLL1; - break; - case PORT_CLK_SEL_WRPLL2: - id = DPLL_ID_WRPLL2; - break; - case PORT_CLK_SEL_SPLL: - id = DPLL_ID_SPLL; - break; - case PORT_CLK_SEL_LCPLL_810: - id = DPLL_ID_LCPLL_810; - break; - case PORT_CLK_SEL_LCPLL_1350: - id = DPLL_ID_LCPLL_1350; - break; - case PORT_CLK_SEL_LCPLL_2700: - id = DPLL_ID_LCPLL_2700; - break; - default: - MISSING_CASE(ddi_pll_sel); - /* fall through */ - case PORT_CLK_SEL_NONE: - return; - } - - pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id); -} - static bool hsw_get_transcoder_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config, unsigned long *power_domain_mask) @@ -10638,6 +10531,7 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_encoder *encoder; struct intel_shared_dpll *pll; enum port port; uint32_t tmp; @@ -10646,14 +10540,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT; - if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) - skylake_get_ddi_pll(dev_priv, port, pipe_config); - else if (IS_BROXTON(dev)) - bxt_get_ddi_pll(dev_priv, port, pipe_config); - else - haswell_get_ddi_pll(dev_priv, port, pipe_config); - - pll = pipe_config->shared_dpll; + encoder = intel_ddi_get_port_encoder(dev_priv, port); + pipe_config->shared_dpll = pll = intel_get_encoder_dpll(encoder); if (pll) { WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll, &pipe_config->dpll_hw_state)); diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 3ffbd69..cb097fb 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -150,8 +150,8 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder, DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links); if (intel_dp->active_mst_links == 0) { - intel_ddi_clk_select(&intel_dig_port->base, - pipe_config->shared_dpll); + intel_dpll_map_to_encoder(pipe_config->shared_dpll, + &intel_dig_port->base); intel_prepare_dp_ddi_buffers(&intel_dig_port->base); intel_dp_set_link_params(intel_dp, diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 9b02d9c..532236d 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -40,6 +40,12 @@ * Changes to the users are first staged in the atomic state, and then made * effective by calling intel_shared_dpll_swap_state() during the atomic * commit phase. + * + * The functions intel_dpll_map_to_crtc(), intel_dpll_map_to_encoder(), + * intel_get_crtc_dpll() and intel_get_encoder_dpll() allows the mapping of + * dplls to crtcs and encoders to be queried and changed. Whether plls map + * to encoders or crtcs depends on the platform. The caller needs to know + * which of the functions to use. */ struct intel_shared_dpll * @@ -447,6 +453,54 @@ ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, return pll; } +static struct intel_shared_dpll * +ibx_get_crtc_dpll(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum intel_dpll_id pll_id; + u32 tmp; + + if (HAS_PCH_IBX(dev_priv)) { + /* + * The pipe->pch transcoder and pch transcoder->pll + * mapping is fixed. + */ + pll_id = (enum intel_dpll_id) crtc->pipe; + } else { + tmp = I915_READ(PCH_DPLL_SEL); + if (tmp & TRANS_DPLLB_SEL(crtc->pipe)) + pll_id = DPLL_ID_PCH_PLL_B; + else + pll_id= DPLL_ID_PCH_PLL_A; + } + + return intel_get_shared_dpll_by_id(dev_priv, pll_id); +} + +static void +ibx_dpll_map_to_crtc(struct intel_shared_dpll *dpll, struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum pipe pipe = crtc->pipe; + u32 temp, sel; + + if (!HAS_PCH_CPT(dev_priv)) + return; + + temp = I915_READ(PCH_DPLL_SEL); + if (dpll) { + temp |= TRANS_DPLL_ENABLE(pipe); + sel = TRANS_DPLLB_SEL(pipe); + if (dpll->id == DPLL_ID_PCH_PLL_B) + temp |= sel; + else + temp &= ~sel; + } else { + temp &= ~(TRANS_DPLL_ENABLE(pipe) | TRANS_DPLLB_SEL(pipe)); + } + I915_WRITE(PCH_DPLL_SEL, temp); +} + static void ibx_dump_hw_state(struct drm_i915_private *dev_priv, struct intel_dpll_hw_state *hw_state) { @@ -844,6 +898,73 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, return pll; } +static enum intel_dpll_id hsw_reg_to_pll_id(uint32_t ddi_pll_sel) +{ + switch (ddi_pll_sel) { + case PORT_CLK_SEL_WRPLL1: + return DPLL_ID_WRPLL1; + case PORT_CLK_SEL_WRPLL2: + return DPLL_ID_WRPLL2; + case PORT_CLK_SEL_SPLL: + return DPLL_ID_SPLL; + case PORT_CLK_SEL_LCPLL_810: + return DPLL_ID_LCPLL_810; + case PORT_CLK_SEL_LCPLL_1350: + return DPLL_ID_LCPLL_1350; + case PORT_CLK_SEL_LCPLL_2700: + return DPLL_ID_LCPLL_2700; + default: + MISSING_CASE(ddi_pll_sel); + /* fall through */ + case PORT_CLK_SEL_NONE: + return DPLL_ID_PRIVATE; + } +} + +static uint32_t hsw_pll_id_to_reg(enum intel_dpll_id id) +{ + switch (id) { + case DPLL_ID_WRPLL1: + return PORT_CLK_SEL_WRPLL1; + case DPLL_ID_WRPLL2: + return PORT_CLK_SEL_WRPLL2; + case DPLL_ID_SPLL: + return PORT_CLK_SEL_SPLL; + case DPLL_ID_LCPLL_810: + return PORT_CLK_SEL_LCPLL_810; + case DPLL_ID_LCPLL_1350: + return PORT_CLK_SEL_LCPLL_1350; + case DPLL_ID_LCPLL_2700: + return PORT_CLK_SEL_LCPLL_2700; + default: + MISSING_CASE(id); + /* fall through */ + case DPLL_ID_PRIVATE: + return PORT_CLK_SEL_NONE; + } +} + +static struct intel_shared_dpll * +hsw_get_encoder_dpll(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = intel_ddi_get_encoder_port(encoder); + uint32_t ddi_pll_sel = I915_READ(PORT_CLK_SEL(port)); + + return intel_get_shared_dpll_by_id(dev_priv, + hsw_reg_to_pll_id(ddi_pll_sel)); +} + +static void +hsw_dpll_map_to_encoder(struct intel_shared_dpll *dpll, + struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = intel_ddi_get_encoder_port(encoder); + + I915_WRITE(PORT_CLK_SEL(port), hsw_pll_id_to_reg(dpll->id)); +} + static void hsw_dump_hw_state(struct drm_i915_private *dev_priv, struct intel_dpll_hw_state *hw_state) { @@ -1406,6 +1527,41 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, return pll; } +static struct intel_shared_dpll * +skl_get_encoder_dpll(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = intel_ddi_get_encoder_port(encoder); + enum intel_dpll_id id; + u32 temp; + + temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port); + id = temp >> (port * 3 + 1); + + if (WARN_ON(id < SKL_DPLL0 || id > SKL_DPLL3)) + return NULL; + + return intel_get_shared_dpll_by_id(dev_priv, id); +} + +static void +skl_dpll_map_to_encoder(struct intel_shared_dpll *dpll, + struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = intel_ddi_get_encoder_port(encoder); + uint32_t val; + + val = I915_READ(DPLL_CTRL2); + + val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) | + DPLL_CTRL2_DDI_CLK_SEL_MASK(port)); + val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll->id, port) | + DPLL_CTRL2_DDI_SEL_OVERRIDE(port)); + + I915_WRITE(DPLL_CTRL2, val); +} + static void skl_dump_hw_state(struct drm_i915_private *dev_priv, struct intel_dpll_hw_state *hw_state) { @@ -1812,6 +1968,38 @@ bxt_get_dpll(struct intel_crtc *crtc, return pll; } +static struct intel_shared_dpll * +bxt_get_encoder_dpll(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = intel_ddi_get_encoder_port(encoder); + enum intel_dpll_id id; + + switch (port) { + case PORT_A: + id = DPLL_ID_SKL_DPLL0; + break; + case PORT_B: + id = DPLL_ID_SKL_DPLL1; + break; + case PORT_C: + id = DPLL_ID_SKL_DPLL2; + break; + default: + DRM_ERROR("Incorrect port type\n"); + return NULL; + } + + return intel_get_shared_dpll_by_id(dev_priv, id); +} + +static void +bxt_dpll_map_to_encoder(struct intel_shared_dpll *dpll, + struct intel_encoder *encoder) +{ + /* Fixed mapping, nothing to do */ +} + static void bxt_dump_hw_state(struct drm_i915_private *dev_priv, struct intel_dpll_hw_state *hw_state) @@ -1859,6 +2047,33 @@ static void intel_ddi_pll_init(struct drm_device *dev) } } +static void +noop_dpll_map_to_crtc(struct intel_shared_dpll *dpll, struct intel_crtc *crtc) +{ + WARN(1, "Platform does not support mapping DPLLs to CRTCs."); +} + +static struct intel_shared_dpll * +noop_get_crtc_dpll(struct intel_crtc *crtc) +{ + WARN(1, "Platform does not support mapping DPLLs to CRTCs."); + return NULL; +} + +static void +noop_dpll_map_to_encoder(struct intel_shared_dpll *dpll, struct intel_encoder *encoder) +{ + WARN(1, "Platform does not support mapping DPLLs to encoders."); +} + +static struct intel_shared_dpll * +noop_get_encoder_dpll(struct intel_encoder *encoder) +{ + WARN(1, "Platform does not support mapping DPLLs to encoders."); + return NULL; +} + + struct dpll_info { const char *name; const int id; @@ -1873,6 +2088,14 @@ struct intel_dpll_mgr { struct intel_crtc_state *crtc_state, struct intel_encoder *encoder); + struct intel_shared_dpll *(*get_crtc_dpll)(struct intel_crtc *crtc); + struct intel_shared_dpll *(*get_encoder_dpll)(struct intel_encoder *encoder); + + void (*map_to_crtc)(struct intel_shared_dpll *dpll, + struct intel_crtc *crtc); + void (*map_to_encoder)(struct intel_shared_dpll *dpll, + struct intel_encoder *encoder); + void (*dump_hw_state)(struct drm_i915_private *dev_priv, struct intel_dpll_hw_state *hw_state); }; @@ -1886,6 +2109,10 @@ static const struct dpll_info pch_plls[] = { static const struct intel_dpll_mgr pch_pll_mgr = { .dpll_info = pch_plls, .get_dpll = ibx_get_dpll, + .get_crtc_dpll = ibx_get_crtc_dpll, + .map_to_crtc = ibx_dpll_map_to_crtc, + .get_encoder_dpll = noop_get_encoder_dpll, + .map_to_encoder = noop_dpll_map_to_encoder, .dump_hw_state = ibx_dump_hw_state, }; @@ -1902,6 +2129,10 @@ static const struct dpll_info hsw_plls[] = { static const struct intel_dpll_mgr hsw_pll_mgr = { .dpll_info = hsw_plls, .get_dpll = hsw_get_dpll, + .get_crtc_dpll = noop_get_crtc_dpll, + .map_to_crtc = noop_dpll_map_to_crtc, + .get_encoder_dpll = hsw_get_encoder_dpll, + .map_to_encoder = hsw_dpll_map_to_encoder, .dump_hw_state = hsw_dump_hw_state, }; @@ -1916,6 +2147,10 @@ static const struct dpll_info skl_plls[] = { static const struct intel_dpll_mgr skl_pll_mgr = { .dpll_info = skl_plls, .get_dpll = skl_get_dpll, + .get_crtc_dpll = noop_get_crtc_dpll, + .map_to_crtc = noop_dpll_map_to_crtc, + .get_encoder_dpll = skl_get_encoder_dpll, + .map_to_encoder = skl_dpll_map_to_encoder, .dump_hw_state = skl_dump_hw_state, }; @@ -1929,6 +2164,10 @@ static const struct dpll_info bxt_plls[] = { static const struct intel_dpll_mgr bxt_pll_mgr = { .dpll_info = bxt_plls, .get_dpll = bxt_get_dpll, + .get_crtc_dpll = noop_get_crtc_dpll, + .map_to_crtc = noop_dpll_map_to_crtc, + .get_encoder_dpll = bxt_get_encoder_dpll, + .map_to_encoder = bxt_dpll_map_to_encoder, .dump_hw_state = bxt_dump_hw_state, }; @@ -2031,6 +2270,66 @@ void intel_release_shared_dpll(struct intel_shared_dpll *dpll, } /** + * intel_get_crtc_dpll - Get which pll is mapped to a pipe + * @crtc: pipe + * + * Returns the DPLL is mapped to @crtc. NULL indicates no DPLL is mapped to + * @crtc. + */ +struct intel_shared_dpll *intel_get_crtc_dpll(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + + return dev_priv->dpll_mgr->get_crtc_dpll(crtc); +} + +/** + * intel_get_encoder_dpll - Get which pll is mapped to an encoder + * @encoder: encoder + * + * Returns the DPLL is mapped to @encoder. NULL indicates no DPLL is mapped to + * @encoder. + */ +struct intel_shared_dpll *intel_get_encoder_dpll(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + + return dev_priv->dpll_mgr->get_encoder_dpll(encoder); +} + +/** + * intel_dpll_map_to_crtc - Map DPLL to pipe + * @dpll: dpll to map + * @crtc: pipe to map the @dpll to + * + * For platforms where DPLLs are mapped to crtcs, program the appropriate + * bits so that @dpll is mapped to @crtc. + */ +void intel_dpll_map_to_crtc(struct intel_shared_dpll *dpll, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + + dev_priv->dpll_mgr->map_to_crtc(dpll, crtc); +} + +/** + * intel_dpll_map_to_encoder - Map DPLL to encoder + * @dpll: dpll to map + * @encoder: encoder to map the @dpll to + * + * For platforms where DPLLs are mapped to encoders, program the appropriate + * bits so that @dpll is mapped to @encoder. + */ +void intel_dpll_map_to_encoder(struct intel_shared_dpll *dpll, + struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + + dev_priv->dpll_mgr->map_to_encoder(dpll, encoder); +} + +/** * intel_shared_dpll_dump_hw_state - write hw_state to dmesg * @dev_priv: i915 drm device * @hw_state: hw state to be written to the log diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index 76111a4..7b46c88 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -280,6 +280,13 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc); void intel_shared_dpll_swap_state(struct drm_atomic_state *state); void intel_shared_dpll_init(struct drm_device *dev); +struct intel_shared_dpll *intel_get_crtc_dpll(struct intel_crtc *crtc); +struct intel_shared_dpll *intel_get_encoder_dpll(struct intel_encoder *encoder); +void intel_dpll_map_to_crtc(struct intel_shared_dpll *dpll, + struct intel_crtc *crtc); +void intel_dpll_map_to_encoder(struct intel_shared_dpll *dpll, + struct intel_encoder *encoder); + void intel_dpll_dump_hw_state(struct drm_i915_private *dev_priv, struct intel_dpll_hw_state *hw_state); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7874f66..a04d917 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1136,8 +1136,6 @@ void intel_crt_init(struct drm_device *dev); void intel_crt_reset(struct drm_encoder *encoder); /* intel_ddi.c */ -void intel_ddi_clk_select(struct intel_encoder *encoder, - struct intel_shared_dpll *pll); void intel_ddi_fdi_post_disable(struct intel_encoder *intel_encoder, struct intel_crtc_state *old_crtc_state, struct drm_connector_state *old_conn_state); @@ -1145,6 +1143,8 @@ void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder); void hsw_fdi_link_train(struct drm_crtc *crtc); void intel_ddi_init(struct drm_device *dev, enum port port); enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder); +struct intel_encoder * +intel_ddi_get_port_encoder(struct drm_i915_private *dev_priv, enum port port); bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc); void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,