From patchwork Mon Feb 29 09:08:19 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: 8450551 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9A4789F38C for ; Mon, 29 Feb 2016 09:08:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 457E620221 for ; Mon, 29 Feb 2016 09:08:20 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id DBDD220165 for ; Mon, 29 Feb 2016 09:08:18 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 78C866E228; Mon, 29 Feb 2016 09:08:18 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTP id EE2396E228 for ; Mon, 29 Feb 2016 09:08:16 +0000 (UTC) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga103.fm.intel.com with ESMTP; 29 Feb 2016 01:08:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,520,1449561600"; d="scan'208";a="56674808" Received: from linux.intel.com ([10.23.219.25]) by fmsmga004.fm.intel.com with ESMTP; 29 Feb 2016 01:08:16 -0800 Received: from localhost (aconselv-mobl3.ger.corp.intel.com [10.237.66.146]) by linux.intel.com (Postfix) with ESMTP id D8F6D6A4002; Mon, 29 Feb 2016 01:56:03 -0800 (PST) From: Ander Conselvan de Oliveira To: intel-gfx@lists.freedesktop.org Date: Mon, 29 Feb 2016 11:08:19 +0200 Message-Id: <1456736899-4195-1-git-send-email-ander.conselvan.de.oliveira@intel.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1456494866-7665-13-git-send-email-ander.conselvan.de.oliveira@intel.com> References: <1456494866-7665-13-git-send-email-ander.conselvan.de.oliveira@intel.com> Cc: Ander Conselvan de Oliveira Subject: [Intel-gfx] [PATCH v2 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Manage the LCPLLs used with DisplayPort, so that all the HSW/BDW DPLLs are managed by the shared dpll code. v2: Introduce INTEL_DPLL_ALWAYS_ON flag to please state checker. (Ander) Signed-off-by: Ander Conselvan de Oliveira --- drivers/gpu/drm/i915/intel_ddi.c | 18 +++---- drivers/gpu/drm/i915/intel_display.c | 25 ++++++---- drivers/gpu/drm/i915/intel_dp.c | 23 +-------- drivers/gpu/drm/i915/intel_dp_mst.c | 4 -- drivers/gpu/drm/i915/intel_dpll_mgr.c | 89 ++++++++++++++++++++++++++++------- drivers/gpu/drm/i915/intel_dpll_mgr.h | 12 ++++- drivers/gpu/drm/i915/intel_drv.h | 1 - 7 files changed, 107 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ad7888c..3cb9f36 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -992,17 +992,13 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc, { struct intel_shared_dpll *pll; - if (intel_encoder->type == INTEL_OUTPUT_HDMI || - intel_encoder->type == INTEL_OUTPUT_ANALOG) { - pll = intel_get_shared_dpll(intel_crtc, crtc_state, - intel_encoder); - if (!pll) - DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", - pipe_name(intel_crtc->pipe)); - return pll; - } else { - return true; - } + pll = intel_get_shared_dpll(intel_crtc, crtc_state, + intel_encoder); + if (!pll) + DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n", + pipe_name(intel_crtc->pipe)); + + return pll; } static bool diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 17f4f34..7dcb02b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9660,13 +9660,19 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv, 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(pipe_config->ddi_pll_sel); /* fall through */ case PORT_CLK_SEL_NONE: - case PORT_CLK_SEL_LCPLL_810: - case PORT_CLK_SEL_LCPLL_1350: - case PORT_CLK_SEL_LCPLL_2700: return; } @@ -12735,11 +12741,14 @@ check_shared_dpll_state(struct drm_device *dev) pll->active, hweight32(pll->config.crtc_mask)); I915_STATE_WARN(pll->active && !pll->on, "pll in active use but not on in sw tracking\n"); - I915_STATE_WARN(pll->on && !pll->active, - "pll in on but not on in use in sw tracking\n"); - I915_STATE_WARN(pll->on != active, - "pll on state mismatch (expected %i, found %i)\n", - pll->on, active); + + if (!(pll->flags & INTEL_DPLL_ALWAYS_ON)) { + I915_STATE_WARN(pll->on && !pll->active, + "pll in on but not on in use in sw tracking\n"); + I915_STATE_WARN(pll->on != active, + "pll on state mismatch (expected %i, found %i)\n", + pll->on, active); + } for_each_intel_crtc(dev, crtc) { if (crtc->base.state->enable && crtc->config->shared_dpll == pll) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cbc0659..5be6892 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1275,25 +1275,6 @@ skl_edp_set_pll_config(struct intel_crtc_state *pipe_config) pipe_config->dpll_hw_state.ctrl1 = ctrl1; } -void -hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config) -{ - memset(&pipe_config->dpll_hw_state, 0, - sizeof(pipe_config->dpll_hw_state)); - - switch (pipe_config->port_clock / 2) { - case 81000: - pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_810; - break; - case 135000: - pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_1350; - break; - case 270000: - pipe_config->ddi_pll_sel = PORT_CLK_SEL_LCPLL_2700; - break; - } -} - static int intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates) { @@ -1653,10 +1634,8 @@ found: if ((IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) && is_edp(intel_dp)) skl_edp_set_pll_config(pipe_config); - else if (IS_BROXTON(dev)) + else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev)) /* handled in ddi */; - else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) - hsw_dp_set_ddi_pll_sel(pipe_config); else intel_dp_set_clock(encoder, pipe_config); diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index a2bd698..8d1b703 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -33,7 +33,6 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_device *dev = encoder->base.dev; struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); struct intel_digital_port *intel_dig_port = intel_mst->primary; struct intel_dp *intel_dp = &intel_dig_port->dp; @@ -92,9 +91,6 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->dp_m_n.tu = slots; - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) - hsw_dp_set_ddi_pll_sel(pipe_config); - return true; } diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c index 043b7a4..d371680 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c @@ -447,6 +447,12 @@ static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll) 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: return PORT_CLK_SEL_NONE; } @@ -671,9 +677,13 @@ static struct intel_shared_dpll * hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) { + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_shared_dpll *pll; int clock = crtc_state->port_clock; + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + if (encoder->type == INTEL_OUTPUT_HDMI) { uint32_t val; unsigned p, n2, r2; @@ -684,21 +694,37 @@ hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state, WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | WRPLL_DIVIDER_POST(p); - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - crtc_state->dpll_hw_state.wrpll = val; pll = intel_find_shared_dpll(crtc, crtc_state, DPLL_ID_WRPLL1, DPLL_ID_WRPLL2); + } else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || + encoder->type == INTEL_OUTPUT_DP_MST || + encoder->type == INTEL_OUTPUT_EDP) { + enum intel_dpll_id pll_id; + + switch (clock / 2) { + case 81000: + pll_id = DPLL_ID_LCPLL_810; + break; + case 135000: + pll_id = DPLL_ID_LCPLL_1350; + break; + case 270000: + pll_id = DPLL_ID_LCPLL_2700; + break; + default: + DRM_DEBUG_KMS("Invalid clock for DP: %d\n", clock); + return NULL; + } + + pll = intel_get_shared_dpll_by_id(dev_priv, pll_id); + } else if (encoder->type == INTEL_OUTPUT_ANALOG) { if (WARN_ON(crtc_state->port_clock / 2 != 135000)) return NULL; - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - crtc_state->dpll_hw_state.spll = SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC; @@ -731,6 +757,29 @@ static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = { .get_hw_state = hsw_ddi_spll_get_hw_state, }; +static void hsw_ddi_lcpll_enable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ +} + +static void hsw_ddi_lcpll_disable(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll) +{ +} + +static bool hsw_ddi_lcpll_get_hw_state(struct drm_i915_private *dev_priv, + struct intel_shared_dpll *pll, + struct intel_dpll_hw_state *hw_state) +{ + return true; +} + +static const struct intel_shared_dpll_funcs hsw_ddi_lcpll_funcs = { + .enable = hsw_ddi_lcpll_enable, + .disable = hsw_ddi_lcpll_disable, + .get_hw_state = hsw_ddi_lcpll_get_hw_state, +}; + struct skl_dpll_regs { i915_reg_t ctl, cfgcr1, cfgcr2; }; @@ -1537,6 +1586,7 @@ struct dpll_info { const char *name; const int id; const struct intel_shared_dpll_funcs *funcs; + uint32_t flags; }; struct intel_dpll_mgr { @@ -1548,9 +1598,9 @@ struct intel_dpll_mgr { }; static const struct dpll_info pch_plls[] = { - { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs }, - { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs }, - { NULL, -1, NULL }, + { "PCH DPLL A", DPLL_ID_PCH_PLL_A, &ibx_pch_dpll_funcs, 0 }, + { "PCH DPLL B", DPLL_ID_PCH_PLL_B, &ibx_pch_dpll_funcs, 0 }, + { NULL, -1, NULL, 0 }, }; static const struct intel_dpll_mgr pch_pll_mgr = { @@ -1559,9 +1609,12 @@ static const struct intel_dpll_mgr pch_pll_mgr = { }; static const struct dpll_info hsw_plls[] = { - { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs }, - { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs }, - { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs }, + { "WRPLL 1", DPLL_ID_WRPLL1, &hsw_ddi_wrpll_funcs, 0 }, + { "WRPLL 2", DPLL_ID_WRPLL2, &hsw_ddi_wrpll_funcs, 0 }, + { "SPLL", DPLL_ID_SPLL, &hsw_ddi_spll_funcs, 0 }, + { "LCPLL 810", DPLL_ID_LCPLL_810, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON }, + { "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON }, + { "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs, INTEL_DPLL_ALWAYS_ON }, { NULL, -1, NULL, }, }; @@ -1571,9 +1624,9 @@ static const struct intel_dpll_mgr hsw_pll_mgr = { }; static const struct dpll_info skl_plls[] = { - { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs }, - { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs }, - { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs }, + { "DPPL 1", DPLL_ID_SKL_DPLL1, &skl_ddi_pll_funcs, 0 }, + { "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 }, + { "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 }, { NULL, -1, NULL, }, }; @@ -1583,9 +1636,9 @@ static const struct intel_dpll_mgr skl_pll_mgr = { }; static const struct dpll_info bxt_plls[] = { - { "PORT PLL A", 0, &bxt_ddi_pll_funcs }, - { "PORT PLL B", 1, &bxt_ddi_pll_funcs }, - { "PORT PLL C", 2, &bxt_ddi_pll_funcs }, + { "PORT PLL A", 0, &bxt_ddi_pll_funcs, 0 }, + { "PORT PLL B", 1, &bxt_ddi_pll_funcs, 0 }, + { "PORT PLL C", 2, &bxt_ddi_pll_funcs, 0 }, { NULL, -1, NULL, }, }; diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h index 82e53f5..adf4706 100644 --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h @@ -49,13 +49,21 @@ enum intel_dpll_id { DPLL_ID_WRPLL1 = 0, DPLL_ID_WRPLL2 = 1, DPLL_ID_SPLL = 2, + DPLL_ID_LCPLL_810 = 3, + DPLL_ID_LCPLL_1350 = 4, + DPLL_ID_LCPLL_2700 = 5, /* skl */ DPLL_ID_SKL_DPLL1 = 0, DPLL_ID_SKL_DPLL2 = 1, DPLL_ID_SKL_DPLL3 = 2, }; -#define I915_NUM_PLLS 3 +#define I915_NUM_PLLS 6 + +/** Inform the state checker that the DPLL is kept enabled even if not + * in use by any crtc. + */ +#define INTEL_DPLL_ALWAYS_ON (1 << 0) struct intel_dpll_hw_state { /* i9xx, pch plls */ @@ -113,6 +121,8 @@ struct intel_shared_dpll { enum intel_dpll_id id; struct intel_shared_dpll_funcs funcs; + + uint32_t flags; }; #define SKL_DPLL0 0 diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c9e5030..18aa287 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1258,7 +1258,6 @@ void intel_edp_drrs_invalidate(struct drm_device *dev, void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits); bool intel_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *port); -void hsw_dp_set_ddi_pll_sel(struct intel_crtc_state *pipe_config); void intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,