All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] Shared pll improvements
@ 2016-02-26 13:54 Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 01/13] drm/i915: Move shared dpll code to a new file Ander Conselvan de Oliveira
                   ` (13 more replies)
  0 siblings, 14 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Hi,

This patch series attempts to improve the shared pll interfaces. The
idea is to hide the details of which PLL to use behind the call to
intel_get_shared_dpll(), instead of having the weird mix currently
used with DDI platforms. I plan to keep working on the interfaces to
make it usuable by other platforms too, but that will come in a later
series.

With these patches, all DPLLS used with DDI are managed, including
LCPLL in HSW/BDW and DPLL0 in SKL/KBL (although I wasn't able to test
the latter).

The avid reviewer might notice that this series leaves all the
*_ddi_pll_select() function looking pretty much the same. I have
a clean up lined up for that, but it involves removing the
haswell_crtc_compute_clock() function and I haven't yet figured out
how/where to release the used dplls.

So this is still work in progress, but it is probably better to get
feedback now before there are even more patches.

Thanks,
Ander

Ander Conselvan de Oliveira (13):
  drm/i915: Move shared dpll code to a new file
  drm/i915: Move ddi shared dpll code to intel_dpll_mgr.c
  drm/i915: Split intel_get_shared_dpll() into smaller functions
  drm/i915: Store a direct pointer to shared dpll in intel_crtc_state
  drm/i915: Move shared dpll struct definitions to separate header file
  drm/i915: Move shared dpll function prototypes to intel_dpll_mgr.h
  drm/i915: Use a table to initilize shared dplls
  drm/i915: Refactor platform specifics out of intel_get_shared_dpll()
  drm/i915: Move HSW/BDW pll selection logic to intel_dpll_mgr.c
  drm/i915: Move SKL/KLB pll selection logic to intel_dpll_mgr.c
  drm/i915: Move BXT pll configuration logic to intel_dpll_mgr.c
  drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface
  drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code

 drivers/gpu/drm/i915/Makefile         |    1 +
 drivers/gpu/drm/i915/i915_drv.h       |   77 +-
 drivers/gpu/drm/i915/intel_crt.c      |    8 +-
 drivers/gpu/drm/i915/intel_ddi.c      | 1200 +---------------------
 drivers/gpu/drm/i915/intel_display.c  |  493 ++-------
 drivers/gpu/drm/i915/intel_dp.c       |   73 +-
 drivers/gpu/drm/i915/intel_dp_mst.c   |    4 -
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 1789 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  157 +++
 drivers/gpu/drm/i915/intel_drv.h      |   17 +-
 drivers/gpu/drm/i915/intel_lvds.c     |    2 +-
 11 files changed, 2068 insertions(+), 1753 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_dpll_mgr.c
 create mode 100644 drivers/gpu/drm/i915/intel_dpll_mgr.h

-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/13] drm/i915: Move shared dpll code to a new file
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 02/13] drm/i915: Move ddi shared dpll code to intel_dpll_mgr.c Ander Conselvan de Oliveira
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Create the new file intel_dpll_mgr.c and move the shared dpll code to
it. Follow up patches that reorganize pll handling will move more code
there and tweak the interface.

No functional changes.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/Makefile         |   1 +
 drivers/gpu/drm/i915/intel_display.c  | 348 +-------------------------------
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 368 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h      |   8 +
 4 files changed, 379 insertions(+), 346 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_dpll_mgr.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0851de07..5558a03 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -56,6 +56,7 @@ i915-y += intel_audio.o \
 	  intel_atomic_plane.o \
 	  intel_bios.o \
 	  intel_display.o \
+	  intel_dpll_mgr.o \
 	  intel_fbc.o \
 	  intel_fifo_underrun.o \
 	  intel_frontbuffer.o \
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8b7b8b6..df49324 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1182,34 +1182,6 @@ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
 #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
 #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
 
-struct intel_shared_dpll *
-intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
-{
-	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
-
-	if (crtc->config->shared_dpll < 0)
-		return NULL;
-
-	return &dev_priv->shared_dplls[crtc->config->shared_dpll];
-}
-
-/* For ILK+ */
-void assert_shared_dpll(struct drm_i915_private *dev_priv,
-			struct intel_shared_dpll *pll,
-			bool state)
-{
-	bool cur_state;
-	struct intel_dpll_hw_state hw_state;
-
-	if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
-		return;
-
-	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
-	I915_STATE_WARN(cur_state != state,
-	     "%s assertion failure (expected %s, current %s)\n",
-			pll->name, onoff(state), onoff(cur_state));
-}
-
 static void assert_fdi_tx(struct drm_i915_private *dev_priv,
 			  enum pipe pipe, bool state)
 {
@@ -1446,21 +1418,8 @@ static void assert_vblank_disabled(struct drm_crtc *crtc)
 		drm_crtc_vblank_put(crtc);
 }
 
-static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
-{
-	u32 val;
-	bool enabled;
-
-	I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv->dev) || HAS_PCH_CPT(dev_priv->dev)));
-
-	val = I915_READ(PCH_DREF_CONTROL);
-	enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
-			    DREF_SUPERSPREAD_SOURCE_MASK));
-	I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
-}
-
-static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
-					   enum pipe pipe)
+void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
+				    enum pipe pipe)
 {
 	u32 val;
 	bool enabled;
@@ -1856,100 +1815,6 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
 		     port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask);
 }
 
-static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
-
-	if (WARN_ON(pll == NULL))
-		return;
-
-	WARN_ON(!pll->config.crtc_mask);
-	if (pll->active == 0) {
-		DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
-		WARN_ON(pll->on);
-		assert_shared_dpll_disabled(dev_priv, pll);
-
-		pll->mode_set(dev_priv, pll);
-	}
-}
-
-/**
- * intel_enable_shared_dpll - enable PCH PLL
- * @dev_priv: i915 private structure
- * @pipe: pipe PLL to enable
- *
- * The PCH PLL needs to be enabled before the PCH transcoder, since it
- * drives the transcoder clock.
- */
-static void intel_enable_shared_dpll(struct intel_crtc *crtc)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
-
-	if (WARN_ON(pll == NULL))
-		return;
-
-	if (WARN_ON(pll->config.crtc_mask == 0))
-		return;
-
-	DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n",
-		      pll->name, pll->active, pll->on,
-		      crtc->base.base.id);
-
-	if (pll->active++) {
-		WARN_ON(!pll->on);
-		assert_shared_dpll_enabled(dev_priv, pll);
-		return;
-	}
-	WARN_ON(pll->on);
-
-	intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
-
-	DRM_DEBUG_KMS("enabling %s\n", pll->name);
-	pll->enable(dev_priv, pll);
-	pll->on = true;
-}
-
-static void intel_disable_shared_dpll(struct intel_crtc *crtc)
-{
-	struct drm_device *dev = crtc->base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
-
-	/* PCH only available on ILK+ */
-	if (INTEL_INFO(dev)->gen < 5)
-		return;
-
-	if (pll == NULL)
-		return;
-
-	if (WARN_ON(!(pll->config.crtc_mask & (1 << drm_crtc_index(&crtc->base)))))
-		return;
-
-	DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n",
-		      pll->name, pll->active, pll->on,
-		      crtc->base.base.id);
-
-	if (WARN_ON(pll->active == 0)) {
-		assert_shared_dpll_disabled(dev_priv, pll);
-		return;
-	}
-
-	assert_shared_dpll_enabled(dev_priv, pll);
-	WARN_ON(!pll->on);
-	if (--pll->active)
-		return;
-
-	DRM_DEBUG_KMS("disabling %s\n", pll->name);
-	pll->disable(dev_priv, pll);
-	pll->on = false;
-
-	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-}
-
 static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
 					   enum pipe pipe)
 {
@@ -4238,113 +4103,6 @@ static void lpt_pch_enable(struct drm_crtc *crtc)
 	lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
 }
 
-struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
-						struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
-	struct intel_shared_dpll *pll;
-	struct intel_shared_dpll_config *shared_dpll;
-	enum intel_dpll_id i;
-	int max = dev_priv->num_shared_dpll;
-
-	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
-
-	if (HAS_PCH_IBX(dev_priv->dev)) {
-		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
-		i = (enum intel_dpll_id) crtc->pipe;
-		pll = &dev_priv->shared_dplls[i];
-
-		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
-			      crtc->base.base.id, pll->name);
-
-		WARN_ON(shared_dpll[i].crtc_mask);
-
-		goto found;
-	}
-
-	if (IS_BROXTON(dev_priv->dev)) {
-		/* PLL is attached to port in bxt */
-		struct intel_encoder *encoder;
-		struct intel_digital_port *intel_dig_port;
-
-		encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
-		if (WARN_ON(!encoder))
-			return NULL;
-
-		intel_dig_port = enc_to_dig_port(&encoder->base);
-		/* 1:1 mapping between ports and PLLs */
-		i = (enum intel_dpll_id)intel_dig_port->port;
-		pll = &dev_priv->shared_dplls[i];
-		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
-			crtc->base.base.id, pll->name);
-		WARN_ON(shared_dpll[i].crtc_mask);
-
-		goto found;
-	} else if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
-		/* Do not consider SPLL */
-		max = 2;
-
-	for (i = 0; i < max; i++) {
-		pll = &dev_priv->shared_dplls[i];
-
-		/* Only want to check enabled timings first */
-		if (shared_dpll[i].crtc_mask == 0)
-			continue;
-
-		if (memcmp(&crtc_state->dpll_hw_state,
-			   &shared_dpll[i].hw_state,
-			   sizeof(crtc_state->dpll_hw_state)) == 0) {
-			DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n",
-				      crtc->base.base.id, pll->name,
-				      shared_dpll[i].crtc_mask,
-				      pll->active);
-			goto found;
-		}
-	}
-
-	/* Ok no matching timings, maybe there's a free one? */
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		pll = &dev_priv->shared_dplls[i];
-		if (shared_dpll[i].crtc_mask == 0) {
-			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
-				      crtc->base.base.id, pll->name);
-			goto found;
-		}
-	}
-
-	return NULL;
-
-found:
-	if (shared_dpll[i].crtc_mask == 0)
-		shared_dpll[i].hw_state =
-			crtc_state->dpll_hw_state;
-
-	crtc_state->shared_dpll = i;
-	DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
-			 pipe_name(crtc->pipe));
-
-	shared_dpll[i].crtc_mask |= 1 << crtc->pipe;
-
-	return pll;
-}
-
-static void intel_shared_dpll_commit(struct drm_atomic_state *state)
-{
-	struct drm_i915_private *dev_priv = to_i915(state->dev);
-	struct intel_shared_dpll_config *shared_dpll;
-	struct intel_shared_dpll *pll;
-	enum intel_dpll_id i;
-
-	if (!to_intel_atomic_state(state)->dpll_set)
-		return;
-
-	shared_dpll = to_intel_atomic_state(state)->shared_dpll;
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		pll = &dev_priv->shared_dplls[i];
-		pll->config = shared_dpll[i];
-	}
-}
-
 static void cpt_verify_modeset(struct drm_device *dev, int pipe)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -13677,108 +13435,6 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
 	.atomic_destroy_state = intel_crtc_destroy_state,
 };
 
-static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
-				      struct intel_shared_dpll *pll,
-				      struct intel_dpll_hw_state *hw_state)
-{
-	uint32_t val;
-
-	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
-		return false;
-
-	val = I915_READ(PCH_DPLL(pll->id));
-	hw_state->dpll = val;
-	hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
-	hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
-
-	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-
-	return val & DPLL_VCO_ENABLE;
-}
-
-static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv,
-				  struct intel_shared_dpll *pll)
-{
-	I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0);
-	I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1);
-}
-
-static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
-				struct intel_shared_dpll *pll)
-{
-	/* PCH refclock must be enabled first */
-	ibx_assert_pch_refclk_enabled(dev_priv);
-
-	I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
-
-	/* Wait for the clocks to stabilize. */
-	POSTING_READ(PCH_DPLL(pll->id));
-	udelay(150);
-
-	/* The pixel multiplier can only be updated once the
-	 * DPLL is enabled and the clocks are stable.
-	 *
-	 * So write it again.
-	 */
-	I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
-	POSTING_READ(PCH_DPLL(pll->id));
-	udelay(200);
-}
-
-static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
-				 struct intel_shared_dpll *pll)
-{
-	struct drm_device *dev = dev_priv->dev;
-	struct intel_crtc *crtc;
-
-	/* Make sure no transcoder isn't still depending on us. */
-	for_each_intel_crtc(dev, crtc) {
-		if (intel_crtc_to_shared_dpll(crtc) == pll)
-			assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
-	}
-
-	I915_WRITE(PCH_DPLL(pll->id), 0);
-	POSTING_READ(PCH_DPLL(pll->id));
-	udelay(200);
-}
-
-static char *ibx_pch_dpll_names[] = {
-	"PCH DPLL A",
-	"PCH DPLL B",
-};
-
-static void ibx_pch_dpll_init(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	int i;
-
-	dev_priv->num_shared_dpll = 2;
-
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		dev_priv->shared_dplls[i].id = i;
-		dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
-		dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set;
-		dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
-		dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
-		dev_priv->shared_dplls[i].get_hw_state =
-			ibx_pch_dpll_get_hw_state;
-	}
-}
-
-static void intel_shared_dpll_init(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	if (HAS_DDI(dev))
-		intel_ddi_pll_init(dev);
-	else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
-		ibx_pch_dpll_init(dev);
-	else
-		dev_priv->num_shared_dpll = 0;
-
-	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
-}
-
 /**
  * intel_prepare_plane_fb - Prepare fb for usage on plane
  * @plane: drm plane to prepare for
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
new file mode 100644
index 0000000..d7ebac6
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright © 2006-2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "intel_drv.h"
+
+struct intel_shared_dpll *
+intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+
+	if (crtc->config->shared_dpll < 0)
+		return NULL;
+
+	return &dev_priv->shared_dplls[crtc->config->shared_dpll];
+}
+
+/* For ILK+ */
+void assert_shared_dpll(struct drm_i915_private *dev_priv,
+			struct intel_shared_dpll *pll,
+			bool state)
+{
+	bool cur_state;
+	struct intel_dpll_hw_state hw_state;
+
+	if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
+		return;
+
+	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
+	I915_STATE_WARN(cur_state != state,
+	     "%s assertion failure (expected %s, current %s)\n",
+			pll->name, onoff(state), onoff(cur_state));
+}
+
+void intel_prepare_shared_dpll(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+
+	if (WARN_ON(pll == NULL))
+		return;
+
+	WARN_ON(!pll->config.crtc_mask);
+	if (pll->active == 0) {
+		DRM_DEBUG_DRIVER("setting up %s\n", pll->name);
+		WARN_ON(pll->on);
+		assert_shared_dpll_disabled(dev_priv, pll);
+
+		pll->mode_set(dev_priv, pll);
+	}
+}
+
+/**
+ * intel_enable_shared_dpll - enable PCH PLL
+ * @dev_priv: i915 private structure
+ * @pipe: pipe PLL to enable
+ *
+ * The PCH PLL needs to be enabled before the PCH transcoder, since it
+ * drives the transcoder clock.
+ */
+void intel_enable_shared_dpll(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+
+	if (WARN_ON(pll == NULL))
+		return;
+
+	if (WARN_ON(pll->config.crtc_mask == 0))
+		return;
+
+	DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n",
+		      pll->name, pll->active, pll->on,
+		      crtc->base.base.id);
+
+	if (pll->active++) {
+		WARN_ON(!pll->on);
+		assert_shared_dpll_enabled(dev_priv, pll);
+		return;
+	}
+	WARN_ON(pll->on);
+
+	intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
+
+	DRM_DEBUG_KMS("enabling %s\n", pll->name);
+	pll->enable(dev_priv, pll);
+	pll->on = true;
+}
+
+void intel_disable_shared_dpll(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+
+	/* PCH only available on ILK+ */
+	if (INTEL_INFO(dev)->gen < 5)
+		return;
+
+	if (pll == NULL)
+		return;
+
+	if (WARN_ON(!(pll->config.crtc_mask & (1 << drm_crtc_index(&crtc->base)))))
+		return;
+
+	DRM_DEBUG_KMS("disable %s (active %d, on? %d) for crtc %d\n",
+		      pll->name, pll->active, pll->on,
+		      crtc->base.base.id);
+
+	if (WARN_ON(pll->active == 0)) {
+		assert_shared_dpll_disabled(dev_priv, pll);
+		return;
+	}
+
+	assert_shared_dpll_enabled(dev_priv, pll);
+	WARN_ON(!pll->on);
+	if (--pll->active)
+		return;
+
+	DRM_DEBUG_KMS("disabling %s\n", pll->name);
+	pll->disable(dev_priv, pll);
+	pll->on = false;
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+}
+
+struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
+						struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_shared_dpll *pll;
+	struct intel_shared_dpll_config *shared_dpll;
+	enum intel_dpll_id i;
+	int max = dev_priv->num_shared_dpll;
+
+	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
+
+	if (HAS_PCH_IBX(dev_priv->dev)) {
+		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
+		i = (enum intel_dpll_id) crtc->pipe;
+		pll = &dev_priv->shared_dplls[i];
+
+		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
+			      crtc->base.base.id, pll->name);
+
+		WARN_ON(shared_dpll[i].crtc_mask);
+
+		goto found;
+	}
+
+	if (IS_BROXTON(dev_priv->dev)) {
+		/* PLL is attached to port in bxt */
+		struct intel_encoder *encoder;
+		struct intel_digital_port *intel_dig_port;
+
+		encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
+		if (WARN_ON(!encoder))
+			return NULL;
+
+		intel_dig_port = enc_to_dig_port(&encoder->base);
+		/* 1:1 mapping between ports and PLLs */
+		i = (enum intel_dpll_id)intel_dig_port->port;
+		pll = &dev_priv->shared_dplls[i];
+		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
+			crtc->base.base.id, pll->name);
+		WARN_ON(shared_dpll[i].crtc_mask);
+
+		goto found;
+	} else if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
+		/* Do not consider SPLL */
+		max = 2;
+
+	for (i = 0; i < max; i++) {
+		pll = &dev_priv->shared_dplls[i];
+
+		/* Only want to check enabled timings first */
+		if (shared_dpll[i].crtc_mask == 0)
+			continue;
+
+		if (memcmp(&crtc_state->dpll_hw_state,
+			   &shared_dpll[i].hw_state,
+			   sizeof(crtc_state->dpll_hw_state)) == 0) {
+			DRM_DEBUG_KMS("CRTC:%d sharing existing %s (crtc mask 0x%08x, ative %d)\n",
+				      crtc->base.base.id, pll->name,
+				      shared_dpll[i].crtc_mask,
+				      pll->active);
+			goto found;
+		}
+	}
+
+	/* Ok no matching timings, maybe there's a free one? */
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		pll = &dev_priv->shared_dplls[i];
+		if (shared_dpll[i].crtc_mask == 0) {
+			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
+				      crtc->base.base.id, pll->name);
+			goto found;
+		}
+	}
+
+	return NULL;
+
+found:
+	if (shared_dpll[i].crtc_mask == 0)
+		shared_dpll[i].hw_state =
+			crtc_state->dpll_hw_state;
+
+	crtc_state->shared_dpll = i;
+	DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
+			 pipe_name(crtc->pipe));
+
+	shared_dpll[i].crtc_mask |= 1 << crtc->pipe;
+
+	return pll;
+}
+
+void intel_shared_dpll_commit(struct drm_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->dev);
+	struct intel_shared_dpll_config *shared_dpll;
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id i;
+
+	if (!to_intel_atomic_state(state)->dpll_set)
+		return;
+
+	shared_dpll = to_intel_atomic_state(state)->shared_dpll;
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		pll = &dev_priv->shared_dplls[i];
+		pll->config = shared_dpll[i];
+	}
+}
+
+static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv,
+				      struct intel_shared_dpll *pll,
+				      struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	val = I915_READ(PCH_DPLL(pll->id));
+	hw_state->dpll = val;
+	hw_state->fp0 = I915_READ(PCH_FP0(pll->id));
+	hw_state->fp1 = I915_READ(PCH_FP1(pll->id));
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return val & DPLL_VCO_ENABLE;
+}
+
+static void ibx_pch_dpll_mode_set(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll *pll)
+{
+	I915_WRITE(PCH_FP0(pll->id), pll->config.hw_state.fp0);
+	I915_WRITE(PCH_FP1(pll->id), pll->config.hw_state.fp1);
+}
+
+static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
+{
+	u32 val;
+	bool enabled;
+
+	I915_STATE_WARN_ON(!(HAS_PCH_IBX(dev_priv->dev) || HAS_PCH_CPT(dev_priv->dev)));
+
+	val = I915_READ(PCH_DREF_CONTROL);
+	enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK |
+			    DREF_SUPERSPREAD_SOURCE_MASK));
+	I915_STATE_WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n");
+}
+
+static void ibx_pch_dpll_enable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	/* PCH refclock must be enabled first */
+	ibx_assert_pch_refclk_enabled(dev_priv);
+
+	I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
+
+	/* Wait for the clocks to stabilize. */
+	POSTING_READ(PCH_DPLL(pll->id));
+	udelay(150);
+
+	/* The pixel multiplier can only be updated once the
+	 * DPLL is enabled and the clocks are stable.
+	 *
+	 * So write it again.
+	 */
+	I915_WRITE(PCH_DPLL(pll->id), pll->config.hw_state.dpll);
+	POSTING_READ(PCH_DPLL(pll->id));
+	udelay(200);
+}
+
+static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll)
+{
+	struct drm_device *dev = dev_priv->dev;
+	struct intel_crtc *crtc;
+
+	/* Make sure no transcoder isn't still depending on us. */
+	for_each_intel_crtc(dev, crtc) {
+		if (intel_crtc_to_shared_dpll(crtc) == pll)
+			assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
+	}
+
+	I915_WRITE(PCH_DPLL(pll->id), 0);
+	POSTING_READ(PCH_DPLL(pll->id));
+	udelay(200);
+}
+
+static char *ibx_pch_dpll_names[] = {
+	"PCH DPLL A",
+	"PCH DPLL B",
+};
+
+static void ibx_pch_dpll_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int i;
+
+	dev_priv->num_shared_dpll = 2;
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		dev_priv->shared_dplls[i].id = i;
+		dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
+		dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set;
+		dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
+		dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
+		dev_priv->shared_dplls[i].get_hw_state =
+			ibx_pch_dpll_get_hw_state;
+	}
+}
+
+void intel_shared_dpll_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (HAS_DDI(dev))
+		intel_ddi_pll_init(dev);
+	else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
+		ibx_pch_dpll_init(dev);
+	else
+		dev_priv->num_shared_dpll = 0;
+
+	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
+}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4c027d6..48716ba 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1144,6 +1144,9 @@ intel_rotation_90_or_270(unsigned int rotation)
 void intel_create_rotation_property(struct drm_device *dev,
 					struct intel_plane *plane);
 
+void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
+				    enum pipe pipe);
+
 /* shared dpll functions */
 struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
 void assert_shared_dpll(struct drm_i915_private *dev_priv,
@@ -1153,6 +1156,11 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
 #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
 struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 						struct intel_crtc_state *state);
+void intel_prepare_shared_dpll(struct intel_crtc *crtc);
+void intel_enable_shared_dpll(struct intel_crtc *crtc);
+void intel_disable_shared_dpll(struct intel_crtc *crtc);
+void intel_shared_dpll_commit(struct drm_atomic_state *state);
+void intel_shared_dpll_init(struct drm_device *dev);
 
 int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
 		     const struct dpll *dpll);
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/13] drm/i915: Move ddi shared dpll code to intel_dpll_mgr.c
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 01/13] drm/i915: Move shared dpll code to a new file Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 03/13] drm/i915: Split intel_get_shared_dpll() into smaller functions Ander Conselvan de Oliveira
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

No functional changes.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      | 472 ----------------------------------
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 472 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h      |   1 -
 3 files changed, 472 insertions(+), 473 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 21a9b83..eb6b55c 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2430,235 +2430,6 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
 	}
 }
 
-static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
-			       struct intel_shared_dpll *pll)
-{
-	I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
-	POSTING_READ(WRPLL_CTL(pll->id));
-	udelay(20);
-}
-
-static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
-				struct intel_shared_dpll *pll)
-{
-	I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
-	POSTING_READ(SPLL_CTL);
-	udelay(20);
-}
-
-static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
-				  struct intel_shared_dpll *pll)
-{
-	uint32_t val;
-
-	val = I915_READ(WRPLL_CTL(pll->id));
-	I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
-	POSTING_READ(WRPLL_CTL(pll->id));
-}
-
-static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
-				 struct intel_shared_dpll *pll)
-{
-	uint32_t val;
-
-	val = I915_READ(SPLL_CTL);
-	I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
-	POSTING_READ(SPLL_CTL);
-}
-
-static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
-				       struct intel_shared_dpll *pll,
-				       struct intel_dpll_hw_state *hw_state)
-{
-	uint32_t val;
-
-	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
-		return false;
-
-	val = I915_READ(WRPLL_CTL(pll->id));
-	hw_state->wrpll = val;
-
-	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-
-	return val & WRPLL_PLL_ENABLE;
-}
-
-static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
-				      struct intel_shared_dpll *pll,
-				      struct intel_dpll_hw_state *hw_state)
-{
-	uint32_t val;
-
-	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
-		return false;
-
-	val = I915_READ(SPLL_CTL);
-	hw_state->spll = val;
-
-	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-
-	return val & SPLL_PLL_ENABLE;
-}
-
-
-static const char * const hsw_ddi_pll_names[] = {
-	"WRPLL 1",
-	"WRPLL 2",
-	"SPLL"
-};
-
-static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
-{
-	int i;
-
-	dev_priv->num_shared_dpll = 3;
-
-	for (i = 0; i < 2; i++) {
-		dev_priv->shared_dplls[i].id = i;
-		dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
-		dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
-		dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
-		dev_priv->shared_dplls[i].get_hw_state =
-			hsw_ddi_wrpll_get_hw_state;
-	}
-
-	/* SPLL is special, but needs to be initialized anyway.. */
-	dev_priv->shared_dplls[i].id = i;
-	dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
-	dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
-	dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
-	dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
-
-}
-
-static const char * const skl_ddi_pll_names[] = {
-	"DPLL 1",
-	"DPLL 2",
-	"DPLL 3",
-};
-
-struct skl_dpll_regs {
-	i915_reg_t ctl, cfgcr1, cfgcr2;
-};
-
-/* this array is indexed by the *shared* pll id */
-static const struct skl_dpll_regs skl_dpll_regs[3] = {
-	{
-		/* DPLL 1 */
-		.ctl = LCPLL2_CTL,
-		.cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
-		.cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
-	},
-	{
-		/* DPLL 2 */
-		.ctl = WRPLL_CTL(0),
-		.cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
-		.cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
-	},
-	{
-		/* DPLL 3 */
-		.ctl = WRPLL_CTL(1),
-		.cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
-		.cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
-	},
-};
-
-static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
-			       struct intel_shared_dpll *pll)
-{
-	uint32_t val;
-	unsigned int dpll;
-	const struct skl_dpll_regs *regs = skl_dpll_regs;
-
-	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
-	dpll = pll->id + 1;
-
-	val = I915_READ(DPLL_CTRL1);
-
-	val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
-		 DPLL_CTRL1_LINK_RATE_MASK(dpll));
-	val |= pll->config.hw_state.ctrl1 << (dpll * 6);
-
-	I915_WRITE(DPLL_CTRL1, val);
-	POSTING_READ(DPLL_CTRL1);
-
-	I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
-	I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
-	POSTING_READ(regs[pll->id].cfgcr1);
-	POSTING_READ(regs[pll->id].cfgcr2);
-
-	/* the enable bit is always bit 31 */
-	I915_WRITE(regs[pll->id].ctl,
-		   I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
-
-	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
-		DRM_ERROR("DPLL %d not locked\n", dpll);
-}
-
-static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
-				struct intel_shared_dpll *pll)
-{
-	const struct skl_dpll_regs *regs = skl_dpll_regs;
-
-	/* the enable bit is always bit 31 */
-	I915_WRITE(regs[pll->id].ctl,
-		   I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
-	POSTING_READ(regs[pll->id].ctl);
-}
-
-static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
-				     struct intel_shared_dpll *pll,
-				     struct intel_dpll_hw_state *hw_state)
-{
-	uint32_t val;
-	unsigned int dpll;
-	const struct skl_dpll_regs *regs = skl_dpll_regs;
-	bool ret;
-
-	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
-		return false;
-
-	ret = false;
-
-	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
-	dpll = pll->id + 1;
-
-	val = I915_READ(regs[pll->id].ctl);
-	if (!(val & LCPLL_PLL_ENABLE))
-		goto out;
-
-	val = I915_READ(DPLL_CTRL1);
-	hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
-
-	/* avoid reading back stale values if HDMI mode is not enabled */
-	if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
-		hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
-		hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
-	}
-	ret = true;
-
-out:
-	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-
-	return ret;
-}
-
-static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
-{
-	int i;
-
-	dev_priv->num_shared_dpll = 3;
-
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		dev_priv->shared_dplls[i].id = i;
-		dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
-		dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
-		dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
-		dev_priv->shared_dplls[i].get_hw_state =
-			skl_ddi_pll_get_hw_state;
-	}
-}
-
 static void broxton_phy_init(struct drm_i915_private *dev_priv,
 			     enum dpio_phy phy)
 {
@@ -2783,249 +2554,6 @@ void broxton_ddi_phy_uninit(struct drm_device *dev)
 	I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
 }
 
-static const char * const bxt_ddi_pll_names[] = {
-	"PORT PLL A",
-	"PORT PLL B",
-	"PORT PLL C",
-};
-
-static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
-				struct intel_shared_dpll *pll)
-{
-	uint32_t temp;
-	enum port port = (enum port)pll->id;	/* 1:1 port->PLL mapping */
-
-	temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
-	temp &= ~PORT_PLL_REF_SEL;
-	/* Non-SSC reference */
-	I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
-
-	/* Disable 10 bit clock */
-	temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
-	temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
-	I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
-
-	/* Write P1 & P2 */
-	temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
-	temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
-	temp |= pll->config.hw_state.ebb0;
-	I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
-
-	/* Write M2 integer */
-	temp = I915_READ(BXT_PORT_PLL(port, 0));
-	temp &= ~PORT_PLL_M2_MASK;
-	temp |= pll->config.hw_state.pll0;
-	I915_WRITE(BXT_PORT_PLL(port, 0), temp);
-
-	/* Write N */
-	temp = I915_READ(BXT_PORT_PLL(port, 1));
-	temp &= ~PORT_PLL_N_MASK;
-	temp |= pll->config.hw_state.pll1;
-	I915_WRITE(BXT_PORT_PLL(port, 1), temp);
-
-	/* Write M2 fraction */
-	temp = I915_READ(BXT_PORT_PLL(port, 2));
-	temp &= ~PORT_PLL_M2_FRAC_MASK;
-	temp |= pll->config.hw_state.pll2;
-	I915_WRITE(BXT_PORT_PLL(port, 2), temp);
-
-	/* Write M2 fraction enable */
-	temp = I915_READ(BXT_PORT_PLL(port, 3));
-	temp &= ~PORT_PLL_M2_FRAC_ENABLE;
-	temp |= pll->config.hw_state.pll3;
-	I915_WRITE(BXT_PORT_PLL(port, 3), temp);
-
-	/* Write coeff */
-	temp = I915_READ(BXT_PORT_PLL(port, 6));
-	temp &= ~PORT_PLL_PROP_COEFF_MASK;
-	temp &= ~PORT_PLL_INT_COEFF_MASK;
-	temp &= ~PORT_PLL_GAIN_CTL_MASK;
-	temp |= pll->config.hw_state.pll6;
-	I915_WRITE(BXT_PORT_PLL(port, 6), temp);
-
-	/* Write calibration val */
-	temp = I915_READ(BXT_PORT_PLL(port, 8));
-	temp &= ~PORT_PLL_TARGET_CNT_MASK;
-	temp |= pll->config.hw_state.pll8;
-	I915_WRITE(BXT_PORT_PLL(port, 8), temp);
-
-	temp = I915_READ(BXT_PORT_PLL(port, 9));
-	temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
-	temp |= pll->config.hw_state.pll9;
-	I915_WRITE(BXT_PORT_PLL(port, 9), temp);
-
-	temp = I915_READ(BXT_PORT_PLL(port, 10));
-	temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
-	temp &= ~PORT_PLL_DCO_AMP_MASK;
-	temp |= pll->config.hw_state.pll10;
-	I915_WRITE(BXT_PORT_PLL(port, 10), temp);
-
-	/* Recalibrate with new settings */
-	temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
-	temp |= PORT_PLL_RECALIBRATE;
-	I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
-	temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
-	temp |= pll->config.hw_state.ebb4;
-	I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
-
-	/* Enable PLL */
-	temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
-	temp |= PORT_PLL_ENABLE;
-	I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
-	POSTING_READ(BXT_PORT_PLL_ENABLE(port));
-
-	if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
-			PORT_PLL_LOCK), 200))
-		DRM_ERROR("PLL %d not locked\n", port);
-
-	/*
-	 * While we write to the group register to program all lanes at once we
-	 * can read only lane registers and we pick lanes 0/1 for that.
-	 */
-	temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
-	temp &= ~LANE_STAGGER_MASK;
-	temp &= ~LANESTAGGER_STRAP_OVRD;
-	temp |= pll->config.hw_state.pcsdw12;
-	I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
-}
-
-static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
-					struct intel_shared_dpll *pll)
-{
-	enum port port = (enum port)pll->id;	/* 1:1 port->PLL mapping */
-	uint32_t temp;
-
-	temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
-	temp &= ~PORT_PLL_ENABLE;
-	I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
-	POSTING_READ(BXT_PORT_PLL_ENABLE(port));
-}
-
-static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
-					struct intel_shared_dpll *pll,
-					struct intel_dpll_hw_state *hw_state)
-{
-	enum port port = (enum port)pll->id;	/* 1:1 port->PLL mapping */
-	uint32_t val;
-	bool ret;
-
-	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
-		return false;
-
-	ret = false;
-
-	val = I915_READ(BXT_PORT_PLL_ENABLE(port));
-	if (!(val & PORT_PLL_ENABLE))
-		goto out;
-
-	hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
-	hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
-
-	hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
-	hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
-
-	hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
-	hw_state->pll0 &= PORT_PLL_M2_MASK;
-
-	hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
-	hw_state->pll1 &= PORT_PLL_N_MASK;
-
-	hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
-	hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
-
-	hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
-	hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
-
-	hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
-	hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
-			  PORT_PLL_INT_COEFF_MASK |
-			  PORT_PLL_GAIN_CTL_MASK;
-
-	hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
-	hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
-
-	hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
-	hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
-
-	hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
-	hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
-			   PORT_PLL_DCO_AMP_MASK;
-
-	/*
-	 * While we write to the group register to program all lanes at once we
-	 * can read only lane registers. We configure all lanes the same way, so
-	 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
-	 */
-	hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
-	if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
-		DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
-				 hw_state->pcsdw12,
-				 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
-	hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
-
-	ret = true;
-
-out:
-	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
-
-	return ret;
-}
-
-static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
-{
-	int i;
-
-	dev_priv->num_shared_dpll = 3;
-
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		dev_priv->shared_dplls[i].id = i;
-		dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
-		dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
-		dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
-		dev_priv->shared_dplls[i].get_hw_state =
-			bxt_ddi_pll_get_hw_state;
-	}
-}
-
-void intel_ddi_pll_init(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	uint32_t val = I915_READ(LCPLL_CTL);
-
-	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
-		skl_shared_dplls_init(dev_priv);
-	else if (IS_BROXTON(dev))
-		bxt_shared_dplls_init(dev_priv);
-	else
-		hsw_shared_dplls_init(dev_priv);
-
-	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
-		int cdclk_freq;
-
-		cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
-		dev_priv->skl_boot_cdclk = cdclk_freq;
-		if (skl_sanitize_cdclk(dev_priv))
-			DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
-		if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
-			DRM_ERROR("LCPLL1 is disabled\n");
-	} else if (IS_BROXTON(dev)) {
-		broxton_init_cdclk(dev);
-		broxton_ddi_phy_init(dev);
-	} else {
-		/*
-		 * The LCPLL register should be turned on by the BIOS. For now
-		 * let's just check its state and print errors in case
-		 * something is wrong.  Don't even try to turn it on.
-		 */
-
-		if (val & LCPLL_CD_SOURCE_FCLK)
-			DRM_ERROR("CDCLK source is not LCPLL\n");
-
-		if (val & LCPLL_PLL_DISABLE)
-			DRM_ERROR("LCPLL is disabled\n");
-	}
-}
-
 void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index d7ebac6..6be0cd0 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -353,6 +353,478 @@ static void ibx_pch_dpll_init(struct drm_device *dev)
 	}
 }
 
+static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
+			       struct intel_shared_dpll *pll)
+{
+	I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
+	POSTING_READ(WRPLL_CTL(pll->id));
+	udelay(20);
+}
+
+static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
+	POSTING_READ(SPLL_CTL);
+	udelay(20);
+}
+
+static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll *pll)
+{
+	uint32_t val;
+
+	val = I915_READ(WRPLL_CTL(pll->id));
+	I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
+	POSTING_READ(WRPLL_CTL(pll->id));
+}
+
+static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll)
+{
+	uint32_t val;
+
+	val = I915_READ(SPLL_CTL);
+	I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
+	POSTING_READ(SPLL_CTL);
+}
+
+static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
+				       struct intel_shared_dpll *pll,
+				       struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	val = I915_READ(WRPLL_CTL(pll->id));
+	hw_state->wrpll = val;
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return val & WRPLL_PLL_ENABLE;
+}
+
+static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
+				      struct intel_shared_dpll *pll,
+				      struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	val = I915_READ(SPLL_CTL);
+	hw_state->spll = val;
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return val & SPLL_PLL_ENABLE;
+}
+
+
+static const char * const hsw_ddi_pll_names[] = {
+	"WRPLL 1",
+	"WRPLL 2",
+	"SPLL"
+};
+
+static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
+{
+	int i;
+
+	dev_priv->num_shared_dpll = 3;
+
+	for (i = 0; i < 2; i++) {
+		dev_priv->shared_dplls[i].id = i;
+		dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
+		dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
+		dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
+		dev_priv->shared_dplls[i].get_hw_state =
+			hsw_ddi_wrpll_get_hw_state;
+	}
+
+	/* SPLL is special, but needs to be initialized anyway.. */
+	dev_priv->shared_dplls[i].id = i;
+	dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
+	dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
+	dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
+	dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
+
+}
+
+static const char * const skl_ddi_pll_names[] = {
+	"DPLL 1",
+	"DPLL 2",
+	"DPLL 3",
+};
+
+struct skl_dpll_regs {
+	i915_reg_t ctl, cfgcr1, cfgcr2;
+};
+
+/* this array is indexed by the *shared* pll id */
+static const struct skl_dpll_regs skl_dpll_regs[3] = {
+	{
+		/* DPLL 1 */
+		.ctl = LCPLL2_CTL,
+		.cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
+		.cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
+	},
+	{
+		/* DPLL 2 */
+		.ctl = WRPLL_CTL(0),
+		.cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
+		.cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
+	},
+	{
+		/* DPLL 3 */
+		.ctl = WRPLL_CTL(1),
+		.cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
+		.cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
+	},
+};
+
+static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
+			       struct intel_shared_dpll *pll)
+{
+	uint32_t val;
+	unsigned int dpll;
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+
+	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
+	dpll = pll->id + 1;
+
+	val = I915_READ(DPLL_CTRL1);
+
+	val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
+		 DPLL_CTRL1_LINK_RATE_MASK(dpll));
+	val |= pll->config.hw_state.ctrl1 << (dpll * 6);
+
+	I915_WRITE(DPLL_CTRL1, val);
+	POSTING_READ(DPLL_CTRL1);
+
+	I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
+	I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
+	POSTING_READ(regs[pll->id].cfgcr1);
+	POSTING_READ(regs[pll->id].cfgcr2);
+
+	/* the enable bit is always bit 31 */
+	I915_WRITE(regs[pll->id].ctl,
+		   I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
+
+	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
+		DRM_ERROR("DPLL %d not locked\n", dpll);
+}
+
+static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+
+	/* the enable bit is always bit 31 */
+	I915_WRITE(regs[pll->id].ctl,
+		   I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
+	POSTING_READ(regs[pll->id].ctl);
+}
+
+static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
+				     struct intel_shared_dpll *pll,
+				     struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+	unsigned int dpll;
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+	bool ret;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	ret = false;
+
+	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
+	dpll = pll->id + 1;
+
+	val = I915_READ(regs[pll->id].ctl);
+	if (!(val & LCPLL_PLL_ENABLE))
+		goto out;
+
+	val = I915_READ(DPLL_CTRL1);
+	hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
+
+	/* avoid reading back stale values if HDMI mode is not enabled */
+	if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
+		hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
+		hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
+	}
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return ret;
+}
+
+static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
+{
+	int i;
+
+	dev_priv->num_shared_dpll = 3;
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		dev_priv->shared_dplls[i].id = i;
+		dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
+		dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
+		dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
+		dev_priv->shared_dplls[i].get_hw_state =
+			skl_ddi_pll_get_hw_state;
+	}
+}
+
+static const char * const bxt_ddi_pll_names[] = {
+	"PORT PLL A",
+	"PORT PLL B",
+	"PORT PLL C",
+};
+
+static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
+				struct intel_shared_dpll *pll)
+{
+	uint32_t temp;
+	enum port port = (enum port)pll->id;	/* 1:1 port->PLL mapping */
+
+	temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
+	temp &= ~PORT_PLL_REF_SEL;
+	/* Non-SSC reference */
+	I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
+
+	/* Disable 10 bit clock */
+	temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
+	temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
+	I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
+
+	/* Write P1 & P2 */
+	temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
+	temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
+	temp |= pll->config.hw_state.ebb0;
+	I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
+
+	/* Write M2 integer */
+	temp = I915_READ(BXT_PORT_PLL(port, 0));
+	temp &= ~PORT_PLL_M2_MASK;
+	temp |= pll->config.hw_state.pll0;
+	I915_WRITE(BXT_PORT_PLL(port, 0), temp);
+
+	/* Write N */
+	temp = I915_READ(BXT_PORT_PLL(port, 1));
+	temp &= ~PORT_PLL_N_MASK;
+	temp |= pll->config.hw_state.pll1;
+	I915_WRITE(BXT_PORT_PLL(port, 1), temp);
+
+	/* Write M2 fraction */
+	temp = I915_READ(BXT_PORT_PLL(port, 2));
+	temp &= ~PORT_PLL_M2_FRAC_MASK;
+	temp |= pll->config.hw_state.pll2;
+	I915_WRITE(BXT_PORT_PLL(port, 2), temp);
+
+	/* Write M2 fraction enable */
+	temp = I915_READ(BXT_PORT_PLL(port, 3));
+	temp &= ~PORT_PLL_M2_FRAC_ENABLE;
+	temp |= pll->config.hw_state.pll3;
+	I915_WRITE(BXT_PORT_PLL(port, 3), temp);
+
+	/* Write coeff */
+	temp = I915_READ(BXT_PORT_PLL(port, 6));
+	temp &= ~PORT_PLL_PROP_COEFF_MASK;
+	temp &= ~PORT_PLL_INT_COEFF_MASK;
+	temp &= ~PORT_PLL_GAIN_CTL_MASK;
+	temp |= pll->config.hw_state.pll6;
+	I915_WRITE(BXT_PORT_PLL(port, 6), temp);
+
+	/* Write calibration val */
+	temp = I915_READ(BXT_PORT_PLL(port, 8));
+	temp &= ~PORT_PLL_TARGET_CNT_MASK;
+	temp |= pll->config.hw_state.pll8;
+	I915_WRITE(BXT_PORT_PLL(port, 8), temp);
+
+	temp = I915_READ(BXT_PORT_PLL(port, 9));
+	temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
+	temp |= pll->config.hw_state.pll9;
+	I915_WRITE(BXT_PORT_PLL(port, 9), temp);
+
+	temp = I915_READ(BXT_PORT_PLL(port, 10));
+	temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
+	temp &= ~PORT_PLL_DCO_AMP_MASK;
+	temp |= pll->config.hw_state.pll10;
+	I915_WRITE(BXT_PORT_PLL(port, 10), temp);
+
+	/* Recalibrate with new settings */
+	temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
+	temp |= PORT_PLL_RECALIBRATE;
+	I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
+	temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
+	temp |= pll->config.hw_state.ebb4;
+	I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
+
+	/* Enable PLL */
+	temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
+	temp |= PORT_PLL_ENABLE;
+	I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
+	POSTING_READ(BXT_PORT_PLL_ENABLE(port));
+
+	if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
+			PORT_PLL_LOCK), 200))
+		DRM_ERROR("PLL %d not locked\n", port);
+
+	/*
+	 * While we write to the group register to program all lanes at once we
+	 * can read only lane registers and we pick lanes 0/1 for that.
+	 */
+	temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
+	temp &= ~LANE_STAGGER_MASK;
+	temp &= ~LANESTAGGER_STRAP_OVRD;
+	temp |= pll->config.hw_state.pcsdw12;
+	I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
+}
+
+static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
+					struct intel_shared_dpll *pll)
+{
+	enum port port = (enum port)pll->id;	/* 1:1 port->PLL mapping */
+	uint32_t temp;
+
+	temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
+	temp &= ~PORT_PLL_ENABLE;
+	I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
+	POSTING_READ(BXT_PORT_PLL_ENABLE(port));
+}
+
+static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
+					struct intel_shared_dpll *pll,
+					struct intel_dpll_hw_state *hw_state)
+{
+	enum port port = (enum port)pll->id;	/* 1:1 port->PLL mapping */
+	uint32_t val;
+	bool ret;
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	ret = false;
+
+	val = I915_READ(BXT_PORT_PLL_ENABLE(port));
+	if (!(val & PORT_PLL_ENABLE))
+		goto out;
+
+	hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
+	hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
+
+	hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
+	hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
+
+	hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
+	hw_state->pll0 &= PORT_PLL_M2_MASK;
+
+	hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
+	hw_state->pll1 &= PORT_PLL_N_MASK;
+
+	hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
+	hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
+
+	hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
+	hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
+
+	hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
+	hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
+			  PORT_PLL_INT_COEFF_MASK |
+			  PORT_PLL_GAIN_CTL_MASK;
+
+	hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
+	hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
+
+	hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
+	hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
+
+	hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
+	hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
+			   PORT_PLL_DCO_AMP_MASK;
+
+	/*
+	 * While we write to the group register to program all lanes at once we
+	 * can read only lane registers. We configure all lanes the same way, so
+	 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
+	 */
+	hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
+	if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
+		DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
+				 hw_state->pcsdw12,
+				 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
+	hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
+
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return ret;
+}
+
+static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
+{
+	int i;
+
+	dev_priv->num_shared_dpll = 3;
+
+	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+		dev_priv->shared_dplls[i].id = i;
+		dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
+		dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
+		dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
+		dev_priv->shared_dplls[i].get_hw_state =
+			bxt_ddi_pll_get_hw_state;
+	}
+}
+
+static void intel_ddi_pll_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t val = I915_READ(LCPLL_CTL);
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+		skl_shared_dplls_init(dev_priv);
+	else if (IS_BROXTON(dev))
+		bxt_shared_dplls_init(dev_priv);
+	else
+		hsw_shared_dplls_init(dev_priv);
+
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
+		int cdclk_freq;
+
+		cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
+		dev_priv->skl_boot_cdclk = cdclk_freq;
+		if (skl_sanitize_cdclk(dev_priv))
+			DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
+		if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
+			DRM_ERROR("LCPLL1 is disabled\n");
+	} else if (IS_BROXTON(dev)) {
+		broxton_init_cdclk(dev);
+		broxton_ddi_phy_init(dev);
+	} else {
+		/*
+		 * The LCPLL register should be turned on by the BIOS. For now
+		 * let's just check its state and print errors in case
+		 * something is wrong.  Don't even try to turn it on.
+		 */
+
+		if (val & LCPLL_CD_SOURCE_FCLK)
+			DRM_ERROR("CDCLK source is not LCPLL\n");
+
+		if (val & LCPLL_PLL_DISABLE)
+			DRM_ERROR("LCPLL is disabled\n");
+	}
+}
+
 void intel_shared_dpll_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 48716ba..96e84d3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1007,7 +1007,6 @@ 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);
 bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe);
-void intel_ddi_pll_init(struct drm_device *dev);
 void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc);
 void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
 				       enum transcoder cpu_transcoder);
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/13] drm/i915: Split intel_get_shared_dpll() into smaller functions
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 01/13] drm/i915: Move shared dpll code to a new file Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 02/13] drm/i915: Move ddi shared dpll code to intel_dpll_mgr.c Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 04/13] drm/i915: Store a direct pointer to shared dpll in intel_crtc_state Ander Conselvan de Oliveira
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Make the code neater by splitting the code for platforms with fixed PLL
to their own functions and splitting the logic for finding a shareable
or unused pll from the logic for setting it up.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 109 +++++++++++++++++++++++-----------
 1 file changed, 74 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 6be0cd0..11effe3 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -145,52 +145,65 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
 	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
 }
 
-struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
-						struct intel_crtc_state *crtc_state)
+static enum intel_dpll_id
+ibx_get_fixed_dpll(struct intel_crtc *crtc,
+		   struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_shared_dpll *pll;
-	struct intel_shared_dpll_config *shared_dpll;
 	enum intel_dpll_id i;
-	int max = dev_priv->num_shared_dpll;
 
-	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
+	/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
+	i = (enum intel_dpll_id) crtc->pipe;
+	pll = &dev_priv->shared_dplls[i];
 
-	if (HAS_PCH_IBX(dev_priv->dev)) {
-		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
-		i = (enum intel_dpll_id) crtc->pipe;
-		pll = &dev_priv->shared_dplls[i];
+	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
+		      crtc->base.base.id, pll->name);
 
-		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
-			      crtc->base.base.id, pll->name);
+	return i;
+}
 
-		WARN_ON(shared_dpll[i].crtc_mask);
+static enum intel_dpll_id
+bxt_get_fixed_dpll(struct intel_crtc *crtc,
+		   struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_encoder *encoder;
+	struct intel_digital_port *intel_dig_port;
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id i;
 
-		goto found;
-	}
+	/* PLL is attached to port in bxt */
+	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
+	if (WARN_ON(!encoder))
+		return DPLL_ID_PRIVATE;
 
-	if (IS_BROXTON(dev_priv->dev)) {
-		/* PLL is attached to port in bxt */
-		struct intel_encoder *encoder;
-		struct intel_digital_port *intel_dig_port;
+	intel_dig_port = enc_to_dig_port(&encoder->base);
+	/* 1:1 mapping between ports and PLLs */
+	i = (enum intel_dpll_id)intel_dig_port->port;
+	pll = &dev_priv->shared_dplls[i];
+	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
+		crtc->base.base.id, pll->name);
 
-		encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
-		if (WARN_ON(!encoder))
-			return NULL;
+	return i;
+}
 
-		intel_dig_port = enc_to_dig_port(&encoder->base);
-		/* 1:1 mapping between ports and PLLs */
-		i = (enum intel_dpll_id)intel_dig_port->port;
-		pll = &dev_priv->shared_dplls[i];
-		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
-			crtc->base.base.id, pll->name);
-		WARN_ON(shared_dpll[i].crtc_mask);
+static enum intel_dpll_id
+intel_find_shared_dpll(struct intel_crtc *crtc,
+		       struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_shared_dpll *pll;
+	struct intel_shared_dpll_config *shared_dpll;
+	enum intel_dpll_id i;
+	int max = dev_priv->num_shared_dpll;
 
-		goto found;
-	} else if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
+	if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
 		/* Do not consider SPLL */
 		max = 2;
 
+	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
+
 	for (i = 0; i < max; i++) {
 		pll = &dev_priv->shared_dplls[i];
 
@@ -205,7 +218,7 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 				      crtc->base.base.id, pll->name,
 				      shared_dpll[i].crtc_mask,
 				      pll->active);
-			goto found;
+			return i;
 		}
 	}
 
@@ -215,13 +228,39 @@ struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
 		if (shared_dpll[i].crtc_mask == 0) {
 			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
 				      crtc->base.base.id, pll->name);
-			goto found;
+			return i;
 		}
 	}
 
-	return NULL;
+	return DPLL_ID_PRIVATE;
+}
+
+struct intel_shared_dpll *
+intel_get_shared_dpll(struct intel_crtc *crtc,
+		      struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	struct intel_shared_dpll *pll;
+	struct intel_shared_dpll_config *shared_dpll;
+	enum intel_dpll_id i;
+
+	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
+
+	if (HAS_PCH_IBX(dev_priv->dev)) {
+		i = ibx_get_fixed_dpll(crtc, crtc_state);
+		WARN_ON(shared_dpll[i].crtc_mask);
+	} else if (IS_BROXTON(dev_priv->dev)) {
+		i = bxt_get_fixed_dpll(crtc, crtc_state);
+		WARN_ON(shared_dpll[i].crtc_mask);
+	} else {
+		i = intel_find_shared_dpll(crtc, crtc_state);
+	}
+
+	if (i < 0)
+		return NULL;
+
+	pll = &dev_priv->shared_dplls[i];
 
-found:
 	if (shared_dpll[i].crtc_mask == 0)
 		shared_dpll[i].hw_state =
 			crtc_state->dpll_hw_state;
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/13] drm/i915: Store a direct pointer to shared dpll in intel_crtc_state
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (2 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 03/13] drm/i915: Split intel_get_shared_dpll() into smaller functions Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 05/13] drm/i915: Move shared dpll struct definitions to separate header file Ander Conselvan de Oliveira
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Change the type of intel_crtc_state->shared_dpll to be a pointer to a
shared dpll. With this there is no need to first convert the id stored
in the crtc state to a pointer in order to use it. It does introduce a
bit of hassle on doing the opposite.

The long term objective is to hide details about dpll ids behind the
shared dpll interface.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      |   4 +-
 drivers/gpu/drm/i915/intel_display.c  | 108 ++++++++++++++++++++++------------
 drivers/gpu/drm/i915/intel_dpll_mgr.c |  51 ++++++++++++----
 drivers/gpu/drm/i915/intel_drv.h      |  19 +++++-
 drivers/gpu/drm/i915/intel_lvds.c     |   2 +-
 5 files changed, 132 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index eb6b55c..a2b33d0 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1209,6 +1209,7 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
 		   struct intel_crtc_state *crtc_state,
 		   struct intel_encoder *intel_encoder)
 {
+	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
 	int clock = crtc_state->port_clock;
 
 	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
@@ -1244,7 +1245,8 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
 		    WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
 			return false;
 
-		crtc_state->shared_dpll = DPLL_ID_SPLL;
+		crtc_state->shared_dpll =
+			intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_SPLL);
 		spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
 		spll->crtc_mask |= 1 << intel_crtc->pipe;
 	}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index df49324..e723323 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1828,8 +1828,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
 	BUG_ON(!HAS_PCH_SPLIT(dev));
 
 	/* Make sure PCH DPLL is enabled */
-	assert_shared_dpll_enabled(dev_priv,
-				   intel_crtc_to_shared_dpll(intel_crtc));
+	assert_shared_dpll_enabled(dev_priv, intel_crtc->config->shared_dpll);
 
 	/* FDI must be feeding us bits for PCH ports */
 	assert_fdi_tx_enabled(dev_priv, pipe);
@@ -4024,7 +4023,8 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
 		temp = I915_READ(PCH_DPLL_SEL);
 		temp |= TRANS_DPLL_ENABLE(pipe);
 		sel = TRANS_DPLLB_SEL(pipe);
-		if (intel_crtc->config->shared_dpll == DPLL_ID_PCH_PLL_B)
+		if (intel_crtc->config->shared_dpll ==
+		    intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_PCH_PLL_B))
 			temp |= sel;
 		else
 			temp &= ~sel;
@@ -4724,7 +4724,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 		intel_set_pch_fifo_underrun_reporting(dev_priv, TRANSCODER_A,
 						      false);
 
-	if (intel_crtc_to_shared_dpll(intel_crtc))
+	if (intel_crtc->config->shared_dpll)
 		intel_enable_shared_dpll(intel_crtc);
 
 	if (intel_crtc->config->has_dp_encoder)
@@ -7891,7 +7891,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 		return false;
 
 	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
-	pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+	pipe_config->shared_dpll = NULL;
 
 	ret = false;
 
@@ -9095,7 +9095,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
 		return false;
 
 	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
-	pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+	pipe_config->shared_dpll = NULL;
 
 	ret = false;
 	tmp = I915_READ(PIPECONF(crtc->pipe));
@@ -9124,6 +9124,7 @@ 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;
 
@@ -9134,17 +9135,18 @@ 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->dev)) {
-			pipe_config->shared_dpll =
-				(enum intel_dpll_id) crtc->pipe;
+			pll_id = (enum intel_dpll_id) crtc->pipe;
 		} else {
 			tmp = I915_READ(PCH_DPLL_SEL);
 			if (tmp & TRANS_DPLLB_SEL(crtc->pipe))
-				pipe_config->shared_dpll = DPLL_ID_PCH_PLL_B;
+				pll_id = DPLL_ID_PCH_PLL_B;
 			else
-				pipe_config->shared_dpll = DPLL_ID_PCH_PLL_A;
+				pll_id= DPLL_ID_PCH_PLL_A;
 		}
 
-		pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
+		pipe_config->shared_dpll =
+			intel_get_shared_dpll_by_id(dev_priv, pll_id);
+		pll = pipe_config->shared_dpll;
 
 		WARN_ON(!pll->get_hw_state(dev_priv, pll,
 					   &pipe_config->dpll_hw_state));
@@ -9580,28 +9582,34 @@ 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:
 		pipe_config->ddi_pll_sel = SKL_DPLL0;
-		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
+		id = DPLL_ID_SKL_DPLL1;
 		break;
 	case PORT_B:
 		pipe_config->ddi_pll_sel = SKL_DPLL1;
-		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
+		id = DPLL_ID_SKL_DPLL2;
 		break;
 	case PORT_C:
 		pipe_config->ddi_pll_sel = SKL_DPLL2;
-		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
+		id = DPLL_ID_SKL_DPLL3;
 		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, dpll_ctl1;
 
 	temp = I915_READ(DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_SEL_MASK(port);
@@ -9616,36 +9624,53 @@ static void skylake_get_ddi_pll(struct drm_i915_private *dev_priv,
 		 */
 		dpll_ctl1 = I915_READ(DPLL_CTRL1);
 		pipe_config->dpll_hw_state.ctrl1 = dpll_ctl1 & 0x3f;
-		break;
+		return;
 	case SKL_DPLL1:
-		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL1;
+		id = DPLL_ID_SKL_DPLL1;
 		break;
 	case SKL_DPLL2:
-		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL2;
+		id = DPLL_ID_SKL_DPLL2;
 		break;
 	case SKL_DPLL3:
-		pipe_config->shared_dpll = DPLL_ID_SKL_DPLL3;
+		id = DPLL_ID_SKL_DPLL3;
 		break;
+	default:
+		MISSING_CASE(pipe_config->ddi_pll_sel);
+		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;
+
 	pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port));
 
 	switch (pipe_config->ddi_pll_sel) {
 	case PORT_CLK_SEL_WRPLL1:
-		pipe_config->shared_dpll = DPLL_ID_WRPLL1;
+		id = DPLL_ID_WRPLL1;
 		break;
 	case PORT_CLK_SEL_WRPLL2:
-		pipe_config->shared_dpll = DPLL_ID_WRPLL2;
+		id = DPLL_ID_WRPLL2;
 		break;
 	case PORT_CLK_SEL_SPLL:
-		pipe_config->shared_dpll = DPLL_ID_SPLL;
+		id = DPLL_ID_SPLL;
 		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;
 	}
+
+	pipe_config->shared_dpll = intel_get_shared_dpll_by_id(dev_priv, id);
 }
 
 static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
@@ -9668,9 +9693,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
 	else
 		haswell_get_ddi_pll(dev_priv, port, pipe_config);
 
-	if (pipe_config->shared_dpll >= 0) {
-		pll = &dev_priv->shared_dplls[pipe_config->shared_dpll];
-
+	pll = pipe_config->shared_dpll;
+	if (pll) {
 		WARN_ON(!pll->get_hw_state(dev_priv, pll,
 					   &pipe_config->dpll_hw_state));
 	}
@@ -9710,7 +9734,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 	ret = false;
 
 	pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
-	pipe_config->shared_dpll = DPLL_ID_PRIVATE;
+	pipe_config->shared_dpll = NULL;
 
 	tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
 	if (tmp & TRANS_DDI_FUNC_ENABLE) {
@@ -11702,7 +11726,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 
 	if (mode_changed && crtc_state->enable &&
 	    dev_priv->display.crtc_compute_clock &&
-	    !WARN_ON(pipe_config->shared_dpll != DPLL_ID_PRIVATE)) {
+	    !WARN_ON(pipe_config->shared_dpll)) {
 		ret = dev_priv->display.crtc_compute_clock(intel_crtc,
 							   pipe_config);
 		if (ret)
@@ -12026,7 +12050,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	struct drm_crtc_state tmp_state;
 	struct intel_crtc_scaler_state scaler_state;
 	struct intel_dpll_hw_state dpll_hw_state;
-	enum intel_dpll_id shared_dpll;
+	struct intel_shared_dpll *shared_dpll;
 	uint32_t ddi_pll_sel;
 	bool force_thru;
 
@@ -12296,6 +12320,15 @@ intel_pipe_config_compare(struct drm_device *dev,
 		ret = false; \
 	}
 
+#define PIPE_CONF_CHECK_P(name)	\
+	if (current_config->name != pipe_config->name) { \
+		INTEL_ERR_OR_DBG_KMS("mismatch in " #name " " \
+			  "(expected %p, found %p)\n", \
+			  current_config->name, \
+			  pipe_config->name); \
+		ret = false; \
+	}
+
 #define PIPE_CONF_CHECK_M_N(name) \
 	if (!intel_compare_link_m_n(&current_config->name, \
 				    &pipe_config->name,\
@@ -12463,7 +12496,7 @@ intel_pipe_config_compare(struct drm_device *dev,
 
 	PIPE_CONF_CHECK_X(ddi_pll_sel);
 
-	PIPE_CONF_CHECK_I(shared_dpll);
+	PIPE_CONF_CHECK_P(shared_dpll);
 	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
 	PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
 	PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
@@ -12482,6 +12515,7 @@ intel_pipe_config_compare(struct drm_device *dev,
 
 #undef PIPE_CONF_CHECK_X
 #undef PIPE_CONF_CHECK_I
+#undef PIPE_CONF_CHECK_P
 #undef PIPE_CONF_CHECK_I_ALT
 #undef PIPE_CONF_CHECK_FLAGS
 #undef PIPE_CONF_CHECK_CLOCK_FUZZY
@@ -12685,7 +12719,8 @@ check_shared_dpll_state(struct drm_device *dev)
 	int i;
 
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
+		struct intel_shared_dpll *pll =
+			intel_get_shared_dpll_by_id(dev_priv, i);
 		int enabled_crtcs = 0, active_crtcs = 0;
 		bool active;
 
@@ -12707,9 +12742,9 @@ check_shared_dpll_state(struct drm_device *dev)
 		     pll->on, active);
 
 		for_each_intel_crtc(dev, crtc) {
-			if (crtc->base.state->enable && intel_crtc_to_shared_dpll(crtc) == pll)
+			if (crtc->base.state->enable && crtc->config->shared_dpll == pll)
 				enabled_crtcs++;
-			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll)
+			if (crtc->active && crtc->config->shared_dpll == pll)
 				active_crtcs++;
 		}
 		I915_STATE_WARN(pll->active != active_crtcs,
@@ -12800,20 +12835,21 @@ static void intel_modeset_clear_plls(struct drm_atomic_state *state)
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
 		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-		int old_dpll = to_intel_crtc_state(crtc->state)->shared_dpll;
+		struct intel_shared_dpll *old_dpll =
+			to_intel_crtc_state(crtc->state)->shared_dpll;
 
 		if (!needs_modeset(crtc_state))
 			continue;
 
-		to_intel_crtc_state(crtc_state)->shared_dpll = DPLL_ID_PRIVATE;
+		to_intel_crtc_state(crtc_state)->shared_dpll = NULL;
 
-		if (old_dpll == DPLL_ID_PRIVATE)
+		if (!old_dpll)
 			continue;
 
 		if (!shared_dpll)
 			shared_dpll = intel_atomic_get_shared_dpll_state(state);
 
-		shared_dpll[old_dpll].crtc_mask &= ~(1 << intel_crtc->pipe);
+		intel_shared_dpll_config_put(shared_dpll, old_dpll, intel_crtc);
 	}
 }
 
@@ -15435,7 +15471,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		pll->active = 0;
 		pll->config.crtc_mask = 0;
 		for_each_intel_crtc(dev, crtc) {
-			if (crtc->active && intel_crtc_to_shared_dpll(crtc) == pll) {
+			if (crtc->active && crtc->config->shared_dpll == pll) {
 				pll->active++;
 				pll->config.crtc_mask |= 1 << crtc->pipe;
 			}
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 11effe3..889ceed 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -24,14 +24,43 @@
 #include "intel_drv.h"
 
 struct intel_shared_dpll *
-intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
+intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
+			    enum intel_dpll_id id)
 {
-	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+	return &dev_priv->shared_dplls[id];
+}
 
-	if (crtc->config->shared_dpll < 0)
-		return NULL;
+enum intel_dpll_id
+intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
+			 struct intel_shared_dpll *pll)
+{
+	if (WARN_ON(pll < dev_priv->shared_dplls||
+		    pll > &dev_priv->shared_dplls[dev_priv->num_shared_dpll]))
+		return -1;
+
+	return (enum intel_dpll_id) (pll - dev_priv->shared_dplls);
+}
+
+void
+intel_shared_dpll_config_get(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll);
+
+	config[id].crtc_mask |= 1 << crtc->pipe;
+}
+
+void
+intel_shared_dpll_config_put(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum intel_dpll_id id = intel_get_shared_dpll_id(dev_priv, pll);
 
-	return &dev_priv->shared_dplls[crtc->config->shared_dpll];
+	config[id].crtc_mask &= ~(1 << crtc->pipe);
 }
 
 /* For ILK+ */
@@ -55,7 +84,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+	struct intel_shared_dpll *pll = crtc->config->shared_dpll;
 
 	if (WARN_ON(pll == NULL))
 		return;
@@ -82,7 +111,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+	struct intel_shared_dpll *pll = crtc->config->shared_dpll;
 
 	if (WARN_ON(pll == NULL))
 		return;
@@ -112,7 +141,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_shared_dpll *pll = intel_crtc_to_shared_dpll(crtc);
+	struct intel_shared_dpll *pll = crtc->config->shared_dpll;
 
 	/* PCH only available on ILK+ */
 	if (INTEL_INFO(dev)->gen < 5)
@@ -265,11 +294,11 @@ intel_get_shared_dpll(struct intel_crtc *crtc,
 		shared_dpll[i].hw_state =
 			crtc_state->dpll_hw_state;
 
-	crtc_state->shared_dpll = i;
+	crtc_state->shared_dpll = pll;
 	DRM_DEBUG_DRIVER("using %s for pipe %c\n", pll->name,
 			 pipe_name(crtc->pipe));
 
-	shared_dpll[i].crtc_mask |= 1 << crtc->pipe;
+	intel_shared_dpll_config_get(shared_dpll, pll, crtc);
 
 	return pll;
 }
@@ -360,7 +389,7 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
 
 	/* Make sure no transcoder isn't still depending on us. */
 	for_each_intel_crtc(dev, crtc) {
-		if (intel_crtc_to_shared_dpll(crtc) == pll)
+		if (crtc->config->shared_dpll == pll)
 			assert_pch_transcoder_disabled(dev_priv, crtc->pipe);
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 96e84d3..0a929c1 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -441,8 +441,8 @@ struct intel_crtc_state {
 	 * haswell. */
 	struct dpll dpll;
 
-	/* Selected dpll when shared or DPLL_ID_PRIVATE. */
-	enum intel_dpll_id shared_dpll;
+	/* Selected dpll when shared or NULL. */
+	struct intel_shared_dpll *shared_dpll;
 
 	/*
 	 * - PORT_CLK_SEL for DDI ports on HSW/BDW.
@@ -1147,7 +1147,20 @@ void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
 				    enum pipe pipe);
 
 /* shared dpll functions */
-struct intel_shared_dpll *intel_crtc_to_shared_dpll(struct intel_crtc *crtc);
+struct intel_shared_dpll *
+intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
+			    enum intel_dpll_id id);
+enum intel_dpll_id
+intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
+			 struct intel_shared_dpll *pll);
+void
+intel_shared_dpll_config_get(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc);
+void
+intel_shared_dpll_config_put(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc);
 void assert_shared_dpll(struct drm_i915_private *dev_priv,
 			struct intel_shared_dpll *pll,
 			bool state);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 30a8403..a042a6f28 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -151,7 +151,7 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
 	if (HAS_PCH_SPLIT(dev)) {
 		assert_fdi_rx_pll_disabled(dev_priv, pipe);
 		assert_shared_dpll_disabled(dev_priv,
-					    intel_crtc_to_shared_dpll(crtc));
+					    crtc->config->shared_dpll);
 	} else {
 		assert_pll_disabled(dev_priv, pipe);
 	}
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/13] drm/i915: Move shared dpll struct definitions to separate header file
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (3 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 04/13] drm/i915: Store a direct pointer to shared dpll in intel_crtc_state Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 06/13] drm/i915: Move shared dpll function prototypes to intel_dpll_mgr.h Ander Conselvan de Oliveira
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move the declarations related to shared dplls from i915_drv.h to their
own header file.

The code that became the shared dpll infrastructre was first introcude
in commit ee7b9f93fd96 ("drm/i915: manage PCH PLLs separately from
pipes"), hence the 2012-2016 copyright years in the new header file.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h       |  76 +-----------------------
 drivers/gpu/drm/i915/intel_dpll_mgr.h | 106 ++++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+), 75 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_dpll_mgr.h

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9e76bfc..6de93dc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -53,6 +53,7 @@
 #include <linux/kref.h>
 #include <linux/pm_qos.h>
 #include "intel_guc.h"
+#include "intel_dpll_mgr.h"
 
 /* General customization:
  */
@@ -340,81 +341,6 @@ struct drm_i915_file_private {
 	unsigned int bsd_ring;
 };
 
-enum intel_dpll_id {
-	DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
-	/* real shared dpll ids must be >= 0 */
-	DPLL_ID_PCH_PLL_A = 0,
-	DPLL_ID_PCH_PLL_B = 1,
-	/* hsw/bdw */
-	DPLL_ID_WRPLL1 = 0,
-	DPLL_ID_WRPLL2 = 1,
-	DPLL_ID_SPLL = 2,
-
-	/* skl */
-	DPLL_ID_SKL_DPLL1 = 0,
-	DPLL_ID_SKL_DPLL2 = 1,
-	DPLL_ID_SKL_DPLL3 = 2,
-};
-#define I915_NUM_PLLS 3
-
-struct intel_dpll_hw_state {
-	/* i9xx, pch plls */
-	uint32_t dpll;
-	uint32_t dpll_md;
-	uint32_t fp0;
-	uint32_t fp1;
-
-	/* hsw, bdw */
-	uint32_t wrpll;
-	uint32_t spll;
-
-	/* skl */
-	/*
-	 * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in
-	 * lower part of ctrl1 and they get shifted into position when writing
-	 * the register.  This allows us to easily compare the state to share
-	 * the DPLL.
-	 */
-	uint32_t ctrl1;
-	/* HDMI only, 0 when used for DP */
-	uint32_t cfgcr1, cfgcr2;
-
-	/* bxt */
-	uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10,
-		 pcsdw12;
-};
-
-struct intel_shared_dpll_config {
-	unsigned crtc_mask; /* mask of CRTCs sharing this PLL */
-	struct intel_dpll_hw_state hw_state;
-};
-
-struct intel_shared_dpll {
-	struct intel_shared_dpll_config config;
-
-	int active; /* count of number of active CRTCs (i.e. DPMS on) */
-	bool on; /* is the PLL actually active? Disabled during modeset */
-	const char *name;
-	/* should match the index in the dev_priv->shared_dplls array */
-	enum intel_dpll_id id;
-	/* The mode_set hook is optional and should be used together with the
-	 * intel_prepare_shared_dpll function. */
-	void (*mode_set)(struct drm_i915_private *dev_priv,
-			 struct intel_shared_dpll *pll);
-	void (*enable)(struct drm_i915_private *dev_priv,
-		       struct intel_shared_dpll *pll);
-	void (*disable)(struct drm_i915_private *dev_priv,
-			struct intel_shared_dpll *pll);
-	bool (*get_hw_state)(struct drm_i915_private *dev_priv,
-			     struct intel_shared_dpll *pll,
-			     struct intel_dpll_hw_state *hw_state);
-};
-
-#define SKL_DPLL0 0
-#define SKL_DPLL1 1
-#define SKL_DPLL2 2
-#define SKL_DPLL3 3
-
 /* Used by dp and fdi links */
 struct intel_link_m_n {
 	uint32_t	tu;
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
new file mode 100644
index 0000000..a62d1ba
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright © 2012-2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _INTEL_DPLL_MGR_H_
+#define _INTEL_DPLL_MGR_H_
+
+struct drm_i915_private;
+
+enum intel_dpll_id {
+	DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
+	/* real shared dpll ids must be >= 0 */
+	DPLL_ID_PCH_PLL_A = 0,
+	DPLL_ID_PCH_PLL_B = 1,
+	/* hsw/bdw */
+	DPLL_ID_WRPLL1 = 0,
+	DPLL_ID_WRPLL2 = 1,
+	DPLL_ID_SPLL = 2,
+
+	/* skl */
+	DPLL_ID_SKL_DPLL1 = 0,
+	DPLL_ID_SKL_DPLL2 = 1,
+	DPLL_ID_SKL_DPLL3 = 2,
+};
+#define I915_NUM_PLLS 3
+
+struct intel_dpll_hw_state {
+	/* i9xx, pch plls */
+	uint32_t dpll;
+	uint32_t dpll_md;
+	uint32_t fp0;
+	uint32_t fp1;
+
+	/* hsw, bdw */
+	uint32_t wrpll;
+	uint32_t spll;
+
+	/* skl */
+	/*
+	 * DPLL_CTRL1 has 6 bits for each each this DPLL. We store those in
+	 * lower part of ctrl1 and they get shifted into position when writing
+	 * the register.  This allows us to easily compare the state to share
+	 * the DPLL.
+	 */
+	uint32_t ctrl1;
+	/* HDMI only, 0 when used for DP */
+	uint32_t cfgcr1, cfgcr2;
+
+	/* bxt */
+	uint32_t ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10,
+		 pcsdw12;
+};
+
+struct intel_shared_dpll_config {
+	unsigned crtc_mask; /* mask of CRTCs sharing this PLL */
+	struct intel_dpll_hw_state hw_state;
+};
+
+struct intel_shared_dpll {
+	struct intel_shared_dpll_config config;
+
+	int active; /* count of number of active CRTCs (i.e. DPMS on) */
+	bool on; /* is the PLL actually active? Disabled during modeset */
+	const char *name;
+	/* should match the index in the dev_priv->shared_dplls array */
+	enum intel_dpll_id id;
+	/* The mode_set hook is optional and should be used together with the
+	 * intel_prepare_shared_dpll function. */
+	void (*mode_set)(struct drm_i915_private *dev_priv,
+			 struct intel_shared_dpll *pll);
+	void (*enable)(struct drm_i915_private *dev_priv,
+		       struct intel_shared_dpll *pll);
+	void (*disable)(struct drm_i915_private *dev_priv,
+			struct intel_shared_dpll *pll);
+	bool (*get_hw_state)(struct drm_i915_private *dev_priv,
+			     struct intel_shared_dpll *pll,
+			     struct intel_dpll_hw_state *hw_state);
+};
+
+#define SKL_DPLL0 0
+#define SKL_DPLL1 1
+#define SKL_DPLL2 2
+#define SKL_DPLL3 3
+
+
+#endif /* _INTEL_DPLL_MGR_H_ */
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/13] drm/i915: Move shared dpll function prototypes to intel_dpll_mgr.h
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (4 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 05/13] drm/i915: Move shared dpll struct definitions to separate header file Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-03-02 14:56   ` Maarten Lankhorst
  2016-02-26 13:54 ` [PATCH 07/13] drm/i915: Use a table to initilize shared dplls Ander Conselvan de Oliveira
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move shared dpll function prototype together with other shared dpll
definitions.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_dpll_mgr.h | 30 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h      | 28 ----------------------------
 2 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index a62d1ba..a2ecf80 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -26,6 +26,8 @@
 #define _INTEL_DPLL_MGR_H_
 
 struct drm_i915_private;
+struct intel_crtc;
+struct intel_crtc_state;
 
 enum intel_dpll_id {
 	DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
@@ -102,5 +104,33 @@ struct intel_shared_dpll {
 #define SKL_DPLL2 2
 #define SKL_DPLL3 3
 
+/* shared dpll functions */
+struct intel_shared_dpll *
+intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
+			    enum intel_dpll_id id);
+enum intel_dpll_id
+intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
+			 struct intel_shared_dpll *pll);
+void
+intel_shared_dpll_config_get(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc);
+void
+intel_shared_dpll_config_put(struct intel_shared_dpll_config *config,
+			     struct intel_shared_dpll *pll,
+			     struct intel_crtc *crtc);
+void assert_shared_dpll(struct drm_i915_private *dev_priv,
+			struct intel_shared_dpll *pll,
+			bool state);
+#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
+#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
+struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
+						struct intel_crtc_state *state);
+void intel_prepare_shared_dpll(struct intel_crtc *crtc);
+void intel_enable_shared_dpll(struct intel_crtc *crtc);
+void intel_disable_shared_dpll(struct intel_crtc *crtc);
+void intel_shared_dpll_commit(struct drm_atomic_state *state);
+void intel_shared_dpll_init(struct drm_device *dev);
+
 
 #endif /* _INTEL_DPLL_MGR_H_ */
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 0a929c1..c9e5030 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1146,34 +1146,6 @@ void intel_create_rotation_property(struct drm_device *dev,
 void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
 				    enum pipe pipe);
 
-/* shared dpll functions */
-struct intel_shared_dpll *
-intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
-			    enum intel_dpll_id id);
-enum intel_dpll_id
-intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
-			 struct intel_shared_dpll *pll);
-void
-intel_shared_dpll_config_get(struct intel_shared_dpll_config *config,
-			     struct intel_shared_dpll *pll,
-			     struct intel_crtc *crtc);
-void
-intel_shared_dpll_config_put(struct intel_shared_dpll_config *config,
-			     struct intel_shared_dpll *pll,
-			     struct intel_crtc *crtc);
-void assert_shared_dpll(struct drm_i915_private *dev_priv,
-			struct intel_shared_dpll *pll,
-			bool state);
-#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
-#define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
-struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
-						struct intel_crtc_state *state);
-void intel_prepare_shared_dpll(struct intel_crtc *crtc);
-void intel_enable_shared_dpll(struct intel_crtc *crtc);
-void intel_disable_shared_dpll(struct intel_crtc *crtc);
-void intel_shared_dpll_commit(struct drm_atomic_state *state);
-void intel_shared_dpll_init(struct drm_device *dev);
-
 int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
 		     const struct dpll *dpll);
 void vlv_force_pll_off(struct drm_device *dev, enum pipe pipe);
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/13] drm/i915: Use a table to initilize shared dplls
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (5 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 06/13] drm/i915: Move shared dpll function prototypes to intel_dpll_mgr.h Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-03-02 15:30   ` Maarten Lankhorst
  2016-02-26 13:54 ` [PATCH 08/13] drm/i915: Refactor platform specifics out of intel_get_shared_dpll() Ander Conselvan de Oliveira
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Use a table to store the per-platform shared dpll information in one
place. This way, there is no need for platform specific init funtions.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c  |  16 +--
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 189 ++++++++++++++++------------------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  22 ++--
 3 files changed, 108 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e723323..133b6b7 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9148,8 +9148,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
 			intel_get_shared_dpll_by_id(dev_priv, pll_id);
 		pll = pipe_config->shared_dpll;
 
-		WARN_ON(!pll->get_hw_state(dev_priv, pll,
-					   &pipe_config->dpll_hw_state));
+		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
+						 &pipe_config->dpll_hw_state));
 
 		tmp = pipe_config->dpll_hw_state.dpll;
 		pipe_config->pixel_multiplier =
@@ -9695,8 +9695,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
 
 	pll = pipe_config->shared_dpll;
 	if (pll) {
-		WARN_ON(!pll->get_hw_state(dev_priv, pll,
-					   &pipe_config->dpll_hw_state));
+		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
+						 &pipe_config->dpll_hw_state));
 	}
 
 	/*
@@ -12728,7 +12728,7 @@ check_shared_dpll_state(struct drm_device *dev)
 
 		DRM_DEBUG_KMS("%s\n", pll->name);
 
-		active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state);
+		active = pll->funcs.get_hw_state(dev_priv, pll, &dpll_hw_state);
 
 		I915_STATE_WARN(pll->active > hweight32(pll->config.crtc_mask),
 		     "more active pll users than references: %i vs %i\n",
@@ -15466,8 +15466,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
 		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
 
-		pll->on = pll->get_hw_state(dev_priv, pll,
-					    &pll->config.hw_state);
+		pll->on = pll->funcs.get_hw_state(dev_priv, pll,
+						  &pll->config.hw_state);
 		pll->active = 0;
 		pll->config.crtc_mask = 0;
 		for_each_intel_crtc(dev, crtc) {
@@ -15602,7 +15602,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
 
 		DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name);
 
-		pll->disable(dev_priv, pll);
+		pll->funcs.disable(dev_priv, pll);
 		pll->on = false;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 889ceed..e88dc46 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -74,7 +74,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
 	if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
 		return;
 
-	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
+	cur_state = pll->funcs.get_hw_state(dev_priv, pll, &hw_state);
 	I915_STATE_WARN(cur_state != state,
 	     "%s assertion failure (expected %s, current %s)\n",
 			pll->name, onoff(state), onoff(cur_state));
@@ -95,7 +95,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc)
 		WARN_ON(pll->on);
 		assert_shared_dpll_disabled(dev_priv, pll);
 
-		pll->mode_set(dev_priv, pll);
+		pll->funcs.mode_set(dev_priv, pll);
 	}
 }
 
@@ -133,7 +133,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc)
 	intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
 
 	DRM_DEBUG_KMS("enabling %s\n", pll->name);
-	pll->enable(dev_priv, pll);
+	pll->funcs.enable(dev_priv, pll);
 	pll->on = true;
 }
 
@@ -168,7 +168,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
 		return;
 
 	DRM_DEBUG_KMS("disabling %s\n", pll->name);
-	pll->disable(dev_priv, pll);
+	pll->funcs.disable(dev_priv, pll);
 	pll->on = false;
 
 	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
@@ -398,29 +398,13 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
 	udelay(200);
 }
 
-static char *ibx_pch_dpll_names[] = {
-	"PCH DPLL A",
-	"PCH DPLL B",
+static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
+	.mode_set = ibx_pch_dpll_mode_set,
+	.enable = ibx_pch_dpll_enable,
+	.disable = ibx_pch_dpll_disable,
+	.get_hw_state = ibx_pch_dpll_get_hw_state,
 };
 
-static void ibx_pch_dpll_init(struct drm_device *dev)
-{
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	int i;
-
-	dev_priv->num_shared_dpll = 2;
-
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		dev_priv->shared_dplls[i].id = i;
-		dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
-		dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set;
-		dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
-		dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
-		dev_priv->shared_dplls[i].get_hw_state =
-			ibx_pch_dpll_get_hw_state;
-	}
-}
-
 static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
 			       struct intel_shared_dpll *pll)
 {
@@ -492,40 +476,16 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
 }
 
 
-static const char * const hsw_ddi_pll_names[] = {
-	"WRPLL 1",
-	"WRPLL 2",
-	"SPLL"
+static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
+	.enable = hsw_ddi_wrpll_enable,
+	.disable = hsw_ddi_wrpll_disable,
+	.get_hw_state = hsw_ddi_wrpll_get_hw_state,
 };
 
-static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
-{
-	int i;
-
-	dev_priv->num_shared_dpll = 3;
-
-	for (i = 0; i < 2; i++) {
-		dev_priv->shared_dplls[i].id = i;
-		dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
-		dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
-		dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
-		dev_priv->shared_dplls[i].get_hw_state =
-			hsw_ddi_wrpll_get_hw_state;
-	}
-
-	/* SPLL is special, but needs to be initialized anyway.. */
-	dev_priv->shared_dplls[i].id = i;
-	dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
-	dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
-	dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
-	dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
-
-}
-
-static const char * const skl_ddi_pll_names[] = {
-	"DPLL 1",
-	"DPLL 2",
-	"DPLL 3",
+static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
+	.enable = hsw_ddi_spll_enable,
+	.disable = hsw_ddi_spll_disable,
+	.get_hw_state = hsw_ddi_spll_get_hw_state,
 };
 
 struct skl_dpll_regs {
@@ -634,26 +594,10 @@ out:
 	return ret;
 }
 
-static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
-{
-	int i;
-
-	dev_priv->num_shared_dpll = 3;
-
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		dev_priv->shared_dplls[i].id = i;
-		dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
-		dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
-		dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
-		dev_priv->shared_dplls[i].get_hw_state =
-			skl_ddi_pll_get_hw_state;
-	}
-}
-
-static const char * const bxt_ddi_pll_names[] = {
-	"PORT PLL A",
-	"PORT PLL B",
-	"PORT PLL C",
+static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
+	.enable = skl_ddi_pll_enable,
+	.disable = skl_ddi_pll_disable,
+	.get_hw_state = skl_ddi_pll_get_hw_state,
 };
 
 static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
@@ -838,34 +782,17 @@ out:
 	return ret;
 }
 
-static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
-{
-	int i;
-
-	dev_priv->num_shared_dpll = 3;
-
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
-		dev_priv->shared_dplls[i].id = i;
-		dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
-		dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
-		dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
-		dev_priv->shared_dplls[i].get_hw_state =
-			bxt_ddi_pll_get_hw_state;
-	}
-}
+static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
+	.enable = bxt_ddi_pll_enable,
+	.disable = bxt_ddi_pll_disable,
+	.get_hw_state = bxt_ddi_pll_get_hw_state,
+};
 
 static void intel_ddi_pll_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t val = I915_READ(LCPLL_CTL);
 
-	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
-		skl_shared_dplls_init(dev_priv);
-	else if (IS_BROXTON(dev))
-		bxt_shared_dplls_init(dev_priv);
-	else
-		hsw_shared_dplls_init(dev_priv);
-
 	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
 		int cdclk_freq;
 
@@ -893,16 +820,72 @@ static void intel_ddi_pll_init(struct drm_device *dev)
 	}
 }
 
+struct dpll_info {
+	const char *name;
+	const int id;
+	const struct intel_shared_dpll_funcs *funcs;
+};
+
+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 },
+};
+
+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 },
+	{ NULL, -1, NULL, },
+};
+
+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 },
+	{ NULL, -1, NULL, },
+};
+
+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 },
+	{ NULL, -1, NULL, },
+};
+
 void intel_shared_dpll_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	const struct dpll_info *dpll_info = NULL;
+	int i;
 
-	if (HAS_DDI(dev))
-		intel_ddi_pll_init(dev);
+	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
+		dpll_info = skl_plls;
+	else if IS_BROXTON(dev)
+		dpll_info = bxt_plls;
+	else if (HAS_DDI(dev))
+		dpll_info = hsw_plls;
 	else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
-		ibx_pch_dpll_init(dev);
-	else
+		dpll_info = pch_plls;
+
+	if (!dpll_info) {
 		dev_priv->num_shared_dpll = 0;
+		return;
+	}
+
+	for (i = 0; dpll_info[i].id >= 0; i++) {
+		WARN_ON(i != dpll_info[i].id);
+
+		dev_priv->shared_dplls[i].id = dpll_info[i].id;
+		dev_priv->shared_dplls[i].name = dpll_info[i].name;
+		dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
+	}
+
+	dev_priv->num_shared_dpll = i;
 
 	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
+
+	/* FIXME: Move this to a more suitable place */
+	if (HAS_DDI(dev))
+		intel_ddi_pll_init(dev);
 }
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index a2ecf80..8be2478 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -28,6 +28,7 @@
 struct drm_i915_private;
 struct intel_crtc;
 struct intel_crtc_state;
+struct intel_shared_dpll;
 
 enum intel_dpll_id {
 	DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
@@ -78,14 +79,7 @@ struct intel_shared_dpll_config {
 	struct intel_dpll_hw_state hw_state;
 };
 
-struct intel_shared_dpll {
-	struct intel_shared_dpll_config config;
-
-	int active; /* count of number of active CRTCs (i.e. DPMS on) */
-	bool on; /* is the PLL actually active? Disabled during modeset */
-	const char *name;
-	/* should match the index in the dev_priv->shared_dplls array */
-	enum intel_dpll_id id;
+struct intel_shared_dpll_funcs {
 	/* The mode_set hook is optional and should be used together with the
 	 * intel_prepare_shared_dpll function. */
 	void (*mode_set)(struct drm_i915_private *dev_priv,
@@ -99,6 +93,18 @@ struct intel_shared_dpll {
 			     struct intel_dpll_hw_state *hw_state);
 };
 
+struct intel_shared_dpll {
+	struct intel_shared_dpll_config config;
+
+	int active; /* count of number of active CRTCs (i.e. DPMS on) */
+	bool on; /* is the PLL actually active? Disabled during modeset */
+	const char *name;
+	/* should match the index in the dev_priv->shared_dplls array */
+	enum intel_dpll_id id;
+
+	struct intel_shared_dpll_funcs funcs;
+};
+
 #define SKL_DPLL0 0
 #define SKL_DPLL1 1
 #define SKL_DPLL2 2
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/13] drm/i915: Refactor platform specifics out of intel_get_shared_dpll()
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (6 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 07/13] drm/i915: Use a table to initilize shared dplls Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-03-03 14:08   ` Maarten Lankhorst
  2016-02-26 13:54 ` [PATCH 09/13] drm/i915: Move HSW/BDW pll selection logic to intel_dpll_mgr.c Ander Conselvan de Oliveira
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

The function intel_get_shared_dpll() had a more or less generic
implementation with some platform specific checks to handle smaller
differences between platforms. However, the minimalist approach forces
bigger differences between platforms to be implemented outside of the
shared dpll code (see the *_ddi_pll_select() functions in intel_ddi.c,
for instance).

This patch changes the implementation of intel_get_share_dpll() so that
a completely platform specific version can be used, providing helpers to
reduce code duplication. This should allow the code from the ddi pll
select functions to be moved, and also make room for making more dplls
managed by the shared dpll infrastructure.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h       |   1 +
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 226 +++++++++++++++++++++-------------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |   2 +
 3 files changed, 145 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6de93dc..b858801 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1802,6 +1802,7 @@ struct drm_i915_private {
 	/* dpll and cdclk state is protected by connection_mutex */
 	int num_shared_dpll;
 	struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
+	const struct intel_dpll_mgr *dpll_mgr;
 
 	unsigned int active_crtcs;
 	unsigned int min_pixclk[I915_MAX_PIPES];
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index e88dc46..3553324 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -174,66 +174,20 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
 	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
 }
 
-static enum intel_dpll_id
-ibx_get_fixed_dpll(struct intel_crtc *crtc,
-		   struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct intel_shared_dpll *pll;
-	enum intel_dpll_id i;
-
-	/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
-	i = (enum intel_dpll_id) crtc->pipe;
-	pll = &dev_priv->shared_dplls[i];
-
-	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
-		      crtc->base.base.id, pll->name);
-
-	return i;
-}
-
-static enum intel_dpll_id
-bxt_get_fixed_dpll(struct intel_crtc *crtc,
-		   struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct intel_encoder *encoder;
-	struct intel_digital_port *intel_dig_port;
-	struct intel_shared_dpll *pll;
-	enum intel_dpll_id i;
-
-	/* PLL is attached to port in bxt */
-	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
-	if (WARN_ON(!encoder))
-		return DPLL_ID_PRIVATE;
-
-	intel_dig_port = enc_to_dig_port(&encoder->base);
-	/* 1:1 mapping between ports and PLLs */
-	i = (enum intel_dpll_id)intel_dig_port->port;
-	pll = &dev_priv->shared_dplls[i];
-	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
-		crtc->base.base.id, pll->name);
-
-	return i;
-}
-
-static enum intel_dpll_id
+static struct intel_shared_dpll *
 intel_find_shared_dpll(struct intel_crtc *crtc,
-		       struct intel_crtc_state *crtc_state)
+		       struct intel_crtc_state *crtc_state,
+		       enum intel_dpll_id range_min,
+		       enum intel_dpll_id range_max)
 {
 	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
 	struct intel_shared_dpll *pll;
 	struct intel_shared_dpll_config *shared_dpll;
 	enum intel_dpll_id i;
-	int max = dev_priv->num_shared_dpll;
-
-	if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
-		/* Do not consider SPLL */
-		max = 2;
 
 	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
 
-	for (i = 0; i < max; i++) {
+	for (i = range_min; i <= range_max; i++) {
 		pll = &dev_priv->shared_dplls[i];
 
 		/* Only want to check enabled timings first */
@@ -247,49 +201,33 @@ intel_find_shared_dpll(struct intel_crtc *crtc,
 				      crtc->base.base.id, pll->name,
 				      shared_dpll[i].crtc_mask,
 				      pll->active);
-			return i;
+			return pll;
 		}
 	}
 
 	/* Ok no matching timings, maybe there's a free one? */
-	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+	for (i = range_min; i <= range_max; i++) {
 		pll = &dev_priv->shared_dplls[i];
 		if (shared_dpll[i].crtc_mask == 0) {
 			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
 				      crtc->base.base.id, pll->name);
-			return i;
+			return pll;
 		}
 	}
 
-	return DPLL_ID_PRIVATE;
+	return NULL;
 }
 
-struct intel_shared_dpll *
-intel_get_shared_dpll(struct intel_crtc *crtc,
-		      struct intel_crtc_state *crtc_state)
+static void
+intel_reference_shared_dpll(struct intel_shared_dpll *pll,
+			    struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
-	struct intel_shared_dpll *pll;
 	struct intel_shared_dpll_config *shared_dpll;
-	enum intel_dpll_id i;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	enum intel_dpll_id i = pll->id;
 
 	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
 
-	if (HAS_PCH_IBX(dev_priv->dev)) {
-		i = ibx_get_fixed_dpll(crtc, crtc_state);
-		WARN_ON(shared_dpll[i].crtc_mask);
-	} else if (IS_BROXTON(dev_priv->dev)) {
-		i = bxt_get_fixed_dpll(crtc, crtc_state);
-		WARN_ON(shared_dpll[i].crtc_mask);
-	} else {
-		i = intel_find_shared_dpll(crtc, crtc_state);
-	}
-
-	if (i < 0)
-		return NULL;
-
-	pll = &dev_priv->shared_dplls[i];
-
 	if (shared_dpll[i].crtc_mask == 0)
 		shared_dpll[i].hw_state =
 			crtc_state->dpll_hw_state;
@@ -299,8 +237,6 @@ intel_get_shared_dpll(struct intel_crtc *crtc,
 			 pipe_name(crtc->pipe));
 
 	intel_shared_dpll_config_get(shared_dpll, pll, crtc);
-
-	return pll;
 }
 
 void intel_shared_dpll_commit(struct drm_atomic_state *state)
@@ -398,6 +334,32 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
 	udelay(200);
 }
 
+static struct intel_shared_dpll *
+ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id i;
+
+	if (HAS_PCH_IBX(dev_priv)) {
+		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
+		i = (enum intel_dpll_id) crtc->pipe;
+		pll = &dev_priv->shared_dplls[i];
+
+		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
+			      crtc->base.base.id, pll->name);
+	} else {
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_PCH_PLL_A,
+					     DPLL_ID_PCH_PLL_B);
+	}
+
+	/* reference the pll */
+	intel_reference_shared_dpll(pll, crtc_state);
+
+	return pll;
+}
+
 static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
 	.mode_set = ibx_pch_dpll_mode_set,
 	.enable = ibx_pch_dpll_enable,
@@ -475,6 +437,19 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
 	return val & SPLL_PLL_ENABLE;
 }
 
+static struct intel_shared_dpll *
+hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
+{
+	struct intel_shared_dpll *pll;
+
+	pll = intel_find_shared_dpll(crtc, crtc_state,
+				     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
+	if (pll)
+		intel_reference_shared_dpll(pll, crtc_state);
+
+	return pll;
+}
+
 
 static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
 	.enable = hsw_ddi_wrpll_enable,
@@ -594,6 +569,19 @@ out:
 	return ret;
 }
 
+static struct intel_shared_dpll *
+skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
+{
+	struct intel_shared_dpll *pll;
+
+	pll = intel_find_shared_dpll(crtc, crtc_state,
+				     DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3);
+	if (pll)
+		intel_reference_shared_dpll(pll, crtc_state);
+
+	return pll;
+}
+
 static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
 	.enable = skl_ddi_pll_enable,
 	.disable = skl_ddi_pll_disable,
@@ -782,6 +770,32 @@ out:
 	return ret;
 }
 
+static struct intel_shared_dpll *
+bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_encoder *encoder;
+	struct intel_digital_port *intel_dig_port;
+	struct intel_shared_dpll *pll;
+	enum intel_dpll_id i;
+
+	/* PLL is attached to port in bxt */
+	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
+	if (WARN_ON(!encoder))
+		return NULL;
+
+	intel_dig_port = enc_to_dig_port(&encoder->base);
+	/* 1:1 mapping between ports and PLLs */
+	i = (enum intel_dpll_id)intel_dig_port->port;
+	pll = &dev_priv->shared_dplls[i];
+	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
+		crtc->base.base.id, pll->name);
+
+	intel_reference_shared_dpll(pll, crtc_state);
+
+	return pll;
+}
+
 static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
 	.enable = bxt_ddi_pll_enable,
 	.disable = bxt_ddi_pll_disable,
@@ -826,12 +840,24 @@ struct dpll_info {
 	const struct intel_shared_dpll_funcs *funcs;
 };
 
+struct intel_dpll_mgr {
+	const struct dpll_info *dpll_info;
+
+	struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
+					      struct intel_crtc_state *crtc_state);
+};
+
 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 },
 };
 
+static const struct intel_dpll_mgr pch_pll_mgr = {
+	.dpll_info = pch_plls,
+	.get_dpll = ibx_get_dpll,
+};
+
 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 },
@@ -839,6 +865,11 @@ static const struct dpll_info hsw_plls[] = {
 	{ NULL, -1, NULL, },
 };
 
+static const struct intel_dpll_mgr hsw_pll_mgr = {
+	.dpll_info = hsw_plls,
+	.get_dpll = hsw_get_dpll,
+};
+
 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 },
@@ -846,6 +877,11 @@ static const struct dpll_info skl_plls[] = {
 	{ NULL, -1, NULL, },
 };
 
+static const struct intel_dpll_mgr skl_pll_mgr = {
+	.dpll_info = skl_plls,
+	.get_dpll = skl_get_dpll,
+};
+
 static const struct dpll_info bxt_plls[] = {
 	{ "PORT PLL A", 0, &bxt_ddi_pll_funcs },
 	{ "PORT PLL B", 1, &bxt_ddi_pll_funcs },
@@ -853,26 +889,34 @@ static const struct dpll_info bxt_plls[] = {
 	{ NULL, -1, NULL, },
 };
 
+static const struct intel_dpll_mgr bxt_pll_mgr = {
+	.dpll_info = bxt_plls,
+	.get_dpll = bxt_get_dpll,
+};
+
 void intel_shared_dpll_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	const struct dpll_info *dpll_info = NULL;
+	const struct intel_dpll_mgr *dpll_mgr = NULL;
+	const struct dpll_info *dpll_info;
 	int i;
 
 	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
-		dpll_info = skl_plls;
+		dpll_mgr = &skl_pll_mgr;
 	else if IS_BROXTON(dev)
-		dpll_info = bxt_plls;
+		dpll_mgr = &bxt_pll_mgr;
 	else if (HAS_DDI(dev))
-		dpll_info = hsw_plls;
+		dpll_mgr = &hsw_pll_mgr;
 	else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
-		dpll_info = pch_plls;
+		dpll_mgr = &pch_pll_mgr;
 
-	if (!dpll_info) {
+	if (!dpll_mgr) {
 		dev_priv->num_shared_dpll = 0;
 		return;
 	}
 
+	dpll_info = dpll_mgr->dpll_info;
+
 	for (i = 0; dpll_info[i].id >= 0; i++) {
 		WARN_ON(i != dpll_info[i].id);
 
@@ -881,6 +925,7 @@ void intel_shared_dpll_init(struct drm_device *dev)
 		dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
 	}
 
+	dev_priv->dpll_mgr = dpll_mgr;
 	dev_priv->num_shared_dpll = i;
 
 	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
@@ -889,3 +934,16 @@ void intel_shared_dpll_init(struct drm_device *dev)
 	if (HAS_DDI(dev))
 		intel_ddi_pll_init(dev);
 }
+
+struct intel_shared_dpll *
+intel_get_shared_dpll(struct intel_crtc *crtc,
+		      struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
+
+	if (dpll_mgr)
+		return dpll_mgr->get_dpll(crtc, crtc_state);
+	else
+		return NULL;
+}
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index 8be2478..7794c7a 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -30,6 +30,8 @@ struct intel_crtc;
 struct intel_crtc_state;
 struct intel_shared_dpll;
 
+struct intel_dpll_mgr;
+
 enum intel_dpll_id {
 	DPLL_ID_PRIVATE = -1, /* non-shared dpll in use */
 	/* real shared dpll ids must be >= 0 */
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/13] drm/i915: Move HSW/BDW pll selection logic to intel_dpll_mgr.c
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (7 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 08/13] drm/i915: Refactor platform specifics out of intel_get_shared_dpll() Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 10/13] drm/i915: Move SKL/KLB " Ander Conselvan de Oliveira
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move the code for selecting and configuring HSW/BDW DDI PLLs into the
shared dpll infrastructure. With this most of the PLL selection logic
for those platforms is in one place. DisplayPort is handled separately,
but that should be fixed on a follow up patch. It also allows a small
clean up of the SPLL logic.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_crt.c      |   8 +-
 drivers/gpu/drm/i915/intel_ddi.c      | 271 ++-----------------------------
 drivers/gpu/drm/i915/intel_display.c  |   2 +-
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 295 ++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  13 +-
 5 files changed, 307 insertions(+), 282 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 505fc5c..6353857 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -261,15 +261,9 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder,
 		pipe_config->pipe_bpp = 24;
 
 	/* FDI must always be 2.7 GHz */
-	if (HAS_DDI(dev)) {
-		pipe_config->ddi_pll_sel = PORT_CLK_SEL_SPLL;
+	if (HAS_DDI(dev))
 		pipe_config->port_clock = 135000 * 2;
 
-		pipe_config->dpll_hw_state.wrpll = 0;
-		pipe_config->dpll_hw_state.spll =
-			SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC;
-	}
-
 	return true;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index a2b33d0..e1585a5 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -724,160 +724,6 @@ intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
 }
 
 #define LC_FREQ 2700
-#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
-
-#define P_MIN 2
-#define P_MAX 64
-#define P_INC 2
-
-/* Constraints for PLL good behavior */
-#define REF_MIN 48
-#define REF_MAX 400
-#define VCO_MIN 2400
-#define VCO_MAX 4800
-
-#define abs_diff(a, b) ({			\
-	typeof(a) __a = (a);			\
-	typeof(b) __b = (b);			\
-	(void) (&__a == &__b);			\
-	__a > __b ? (__a - __b) : (__b - __a); })
-
-struct hsw_wrpll_rnp {
-	unsigned p, n2, r2;
-};
-
-static unsigned hsw_wrpll_get_budget_for_freq(int clock)
-{
-	unsigned budget;
-
-	switch (clock) {
-	case 25175000:
-	case 25200000:
-	case 27000000:
-	case 27027000:
-	case 37762500:
-	case 37800000:
-	case 40500000:
-	case 40541000:
-	case 54000000:
-	case 54054000:
-	case 59341000:
-	case 59400000:
-	case 72000000:
-	case 74176000:
-	case 74250000:
-	case 81000000:
-	case 81081000:
-	case 89012000:
-	case 89100000:
-	case 108000000:
-	case 108108000:
-	case 111264000:
-	case 111375000:
-	case 148352000:
-	case 148500000:
-	case 162000000:
-	case 162162000:
-	case 222525000:
-	case 222750000:
-	case 296703000:
-	case 297000000:
-		budget = 0;
-		break;
-	case 233500000:
-	case 245250000:
-	case 247750000:
-	case 253250000:
-	case 298000000:
-		budget = 1500;
-		break;
-	case 169128000:
-	case 169500000:
-	case 179500000:
-	case 202000000:
-		budget = 2000;
-		break;
-	case 256250000:
-	case 262500000:
-	case 270000000:
-	case 272500000:
-	case 273750000:
-	case 280750000:
-	case 281250000:
-	case 286000000:
-	case 291750000:
-		budget = 4000;
-		break;
-	case 267250000:
-	case 268500000:
-		budget = 5000;
-		break;
-	default:
-		budget = 1000;
-		break;
-	}
-
-	return budget;
-}
-
-static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
-				 unsigned r2, unsigned n2, unsigned p,
-				 struct hsw_wrpll_rnp *best)
-{
-	uint64_t a, b, c, d, diff, diff_best;
-
-	/* No best (r,n,p) yet */
-	if (best->p == 0) {
-		best->p = p;
-		best->n2 = n2;
-		best->r2 = r2;
-		return;
-	}
-
-	/*
-	 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
-	 * freq2k.
-	 *
-	 * delta = 1e6 *
-	 *	   abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
-	 *	   freq2k;
-	 *
-	 * and we would like delta <= budget.
-	 *
-	 * If the discrepancy is above the PPM-based budget, always prefer to
-	 * improve upon the previous solution.  However, if you're within the
-	 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
-	 */
-	a = freq2k * budget * p * r2;
-	b = freq2k * budget * best->p * best->r2;
-	diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
-	diff_best = abs_diff(freq2k * best->p * best->r2,
-			     LC_FREQ_2K * best->n2);
-	c = 1000000 * diff;
-	d = 1000000 * diff_best;
-
-	if (a < c && b < d) {
-		/* If both are above the budget, pick the closer */
-		if (best->p * best->r2 * diff < p * r2 * diff_best) {
-			best->p = p;
-			best->n2 = n2;
-			best->r2 = r2;
-		}
-	} else if (a >= c && b < d) {
-		/* If A is below the threshold but B is above it?  Update. */
-		best->p = p;
-		best->n2 = n2;
-		best->r2 = r2;
-	} else if (a >= c && b >= d) {
-		/* Both are below the limit, so pick the higher n2/(r2*r2) */
-		if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
-			best->p = p;
-			best->n2 = n2;
-			best->r2 = r2;
-		}
-	}
-	/* Otherwise a < c && b >= d, do nothing */
-}
 
 static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
 				   i915_reg_t reg)
@@ -1139,119 +985,24 @@ void intel_ddi_clock_get(struct intel_encoder *encoder,
 		bxt_ddi_clock_get(encoder, pipe_config);
 }
 
-static void
-hsw_ddi_calculate_wrpll(int clock /* in Hz */,
-			unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
-{
-	uint64_t freq2k;
-	unsigned p, n2, r2;
-	struct hsw_wrpll_rnp best = { 0, 0, 0 };
-	unsigned budget;
-
-	freq2k = clock / 100;
-
-	budget = hsw_wrpll_get_budget_for_freq(clock);
-
-	/* Special case handling for 540 pixel clock: bypass WR PLL entirely
-	 * and directly pass the LC PLL to it. */
-	if (freq2k == 5400000) {
-		*n2_out = 2;
-		*p_out = 1;
-		*r2_out = 2;
-		return;
-	}
-
-	/*
-	 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
-	 * the WR PLL.
-	 *
-	 * We want R so that REF_MIN <= Ref <= REF_MAX.
-	 * Injecting R2 = 2 * R gives:
-	 *   REF_MAX * r2 > LC_FREQ * 2 and
-	 *   REF_MIN * r2 < LC_FREQ * 2
-	 *
-	 * Which means the desired boundaries for r2 are:
-	 *  LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
-	 *
-	 */
-	for (r2 = LC_FREQ * 2 / REF_MAX + 1;
-	     r2 <= LC_FREQ * 2 / REF_MIN;
-	     r2++) {
-
-		/*
-		 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
-		 *
-		 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
-		 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
-		 *   VCO_MAX * r2 > n2 * LC_FREQ and
-		 *   VCO_MIN * r2 < n2 * LC_FREQ)
-		 *
-		 * Which means the desired boundaries for n2 are:
-		 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
-		 */
-		for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
-		     n2 <= VCO_MAX * r2 / LC_FREQ;
-		     n2++) {
-
-			for (p = P_MIN; p <= P_MAX; p += P_INC)
-				hsw_wrpll_update_rnp(freq2k, budget,
-						     r2, n2, p, &best);
-		}
-	}
-
-	*n2_out = best.n2;
-	*p_out = best.p;
-	*r2_out = best.r2;
-}
-
 static bool
 hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
 		   struct intel_crtc_state *crtc_state,
 		   struct intel_encoder *intel_encoder)
 {
-	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
-	int clock = crtc_state->port_clock;
-
-	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
-		struct intel_shared_dpll *pll;
-		uint32_t val;
-		unsigned p, n2, r2;
-
-		hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
-
-		val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
-		      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;
+	struct intel_shared_dpll *pll;
 
-		pll = intel_get_shared_dpll(intel_crtc, crtc_state);
-		if (pll == NULL) {
+	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 false;
-		}
-
-		crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
-	} else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
-		struct drm_atomic_state *state = crtc_state->base.state;
-		struct intel_shared_dpll_config *spll =
-			&intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
-
-		if (spll->crtc_mask &&
-		    WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
-			return false;
-
-		crtc_state->shared_dpll =
-			intel_get_shared_dpll_by_id(dev_priv, DPLL_ID_SPLL);
-		spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
-		spll->crtc_mask |= 1 << intel_crtc->pipe;
+		return pll;
+	} else {
+		return true;
 	}
-
-	return true;
 }
 
 struct skl_wrpll_context {
@@ -1560,7 +1311,7 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
 	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
 	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
 
-	pll = intel_get_shared_dpll(intel_crtc, crtc_state);
+	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
 	if (pll == NULL) {
 		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
 				 pipe_name(intel_crtc->pipe));
@@ -1707,7 +1458,7 @@ bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
 	crtc_state->dpll_hw_state.pcsdw12 =
 		LANESTAGGER_STRAP_OVRD | lanestagger;
 
-	pll = intel_get_shared_dpll(intel_crtc, crtc_state);
+	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
 	if (pll == NULL) {
 		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
 			pipe_name(intel_crtc->pipe));
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 133b6b7..17f4f34 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8782,7 +8782,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
 		else
 			crtc_state->dpll_hw_state.fp1 = fp;
 
-		pll = intel_get_shared_dpll(crtc, crtc_state);
+		pll = intel_get_shared_dpll(crtc, crtc_state, NULL);
 		if (pll == NULL) {
 			DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
 					 pipe_name(crtc->pipe));
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index 3553324..d1e8544 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -335,7 +335,8 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
 }
 
 static struct intel_shared_dpll *
-ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
+ibx_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;
@@ -437,15 +438,282 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
 	return val & SPLL_PLL_ENABLE;
 }
 
+static uint32_t hsw_pll_to_ddi_pll_sel(struct intel_shared_dpll *pll)
+{
+	switch (pll->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;
+	default:
+		return PORT_CLK_SEL_NONE;
+	}
+}
+
+#define LC_FREQ 2700
+#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
+
+#define P_MIN 2
+#define P_MAX 64
+#define P_INC 2
+
+/* Constraints for PLL good behavior */
+#define REF_MIN 48
+#define REF_MAX 400
+#define VCO_MIN 2400
+#define VCO_MAX 4800
+
+struct hsw_wrpll_rnp {
+	unsigned p, n2, r2;
+};
+
+static unsigned hsw_wrpll_get_budget_for_freq(int clock)
+{
+	unsigned budget;
+
+	switch (clock) {
+	case 25175000:
+	case 25200000:
+	case 27000000:
+	case 27027000:
+	case 37762500:
+	case 37800000:
+	case 40500000:
+	case 40541000:
+	case 54000000:
+	case 54054000:
+	case 59341000:
+	case 59400000:
+	case 72000000:
+	case 74176000:
+	case 74250000:
+	case 81000000:
+	case 81081000:
+	case 89012000:
+	case 89100000:
+	case 108000000:
+	case 108108000:
+	case 111264000:
+	case 111375000:
+	case 148352000:
+	case 148500000:
+	case 162000000:
+	case 162162000:
+	case 222525000:
+	case 222750000:
+	case 296703000:
+	case 297000000:
+		budget = 0;
+		break;
+	case 233500000:
+	case 245250000:
+	case 247750000:
+	case 253250000:
+	case 298000000:
+		budget = 1500;
+		break;
+	case 169128000:
+	case 169500000:
+	case 179500000:
+	case 202000000:
+		budget = 2000;
+		break;
+	case 256250000:
+	case 262500000:
+	case 270000000:
+	case 272500000:
+	case 273750000:
+	case 280750000:
+	case 281250000:
+	case 286000000:
+	case 291750000:
+		budget = 4000;
+		break;
+	case 267250000:
+	case 268500000:
+		budget = 5000;
+		break;
+	default:
+		budget = 1000;
+		break;
+	}
+
+	return budget;
+}
+
+static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
+				 unsigned r2, unsigned n2, unsigned p,
+				 struct hsw_wrpll_rnp *best)
+{
+	uint64_t a, b, c, d, diff, diff_best;
+
+	/* No best (r,n,p) yet */
+	if (best->p == 0) {
+		best->p = p;
+		best->n2 = n2;
+		best->r2 = r2;
+		return;
+	}
+
+	/*
+	 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
+	 * freq2k.
+	 *
+	 * delta = 1e6 *
+	 *	   abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
+	 *	   freq2k;
+	 *
+	 * and we would like delta <= budget.
+	 *
+	 * If the discrepancy is above the PPM-based budget, always prefer to
+	 * improve upon the previous solution.  However, if you're within the
+	 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
+	 */
+	a = freq2k * budget * p * r2;
+	b = freq2k * budget * best->p * best->r2;
+	diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
+	diff_best = abs_diff(freq2k * best->p * best->r2,
+			     LC_FREQ_2K * best->n2);
+	c = 1000000 * diff;
+	d = 1000000 * diff_best;
+
+	if (a < c && b < d) {
+		/* If both are above the budget, pick the closer */
+		if (best->p * best->r2 * diff < p * r2 * diff_best) {
+			best->p = p;
+			best->n2 = n2;
+			best->r2 = r2;
+		}
+	} else if (a >= c && b < d) {
+		/* If A is below the threshold but B is above it?  Update. */
+		best->p = p;
+		best->n2 = n2;
+		best->r2 = r2;
+	} else if (a >= c && b >= d) {
+		/* Both are below the limit, so pick the higher n2/(r2*r2) */
+		if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
+			best->p = p;
+			best->n2 = n2;
+			best->r2 = r2;
+		}
+	}
+	/* Otherwise a < c && b >= d, do nothing */
+}
+
+static void
+hsw_ddi_calculate_wrpll(int clock /* in Hz */,
+			unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
+{
+	uint64_t freq2k;
+	unsigned p, n2, r2;
+	struct hsw_wrpll_rnp best = { 0, 0, 0 };
+	unsigned budget;
+
+	freq2k = clock / 100;
+
+	budget = hsw_wrpll_get_budget_for_freq(clock);
+
+	/* Special case handling for 540 pixel clock: bypass WR PLL entirely
+	 * and directly pass the LC PLL to it. */
+	if (freq2k == 5400000) {
+		*n2_out = 2;
+		*p_out = 1;
+		*r2_out = 2;
+		return;
+	}
+
+	/*
+	 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
+	 * the WR PLL.
+	 *
+	 * We want R so that REF_MIN <= Ref <= REF_MAX.
+	 * Injecting R2 = 2 * R gives:
+	 *   REF_MAX * r2 > LC_FREQ * 2 and
+	 *   REF_MIN * r2 < LC_FREQ * 2
+	 *
+	 * Which means the desired boundaries for r2 are:
+	 *  LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
+	 *
+	 */
+	for (r2 = LC_FREQ * 2 / REF_MAX + 1;
+	     r2 <= LC_FREQ * 2 / REF_MIN;
+	     r2++) {
+
+		/*
+		 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
+		 *
+		 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
+		 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
+		 *   VCO_MAX * r2 > n2 * LC_FREQ and
+		 *   VCO_MIN * r2 < n2 * LC_FREQ)
+		 *
+		 * Which means the desired boundaries for n2 are:
+		 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
+		 */
+		for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
+		     n2 <= VCO_MAX * r2 / LC_FREQ;
+		     n2++) {
+
+			for (p = P_MIN; p <= P_MAX; p += P_INC)
+				hsw_wrpll_update_rnp(freq2k, budget,
+						     r2, n2, p, &best);
+		}
+	}
+
+	*n2_out = best.n2;
+	*p_out = best.p;
+	*r2_out = best.r2;
+}
+
 static struct intel_shared_dpll *
-hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
+hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
 {
 	struct intel_shared_dpll *pll;
+	int clock = crtc_state->port_clock;
 
-	pll = intel_find_shared_dpll(crtc, crtc_state,
-				     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
-	if (pll)
-		intel_reference_shared_dpll(pll, crtc_state);
+	if (encoder->type == INTEL_OUTPUT_HDMI) {
+		uint32_t val;
+		unsigned p, n2, r2;
+
+		hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
+
+		val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
+		      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_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;
+
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_SPLL, DPLL_ID_SPLL);
+	} else {
+		return NULL;
+	}
+
+	if (!pll)
+		return NULL;
+
+	crtc_state->ddi_pll_sel = hsw_pll_to_ddi_pll_sel(pll);
+
+	intel_reference_shared_dpll(pll, crtc_state);
 
 	return pll;
 }
@@ -570,7 +838,8 @@ out:
 }
 
 static struct intel_shared_dpll *
-skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
+skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
+	     struct intel_encoder *encoder)
 {
 	struct intel_shared_dpll *pll;
 
@@ -771,10 +1040,10 @@ out:
 }
 
 static struct intel_shared_dpll *
-bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
+bxt_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_encoder *encoder;
 	struct intel_digital_port *intel_dig_port;
 	struct intel_shared_dpll *pll;
 	enum intel_dpll_id i;
@@ -844,7 +1113,8 @@ struct intel_dpll_mgr {
 	const struct dpll_info *dpll_info;
 
 	struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
-					      struct intel_crtc_state *crtc_state);
+					      struct intel_crtc_state *crtc_state,
+					      struct intel_encoder *encoder);
 };
 
 static const struct dpll_info pch_plls[] = {
@@ -937,13 +1207,14 @@ void intel_shared_dpll_init(struct drm_device *dev)
 
 struct intel_shared_dpll *
 intel_get_shared_dpll(struct intel_crtc *crtc,
-		      struct intel_crtc_state *crtc_state)
+		      struct intel_crtc_state *crtc_state,
+		      struct intel_encoder *encoder)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
 
 	if (dpll_mgr)
-		return dpll_mgr->get_dpll(crtc, crtc_state);
+		return dpll_mgr->get_dpll(crtc, crtc_state, encoder);
 	else
 		return NULL;
 }
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index 7794c7a..82e53f5 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -25,11 +25,19 @@
 #ifndef _INTEL_DPLL_MGR_H_
 #define _INTEL_DPLL_MGR_H_
 
+/*FIXME: Move this to a more appropriate place. */
+#define abs_diff(a, b) ({			\
+	typeof(a) __a = (a);			\
+	typeof(b) __b = (b);			\
+	(void) (&__a == &__b);			\
+	__a > __b ? (__a - __b) : (__b - __a); })
+
 struct drm_i915_private;
 struct intel_crtc;
 struct intel_crtc_state;
-struct intel_shared_dpll;
+struct intel_encoder;
 
+struct intel_shared_dpll;
 struct intel_dpll_mgr;
 
 enum intel_dpll_id {
@@ -133,7 +141,8 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
 #define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
 #define assert_shared_dpll_disabled(d, p) assert_shared_dpll(d, p, false)
 struct intel_shared_dpll *intel_get_shared_dpll(struct intel_crtc *crtc,
-						struct intel_crtc_state *state);
+						struct intel_crtc_state *state,
+						struct intel_encoder *encoder);
 void intel_prepare_shared_dpll(struct intel_crtc *crtc);
 void intel_enable_shared_dpll(struct intel_crtc *crtc);
 void intel_disable_shared_dpll(struct intel_crtc *crtc);
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/13] drm/i915: Move SKL/KLB pll selection logic to intel_dpll_mgr.c
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (8 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 09/13] drm/i915: Move HSW/BDW pll selection logic to intel_dpll_mgr.c Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 11/13] drm/i915: Move BXT pll configuration " Ander Conselvan de Oliveira
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move the code for selecting plls for SKL/KLB into the shared dpll code,
so that the platform specific details are hidden behind that interface.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      | 301 +--------------------------------
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 307 +++++++++++++++++++++++++++++++++-
 2 files changed, 306 insertions(+), 302 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index e1585a5..8258acd 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1005,311 +1005,15 @@ hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
 	}
 }
 
-struct skl_wrpll_context {
-	uint64_t min_deviation;		/* current minimal deviation */
-	uint64_t central_freq;		/* chosen central freq */
-	uint64_t dco_freq;		/* chosen dco freq */
-	unsigned int p;			/* chosen divider */
-};
-
-static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
-{
-	memset(ctx, 0, sizeof(*ctx));
-
-	ctx->min_deviation = U64_MAX;
-}
-
-/* DCO freq must be within +1%/-6%  of the DCO central freq */
-#define SKL_DCO_MAX_PDEVIATION	100
-#define SKL_DCO_MAX_NDEVIATION	600
-
-static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
-				  uint64_t central_freq,
-				  uint64_t dco_freq,
-				  unsigned int divider)
-{
-	uint64_t deviation;
-
-	deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
-			      central_freq);
-
-	/* positive deviation */
-	if (dco_freq >= central_freq) {
-		if (deviation < SKL_DCO_MAX_PDEVIATION &&
-		    deviation < ctx->min_deviation) {
-			ctx->min_deviation = deviation;
-			ctx->central_freq = central_freq;
-			ctx->dco_freq = dco_freq;
-			ctx->p = divider;
-		}
-	/* negative deviation */
-	} else if (deviation < SKL_DCO_MAX_NDEVIATION &&
-		   deviation < ctx->min_deviation) {
-		ctx->min_deviation = deviation;
-		ctx->central_freq = central_freq;
-		ctx->dco_freq = dco_freq;
-		ctx->p = divider;
-	}
-}
-
-static void skl_wrpll_get_multipliers(unsigned int p,
-				      unsigned int *p0 /* out */,
-				      unsigned int *p1 /* out */,
-				      unsigned int *p2 /* out */)
-{
-	/* even dividers */
-	if (p % 2 == 0) {
-		unsigned int half = p / 2;
-
-		if (half == 1 || half == 2 || half == 3 || half == 5) {
-			*p0 = 2;
-			*p1 = 1;
-			*p2 = half;
-		} else if (half % 2 == 0) {
-			*p0 = 2;
-			*p1 = half / 2;
-			*p2 = 2;
-		} else if (half % 3 == 0) {
-			*p0 = 3;
-			*p1 = half / 3;
-			*p2 = 2;
-		} else if (half % 7 == 0) {
-			*p0 = 7;
-			*p1 = half / 7;
-			*p2 = 2;
-		}
-	} else if (p == 3 || p == 9) {  /* 3, 5, 7, 9, 15, 21, 35 */
-		*p0 = 3;
-		*p1 = 1;
-		*p2 = p / 3;
-	} else if (p == 5 || p == 7) {
-		*p0 = p;
-		*p1 = 1;
-		*p2 = 1;
-	} else if (p == 15) {
-		*p0 = 3;
-		*p1 = 1;
-		*p2 = 5;
-	} else if (p == 21) {
-		*p0 = 7;
-		*p1 = 1;
-		*p2 = 3;
-	} else if (p == 35) {
-		*p0 = 7;
-		*p1 = 1;
-		*p2 = 5;
-	}
-}
-
-struct skl_wrpll_params {
-	uint32_t        dco_fraction;
-	uint32_t        dco_integer;
-	uint32_t        qdiv_ratio;
-	uint32_t        qdiv_mode;
-	uint32_t        kdiv;
-	uint32_t        pdiv;
-	uint32_t        central_freq;
-};
-
-static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
-				      uint64_t afe_clock,
-				      uint64_t central_freq,
-				      uint32_t p0, uint32_t p1, uint32_t p2)
-{
-	uint64_t dco_freq;
-
-	switch (central_freq) {
-	case 9600000000ULL:
-		params->central_freq = 0;
-		break;
-	case 9000000000ULL:
-		params->central_freq = 1;
-		break;
-	case 8400000000ULL:
-		params->central_freq = 3;
-	}
-
-	switch (p0) {
-	case 1:
-		params->pdiv = 0;
-		break;
-	case 2:
-		params->pdiv = 1;
-		break;
-	case 3:
-		params->pdiv = 2;
-		break;
-	case 7:
-		params->pdiv = 4;
-		break;
-	default:
-		WARN(1, "Incorrect PDiv\n");
-	}
-
-	switch (p2) {
-	case 5:
-		params->kdiv = 0;
-		break;
-	case 2:
-		params->kdiv = 1;
-		break;
-	case 3:
-		params->kdiv = 2;
-		break;
-	case 1:
-		params->kdiv = 3;
-		break;
-	default:
-		WARN(1, "Incorrect KDiv\n");
-	}
-
-	params->qdiv_ratio = p1;
-	params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
-
-	dco_freq = p0 * p1 * p2 * afe_clock;
-
-	/*
-	 * Intermediate values are in Hz.
-	 * Divide by MHz to match bsepc
-	 */
-	params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
-	params->dco_fraction =
-		div_u64((div_u64(dco_freq, 24) -
-			 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
-}
-
-static bool
-skl_ddi_calculate_wrpll(int clock /* in Hz */,
-			struct skl_wrpll_params *wrpll_params)
-{
-	uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
-	uint64_t dco_central_freq[3] = {8400000000ULL,
-					9000000000ULL,
-					9600000000ULL};
-	static const int even_dividers[] = {  4,  6,  8, 10, 12, 14, 16, 18, 20,
-					     24, 28, 30, 32, 36, 40, 42, 44,
-					     48, 52, 54, 56, 60, 64, 66, 68,
-					     70, 72, 76, 78, 80, 84, 88, 90,
-					     92, 96, 98 };
-	static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
-	static const struct {
-		const int *list;
-		int n_dividers;
-	} dividers[] = {
-		{ even_dividers, ARRAY_SIZE(even_dividers) },
-		{ odd_dividers, ARRAY_SIZE(odd_dividers) },
-	};
-	struct skl_wrpll_context ctx;
-	unsigned int dco, d, i;
-	unsigned int p0, p1, p2;
-
-	skl_wrpll_context_init(&ctx);
-
-	for (d = 0; d < ARRAY_SIZE(dividers); d++) {
-		for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
-			for (i = 0; i < dividers[d].n_dividers; i++) {
-				unsigned int p = dividers[d].list[i];
-				uint64_t dco_freq = p * afe_clock;
-
-				skl_wrpll_try_divider(&ctx,
-						      dco_central_freq[dco],
-						      dco_freq,
-						      p);
-				/*
-				 * Skip the remaining dividers if we're sure to
-				 * have found the definitive divider, we can't
-				 * improve a 0 deviation.
-				 */
-				if (ctx.min_deviation == 0)
-					goto skip_remaining_dividers;
-			}
-		}
-
-skip_remaining_dividers:
-		/*
-		 * If a solution is found with an even divider, prefer
-		 * this one.
-		 */
-		if (d == 0 && ctx.p)
-			break;
-	}
-
-	if (!ctx.p) {
-		DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
-		return false;
-	}
-
-	/*
-	 * gcc incorrectly analyses that these can be used without being
-	 * initialized. To be fair, it's hard to guess.
-	 */
-	p0 = p1 = p2 = 0;
-	skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
-	skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
-				  p0, p1, p2);
-
-	return true;
-}
-
 static bool
 skl_ddi_pll_select(struct intel_crtc *intel_crtc,
 		   struct intel_crtc_state *crtc_state,
 		   struct intel_encoder *intel_encoder)
 {
 	struct intel_shared_dpll *pll;
-	uint32_t ctrl1, cfgcr1, cfgcr2;
-	int clock = crtc_state->port_clock;
 
-	/*
-	 * See comment in intel_dpll_hw_state to understand why we always use 0
-	 * as the DPLL id in this function.
-	 */
-
-	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
-
-	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
-		struct skl_wrpll_params wrpll_params = { 0, };
-
-		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
-
-		if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
-			return false;
-
-		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
-			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
-			 wrpll_params.dco_integer;
-
-		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
-			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
-			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
-			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
-			 wrpll_params.central_freq;
-	} else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
-		   intel_encoder->type == INTEL_OUTPUT_DP_MST) {
-		switch (crtc_state->port_clock / 2) {
-		case 81000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
-			break;
-		case 135000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
-			break;
-		case 270000:
-			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
-			break;
-		}
-
-		cfgcr1 = cfgcr2 = 0;
-	} else if (intel_encoder->type == INTEL_OUTPUT_EDP) {
+	if (intel_encoder->type == INTEL_OUTPUT_EDP)
 		return true;
-	} else
-		return false;
-
-	memset(&crtc_state->dpll_hw_state, 0,
-	       sizeof(crtc_state->dpll_hw_state));
-
-	crtc_state->dpll_hw_state.ctrl1 = ctrl1;
-	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
-	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
 
 	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
 	if (pll == NULL) {
@@ -1318,9 +1022,6 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
 		return false;
 	}
 
-	/* shared DPLL id 0 is DPLL 1 */
-	crtc_state->ddi_pll_sel = pll->id + 1;
-
 	return true;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index d1e8544..b118d77 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -837,16 +837,319 @@ out:
 	return ret;
 }
 
+struct skl_wrpll_context {
+	uint64_t min_deviation;		/* current minimal deviation */
+	uint64_t central_freq;		/* chosen central freq */
+	uint64_t dco_freq;		/* chosen dco freq */
+	unsigned int p;			/* chosen divider */
+};
+
+static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
+{
+	memset(ctx, 0, sizeof(*ctx));
+
+	ctx->min_deviation = U64_MAX;
+}
+
+/* DCO freq must be within +1%/-6%  of the DCO central freq */
+#define SKL_DCO_MAX_PDEVIATION	100
+#define SKL_DCO_MAX_NDEVIATION	600
+
+static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
+				  uint64_t central_freq,
+				  uint64_t dco_freq,
+				  unsigned int divider)
+{
+	uint64_t deviation;
+
+	deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
+			      central_freq);
+
+	/* positive deviation */
+	if (dco_freq >= central_freq) {
+		if (deviation < SKL_DCO_MAX_PDEVIATION &&
+		    deviation < ctx->min_deviation) {
+			ctx->min_deviation = deviation;
+			ctx->central_freq = central_freq;
+			ctx->dco_freq = dco_freq;
+			ctx->p = divider;
+		}
+	/* negative deviation */
+	} else if (deviation < SKL_DCO_MAX_NDEVIATION &&
+		   deviation < ctx->min_deviation) {
+		ctx->min_deviation = deviation;
+		ctx->central_freq = central_freq;
+		ctx->dco_freq = dco_freq;
+		ctx->p = divider;
+	}
+}
+
+static void skl_wrpll_get_multipliers(unsigned int p,
+				      unsigned int *p0 /* out */,
+				      unsigned int *p1 /* out */,
+				      unsigned int *p2 /* out */)
+{
+	/* even dividers */
+	if (p % 2 == 0) {
+		unsigned int half = p / 2;
+
+		if (half == 1 || half == 2 || half == 3 || half == 5) {
+			*p0 = 2;
+			*p1 = 1;
+			*p2 = half;
+		} else if (half % 2 == 0) {
+			*p0 = 2;
+			*p1 = half / 2;
+			*p2 = 2;
+		} else if (half % 3 == 0) {
+			*p0 = 3;
+			*p1 = half / 3;
+			*p2 = 2;
+		} else if (half % 7 == 0) {
+			*p0 = 7;
+			*p1 = half / 7;
+			*p2 = 2;
+		}
+	} else if (p == 3 || p == 9) {  /* 3, 5, 7, 9, 15, 21, 35 */
+		*p0 = 3;
+		*p1 = 1;
+		*p2 = p / 3;
+	} else if (p == 5 || p == 7) {
+		*p0 = p;
+		*p1 = 1;
+		*p2 = 1;
+	} else if (p == 15) {
+		*p0 = 3;
+		*p1 = 1;
+		*p2 = 5;
+	} else if (p == 21) {
+		*p0 = 7;
+		*p1 = 1;
+		*p2 = 3;
+	} else if (p == 35) {
+		*p0 = 7;
+		*p1 = 1;
+		*p2 = 5;
+	}
+}
+
+struct skl_wrpll_params {
+	uint32_t        dco_fraction;
+	uint32_t        dco_integer;
+	uint32_t        qdiv_ratio;
+	uint32_t        qdiv_mode;
+	uint32_t        kdiv;
+	uint32_t        pdiv;
+	uint32_t        central_freq;
+};
+
+static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
+				      uint64_t afe_clock,
+				      uint64_t central_freq,
+				      uint32_t p0, uint32_t p1, uint32_t p2)
+{
+	uint64_t dco_freq;
+
+	switch (central_freq) {
+	case 9600000000ULL:
+		params->central_freq = 0;
+		break;
+	case 9000000000ULL:
+		params->central_freq = 1;
+		break;
+	case 8400000000ULL:
+		params->central_freq = 3;
+	}
+
+	switch (p0) {
+	case 1:
+		params->pdiv = 0;
+		break;
+	case 2:
+		params->pdiv = 1;
+		break;
+	case 3:
+		params->pdiv = 2;
+		break;
+	case 7:
+		params->pdiv = 4;
+		break;
+	default:
+		WARN(1, "Incorrect PDiv\n");
+	}
+
+	switch (p2) {
+	case 5:
+		params->kdiv = 0;
+		break;
+	case 2:
+		params->kdiv = 1;
+		break;
+	case 3:
+		params->kdiv = 2;
+		break;
+	case 1:
+		params->kdiv = 3;
+		break;
+	default:
+		WARN(1, "Incorrect KDiv\n");
+	}
+
+	params->qdiv_ratio = p1;
+	params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
+
+	dco_freq = p0 * p1 * p2 * afe_clock;
+
+	/*
+	 * Intermediate values are in Hz.
+	 * Divide by MHz to match bsepc
+	 */
+	params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
+	params->dco_fraction =
+		div_u64((div_u64(dco_freq, 24) -
+			 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
+}
+
+static bool
+skl_ddi_calculate_wrpll(int clock /* in Hz */,
+			struct skl_wrpll_params *wrpll_params)
+{
+	uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
+	uint64_t dco_central_freq[3] = {8400000000ULL,
+					9000000000ULL,
+					9600000000ULL};
+	static const int even_dividers[] = {  4,  6,  8, 10, 12, 14, 16, 18, 20,
+					     24, 28, 30, 32, 36, 40, 42, 44,
+					     48, 52, 54, 56, 60, 64, 66, 68,
+					     70, 72, 76, 78, 80, 84, 88, 90,
+					     92, 96, 98 };
+	static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
+	static const struct {
+		const int *list;
+		int n_dividers;
+	} dividers[] = {
+		{ even_dividers, ARRAY_SIZE(even_dividers) },
+		{ odd_dividers, ARRAY_SIZE(odd_dividers) },
+	};
+	struct skl_wrpll_context ctx;
+	unsigned int dco, d, i;
+	unsigned int p0, p1, p2;
+
+	skl_wrpll_context_init(&ctx);
+
+	for (d = 0; d < ARRAY_SIZE(dividers); d++) {
+		for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
+			for (i = 0; i < dividers[d].n_dividers; i++) {
+				unsigned int p = dividers[d].list[i];
+				uint64_t dco_freq = p * afe_clock;
+
+				skl_wrpll_try_divider(&ctx,
+						      dco_central_freq[dco],
+						      dco_freq,
+						      p);
+				/*
+				 * Skip the remaining dividers if we're sure to
+				 * have found the definitive divider, we can't
+				 * improve a 0 deviation.
+				 */
+				if (ctx.min_deviation == 0)
+					goto skip_remaining_dividers;
+			}
+		}
+
+skip_remaining_dividers:
+		/*
+		 * If a solution is found with an even divider, prefer
+		 * this one.
+		 */
+		if (d == 0 && ctx.p)
+			break;
+	}
+
+	if (!ctx.p) {
+		DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
+		return false;
+	}
+
+	/*
+	 * gcc incorrectly analyses that these can be used without being
+	 * initialized. To be fair, it's hard to guess.
+	 */
+	p0 = p1 = p2 = 0;
+	skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
+	skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
+				  p0, p1, p2);
+
+	return true;
+}
+
 static struct intel_shared_dpll *
 skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	     struct intel_encoder *encoder)
 {
 	struct intel_shared_dpll *pll;
+	uint32_t ctrl1, cfgcr1, cfgcr2;
+	int clock = crtc_state->port_clock;
+
+	/*
+	 * See comment in intel_dpll_hw_state to understand why we always use 0
+	 * as the DPLL id in this function.
+	 */
+
+	ctrl1 = DPLL_CTRL1_OVERRIDE(0);
+
+	if (encoder->type == INTEL_OUTPUT_HDMI) {
+		struct skl_wrpll_params wrpll_params = { 0, };
+
+		ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
+
+		if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
+			return false;
+
+		cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
+			 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
+			 wrpll_params.dco_integer;
+
+		cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
+			 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
+			 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
+			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
+			 wrpll_params.central_freq;
+	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		   encoder->type == INTEL_OUTPUT_DP_MST) {
+		switch (crtc_state->port_clock / 2) {
+		case 81000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
+			break;
+		case 135000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
+			break;
+		case 270000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
+			break;
+		}
+
+		cfgcr1 = cfgcr2 = 0;
+	} else {
+		return NULL;
+	}
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	crtc_state->dpll_hw_state.ctrl1 = ctrl1;
+	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
+	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
 
 	pll = intel_find_shared_dpll(crtc, crtc_state,
 				     DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3);
-	if (pll)
-		intel_reference_shared_dpll(pll, crtc_state);
+	if (!pll)
+		return NULL;
+
+	/* shared DPLL id 0 is DPLL 1 */
+	crtc_state->ddi_pll_sel = pll->id + 1;
+
+	intel_reference_shared_dpll(pll, crtc_state);
 
 	return pll;
 }
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 11/13] drm/i915: Move BXT pll configuration logic to intel_dpll_mgr.c
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (9 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 10/13] drm/i915: Move SKL/KLB " Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-26 13:54 ` [PATCH 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface Ander Conselvan de Oliveira
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Move the code for configurating BXT plls into the shared dpll code, so
that the platform specific details are hidden behind that interface.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      | 141 +---------------------------------
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 139 +++++++++++++++++++++++++++++++--
 2 files changed, 134 insertions(+), 146 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 8258acd..ad7888c 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1025,151 +1025,12 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
 	return true;
 }
 
-/* bxt clock parameters */
-struct bxt_clk_div {
-	int clock;
-	uint32_t p1;
-	uint32_t p2;
-	uint32_t m2_int;
-	uint32_t m2_frac;
-	bool m2_frac_en;
-	uint32_t n;
-};
-
-/* pre-calculated values for DP linkrates */
-static const struct bxt_clk_div bxt_dp_clk_val[] = {
-	{162000, 4, 2, 32, 1677722, 1, 1},
-	{270000, 4, 1, 27,       0, 0, 1},
-	{540000, 2, 1, 27,       0, 0, 1},
-	{216000, 3, 2, 32, 1677722, 1, 1},
-	{243000, 4, 1, 24, 1258291, 1, 1},
-	{324000, 4, 1, 32, 1677722, 1, 1},
-	{432000, 3, 1, 32, 1677722, 1, 1}
-};
-
 static bool
 bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
 		   struct intel_crtc_state *crtc_state,
 		   struct intel_encoder *intel_encoder)
 {
-	struct intel_shared_dpll *pll;
-	struct bxt_clk_div clk_div = {0};
-	int vco = 0;
-	uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
-	uint32_t lanestagger;
-	int clock = crtc_state->port_clock;
-
-	if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
-		intel_clock_t best_clock;
-
-		/* Calculate HDMI div */
-		/*
-		 * FIXME: tie the following calculation into
-		 * i9xx_crtc_compute_clock
-		 */
-		if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
-			DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
-					 clock, pipe_name(intel_crtc->pipe));
-			return false;
-		}
-
-		clk_div.p1 = best_clock.p1;
-		clk_div.p2 = best_clock.p2;
-		WARN_ON(best_clock.m1 != 2);
-		clk_div.n = best_clock.n;
-		clk_div.m2_int = best_clock.m2 >> 22;
-		clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
-		clk_div.m2_frac_en = clk_div.m2_frac != 0;
-
-		vco = best_clock.vco;
-	} else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
-			intel_encoder->type == INTEL_OUTPUT_EDP) {
-		int i;
-
-		clk_div = bxt_dp_clk_val[0];
-		for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
-			if (bxt_dp_clk_val[i].clock == clock) {
-				clk_div = bxt_dp_clk_val[i];
-				break;
-			}
-		}
-		vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
-	}
-
-	if (vco >= 6200000 && vco <= 6700000) {
-		prop_coef = 4;
-		int_coef = 9;
-		gain_ctl = 3;
-		targ_cnt = 8;
-	} else if ((vco > 5400000 && vco < 6200000) ||
-			(vco >= 4800000 && vco < 5400000)) {
-		prop_coef = 5;
-		int_coef = 11;
-		gain_ctl = 3;
-		targ_cnt = 9;
-	} else if (vco == 5400000) {
-		prop_coef = 3;
-		int_coef = 8;
-		gain_ctl = 1;
-		targ_cnt = 9;
-	} else {
-		DRM_ERROR("Invalid VCO\n");
-		return false;
-	}
-
-	memset(&crtc_state->dpll_hw_state, 0,
-	       sizeof(crtc_state->dpll_hw_state));
-
-	if (clock > 270000)
-		lanestagger = 0x18;
-	else if (clock > 135000)
-		lanestagger = 0x0d;
-	else if (clock > 67000)
-		lanestagger = 0x07;
-	else if (clock > 33000)
-		lanestagger = 0x04;
-	else
-		lanestagger = 0x02;
-
-	crtc_state->dpll_hw_state.ebb0 =
-		PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
-	crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
-	crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
-	crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
-
-	if (clk_div.m2_frac_en)
-		crtc_state->dpll_hw_state.pll3 =
-			PORT_PLL_M2_FRAC_ENABLE;
-
-	crtc_state->dpll_hw_state.pll6 =
-		prop_coef | PORT_PLL_INT_COEFF(int_coef);
-	crtc_state->dpll_hw_state.pll6 |=
-		PORT_PLL_GAIN_CTL(gain_ctl);
-
-	crtc_state->dpll_hw_state.pll8 = targ_cnt;
-
-	crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
-
-	crtc_state->dpll_hw_state.pll10 =
-		PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
-		| PORT_PLL_DCO_AMP_OVR_EN_H;
-
-	crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
-
-	crtc_state->dpll_hw_state.pcsdw12 =
-		LANESTAGGER_STRAP_OVRD | lanestagger;
-
-	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
-	if (pll == NULL) {
-		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
-			pipe_name(intel_crtc->pipe));
-		return false;
-	}
-
-	/* shared DPLL id 0 is DPLL A */
-	crtc_state->ddi_pll_sel = pll->id;
-
-	return true;
+	return !!intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
index b118d77..043b7a4 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -1342,29 +1342,156 @@ out:
 	return ret;
 }
 
+/* bxt clock parameters */
+struct bxt_clk_div {
+	int clock;
+	uint32_t p1;
+	uint32_t p2;
+	uint32_t m2_int;
+	uint32_t m2_frac;
+	bool m2_frac_en;
+	uint32_t n;
+};
+
+/* pre-calculated values for DP linkrates */
+static const struct bxt_clk_div bxt_dp_clk_val[] = {
+	{162000, 4, 2, 32, 1677722, 1, 1},
+	{270000, 4, 1, 27,       0, 0, 1},
+	{540000, 2, 1, 27,       0, 0, 1},
+	{216000, 3, 2, 32, 1677722, 1, 1},
+	{243000, 4, 1, 24, 1258291, 1, 1},
+	{324000, 4, 1, 32, 1677722, 1, 1},
+	{432000, 3, 1, 32, 1677722, 1, 1}
+};
+
 static struct intel_shared_dpll *
 bxt_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_digital_port *intel_dig_port;
 	struct intel_shared_dpll *pll;
 	enum intel_dpll_id i;
+	struct intel_digital_port *intel_dig_port;
+	struct bxt_clk_div clk_div = {0};
+	int vco = 0;
+	uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
+	uint32_t lanestagger;
+	int clock = crtc_state->port_clock;
+
+	if (encoder->type == INTEL_OUTPUT_HDMI) {
+		intel_clock_t best_clock;
+
+		/* Calculate HDMI div */
+		/*
+		 * FIXME: tie the following calculation into
+		 * i9xx_crtc_compute_clock
+		 */
+		if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
+			DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
+					 clock, pipe_name(crtc->pipe));
+			return NULL;
+		}
+
+		clk_div.p1 = best_clock.p1;
+		clk_div.p2 = best_clock.p2;
+		WARN_ON(best_clock.m1 != 2);
+		clk_div.n = best_clock.n;
+		clk_div.m2_int = best_clock.m2 >> 22;
+		clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
+		clk_div.m2_frac_en = clk_div.m2_frac != 0;
+
+		vco = best_clock.vco;
+	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
+		   encoder->type == INTEL_OUTPUT_EDP) {
+		int i;
+
+		clk_div = bxt_dp_clk_val[0];
+		for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
+			if (bxt_dp_clk_val[i].clock == clock) {
+				clk_div = bxt_dp_clk_val[i];
+				break;
+			}
+		}
+		vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
+	}
 
-	/* PLL is attached to port in bxt */
-	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
-	if (WARN_ON(!encoder))
+	if (vco >= 6200000 && vco <= 6700000) {
+		prop_coef = 4;
+		int_coef = 9;
+		gain_ctl = 3;
+		targ_cnt = 8;
+	} else if ((vco > 5400000 && vco < 6200000) ||
+			(vco >= 4800000 && vco < 5400000)) {
+		prop_coef = 5;
+		int_coef = 11;
+		gain_ctl = 3;
+		targ_cnt = 9;
+	} else if (vco == 5400000) {
+		prop_coef = 3;
+		int_coef = 8;
+		gain_ctl = 1;
+		targ_cnt = 9;
+	} else {
+		DRM_ERROR("Invalid VCO\n");
 		return NULL;
+	}
+
+	memset(&crtc_state->dpll_hw_state, 0,
+	       sizeof(crtc_state->dpll_hw_state));
+
+	if (clock > 270000)
+		lanestagger = 0x18;
+	else if (clock > 135000)
+		lanestagger = 0x0d;
+	else if (clock > 67000)
+		lanestagger = 0x07;
+	else if (clock > 33000)
+		lanestagger = 0x04;
+	else
+		lanestagger = 0x02;
+
+	crtc_state->dpll_hw_state.ebb0 =
+		PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
+	crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
+	crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
+	crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
+
+	if (clk_div.m2_frac_en)
+		crtc_state->dpll_hw_state.pll3 =
+			PORT_PLL_M2_FRAC_ENABLE;
+
+	crtc_state->dpll_hw_state.pll6 =
+		prop_coef | PORT_PLL_INT_COEFF(int_coef);
+	crtc_state->dpll_hw_state.pll6 |=
+		PORT_PLL_GAIN_CTL(gain_ctl);
+
+	crtc_state->dpll_hw_state.pll8 = targ_cnt;
+
+	crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
+
+	crtc_state->dpll_hw_state.pll10 =
+		PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
+		| PORT_PLL_DCO_AMP_OVR_EN_H;
+
+	crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
+
+	crtc_state->dpll_hw_state.pcsdw12 =
+		LANESTAGGER_STRAP_OVRD | lanestagger;
 
 	intel_dig_port = enc_to_dig_port(&encoder->base);
+
 	/* 1:1 mapping between ports and PLLs */
-	i = (enum intel_dpll_id)intel_dig_port->port;
-	pll = &dev_priv->shared_dplls[i];
+	i = (enum intel_dpll_id) intel_dig_port->port;
+	pll = intel_get_shared_dpll_by_id(dev_priv, i);
+
 	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
 		crtc->base.base.id, pll->name);
 
 	intel_reference_shared_dpll(pll, crtc_state);
 
+	/* shared DPLL id 0 is DPLL A */
+	crtc_state->ddi_pll_sel = pll->id;
+
 	return pll;
 }
 
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (10 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 11/13] drm/i915: Move BXT pll configuration " Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-29  9:08   ` [PATCH v2 " Ander Conselvan de Oliveira
  2016-03-08 11:05   ` [PATCH " Maarten Lankhorst
  2016-02-26 13:54 ` [PATCH 13/13] drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code Ander Conselvan de Oliveira
  2016-02-26 14:27 ` ✗ Fi.CI.BAT: failure for Shared pll improvements Patchwork
  13 siblings, 2 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Manage the LCPLLs used with DisplayPort, so that all the HSW/BDW DPLLs
are managed by the shared dpll code.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c      | 18 ++++----
 drivers/gpu/drm/i915/intel_display.c  | 35 ++++++++++++----
 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 | 79 +++++++++++++++++++++++++++++++----
 drivers/gpu/drm/i915/intel_dpll_mgr.h |  5 ++-
 drivers/gpu/drm/i915/intel_drv.h      |  1 -
 7 files changed, 110 insertions(+), 55 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..9ca31e2 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;
 	}
 
@@ -9695,8 +9701,17 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
 
 	pll = pipe_config->shared_dpll;
 	if (pll) {
-		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
-						 &pipe_config->dpll_hw_state));
+		bool enabled =
+			pll->funcs.get_hw_state(dev_priv, pll,
+						&pipe_config->dpll_hw_state);
+
+		/*
+		 * We keep LCPLL always enabled but its ->get_hw_state() return
+		 * value relies on the crtc_mask to please the state checker.
+		 * That may not have been set yet, so just ignore the value for
+		 * those PLLs, since it shouldn't really matter.
+		 */
+		WARN_ON(pll->id < DPLL_ID_LCPLL_810 && !enabled);
 	}
 
 	/*
@@ -15466,8 +15481,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
 		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
 
-		pll->on = pll->funcs.get_hw_state(dev_priv, pll,
-						  &pll->config.hw_state);
 		pll->active = 0;
 		pll->config.crtc_mask = 0;
 		for_each_intel_crtc(dev, crtc) {
@@ -15477,6 +15490,14 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			}
 		}
 
+		/*
+		 *  Set this after updating crtc_mask because of LCPLL in HSW,
+		 *  since that's always kept enabled and the return value of
+		 *  get_hw_state() depends on that mask.
+		 */
+		pll->on = pll->funcs.get_hw_state(dev_priv, pll,
+						  &pll->config.hw_state);
+
 		DRM_DEBUG_KMS("%s hw state readout: crtc_mask 0x%08x, on %i\n",
 			      pll->name, pll->config.crtc_mask, pll->on);
 
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..78ce487 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,38 @@ 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)
+{
+	/*
+	 * LC PLL is kept enabled all the time since it drives CDCLK. The
+	 * state checker still expects it to be disabled when it is not used
+	 * by any crtc. To avoid adding a case to LC PLL, just tell the
+	 * state checker what it expects.
+	 */
+	if (pll->config.crtc_mask)
+		return true;
+	else
+		return false;
+}
+
+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;
 };
@@ -1559,9 +1617,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 },
+	{ "WRPLL 2",    DPLL_ID_WRPLL2,     &hsw_ddi_wrpll_funcs },
+	{ "SPLL",       DPLL_ID_SPLL,       &hsw_ddi_spll_funcs },
+	{ "LCPLL 810",  DPLL_ID_LCPLL_810,  &hsw_ddi_lcpll_funcs },
+	{ "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs },
+	{ "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs },
 	{ 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..872878e 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -49,13 +49,16 @@ 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
 
 struct intel_dpll_hw_state {
 	/* i9xx, pch plls */
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,
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 13/13] drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (11 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface Ander Conselvan de Oliveira
@ 2016-02-26 13:54 ` Ander Conselvan de Oliveira
  2016-02-29  9:08   ` [PATCH v3 " Ander Conselvan de Oliveira
  2016-02-26 14:27 ` ✗ Fi.CI.BAT: failure for Shared pll improvements Patchwork
  13 siblings, 1 reply; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-26 13:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Include DPLL0 in the managed dplls for SKL/KBL. While it has to be kept
enabled because of it driving CDCLK, it is better to special case that
inside the DPLL code than in the higher level.

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>

---
I wasn't able to test this patch. Would really appreciate a tested by
from someone.

---
 drivers/gpu/drm/i915/intel_ddi.c      |  21 ------
 drivers/gpu/drm/i915/intel_dp.c       |  52 +-------------
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 126 +++++++++++++++++++++++++++-------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |   7 +-
 4 files changed, 107 insertions(+), 99 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 3cb9f36..8ef4d2e 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1008,9 +1008,6 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
 {
 	struct intel_shared_dpll *pll;
 
-	if (intel_encoder->type == INTEL_OUTPUT_EDP)
-		return true;
-
 	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
 	if (pll == NULL) {
 		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
@@ -1570,24 +1567,6 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
 		uint32_t dpll = pipe_config->ddi_pll_sel;
 		uint32_t val;
 
-		/*
-		 * DPLL0 is used for eDP and is the only "private" DPLL (as
-		 * opposed to shared) on SKL
-		 */
-		if (encoder->type == INTEL_OUTPUT_EDP) {
-			WARN_ON(dpll != SKL_DPLL0);
-
-			val = I915_READ(DPLL_CTRL1);
-
-			val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
-				 DPLL_CTRL1_SSC(dpll) |
-				 DPLL_CTRL1_LINK_RATE_MASK(dpll));
-			val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
-
-			I915_WRITE(DPLL_CTRL1, val);
-			POSTING_READ(DPLL_CTRL1);
-		}
-
 		/* DDI -> PLL mapping  */
 		val = I915_READ(DPLL_CTRL2);
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5be6892..9fef877 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1229,52 +1229,6 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector)
 	intel_connector_unregister(intel_connector);
 }
 
-static void
-skl_edp_set_pll_config(struct intel_crtc_state *pipe_config)
-{
-	u32 ctrl1;
-
-	memset(&pipe_config->dpll_hw_state, 0,
-	       sizeof(pipe_config->dpll_hw_state));
-
-	pipe_config->ddi_pll_sel = SKL_DPLL0;
-	pipe_config->dpll_hw_state.cfgcr1 = 0;
-	pipe_config->dpll_hw_state.cfgcr2 = 0;
-
-	ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
-	switch (pipe_config->port_clock / 2) {
-	case 81000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
-					      SKL_DPLL0);
-		break;
-	case 135000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350,
-					      SKL_DPLL0);
-		break;
-	case 270000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700,
-					      SKL_DPLL0);
-		break;
-	case 162000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620,
-					      SKL_DPLL0);
-		break;
-	/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
-	results in CDCLK change. Need to handle the change of CDCLK by
-	disabling pipes and re-enabling them */
-	case 108000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
-					      SKL_DPLL0);
-		break;
-	case 216000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160,
-					      SKL_DPLL0);
-		break;
-
-	}
-	pipe_config->dpll_hw_state.ctrl1 = ctrl1;
-}
-
 static int
 intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
 {
@@ -1632,11 +1586,7 @@ found:
 				&pipe_config->dp_m2_n2);
 	}
 
-	if ((IS_SKYLAKE(dev)  || IS_KABYLAKE(dev)) && is_edp(intel_dp))
-		skl_edp_set_pll_config(pipe_config);
-	else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
-		/* handled in ddi */;
-	else
+	if (!HAS_DDI(dev))
 		intel_dp_set_clock(encoder, 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 78ce487..c695a28 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -794,7 +794,12 @@ struct skl_dpll_regs {
 };
 
 /* this array is indexed by the *shared* pll id */
-static const struct skl_dpll_regs skl_dpll_regs[3] = {
+static const struct skl_dpll_regs skl_dpll_regs[4] = {
+	{
+		/* DPLL 0 */
+		.ctl = LCPLL1_CTL,
+		/* DPLL 0 doesn't support HDMI mode */
+	},
 	{
 		/* DPLL 1 */
 		.ctl = LCPLL2_CTL,
@@ -815,24 +820,29 @@ static const struct skl_dpll_regs skl_dpll_regs[3] = {
 	},
 };
 
-static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
-			       struct intel_shared_dpll *pll)
+static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
+				    struct intel_shared_dpll *pll)
 {
 	uint32_t val;
-	unsigned int dpll;
-	const struct skl_dpll_regs *regs = skl_dpll_regs;
-
-	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
-	dpll = pll->id + 1;
 
 	val = I915_READ(DPLL_CTRL1);
 
-	val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
-		 DPLL_CTRL1_LINK_RATE_MASK(dpll));
-	val |= pll->config.hw_state.ctrl1 << (dpll * 6);
+	val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
+		 DPLL_CTRL1_LINK_RATE_MASK(pll->id));
+	val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
 
 	I915_WRITE(DPLL_CTRL1, val);
 	POSTING_READ(DPLL_CTRL1);
+}
+
+static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
+			       struct intel_shared_dpll *pll)
+{
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+
+	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
+
+	skl_ddi_pll_write_ctrl1(dev_priv, pll);
 
 	I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
 	I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
@@ -843,8 +853,15 @@ static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
 	I915_WRITE(regs[pll->id].ctl,
 		   I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
 
-	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
-		DRM_ERROR("DPLL %d not locked\n", dpll);
+	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
+		DRM_ERROR("DPLL %d not locked\n", pll->id);
+}
+
+static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll)
+{
+	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
+	skl_ddi_pll_write_ctrl1(dev_priv, pll);
 }
 
 static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
@@ -858,32 +875,35 @@ static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
 	POSTING_READ(regs[pll->id].ctl);
 }
 
+static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll *pll)
+{
+}
+
 static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
 				     struct intel_shared_dpll *pll,
 				     struct intel_dpll_hw_state *hw_state)
 {
 	uint32_t val;
-	unsigned int dpll;
 	const struct skl_dpll_regs *regs = skl_dpll_regs;
 	bool ret;
 
+	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
+
 	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
 		return false;
 
 	ret = false;
 
-	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
-	dpll = pll->id + 1;
-
 	val = I915_READ(regs[pll->id].ctl);
 	if (!(val & LCPLL_PLL_ENABLE))
 		goto out;
 
 	val = I915_READ(DPLL_CTRL1);
-	hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
+	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
 
 	/* avoid reading back stale values if HDMI mode is not enabled */
-	if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
+	if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
 		hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
 		hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
 	}
@@ -895,6 +915,38 @@ out:
 	return ret;
 }
 
+static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
+				       struct intel_shared_dpll *pll,
+				       struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+	bool ret;
+
+	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	/*
+	 *  DPLL0 is always enabled since it drives CDCLK. We return whether
+	 *  the pll is in use by a crtc to please the state checker.
+	 */
+	ret = !!pll->config.crtc_mask;
+
+	val = I915_READ(regs[pll->id].ctl);
+	WARN_ON(!(val & LCPLL_PLL_ENABLE));
+
+	if (ret) {
+		val = I915_READ(DPLL_CTRL1);
+		hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
+	}
+
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return ret;
+}
+
 struct skl_wrpll_context {
 	uint64_t min_deviation;		/* current minimal deviation */
 	uint64_t central_freq;		/* chosen central freq */
@@ -1174,7 +1226,8 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
 			 wrpll_params.central_freq;
 	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
-		   encoder->type == INTEL_OUTPUT_DP_MST) {
+		   encoder->type == INTEL_OUTPUT_DP_MST ||
+		   encoder->type == INTEL_OUTPUT_EDP) {
 		switch (crtc_state->port_clock / 2) {
 		case 81000:
 			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
@@ -1185,6 +1238,19 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 		case 270000:
 			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
 			break;
+		/* eDP 1.4 rates */
+		case 162000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
+			break;
+		/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
+		results in CDCLK change. Need to handle the change of CDCLK by
+		disabling pipes and re-enabling them */
+		case 108000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
+			break;
+		case 216000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
+			break;
 		}
 
 		cfgcr1 = cfgcr2 = 0;
@@ -1199,13 +1265,18 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
 	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
 
-	pll = intel_find_shared_dpll(crtc, crtc_state,
-				     DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3);
+	if (encoder->type == INTEL_OUTPUT_EDP)
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_SKL_DPLL0,
+					     DPLL_ID_SKL_DPLL0);
+	else
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_SKL_DPLL1,
+					     DPLL_ID_SKL_DPLL3);
 	if (!pll)
 		return NULL;
 
-	/* shared DPLL id 0 is DPLL 1 */
-	crtc_state->ddi_pll_sel = pll->id + 1;
+	crtc_state->ddi_pll_sel = pll->id;
 
 	intel_reference_shared_dpll(pll, crtc_state);
 
@@ -1218,6 +1289,12 @@ static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
 	.get_hw_state = skl_ddi_pll_get_hw_state,
 };
 
+static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = {
+	.enable = skl_ddi_dpll0_enable,
+	.disable = skl_ddi_dpll0_disable,
+	.get_hw_state = skl_ddi_dpll0_get_hw_state,
+};
+
 static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
 				struct intel_shared_dpll *pll)
 {
@@ -1632,6 +1709,7 @@ static const struct intel_dpll_mgr hsw_pll_mgr = {
 };
 
 static const struct dpll_info skl_plls[] = {
+	{ "DPLL 0", DPLL_ID_SKL_DPLL0, &skl_ddi_dpll0_funcs },
 	{ "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 },
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index 872878e..4189bcf 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -54,9 +54,10 @@ enum intel_dpll_id {
 	DPLL_ID_LCPLL_2700 = 5,
 
 	/* skl */
-	DPLL_ID_SKL_DPLL1 = 0,
-	DPLL_ID_SKL_DPLL2 = 1,
-	DPLL_ID_SKL_DPLL3 = 2,
+	DPLL_ID_SKL_DPLL0 = 0,
+	DPLL_ID_SKL_DPLL1 = 1,
+	DPLL_ID_SKL_DPLL2 = 2,
+	DPLL_ID_SKL_DPLL3 = 3,
 };
 #define I915_NUM_PLLS 6
 
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* ✗ Fi.CI.BAT: failure for Shared pll improvements
  2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
                   ` (12 preceding siblings ...)
  2016-02-26 13:54 ` [PATCH 13/13] drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code Ander Conselvan de Oliveira
@ 2016-02-26 14:27 ` Patchwork
  13 siblings, 0 replies; 31+ messages in thread
From: Patchwork @ 2016-02-26 14:27 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira; +Cc: intel-gfx

== Series Details ==

Series: Shared pll improvements
URL   : https://patchwork.freedesktop.org/series/3850/
State : failure

== Summary ==

Series 3850v1 Shared pll improvements
http://patchwork.freedesktop.org/api/1.0/series/3850/revisions/1/mbox/

Test kms_flip:
        Subgroup basic-flip-vs-dpms:
                pass       -> DMESG-WARN (bdw-ultra)
                dmesg-warn -> PASS       (ilk-hp8440p) UNSTABLE
        Subgroup basic-flip-vs-modeset:
                incomplete -> PASS       (ilk-hp8440p) UNSTABLE
        Subgroup basic-flip-vs-wf_vblank:
                pass       -> FAIL       (snb-x220t)
Test kms_force_connector_basic:
        Subgroup force-load-detect:
                fail       -> DMESG-FAIL (snb-x220t)
                dmesg-fail -> FAIL       (ilk-hp8440p)
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-a:
                pass       -> DMESG-WARN (bdw-ultra)
        Subgroup suspend-read-crc-pipe-b:
                incomplete -> PASS       (hsw-gt2)
                pass       -> DMESG-WARN (bdw-ultra)
        Subgroup suspend-read-crc-pipe-c:
                pass       -> DMESG-WARN (bdw-ultra)
Test pm_rpm:
        Subgroup basic-pci-d3-state:
                pass       -> DMESG-WARN (bsw-nuc-2)

bdw-nuci7        total:166  pass:155  dwarn:0   dfail:0   fail:0   skip:11 
bdw-ultra        total:169  pass:151  dwarn:4   dfail:0   fail:0   skip:14 
bsw-nuc-2        total:169  pass:137  dwarn:1   dfail:0   fail:1   skip:30 
byt-nuc          total:169  pass:144  dwarn:0   dfail:0   fail:0   skip:25 
hsw-brixbox      total:169  pass:155  dwarn:0   dfail:0   fail:0   skip:14 
hsw-gt2          total:169  pass:158  dwarn:0   dfail:1   fail:0   skip:10 
ilk-hp8440p      total:169  pass:119  dwarn:0   dfail:0   fail:1   skip:49 
ivb-t430s        total:169  pass:154  dwarn:0   dfail:0   fail:1   skip:14 
skl-i7k-2        total:169  pass:152  dwarn:1   dfail:0   fail:0   skip:16 
snb-dellxps      total:169  pass:146  dwarn:0   dfail:0   fail:1   skip:22 
snb-x220t        total:169  pass:145  dwarn:0   dfail:1   fail:2   skip:21 

Results at /archive/results/CI_IGT_test/Patchwork_1483/

e511a05b4b3bb4d1dbca99b00af6d0dc0a65d295 drm-intel-nightly: 2016y-02m-26d-13h-42m-46s UTC integration manifest
18253fa9f7d2984ec00687536e95777a19c10f15 drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code
b3041c989419f0d1d72282d697fc3452a66c7548 drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface
56b6dbd16b575c5f7c4715b03bcf47a3c649e1b4 drm/i915: Move BXT pll configuration logic to intel_dpll_mgr.c
9875c10e3933ada70175129384644dcfbebd539b drm/i915: Move SKL/KLB pll selection logic to intel_dpll_mgr.c
076dd92201a86cb74ca38bc592bf2f9c7c79ef82 drm/i915: Move HSW/BDW pll selection logic to intel_dpll_mgr.c
a48e2acab48bf343a929d3956c042d21e403dbdb drm/i915: Refactor platform specifics out of intel_get_shared_dpll()
ccea2d6bd0d09abc60fe5536bf8a5ad5885f341f drm/i915: Use a table to initilize shared dplls
c4671642db12a3adaf585d1c9d307e08c7606757 drm/i915: Move shared dpll function prototypes to intel_dpll_mgr.h
483a9a210246878470950dba9c1738b4403de6bc drm/i915: Move shared dpll struct definitions to separate header file
dc1a46803941180998188ec5fe431e4edc9ec7e5 drm/i915: Store a direct pointer to shared dpll in intel_crtc_state
5c6d7fd24a992bc44f6331487abc4f7893260976 drm/i915: Split intel_get_shared_dpll() into smaller functions
896bc10b27221cb3dd04dd207c877d13265757cf drm/i915: Move ddi shared dpll code to intel_dpll_mgr.c
b8058dc895423649ea6e561e70d89b325e709cd1 drm/i915: Move shared dpll code to a new file

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface
  2016-02-26 13:54 ` [PATCH 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface Ander Conselvan de Oliveira
@ 2016-02-29  9:08   ` Ander Conselvan de Oliveira
  2016-03-08 11:05   ` [PATCH " Maarten Lankhorst
  1 sibling, 0 replies; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-29  9:08 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

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 <ander.conselvan.de.oliveira@intel.com>
---
 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,
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v3 13/13] drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code
  2016-02-26 13:54 ` [PATCH 13/13] drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code Ander Conselvan de Oliveira
@ 2016-02-29  9:08   ` Ander Conselvan de Oliveira
  2016-03-03 13:33     ` Maarten Lankhorst
  0 siblings, 1 reply; 31+ messages in thread
From: Ander Conselvan de Oliveira @ 2016-02-29  9:08 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ander Conselvan de Oliveira

Include DPLL0 in the managed dplls for SKL/KBL. While it has to be kept
enabled because of it driving CDCLK, it is better to special case that
inside the DPLL code than in the higher level.

v2: Use INTEL_DPLL_ALWAYS_ON flag. (Ander)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>

---
I wasn't able to test this patch. Would really appreciate a tested by
from someone.
---
 drivers/gpu/drm/i915/intel_ddi.c      |  21 ------
 drivers/gpu/drm/i915/intel_dp.c       |  52 +-------------
 drivers/gpu/drm/i915/intel_dpll_mgr.c | 131 +++++++++++++++++++++++++++-------
 drivers/gpu/drm/i915/intel_dpll_mgr.h |   7 +-
 4 files changed, 109 insertions(+), 102 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 3cb9f36..8ef4d2e 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -1008,9 +1008,6 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
 {
 	struct intel_shared_dpll *pll;
 
-	if (intel_encoder->type == INTEL_OUTPUT_EDP)
-		return true;
-
 	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
 	if (pll == NULL) {
 		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
@@ -1570,24 +1567,6 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
 		uint32_t dpll = pipe_config->ddi_pll_sel;
 		uint32_t val;
 
-		/*
-		 * DPLL0 is used for eDP and is the only "private" DPLL (as
-		 * opposed to shared) on SKL
-		 */
-		if (encoder->type == INTEL_OUTPUT_EDP) {
-			WARN_ON(dpll != SKL_DPLL0);
-
-			val = I915_READ(DPLL_CTRL1);
-
-			val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
-				 DPLL_CTRL1_SSC(dpll) |
-				 DPLL_CTRL1_LINK_RATE_MASK(dpll));
-			val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
-
-			I915_WRITE(DPLL_CTRL1, val);
-			POSTING_READ(DPLL_CTRL1);
-		}
-
 		/* DDI -> PLL mapping  */
 		val = I915_READ(DPLL_CTRL2);
 
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 5be6892..9fef877 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1229,52 +1229,6 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector)
 	intel_connector_unregister(intel_connector);
 }
 
-static void
-skl_edp_set_pll_config(struct intel_crtc_state *pipe_config)
-{
-	u32 ctrl1;
-
-	memset(&pipe_config->dpll_hw_state, 0,
-	       sizeof(pipe_config->dpll_hw_state));
-
-	pipe_config->ddi_pll_sel = SKL_DPLL0;
-	pipe_config->dpll_hw_state.cfgcr1 = 0;
-	pipe_config->dpll_hw_state.cfgcr2 = 0;
-
-	ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
-	switch (pipe_config->port_clock / 2) {
-	case 81000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
-					      SKL_DPLL0);
-		break;
-	case 135000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350,
-					      SKL_DPLL0);
-		break;
-	case 270000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700,
-					      SKL_DPLL0);
-		break;
-	case 162000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620,
-					      SKL_DPLL0);
-		break;
-	/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
-	results in CDCLK change. Need to handle the change of CDCLK by
-	disabling pipes and re-enabling them */
-	case 108000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
-					      SKL_DPLL0);
-		break;
-	case 216000:
-		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160,
-					      SKL_DPLL0);
-		break;
-
-	}
-	pipe_config->dpll_hw_state.ctrl1 = ctrl1;
-}
-
 static int
 intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
 {
@@ -1632,11 +1586,7 @@ found:
 				&pipe_config->dp_m2_n2);
 	}
 
-	if ((IS_SKYLAKE(dev)  || IS_KABYLAKE(dev)) && is_edp(intel_dp))
-		skl_edp_set_pll_config(pipe_config);
-	else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
-		/* handled in ddi */;
-	else
+	if (!HAS_DDI(dev))
 		intel_dp_set_clock(encoder, 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 d371680..6ec7836 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
@@ -785,7 +785,12 @@ struct skl_dpll_regs {
 };
 
 /* this array is indexed by the *shared* pll id */
-static const struct skl_dpll_regs skl_dpll_regs[3] = {
+static const struct skl_dpll_regs skl_dpll_regs[4] = {
+	{
+		/* DPLL 0 */
+		.ctl = LCPLL1_CTL,
+		/* DPLL 0 doesn't support HDMI mode */
+	},
 	{
 		/* DPLL 1 */
 		.ctl = LCPLL2_CTL,
@@ -806,24 +811,29 @@ static const struct skl_dpll_regs skl_dpll_regs[3] = {
 	},
 };
 
-static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
-			       struct intel_shared_dpll *pll)
+static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
+				    struct intel_shared_dpll *pll)
 {
 	uint32_t val;
-	unsigned int dpll;
-	const struct skl_dpll_regs *regs = skl_dpll_regs;
-
-	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
-	dpll = pll->id + 1;
 
 	val = I915_READ(DPLL_CTRL1);
 
-	val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
-		 DPLL_CTRL1_LINK_RATE_MASK(dpll));
-	val |= pll->config.hw_state.ctrl1 << (dpll * 6);
+	val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
+		 DPLL_CTRL1_LINK_RATE_MASK(pll->id));
+	val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
 
 	I915_WRITE(DPLL_CTRL1, val);
 	POSTING_READ(DPLL_CTRL1);
+}
+
+static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
+			       struct intel_shared_dpll *pll)
+{
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+
+	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
+
+	skl_ddi_pll_write_ctrl1(dev_priv, pll);
 
 	I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
 	I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
@@ -834,8 +844,15 @@ static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
 	I915_WRITE(regs[pll->id].ctl,
 		   I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
 
-	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
-		DRM_ERROR("DPLL %d not locked\n", dpll);
+	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
+		DRM_ERROR("DPLL %d not locked\n", pll->id);
+}
+
+static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
+				 struct intel_shared_dpll *pll)
+{
+	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
+	skl_ddi_pll_write_ctrl1(dev_priv, pll);
 }
 
 static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
@@ -849,32 +866,35 @@ static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
 	POSTING_READ(regs[pll->id].ctl);
 }
 
+static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
+				  struct intel_shared_dpll *pll)
+{
+}
+
 static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
 				     struct intel_shared_dpll *pll,
 				     struct intel_dpll_hw_state *hw_state)
 {
 	uint32_t val;
-	unsigned int dpll;
 	const struct skl_dpll_regs *regs = skl_dpll_regs;
 	bool ret;
 
+	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
+
 	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
 		return false;
 
 	ret = false;
 
-	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
-	dpll = pll->id + 1;
-
 	val = I915_READ(regs[pll->id].ctl);
 	if (!(val & LCPLL_PLL_ENABLE))
 		goto out;
 
 	val = I915_READ(DPLL_CTRL1);
-	hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
+	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
 
 	/* avoid reading back stale values if HDMI mode is not enabled */
-	if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
+	if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
 		hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
 		hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
 	}
@@ -886,6 +906,37 @@ out:
 	return ret;
 }
 
+static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
+				       struct intel_shared_dpll *pll,
+				       struct intel_dpll_hw_state *hw_state)
+{
+	uint32_t val;
+	const struct skl_dpll_regs *regs = skl_dpll_regs;
+	bool ret;
+
+	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
+
+	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
+		return false;
+
+	ret = false;
+
+	/* DPLL0 is always enabled since it drives CDCLK */
+	val = I915_READ(regs[pll->id].ctl);
+	if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
+		goto out;
+
+	val = I915_READ(DPLL_CTRL1);
+	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
+
+	ret = true;
+
+out:
+	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
+
+	return ret;
+}
+
 struct skl_wrpll_context {
 	uint64_t min_deviation;		/* current minimal deviation */
 	uint64_t central_freq;		/* chosen central freq */
@@ -1165,7 +1216,8 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
 			 wrpll_params.central_freq;
 	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
-		   encoder->type == INTEL_OUTPUT_DP_MST) {
+		   encoder->type == INTEL_OUTPUT_DP_MST ||
+		   encoder->type == INTEL_OUTPUT_EDP) {
 		switch (crtc_state->port_clock / 2) {
 		case 81000:
 			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
@@ -1176,6 +1228,19 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 		case 270000:
 			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
 			break;
+		/* eDP 1.4 rates */
+		case 162000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
+			break;
+		/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
+		results in CDCLK change. Need to handle the change of CDCLK by
+		disabling pipes and re-enabling them */
+		case 108000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, 0);
+			break;
+		case 216000:
+			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, 0);
+			break;
 		}
 
 		cfgcr1 = cfgcr2 = 0;
@@ -1190,13 +1255,18 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
 	crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
 	crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
 
-	pll = intel_find_shared_dpll(crtc, crtc_state,
-				     DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3);
+	if (encoder->type == INTEL_OUTPUT_EDP)
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_SKL_DPLL0,
+					     DPLL_ID_SKL_DPLL0);
+	else
+		pll = intel_find_shared_dpll(crtc, crtc_state,
+					     DPLL_ID_SKL_DPLL1,
+					     DPLL_ID_SKL_DPLL3);
 	if (!pll)
 		return NULL;
 
-	/* shared DPLL id 0 is DPLL 1 */
-	crtc_state->ddi_pll_sel = pll->id + 1;
+	crtc_state->ddi_pll_sel = pll->id;
 
 	intel_reference_shared_dpll(pll, crtc_state);
 
@@ -1209,6 +1279,12 @@ static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
 	.get_hw_state = skl_ddi_pll_get_hw_state,
 };
 
+static const struct intel_shared_dpll_funcs skl_ddi_dpll0_funcs = {
+	.enable = skl_ddi_dpll0_enable,
+	.disable = skl_ddi_dpll0_disable,
+	.get_hw_state = skl_ddi_dpll0_get_hw_state,
+};
+
 static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
 				struct intel_shared_dpll *pll)
 {
@@ -1624,9 +1700,10 @@ 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, 0 },
-	{ "DPPL 2", DPLL_ID_SKL_DPLL2, &skl_ddi_pll_funcs, 0 },
-	{ "DPPL 3", DPLL_ID_SKL_DPLL3, &skl_ddi_pll_funcs, 0 },
+	{ "DPLL 0", DPLL_ID_SKL_DPLL0, &skl_ddi_dpll0_funcs, INTEL_DPLL_ALWAYS_ON },
+	{ "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, },
 };
 
diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.h b/drivers/gpu/drm/i915/intel_dpll_mgr.h
index adf4706..1d34147 100644
--- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
@@ -54,9 +54,10 @@ enum intel_dpll_id {
 	DPLL_ID_LCPLL_2700 = 5,
 
 	/* skl */
-	DPLL_ID_SKL_DPLL1 = 0,
-	DPLL_ID_SKL_DPLL2 = 1,
-	DPLL_ID_SKL_DPLL3 = 2,
+	DPLL_ID_SKL_DPLL0 = 0,
+	DPLL_ID_SKL_DPLL1 = 1,
+	DPLL_ID_SKL_DPLL2 = 2,
+	DPLL_ID_SKL_DPLL3 = 3,
 };
 #define I915_NUM_PLLS 6
 
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/13] drm/i915: Move shared dpll function prototypes to intel_dpll_mgr.h
  2016-02-26 13:54 ` [PATCH 06/13] drm/i915: Move shared dpll function prototypes to intel_dpll_mgr.h Ander Conselvan de Oliveira
@ 2016-03-02 14:56   ` Maarten Lankhorst
  0 siblings, 0 replies; 31+ messages in thread
From: Maarten Lankhorst @ 2016-03-02 14:56 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx

Hey,

Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
> Move shared dpll function prototype together with other shared dpll
> definitions.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
>
For patch 1-6,

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 07/13] drm/i915: Use a table to initilize shared dplls
  2016-02-26 13:54 ` [PATCH 07/13] drm/i915: Use a table to initilize shared dplls Ander Conselvan de Oliveira
@ 2016-03-02 15:30   ` Maarten Lankhorst
  2016-03-03 11:32     ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 31+ messages in thread
From: Maarten Lankhorst @ 2016-03-02 15:30 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx

Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
> Use a table to store the per-platform shared dpll information in one
> place. This way, there is no need for platform specific init funtions.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c  |  16 +--
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 189 ++++++++++++++++------------------
>  drivers/gpu/drm/i915/intel_dpll_mgr.h |  22 ++--
>  3 files changed, 108 insertions(+), 119 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index e723323..133b6b7 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9148,8 +9148,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
>  			intel_get_shared_dpll_by_id(dev_priv, pll_id);
>  		pll = pipe_config->shared_dpll;
>  
> -		WARN_ON(!pll->get_hw_state(dev_priv, pll,
> -					   &pipe_config->dpll_hw_state));
> +		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
> +						 &pipe_config->dpll_hw_state));
>  
>  		tmp = pipe_config->dpll_hw_state.dpll;
>  		pipe_config->pixel_multiplier =
> @@ -9695,8 +9695,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
>  
>  	pll = pipe_config->shared_dpll;
>  	if (pll) {
> -		WARN_ON(!pll->get_hw_state(dev_priv, pll,
> -					   &pipe_config->dpll_hw_state));
> +		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
> +						 &pipe_config->dpll_hw_state));
>  	}
>  
>  	/*
> @@ -12728,7 +12728,7 @@ check_shared_dpll_state(struct drm_device *dev)
>  
>  		DRM_DEBUG_KMS("%s\n", pll->name);
>  
> -		active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state);
> +		active = pll->funcs.get_hw_state(dev_priv, pll, &dpll_hw_state);
>  
>  		I915_STATE_WARN(pll->active > hweight32(pll->config.crtc_mask),
>  		     "more active pll users than references: %i vs %i\n",
> @@ -15466,8 +15466,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>  		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
>  
> -		pll->on = pll->get_hw_state(dev_priv, pll,
> -					    &pll->config.hw_state);
> +		pll->on = pll->funcs.get_hw_state(dev_priv, pll,
> +						  &pll->config.hw_state);
>  		pll->active = 0;
>  		pll->config.crtc_mask = 0;
>  		for_each_intel_crtc(dev, crtc) {
> @@ -15602,7 +15602,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
>  
>  		DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name);
>  
> -		pll->disable(dev_priv, pll);
> +		pll->funcs.disable(dev_priv, pll);
>  		pll->on = false;
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> index 889ceed..e88dc46 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -74,7 +74,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
>  	if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
>  		return;
>  
> -	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
> +	cur_state = pll->funcs.get_hw_state(dev_priv, pll, &hw_state);
>  	I915_STATE_WARN(cur_state != state,
>  	     "%s assertion failure (expected %s, current %s)\n",
>  			pll->name, onoff(state), onoff(cur_state));
> @@ -95,7 +95,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc)
>  		WARN_ON(pll->on);
>  		assert_shared_dpll_disabled(dev_priv, pll);
>  
> -		pll->mode_set(dev_priv, pll);
> +		pll->funcs.mode_set(dev_priv, pll);
>  	}
>  }
>  
> @@ -133,7 +133,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc)
>  	intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
>  
>  	DRM_DEBUG_KMS("enabling %s\n", pll->name);
> -	pll->enable(dev_priv, pll);
> +	pll->funcs.enable(dev_priv, pll);
>  	pll->on = true;
>  }
>  
> @@ -168,7 +168,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
>  		return;
>  
>  	DRM_DEBUG_KMS("disabling %s\n", pll->name);
> -	pll->disable(dev_priv, pll);
> +	pll->funcs.disable(dev_priv, pll);
>  	pll->on = false;
>  
>  	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
> @@ -398,29 +398,13 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
>  	udelay(200);
>  }
>  
> -static char *ibx_pch_dpll_names[] = {
> -	"PCH DPLL A",
> -	"PCH DPLL B",
> +static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
> +	.mode_set = ibx_pch_dpll_mode_set,
> +	.enable = ibx_pch_dpll_enable,
> +	.disable = ibx_pch_dpll_disable,
> +	.get_hw_state = ibx_pch_dpll_get_hw_state,
>  };
>  
> -static void ibx_pch_dpll_init(struct drm_device *dev)
> -{
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	int i;
> -
> -	dev_priv->num_shared_dpll = 2;
> -
> -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> -		dev_priv->shared_dplls[i].id = i;
> -		dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
> -		dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set;
> -		dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
> -		dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
> -		dev_priv->shared_dplls[i].get_hw_state =
> -			ibx_pch_dpll_get_hw_state;
> -	}
> -}
> -
>  static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
>  			       struct intel_shared_dpll *pll)
>  {
> @@ -492,40 +476,16 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
>  }
>  
>  
> -static const char * const hsw_ddi_pll_names[] = {
> -	"WRPLL 1",
> -	"WRPLL 2",
> -	"SPLL"
> +static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
> +	.enable = hsw_ddi_wrpll_enable,
> +	.disable = hsw_ddi_wrpll_disable,
> +	.get_hw_state = hsw_ddi_wrpll_get_hw_state,
>  };
>  
> -static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
> -{
> -	int i;
> -
> -	dev_priv->num_shared_dpll = 3;
> -
> -	for (i = 0; i < 2; i++) {
> -		dev_priv->shared_dplls[i].id = i;
> -		dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
> -		dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
> -		dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
> -		dev_priv->shared_dplls[i].get_hw_state =
> -			hsw_ddi_wrpll_get_hw_state;
> -	}
> -
> -	/* SPLL is special, but needs to be initialized anyway.. */
> -	dev_priv->shared_dplls[i].id = i;
> -	dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
> -	dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
> -	dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
> -	dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
> -
> -}
> -
> -static const char * const skl_ddi_pll_names[] = {
> -	"DPLL 1",
> -	"DPLL 2",
> -	"DPLL 3",
> +static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
> +	.enable = hsw_ddi_spll_enable,
> +	.disable = hsw_ddi_spll_disable,
> +	.get_hw_state = hsw_ddi_spll_get_hw_state,
>  };
>  
>  struct skl_dpll_regs {
> @@ -634,26 +594,10 @@ out:
>  	return ret;
>  }
>  
> -static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
> -{
> -	int i;
> -
> -	dev_priv->num_shared_dpll = 3;
> -
> -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> -		dev_priv->shared_dplls[i].id = i;
> -		dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
> -		dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
> -		dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
> -		dev_priv->shared_dplls[i].get_hw_state =
> -			skl_ddi_pll_get_hw_state;
> -	}
> -}
> -
> -static const char * const bxt_ddi_pll_names[] = {
> -	"PORT PLL A",
> -	"PORT PLL B",
> -	"PORT PLL C",
> +static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
> +	.enable = skl_ddi_pll_enable,
> +	.disable = skl_ddi_pll_disable,
> +	.get_hw_state = skl_ddi_pll_get_hw_state,
>  };
>  
>  static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
> @@ -838,34 +782,17 @@ out:
>  	return ret;
>  }
>  
> -static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
> -{
> -	int i;
> -
> -	dev_priv->num_shared_dpll = 3;
> -
> -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> -		dev_priv->shared_dplls[i].id = i;
> -		dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
> -		dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
> -		dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
> -		dev_priv->shared_dplls[i].get_hw_state =
> -			bxt_ddi_pll_get_hw_state;
> -	}
> -}
> +static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
> +	.enable = bxt_ddi_pll_enable,
> +	.disable = bxt_ddi_pll_disable,
> +	.get_hw_state = bxt_ddi_pll_get_hw_state,
> +};
>  
>  static void intel_ddi_pll_init(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
>  	uint32_t val = I915_READ(LCPLL_CTL);
>  
> -	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
> -		skl_shared_dplls_init(dev_priv);
> -	else if (IS_BROXTON(dev))
> -		bxt_shared_dplls_init(dev_priv);
> -	else
> -		hsw_shared_dplls_init(dev_priv);
> -
>  	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
>  		int cdclk_freq;
>  
> @@ -893,16 +820,72 @@ static void intel_ddi_pll_init(struct drm_device *dev)
>  	}
>  }
>  
> +struct dpll_info {
> +	const char *name;
> +	const int id;
> +	const struct intel_shared_dpll_funcs *funcs;
> +};
> +
Seems shared_dplls[i].id == i, so that could be removed. If you also move name to funcs you could kill this struct.

~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 07/13] drm/i915: Use a table to initilize shared dplls
  2016-03-02 15:30   ` Maarten Lankhorst
@ 2016-03-03 11:32     ` Ander Conselvan De Oliveira
  2016-03-03 13:35       ` Maarten Lankhorst
  0 siblings, 1 reply; 31+ messages in thread
From: Ander Conselvan De Oliveira @ 2016-03-03 11:32 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Hi Maarten,

Thanks for reviewing. Comments below.

On Wed, 2016-03-02 at 16:30 +0100, Maarten Lankhorst wrote:
> Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
> > Use a table to store the per-platform shared dpll information in one
> > place. This way, there is no need for platform specific init funtions.
> > 
> > Signed-off-by: Ander Conselvan de Oliveira <
> > ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_display.c  |  16 +--
> >  drivers/gpu/drm/i915/intel_dpll_mgr.c | 189 ++++++++++++++++---------------
> > ---
> >  drivers/gpu/drm/i915/intel_dpll_mgr.h |  22 ++--
> >  3 files changed, 108 insertions(+), 119 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index e723323..133b6b7 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -9148,8 +9148,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc
> > *crtc,
> >  			intel_get_shared_dpll_by_id(dev_priv, pll_id);
> >  		pll = pipe_config->shared_dpll;
> >  
> > -		WARN_ON(!pll->get_hw_state(dev_priv, pll,
> > -					   &pipe_config->dpll_hw_state));
> > +		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
> > +						 &pipe_config
> > ->dpll_hw_state));
> >  
> >  		tmp = pipe_config->dpll_hw_state.dpll;
> >  		pipe_config->pixel_multiplier =
> > @@ -9695,8 +9695,8 @@ static void haswell_get_ddi_port_state(struct
> > intel_crtc *crtc,
> >  
> >  	pll = pipe_config->shared_dpll;
> >  	if (pll) {
> > -		WARN_ON(!pll->get_hw_state(dev_priv, pll,
> > -					   &pipe_config->dpll_hw_state));
> > +		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
> > +						 &pipe_config
> > ->dpll_hw_state));
> >  	}
> >  
> >  	/*
> > @@ -12728,7 +12728,7 @@ check_shared_dpll_state(struct drm_device *dev)
> >  
> >  		DRM_DEBUG_KMS("%s\n", pll->name);
> >  
> > -		active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state);
> > +		active = pll->funcs.get_hw_state(dev_priv, pll,
> > &dpll_hw_state);
> >  
> >  		I915_STATE_WARN(pll->active > hweight32(pll
> > ->config.crtc_mask),
> >  		     "more active pll users than references: %i vs %i\n",
> > @@ -15466,8 +15466,8 @@ static void intel_modeset_readout_hw_state(struct
> > drm_device *dev)
> >  	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> >  		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
> >  
> > -		pll->on = pll->get_hw_state(dev_priv, pll,
> > -					    &pll->config.hw_state);
> > +		pll->on = pll->funcs.get_hw_state(dev_priv, pll,
> > +						  &pll->config.hw_state);
> >  		pll->active = 0;
> >  		pll->config.crtc_mask = 0;
> >  		for_each_intel_crtc(dev, crtc) {
> > @@ -15602,7 +15602,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
> >  
> >  		DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll
> > ->name);
> >  
> > -		pll->disable(dev_priv, pll);
> > +		pll->funcs.disable(dev_priv, pll);
> >  		pll->on = false;
> >  	}
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > index 889ceed..e88dc46 100644
> > --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > @@ -74,7 +74,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
> >  	if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
> >  		return;
> >  
> > -	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
> > +	cur_state = pll->funcs.get_hw_state(dev_priv, pll, &hw_state);
> >  	I915_STATE_WARN(cur_state != state,
> >  	     "%s assertion failure (expected %s, current %s)\n",
> >  			pll->name, onoff(state), onoff(cur_state));
> > @@ -95,7 +95,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc)
> >  		WARN_ON(pll->on);
> >  		assert_shared_dpll_disabled(dev_priv, pll);
> >  
> > -		pll->mode_set(dev_priv, pll);
> > +		pll->funcs.mode_set(dev_priv, pll);
> >  	}
> >  }
> >  
> > @@ -133,7 +133,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc)
> >  	intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
> >  
> >  	DRM_DEBUG_KMS("enabling %s\n", pll->name);
> > -	pll->enable(dev_priv, pll);
> > +	pll->funcs.enable(dev_priv, pll);
> >  	pll->on = true;
> >  }
> >  
> > @@ -168,7 +168,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
> >  		return;
> >  
> >  	DRM_DEBUG_KMS("disabling %s\n", pll->name);
> > -	pll->disable(dev_priv, pll);
> > +	pll->funcs.disable(dev_priv, pll);
> >  	pll->on = false;
> >  
> >  	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
> > @@ -398,29 +398,13 @@ static void ibx_pch_dpll_disable(struct
> > drm_i915_private *dev_priv,
> >  	udelay(200);
> >  }
> >  
> > -static char *ibx_pch_dpll_names[] = {
> > -	"PCH DPLL A",
> > -	"PCH DPLL B",
> > +static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
> > +	.mode_set = ibx_pch_dpll_mode_set,
> > +	.enable = ibx_pch_dpll_enable,
> > +	.disable = ibx_pch_dpll_disable,
> > +	.get_hw_state = ibx_pch_dpll_get_hw_state,
> >  };
> >  
> > -static void ibx_pch_dpll_init(struct drm_device *dev)
> > -{
> > -	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	int i;
> > -
> > -	dev_priv->num_shared_dpll = 2;
> > -
> > -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> > -		dev_priv->shared_dplls[i].id = i;
> > -		dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
> > -		dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set;
> > -		dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
> > -		dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
> > -		dev_priv->shared_dplls[i].get_hw_state =
> > -			ibx_pch_dpll_get_hw_state;
> > -	}
> > -}
> > -
> >  static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
> >  			       struct intel_shared_dpll *pll)
> >  {
> > @@ -492,40 +476,16 @@ static bool hsw_ddi_spll_get_hw_state(struct
> > drm_i915_private *dev_priv,
> >  }
> >  
> >  
> > -static const char * const hsw_ddi_pll_names[] = {
> > -	"WRPLL 1",
> > -	"WRPLL 2",
> > -	"SPLL"
> > +static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
> > +	.enable = hsw_ddi_wrpll_enable,
> > +	.disable = hsw_ddi_wrpll_disable,
> > +	.get_hw_state = hsw_ddi_wrpll_get_hw_state,
> >  };
> >  
> > -static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
> > -{
> > -	int i;
> > -
> > -	dev_priv->num_shared_dpll = 3;
> > -
> > -	for (i = 0; i < 2; i++) {
> > -		dev_priv->shared_dplls[i].id = i;
> > -		dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
> > -		dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
> > -		dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
> > -		dev_priv->shared_dplls[i].get_hw_state =
> > -			hsw_ddi_wrpll_get_hw_state;
> > -	}
> > -
> > -	/* SPLL is special, but needs to be initialized anyway.. */
> > -	dev_priv->shared_dplls[i].id = i;
> > -	dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
> > -	dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
> > -	dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
> > -	dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
> > -
> > -}
> > -
> > -static const char * const skl_ddi_pll_names[] = {
> > -	"DPLL 1",
> > -	"DPLL 2",
> > -	"DPLL 3",
> > +static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
> > +	.enable = hsw_ddi_spll_enable,
> > +	.disable = hsw_ddi_spll_disable,
> > +	.get_hw_state = hsw_ddi_spll_get_hw_state,
> >  };
> >  
> >  struct skl_dpll_regs {
> > @@ -634,26 +594,10 @@ out:
> >  	return ret;
> >  }
> >  
> > -static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
> > -{
> > -	int i;
> > -
> > -	dev_priv->num_shared_dpll = 3;
> > -
> > -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> > -		dev_priv->shared_dplls[i].id = i;
> > -		dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
> > -		dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
> > -		dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
> > -		dev_priv->shared_dplls[i].get_hw_state =
> > -			skl_ddi_pll_get_hw_state;
> > -	}
> > -}
> > -
> > -static const char * const bxt_ddi_pll_names[] = {
> > -	"PORT PLL A",
> > -	"PORT PLL B",
> > -	"PORT PLL C",
> > +static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
> > +	.enable = skl_ddi_pll_enable,
> > +	.disable = skl_ddi_pll_disable,
> > +	.get_hw_state = skl_ddi_pll_get_hw_state,
> >  };
> >  
> >  static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
> > @@ -838,34 +782,17 @@ out:
> >  	return ret;
> >  }
> >  
> > -static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
> > -{
> > -	int i;
> > -
> > -	dev_priv->num_shared_dpll = 3;
> > -
> > -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> > -		dev_priv->shared_dplls[i].id = i;
> > -		dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
> > -		dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
> > -		dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
> > -		dev_priv->shared_dplls[i].get_hw_state =
> > -			bxt_ddi_pll_get_hw_state;
> > -	}
> > -}
> > +static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
> > +	.enable = bxt_ddi_pll_enable,
> > +	.disable = bxt_ddi_pll_disable,
> > +	.get_hw_state = bxt_ddi_pll_get_hw_state,
> > +};
> >  
> >  static void intel_ddi_pll_init(struct drm_device *dev)
> >  {
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	uint32_t val = I915_READ(LCPLL_CTL);
> >  
> > -	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
> > -		skl_shared_dplls_init(dev_priv);
> > -	else if (IS_BROXTON(dev))
> > -		bxt_shared_dplls_init(dev_priv);
> > -	else
> > -		hsw_shared_dplls_init(dev_priv);
> > -
> >  	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
> >  		int cdclk_freq;
> >  
> > @@ -893,16 +820,72 @@ static void intel_ddi_pll_init(struct drm_device *dev)
> >  	}
> >  }
> >  
> > +struct dpll_info {
> > +	const char *name;
> > +	const int id;
> > +	const struct intel_shared_dpll_funcs *funcs;
> > +};
> > +
> Seems shared_dplls[i].id == i, so that could be removed. 

There are places in the code that assume those are equal. I considered not
including the id, but concluded that having the id and a WARN_ON() in
 intel_shared_dpll_init() documents that assumption better.

I think it would be better to remove that assumption, but that require changes
to intel_atomic_state and users. But I think it would be nice if we could have a
per-DPLL state object.

> If you also move name to funcs you could kill this struct.

In a later patch I add a flags field to this struct. I guess I could move that
to funcs too, but then we need to come up with a better name for that struct.
"funcs" starts to sound wrong.

IMO having that extra struct is fine, so I rather let things settle first and
then do another round of clean ups. But if that is a no-go, I can re-spin.

Thanks,
Ander


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v3 13/13] drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code
  2016-02-29  9:08   ` [PATCH v3 " Ander Conselvan de Oliveira
@ 2016-03-03 13:33     ` Maarten Lankhorst
  2016-03-03 13:40       ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 31+ messages in thread
From: Maarten Lankhorst @ 2016-03-03 13:33 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx

Op 29-02-16 om 10:08 schreef Ander Conselvan de Oliveira:
> Include DPLL0 in the managed dplls for SKL/KBL. While it has to be kept
> enabled because of it driving CDCLK, it is better to special case that
> inside the DPLL code than in the higher level.
>
> v2: Use INTEL_DPLL_ALWAYS_ON flag. (Ander)
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
>
> ---
> I wasn't able to test this patch. Would really appreciate a tested by
> from someone.
Unfortunately no skl with eDP here either. :(
>  drivers/gpu/drm/i915/intel_ddi.c      |  21 ------
>  drivers/gpu/drm/i915/intel_dp.c       |  52 +-------------
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 131 +++++++++++++++++++++++++++-------
>  drivers/gpu/drm/i915/intel_dpll_mgr.h |   7 +-
>  4 files changed, 109 insertions(+), 102 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 3cb9f36..8ef4d2e 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -1008,9 +1008,6 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
>  {
>  	struct intel_shared_dpll *pll;
>  
> -	if (intel_encoder->type == INTEL_OUTPUT_EDP)
> -		return true;
> -
>  	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
>  	if (pll == NULL) {
>  		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
> @@ -1570,24 +1567,6 @@ void intel_ddi_clk_select(struct intel_encoder *encoder,
>  		uint32_t dpll = pipe_config->ddi_pll_sel;
>  		uint32_t val;
>  
> -		/*
> -		 * DPLL0 is used for eDP and is the only "private" DPLL (as
> -		 * opposed to shared) on SKL
> -		 */
> -		if (encoder->type == INTEL_OUTPUT_EDP) {
> -			WARN_ON(dpll != SKL_DPLL0);
> -
> -			val = I915_READ(DPLL_CTRL1);
> -
> -			val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
> -				 DPLL_CTRL1_SSC(dpll) |
> -				 DPLL_CTRL1_LINK_RATE_MASK(dpll));
> -			val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
> -
> -			I915_WRITE(DPLL_CTRL1, val);
> -			POSTING_READ(DPLL_CTRL1);
> -		}
> -
>  		/* DDI -> PLL mapping  */
>  		val = I915_READ(DPLL_CTRL2);
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 5be6892..9fef877 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1229,52 +1229,6 @@ intel_dp_connector_unregister(struct intel_connector *intel_connector)
>  	intel_connector_unregister(intel_connector);
>  }
>  
> -static void
> -skl_edp_set_pll_config(struct intel_crtc_state *pipe_config)
> -{
> -	u32 ctrl1;
> -
> -	memset(&pipe_config->dpll_hw_state, 0,
> -	       sizeof(pipe_config->dpll_hw_state));
> -
> -	pipe_config->ddi_pll_sel = SKL_DPLL0;
> -	pipe_config->dpll_hw_state.cfgcr1 = 0;
> -	pipe_config->dpll_hw_state.cfgcr2 = 0;
> -
> -	ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
> -	switch (pipe_config->port_clock / 2) {
> -	case 81000:
> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
> -					      SKL_DPLL0);
> -		break;
> -	case 135000:
> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350,
> -					      SKL_DPLL0);
> -		break;
> -	case 270000:
> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700,
> -					      SKL_DPLL0);
> -		break;
> -	case 162000:
> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620,
> -					      SKL_DPLL0);
> -		break;
> -	/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
> -	results in CDCLK change. Need to handle the change of CDCLK by
> -	disabling pipes and re-enabling them */
> -	case 108000:
> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
> -					      SKL_DPLL0);
> -		break;
> -	case 216000:
> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160,
> -					      SKL_DPLL0);
> -		break;
> -
> -	}
> -	pipe_config->dpll_hw_state.ctrl1 = ctrl1;
> -}
> -
>  static int
>  intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
>  {
> @@ -1632,11 +1586,7 @@ found:
>  				&pipe_config->dp_m2_n2);
>  	}
>  
> -	if ((IS_SKYLAKE(dev)  || IS_KABYLAKE(dev)) && is_edp(intel_dp))
> -		skl_edp_set_pll_config(pipe_config);
> -	else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
> -		/* handled in ddi */;
> -	else
> +	if (!HAS_DDI(dev))
>  		intel_dp_set_clock(encoder, 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 d371680..6ec7836 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -785,7 +785,12 @@ struct skl_dpll_regs {
>  };
>  
>  /* this array is indexed by the *shared* pll id */
> -static const struct skl_dpll_regs skl_dpll_regs[3] = {
> +static const struct skl_dpll_regs skl_dpll_regs[4] = {
> +	{
> +		/* DPLL 0 */
> +		.ctl = LCPLL1_CTL,
> +		/* DPLL 0 doesn't support HDMI mode */
> +	},
>  	{
>  		/* DPLL 1 */
>  		.ctl = LCPLL2_CTL,
> @@ -806,24 +811,29 @@ static const struct skl_dpll_regs skl_dpll_regs[3] = {
>  	},
>  };
>  
> -static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
> -			       struct intel_shared_dpll *pll)
> +static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
> +				    struct intel_shared_dpll *pll)
>  {
>  	uint32_t val;
> -	unsigned int dpll;
> -	const struct skl_dpll_regs *regs = skl_dpll_regs;
> -
> -	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
> -	dpll = pll->id + 1;
>  
>  	val = I915_READ(DPLL_CTRL1);
>  
> -	val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
> -		 DPLL_CTRL1_LINK_RATE_MASK(dpll));
> -	val |= pll->config.hw_state.ctrl1 << (dpll * 6);
> +	val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
> +		 DPLL_CTRL1_LINK_RATE_MASK(pll->id));
> +	val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
>  
>  	I915_WRITE(DPLL_CTRL1, val);
>  	POSTING_READ(DPLL_CTRL1);
> +}
> +
> +static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
> +			       struct intel_shared_dpll *pll)
> +{
> +	const struct skl_dpll_regs *regs = skl_dpll_regs;
> +
> +	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
> +
> +	skl_ddi_pll_write_ctrl1(dev_priv, pll);
>  
>  	I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
>  	I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
> @@ -834,8 +844,15 @@ static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
>  	I915_WRITE(regs[pll->id].ctl,
>  		   I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
>  
> -	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
> -		DRM_ERROR("DPLL %d not locked\n", dpll);
> +	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
> +		DRM_ERROR("DPLL %d not locked\n", pll->id);
> +}
> +
> +static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
> +				 struct intel_shared_dpll *pll)
> +{
> +	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
> +	skl_ddi_pll_write_ctrl1(dev_priv, pll);
>  }
>  
>  static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
> @@ -849,32 +866,35 @@ static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
>  	POSTING_READ(regs[pll->id].ctl);
>  }
>  
> +static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
> +				  struct intel_shared_dpll *pll)
> +{
> +}
> +
>  static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
>  				     struct intel_shared_dpll *pll,
>  				     struct intel_dpll_hw_state *hw_state)
>  {
>  	uint32_t val;
> -	unsigned int dpll;
>  	const struct skl_dpll_regs *regs = skl_dpll_regs;
>  	bool ret;
>  
> +	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
> +
>  	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
>  		return false;
>  
>  	ret = false;
>  
> -	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
> -	dpll = pll->id + 1;
> -
>  	val = I915_READ(regs[pll->id].ctl);
>  	if (!(val & LCPLL_PLL_ENABLE))
>  		goto out;
>  
>  	val = I915_READ(DPLL_CTRL1);
> -	hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
> +	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
>  
>  	/* avoid reading back stale values if HDMI mode is not enabled */
> -	if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
> +	if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
>  		hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
>  		hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
>  	}
> @@ -886,6 +906,37 @@ out:
>  	return ret;
>  }
>  
> +static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
> +				       struct intel_shared_dpll *pll,
> +				       struct intel_dpll_hw_state *hw_state)
> +{
> +	uint32_t val;
> +	const struct skl_dpll_regs *regs = skl_dpll_regs;
> +	bool ret;
> +
> +	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
I'm all for paranoia, but how can this ever happen?

Seems pll0 has its own function pointers, so you'd have to do something like pll1->funcs->get_hw_state(pll0);

I don't think this will ever happen, so all the paranoia from these functions that are called from the function pointer can be removed.
> +	if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
> +		return false;
> +
> +	ret = false;
> +
> +	/* DPLL0 is always enabled since it drives CDCLK */
> +	val = I915_READ(regs[pll->id].ctl);
> +	if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
> +		goto out;
> +
> +	val = I915_READ(DPLL_CTRL1);
> +	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
> +
> +	ret = true;
> +
> +out:
> +	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
> +
> +	return ret;
> +}
> +
>  struct skl_wrpll_context {
>  	uint64_t min_deviation;		/* current minimal deviation */
>  	uint64_t central_freq;		/* chosen central freq */
> @@ -1165,7 +1216,8 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
>  			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
>  			 wrpll_params.central_freq;
>  	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
> -		   encoder->type == INTEL_OUTPUT_DP_MST) {
> +		   encoder->type == INTEL_OUTPUT_DP_MST ||
> +		   encoder->type == INTEL_OUTPUT_EDP) {
>  		switch (crtc_state->port_clock / 2) {
>  		case 81000:
>  			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
> @@ -1176,6 +1228,19 @@ skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state,
>  		case 270000:
>  			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
>  			break;
> +		/* eDP 1.4 rates */
> +		case 162000:
> +			ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
> +			break;
> +		/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
> +		results in CDCLK change. Need to handle the change of CDCLK by
> +		disabling pipes and re-enabling them */
Sounds like we really need to start supporting cdclk changes on SKL, if it's based on this pll?
modeset_calc_cdclk and modeset_commit_cdclk.

~Maarten
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 07/13] drm/i915: Use a table to initilize shared dplls
  2016-03-03 11:32     ` Ander Conselvan De Oliveira
@ 2016-03-03 13:35       ` Maarten Lankhorst
  0 siblings, 0 replies; 31+ messages in thread
From: Maarten Lankhorst @ 2016-03-03 13:35 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira, intel-gfx

Op 03-03-16 om 12:32 schreef Ander Conselvan De Oliveira:
> Hi Maarten,
>
> Thanks for reviewing. Comments below.
>
> On Wed, 2016-03-02 at 16:30 +0100, Maarten Lankhorst wrote:
>> Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
>>> Use a table to store the per-platform shared dpll information in one
>>> place. This way, there is no need for platform specific init funtions.
>>>
>>> Signed-off-by: Ander Conselvan de Oliveira <
>>> ander.conselvan.de.oliveira@intel.com>
>>> ---
>>>  drivers/gpu/drm/i915/intel_display.c  |  16 +--
>>>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 189 ++++++++++++++++---------------
>>> ---
>>>  drivers/gpu/drm/i915/intel_dpll_mgr.h |  22 ++--
>>>  3 files changed, 108 insertions(+), 119 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_display.c
>>> b/drivers/gpu/drm/i915/intel_display.c
>>> index e723323..133b6b7 100644
>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>> @@ -9148,8 +9148,8 @@ static bool ironlake_get_pipe_config(struct intel_crtc
>>> *crtc,
>>>  			intel_get_shared_dpll_by_id(dev_priv, pll_id);
>>>  		pll = pipe_config->shared_dpll;
>>>  
>>> -		WARN_ON(!pll->get_hw_state(dev_priv, pll,
>>> -					   &pipe_config->dpll_hw_state));
>>> +		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
>>> +						 &pipe_config
>>> ->dpll_hw_state));
>>>  
>>>  		tmp = pipe_config->dpll_hw_state.dpll;
>>>  		pipe_config->pixel_multiplier =
>>> @@ -9695,8 +9695,8 @@ static void haswell_get_ddi_port_state(struct
>>> intel_crtc *crtc,
>>>  
>>>  	pll = pipe_config->shared_dpll;
>>>  	if (pll) {
>>> -		WARN_ON(!pll->get_hw_state(dev_priv, pll,
>>> -					   &pipe_config->dpll_hw_state));
>>> +		WARN_ON(!pll->funcs.get_hw_state(dev_priv, pll,
>>> +						 &pipe_config
>>> ->dpll_hw_state));
>>>  	}
>>>  
>>>  	/*
>>> @@ -12728,7 +12728,7 @@ check_shared_dpll_state(struct drm_device *dev)
>>>  
>>>  		DRM_DEBUG_KMS("%s\n", pll->name);
>>>  
>>> -		active = pll->get_hw_state(dev_priv, pll, &dpll_hw_state);
>>> +		active = pll->funcs.get_hw_state(dev_priv, pll,
>>> &dpll_hw_state);
>>>  
>>>  		I915_STATE_WARN(pll->active > hweight32(pll
>>> ->config.crtc_mask),
>>>  		     "more active pll users than references: %i vs %i\n",
>>> @@ -15466,8 +15466,8 @@ static void intel_modeset_readout_hw_state(struct
>>> drm_device *dev)
>>>  	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>>>  		struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
>>>  
>>> -		pll->on = pll->get_hw_state(dev_priv, pll,
>>> -					    &pll->config.hw_state);
>>> +		pll->on = pll->funcs.get_hw_state(dev_priv, pll,
>>> +						  &pll->config.hw_state);
>>>  		pll->active = 0;
>>>  		pll->config.crtc_mask = 0;
>>>  		for_each_intel_crtc(dev, crtc) {
>>> @@ -15602,7 +15602,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
>>>  
>>>  		DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll
>>> ->name);
>>>  
>>> -		pll->disable(dev_priv, pll);
>>> +		pll->funcs.disable(dev_priv, pll);
>>>  		pll->on = false;
>>>  	}
>>>  
>>> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> b/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> index 889ceed..e88dc46 100644
>>> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> @@ -74,7 +74,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
>>>  	if (WARN(!pll, "asserting DPLL %s with no DPLL\n", onoff(state)))
>>>  		return;
>>>  
>>> -	cur_state = pll->get_hw_state(dev_priv, pll, &hw_state);
>>> +	cur_state = pll->funcs.get_hw_state(dev_priv, pll, &hw_state);
>>>  	I915_STATE_WARN(cur_state != state,
>>>  	     "%s assertion failure (expected %s, current %s)\n",
>>>  			pll->name, onoff(state), onoff(cur_state));
>>> @@ -95,7 +95,7 @@ void intel_prepare_shared_dpll(struct intel_crtc *crtc)
>>>  		WARN_ON(pll->on);
>>>  		assert_shared_dpll_disabled(dev_priv, pll);
>>>  
>>> -		pll->mode_set(dev_priv, pll);
>>> +		pll->funcs.mode_set(dev_priv, pll);
>>>  	}
>>>  }
>>>  
>>> @@ -133,7 +133,7 @@ void intel_enable_shared_dpll(struct intel_crtc *crtc)
>>>  	intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
>>>  
>>>  	DRM_DEBUG_KMS("enabling %s\n", pll->name);
>>> -	pll->enable(dev_priv, pll);
>>> +	pll->funcs.enable(dev_priv, pll);
>>>  	pll->on = true;
>>>  }
>>>  
>>> @@ -168,7 +168,7 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
>>>  		return;
>>>  
>>>  	DRM_DEBUG_KMS("disabling %s\n", pll->name);
>>> -	pll->disable(dev_priv, pll);
>>> +	pll->funcs.disable(dev_priv, pll);
>>>  	pll->on = false;
>>>  
>>>  	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
>>> @@ -398,29 +398,13 @@ static void ibx_pch_dpll_disable(struct
>>> drm_i915_private *dev_priv,
>>>  	udelay(200);
>>>  }
>>>  
>>> -static char *ibx_pch_dpll_names[] = {
>>> -	"PCH DPLL A",
>>> -	"PCH DPLL B",
>>> +static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
>>> +	.mode_set = ibx_pch_dpll_mode_set,
>>> +	.enable = ibx_pch_dpll_enable,
>>> +	.disable = ibx_pch_dpll_disable,
>>> +	.get_hw_state = ibx_pch_dpll_get_hw_state,
>>>  };
>>>  
>>> -static void ibx_pch_dpll_init(struct drm_device *dev)
>>> -{
>>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>>> -	int i;
>>> -
>>> -	dev_priv->num_shared_dpll = 2;
>>> -
>>> -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>>> -		dev_priv->shared_dplls[i].id = i;
>>> -		dev_priv->shared_dplls[i].name = ibx_pch_dpll_names[i];
>>> -		dev_priv->shared_dplls[i].mode_set = ibx_pch_dpll_mode_set;
>>> -		dev_priv->shared_dplls[i].enable = ibx_pch_dpll_enable;
>>> -		dev_priv->shared_dplls[i].disable = ibx_pch_dpll_disable;
>>> -		dev_priv->shared_dplls[i].get_hw_state =
>>> -			ibx_pch_dpll_get_hw_state;
>>> -	}
>>> -}
>>> -
>>>  static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
>>>  			       struct intel_shared_dpll *pll)
>>>  {
>>> @@ -492,40 +476,16 @@ static bool hsw_ddi_spll_get_hw_state(struct
>>> drm_i915_private *dev_priv,
>>>  }
>>>  
>>>  
>>> -static const char * const hsw_ddi_pll_names[] = {
>>> -	"WRPLL 1",
>>> -	"WRPLL 2",
>>> -	"SPLL"
>>> +static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
>>> +	.enable = hsw_ddi_wrpll_enable,
>>> +	.disable = hsw_ddi_wrpll_disable,
>>> +	.get_hw_state = hsw_ddi_wrpll_get_hw_state,
>>>  };
>>>  
>>> -static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
>>> -{
>>> -	int i;
>>> -
>>> -	dev_priv->num_shared_dpll = 3;
>>> -
>>> -	for (i = 0; i < 2; i++) {
>>> -		dev_priv->shared_dplls[i].id = i;
>>> -		dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
>>> -		dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
>>> -		dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
>>> -		dev_priv->shared_dplls[i].get_hw_state =
>>> -			hsw_ddi_wrpll_get_hw_state;
>>> -	}
>>> -
>>> -	/* SPLL is special, but needs to be initialized anyway.. */
>>> -	dev_priv->shared_dplls[i].id = i;
>>> -	dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
>>> -	dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
>>> -	dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
>>> -	dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
>>> -
>>> -}
>>> -
>>> -static const char * const skl_ddi_pll_names[] = {
>>> -	"DPLL 1",
>>> -	"DPLL 2",
>>> -	"DPLL 3",
>>> +static const struct intel_shared_dpll_funcs hsw_ddi_spll_funcs = {
>>> +	.enable = hsw_ddi_spll_enable,
>>> +	.disable = hsw_ddi_spll_disable,
>>> +	.get_hw_state = hsw_ddi_spll_get_hw_state,
>>>  };
>>>  
>>>  struct skl_dpll_regs {
>>> @@ -634,26 +594,10 @@ out:
>>>  	return ret;
>>>  }
>>>  
>>> -static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
>>> -{
>>> -	int i;
>>> -
>>> -	dev_priv->num_shared_dpll = 3;
>>> -
>>> -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>>> -		dev_priv->shared_dplls[i].id = i;
>>> -		dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
>>> -		dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
>>> -		dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
>>> -		dev_priv->shared_dplls[i].get_hw_state =
>>> -			skl_ddi_pll_get_hw_state;
>>> -	}
>>> -}
>>> -
>>> -static const char * const bxt_ddi_pll_names[] = {
>>> -	"PORT PLL A",
>>> -	"PORT PLL B",
>>> -	"PORT PLL C",
>>> +static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
>>> +	.enable = skl_ddi_pll_enable,
>>> +	.disable = skl_ddi_pll_disable,
>>> +	.get_hw_state = skl_ddi_pll_get_hw_state,
>>>  };
>>>  
>>>  static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
>>> @@ -838,34 +782,17 @@ out:
>>>  	return ret;
>>>  }
>>>  
>>> -static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
>>> -{
>>> -	int i;
>>> -
>>> -	dev_priv->num_shared_dpll = 3;
>>> -
>>> -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>>> -		dev_priv->shared_dplls[i].id = i;
>>> -		dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
>>> -		dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
>>> -		dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
>>> -		dev_priv->shared_dplls[i].get_hw_state =
>>> -			bxt_ddi_pll_get_hw_state;
>>> -	}
>>> -}
>>> +static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
>>> +	.enable = bxt_ddi_pll_enable,
>>> +	.disable = bxt_ddi_pll_disable,
>>> +	.get_hw_state = bxt_ddi_pll_get_hw_state,
>>> +};
>>>  
>>>  static void intel_ddi_pll_init(struct drm_device *dev)
>>>  {
>>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>>  	uint32_t val = I915_READ(LCPLL_CTL);
>>>  
>>> -	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
>>> -		skl_shared_dplls_init(dev_priv);
>>> -	else if (IS_BROXTON(dev))
>>> -		bxt_shared_dplls_init(dev_priv);
>>> -	else
>>> -		hsw_shared_dplls_init(dev_priv);
>>> -
>>>  	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
>>>  		int cdclk_freq;
>>>  
>>> @@ -893,16 +820,72 @@ static void intel_ddi_pll_init(struct drm_device *dev)
>>>  	}
>>>  }
>>>  
>>> +struct dpll_info {
>>> +	const char *name;
>>> +	const int id;
>>> +	const struct intel_shared_dpll_funcs *funcs;
>>> +};
>>> +
>> Seems shared_dplls[i].id == i, so that could be removed. 
> There are places in the code that assume those are equal. I considered not
> including the id, but concluded that having the id and a WARN_ON() in
>  intel_shared_dpll_init() documents that assumption better.
>
> I think it would be better to remove that assumption, but that require changes
> to intel_atomic_state and users. But I think it would be nice if we could have a
> per-DPLL state object.
Ok, I think the current way is fine then.
>> If you also move name to funcs you could kill this struct.
> In a later patch I add a flags field to this struct. I guess I could move that
> to funcs too, but then we need to come up with a better name for that struct.
> "funcs" starts to sound wrong.
>
> IMO having that extra struct is fine, so I rather let things settle first and
> then do another round of clean ups. But if that is a no-go, I can re-spin.
>
I don't have a strong opinion, you can keep it like it is.

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v3 13/13] drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code
  2016-03-03 13:33     ` Maarten Lankhorst
@ 2016-03-03 13:40       ` Ander Conselvan De Oliveira
  2016-03-03 13:51         ` Maarten Lankhorst
  0 siblings, 1 reply; 31+ messages in thread
From: Ander Conselvan De Oliveira @ 2016-03-03 13:40 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

On Thu, 2016-03-03 at 14:33 +0100, Maarten Lankhorst wrote:
> Op 29-02-16 om 10:08 schreef Ander Conselvan de Oliveira:
> > Include DPLL0 in the managed dplls for SKL/KBL. While it has to be kept
> > enabled because of it driving CDCLK, it is better to special case that
> > inside the DPLL code than in the higher level.
> > 
> > v2: Use INTEL_DPLL_ALWAYS_ON flag. (Ander)
> > 
> > Signed-off-by: Ander Conselvan de Oliveira <
> > ander.conselvan.de.oliveira@intel.com>
> > 
> > ---
> > I wasn't able to test this patch. Would really appreciate a tested by
> > from someone.
> Unfortunately no skl with eDP here either. :(
> >  drivers/gpu/drm/i915/intel_ddi.c      |  21 ------
> >  drivers/gpu/drm/i915/intel_dp.c       |  52 +-------------
> >  drivers/gpu/drm/i915/intel_dpll_mgr.c | 131 +++++++++++++++++++++++++++----
> > ---
> >  drivers/gpu/drm/i915/intel_dpll_mgr.h |   7 +-
> >  4 files changed, 109 insertions(+), 102 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> > b/drivers/gpu/drm/i915/intel_ddi.c
> > index 3cb9f36..8ef4d2e 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -1008,9 +1008,6 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
> >  {
> >  	struct intel_shared_dpll *pll;
> >  
> > -	if (intel_encoder->type == INTEL_OUTPUT_EDP)
> > -		return true;
> > -
> >  	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
> >  	if (pll == NULL) {
> >  		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
> > @@ -1570,24 +1567,6 @@ void intel_ddi_clk_select(struct intel_encoder
> > *encoder,
> >  		uint32_t dpll = pipe_config->ddi_pll_sel;
> >  		uint32_t val;
> >  
> > -		/*
> > -		 * DPLL0 is used for eDP and is the only "private" DPLL (as
> > -		 * opposed to shared) on SKL
> > -		 */
> > -		if (encoder->type == INTEL_OUTPUT_EDP) {
> > -			WARN_ON(dpll != SKL_DPLL0);
> > -
> > -			val = I915_READ(DPLL_CTRL1);
> > -
> > -			val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
> > -				 DPLL_CTRL1_SSC(dpll) |
> > -				 DPLL_CTRL1_LINK_RATE_MASK(dpll));
> > -			val |= pipe_config->dpll_hw_state.ctrl1 << (dpll *
> > 6);
> > -
> > -			I915_WRITE(DPLL_CTRL1, val);
> > -			POSTING_READ(DPLL_CTRL1);
> > -		}
> > -
> >  		/* DDI -> PLL mapping  */
> >  		val = I915_READ(DPLL_CTRL2);
> >  
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index 5be6892..9fef877 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -1229,52 +1229,6 @@ intel_dp_connector_unregister(struct intel_connector
> > *intel_connector)
> >  	intel_connector_unregister(intel_connector);
> >  }
> >  
> > -static void
> > -skl_edp_set_pll_config(struct intel_crtc_state *pipe_config)
> > -{
> > -	u32 ctrl1;
> > -
> > -	memset(&pipe_config->dpll_hw_state, 0,
> > -	       sizeof(pipe_config->dpll_hw_state));
> > -
> > -	pipe_config->ddi_pll_sel = SKL_DPLL0;
> > -	pipe_config->dpll_hw_state.cfgcr1 = 0;
> > -	pipe_config->dpll_hw_state.cfgcr2 = 0;
> > -
> > -	ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
> > -	switch (pipe_config->port_clock / 2) {
> > -	case 81000:
> > -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
> > -					      SKL_DPLL0);
> > -		break;
> > -	case 135000:
> > -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350,
> > -					      SKL_DPLL0);
> > -		break;
> > -	case 270000:
> > -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700,
> > -					      SKL_DPLL0);
> > -		break;
> > -	case 162000:
> > -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620,
> > -					      SKL_DPLL0);
> > -		break;
> > -	/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
> > -	results in CDCLK change. Need to handle the change of CDCLK by
> > -	disabling pipes and re-enabling them */
> > -	case 108000:
> > -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
> > -					      SKL_DPLL0);
> > -		break;
> > -	case 216000:
> > -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160,
> > -					      SKL_DPLL0);
> > -		break;
> > -
> > -	}
> > -	pipe_config->dpll_hw_state.ctrl1 = ctrl1;
> > -}
> > -
> >  static int
> >  intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
> >  {
> > @@ -1632,11 +1586,7 @@ found:
> >  				&pipe_config->dp_m2_n2);
> >  	}
> >  
> > -	if ((IS_SKYLAKE(dev)  || IS_KABYLAKE(dev)) && is_edp(intel_dp))
> > -		skl_edp_set_pll_config(pipe_config);
> > -	else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
> > -		/* handled in ddi */;
> > -	else
> > +	if (!HAS_DDI(dev))
> >  		intel_dp_set_clock(encoder, 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 d371680..6ec7836 100644
> > --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > @@ -785,7 +785,12 @@ struct skl_dpll_regs {
> >  };
> >  
> >  /* this array is indexed by the *shared* pll id */
> > -static const struct skl_dpll_regs skl_dpll_regs[3] = {
> > +static const struct skl_dpll_regs skl_dpll_regs[4] = {
> > +	{
> > +		/* DPLL 0 */
> > +		.ctl = LCPLL1_CTL,
> > +		/* DPLL 0 doesn't support HDMI mode */
> > +	},
> >  	{
> >  		/* DPLL 1 */
> >  		.ctl = LCPLL2_CTL,
> > @@ -806,24 +811,29 @@ static const struct skl_dpll_regs skl_dpll_regs[3] = {
> >  	},
> >  };
> >  
> > -static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
> > -			       struct intel_shared_dpll *pll)
> > +static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
> > +				    struct intel_shared_dpll *pll)
> >  {
> >  	uint32_t val;
> > -	unsigned int dpll;
> > -	const struct skl_dpll_regs *regs = skl_dpll_regs;
> > -
> > -	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1
> > */
> > -	dpll = pll->id + 1;
> >  
> >  	val = I915_READ(DPLL_CTRL1);
> >  
> > -	val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
> > -		 DPLL_CTRL1_LINK_RATE_MASK(dpll));
> > -	val |= pll->config.hw_state.ctrl1 << (dpll * 6);
> > +	val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
> > +		 DPLL_CTRL1_LINK_RATE_MASK(pll->id));
> > +	val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
> >  
> >  	I915_WRITE(DPLL_CTRL1, val);
> >  	POSTING_READ(DPLL_CTRL1);
> > +}
> > +
> > +static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
> > +			       struct intel_shared_dpll *pll)
> > +{
> > +	const struct skl_dpll_regs *regs = skl_dpll_regs;
> > +
> > +	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
> > +
> > +	skl_ddi_pll_write_ctrl1(dev_priv, pll);
> >  
> >  	I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
> >  	I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
> > @@ -834,8 +844,15 @@ static void skl_ddi_pll_enable(struct drm_i915_private
> > *dev_priv,
> >  	I915_WRITE(regs[pll->id].ctl,
> >  		   I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
> >  
> > -	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
> > -		DRM_ERROR("DPLL %d not locked\n", dpll);
> > +	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
> > +		DRM_ERROR("DPLL %d not locked\n", pll->id);
> > +}
> > +
> > +static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
> > +				 struct intel_shared_dpll *pll)
> > +{
> > +	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
> > +	skl_ddi_pll_write_ctrl1(dev_priv, pll);
> >  }
> >  
> >  static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
> > @@ -849,32 +866,35 @@ static void skl_ddi_pll_disable(struct
> > drm_i915_private *dev_priv,
> >  	POSTING_READ(regs[pll->id].ctl);
> >  }
> >  
> > +static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
> > +				  struct intel_shared_dpll *pll)
> > +{
> > +}
> > +
> >  static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
> >  				     struct intel_shared_dpll *pll,
> >  				     struct intel_dpll_hw_state *hw_state)
> >  {
> >  	uint32_t val;
> > -	unsigned int dpll;
> >  	const struct skl_dpll_regs *regs = skl_dpll_regs;
> >  	bool ret;
> >  
> > +	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
> > +
> >  	if (!intel_display_power_get_if_enabled(dev_priv,
> > POWER_DOMAIN_PLLS))
> >  		return false;
> >  
> >  	ret = false;
> >  
> > -	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1
> > */
> > -	dpll = pll->id + 1;
> > -
> >  	val = I915_READ(regs[pll->id].ctl);
> >  	if (!(val & LCPLL_PLL_ENABLE))
> >  		goto out;
> >  
> >  	val = I915_READ(DPLL_CTRL1);
> > -	hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
> > +	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
> >  
> >  	/* avoid reading back stale values if HDMI mode is not enabled */
> > -	if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
> > +	if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
> >  		hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
> >  		hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
> >  	}
> > @@ -886,6 +906,37 @@ out:
> >  	return ret;
> >  }
> >  
> > +static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
> > +				       struct intel_shared_dpll *pll,
> > +				       struct intel_dpll_hw_state
> > *hw_state)
> > +{
> > +	uint32_t val;
> > +	const struct skl_dpll_regs *regs = skl_dpll_regs;
> > +	bool ret;
> > +
> > +	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
> I'm all for paranoia, but how can this ever happen?
> 
> Seems pll0 has its own function pointers, so you'd have to do something like
> pll1->funcs->get_hw_state(pll0);
> 
> I don't think this will ever happen, so all the paranoia from these functions
> that are called from the function pointer can be removed.

I went a bit overboard. Will respin.

> > +	if (!intel_display_power_get_if_enabled(dev_priv,
> > POWER_DOMAIN_PLLS))
> > +		return false;
> > +
> > +	ret = false;
> > +
> > +	/* DPLL0 is always enabled since it drives CDCLK */
> > +	val = I915_READ(regs[pll->id].ctl);
> > +	if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
> > +		goto out;
> > +
> > +	val = I915_READ(DPLL_CTRL1);
> > +	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
> > +
> > +	ret = true;
> > +
> > +out:
> > +	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
> > +
> > +	return ret;
> > +}
> > +
> >  struct skl_wrpll_context {
> >  	uint64_t min_deviation;		/* current minimal deviation
> > */
> >  	uint64_t central_freq;		/* chosen central freq */
> > @@ -1165,7 +1216,8 @@ skl_get_dpll(struct intel_crtc *crtc, struct
> > intel_crtc_state *crtc_state,
> >  			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
> >  			 wrpll_params.central_freq;
> >  	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
> > -		   encoder->type == INTEL_OUTPUT_DP_MST) {
> > +		   encoder->type == INTEL_OUTPUT_DP_MST ||
> > +		   encoder->type == INTEL_OUTPUT_EDP) {
> >  		switch (crtc_state->port_clock / 2) {
> >  		case 81000:
> >  			ctrl1 |=
> > DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
> > @@ -1176,6 +1228,19 @@ skl_get_dpll(struct intel_crtc *crtc, struct
> > intel_crtc_state *crtc_state,
> >  		case 270000:
> >  			ctrl1 |=
> > DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
> >  			break;
> > +		/* eDP 1.4 rates */
> > +		case 162000:
> > +			ctrl1 |=
> > DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
> > +			break;
> > +		/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is
> > 8640 which
> > +		results in CDCLK change. Need to handle the change of CDCLK
> > by
> > +		disabling pipes and re-enabling them */
> Sounds like we really need to start supporting cdclk changes on SKL, if it's
> based on this pll?
> modeset_calc_cdclk and modeset_commit_cdclk.

Clint Taylor has been working on it:

https://lists.freedesktop.org/archives/intel-gfx/2016-February/087796.html


Ander

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v3 13/13] drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code
  2016-03-03 13:40       ` Ander Conselvan De Oliveira
@ 2016-03-03 13:51         ` Maarten Lankhorst
  0 siblings, 0 replies; 31+ messages in thread
From: Maarten Lankhorst @ 2016-03-03 13:51 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira, intel-gfx

Op 03-03-16 om 14:40 schreef Ander Conselvan De Oliveira:
> On Thu, 2016-03-03 at 14:33 +0100, Maarten Lankhorst wrote:
>> Op 29-02-16 om 10:08 schreef Ander Conselvan de Oliveira:
>>> Include DPLL0 in the managed dplls for SKL/KBL. While it has to be kept
>>> enabled because of it driving CDCLK, it is better to special case that
>>> inside the DPLL code than in the higher level.
>>>
>>> v2: Use INTEL_DPLL_ALWAYS_ON flag. (Ander)
>>>
>>> Signed-off-by: Ander Conselvan de Oliveira <
>>> ander.conselvan.de.oliveira@intel.com>
>>>
>>> ---
>>> I wasn't able to test this patch. Would really appreciate a tested by
>>> from someone.
>> Unfortunately no skl with eDP here either. :(
>>>  drivers/gpu/drm/i915/intel_ddi.c      |  21 ------
>>>  drivers/gpu/drm/i915/intel_dp.c       |  52 +-------------
>>>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 131 +++++++++++++++++++++++++++----
>>> ---
>>>  drivers/gpu/drm/i915/intel_dpll_mgr.h |   7 +-
>>>  4 files changed, 109 insertions(+), 102 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c
>>> b/drivers/gpu/drm/i915/intel_ddi.c
>>> index 3cb9f36..8ef4d2e 100644
>>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>>> @@ -1008,9 +1008,6 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
>>>  {
>>>  	struct intel_shared_dpll *pll;
>>>  
>>> -	if (intel_encoder->type == INTEL_OUTPUT_EDP)
>>> -		return true;
>>> -
>>>  	pll = intel_get_shared_dpll(intel_crtc, crtc_state, intel_encoder);
>>>  	if (pll == NULL) {
>>>  		DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
>>> @@ -1570,24 +1567,6 @@ void intel_ddi_clk_select(struct intel_encoder
>>> *encoder,
>>>  		uint32_t dpll = pipe_config->ddi_pll_sel;
>>>  		uint32_t val;
>>>  
>>> -		/*
>>> -		 * DPLL0 is used for eDP and is the only "private" DPLL (as
>>> -		 * opposed to shared) on SKL
>>> -		 */
>>> -		if (encoder->type == INTEL_OUTPUT_EDP) {
>>> -			WARN_ON(dpll != SKL_DPLL0);
>>> -
>>> -			val = I915_READ(DPLL_CTRL1);
>>> -
>>> -			val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
>>> -				 DPLL_CTRL1_SSC(dpll) |
>>> -				 DPLL_CTRL1_LINK_RATE_MASK(dpll));
>>> -			val |= pipe_config->dpll_hw_state.ctrl1 << (dpll *
>>> 6);
>>> -
>>> -			I915_WRITE(DPLL_CTRL1, val);
>>> -			POSTING_READ(DPLL_CTRL1);
>>> -		}
>>> -
>>>  		/* DDI -> PLL mapping  */
>>>  		val = I915_READ(DPLL_CTRL2);
>>>  
>>> diff --git a/drivers/gpu/drm/i915/intel_dp.c
>>> b/drivers/gpu/drm/i915/intel_dp.c
>>> index 5be6892..9fef877 100644
>>> --- a/drivers/gpu/drm/i915/intel_dp.c
>>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>>> @@ -1229,52 +1229,6 @@ intel_dp_connector_unregister(struct intel_connector
>>> *intel_connector)
>>>  	intel_connector_unregister(intel_connector);
>>>  }
>>>  
>>> -static void
>>> -skl_edp_set_pll_config(struct intel_crtc_state *pipe_config)
>>> -{
>>> -	u32 ctrl1;
>>> -
>>> -	memset(&pipe_config->dpll_hw_state, 0,
>>> -	       sizeof(pipe_config->dpll_hw_state));
>>> -
>>> -	pipe_config->ddi_pll_sel = SKL_DPLL0;
>>> -	pipe_config->dpll_hw_state.cfgcr1 = 0;
>>> -	pipe_config->dpll_hw_state.cfgcr2 = 0;
>>> -
>>> -	ctrl1 = DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
>>> -	switch (pipe_config->port_clock / 2) {
>>> -	case 81000:
>>> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
>>> -					      SKL_DPLL0);
>>> -		break;
>>> -	case 135000:
>>> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350,
>>> -					      SKL_DPLL0);
>>> -		break;
>>> -	case 270000:
>>> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700,
>>> -					      SKL_DPLL0);
>>> -		break;
>>> -	case 162000:
>>> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620,
>>> -					      SKL_DPLL0);
>>> -		break;
>>> -	/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is 8640 which
>>> -	results in CDCLK change. Need to handle the change of CDCLK by
>>> -	disabling pipes and re-enabling them */
>>> -	case 108000:
>>> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
>>> -					      SKL_DPLL0);
>>> -		break;
>>> -	case 216000:
>>> -		ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160,
>>> -					      SKL_DPLL0);
>>> -		break;
>>> -
>>> -	}
>>> -	pipe_config->dpll_hw_state.ctrl1 = ctrl1;
>>> -}
>>> -
>>>  static int
>>>  intel_dp_sink_rates(struct intel_dp *intel_dp, const int **sink_rates)
>>>  {
>>> @@ -1632,11 +1586,7 @@ found:
>>>  				&pipe_config->dp_m2_n2);
>>>  	}
>>>  
>>> -	if ((IS_SKYLAKE(dev)  || IS_KABYLAKE(dev)) && is_edp(intel_dp))
>>> -		skl_edp_set_pll_config(pipe_config);
>>> -	else if (IS_BROXTON(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
>>> -		/* handled in ddi */;
>>> -	else
>>> +	if (!HAS_DDI(dev))
>>>  		intel_dp_set_clock(encoder, 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 d371680..6ec7836 100644
>>> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> @@ -785,7 +785,12 @@ struct skl_dpll_regs {
>>>  };
>>>  
>>>  /* this array is indexed by the *shared* pll id */
>>> -static const struct skl_dpll_regs skl_dpll_regs[3] = {
>>> +static const struct skl_dpll_regs skl_dpll_regs[4] = {
>>> +	{
>>> +		/* DPLL 0 */
>>> +		.ctl = LCPLL1_CTL,
>>> +		/* DPLL 0 doesn't support HDMI mode */
>>> +	},
>>>  	{
>>>  		/* DPLL 1 */
>>>  		.ctl = LCPLL2_CTL,
>>> @@ -806,24 +811,29 @@ static const struct skl_dpll_regs skl_dpll_regs[3] = {
>>>  	},
>>>  };
>>>  
>>> -static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
>>> -			       struct intel_shared_dpll *pll)
>>> +static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *dev_priv,
>>> +				    struct intel_shared_dpll *pll)
>>>  {
>>>  	uint32_t val;
>>> -	unsigned int dpll;
>>> -	const struct skl_dpll_regs *regs = skl_dpll_regs;
>>> -
>>> -	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1
>>> */
>>> -	dpll = pll->id + 1;
>>>  
>>>  	val = I915_READ(DPLL_CTRL1);
>>>  
>>> -	val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
>>> -		 DPLL_CTRL1_LINK_RATE_MASK(dpll));
>>> -	val |= pll->config.hw_state.ctrl1 << (dpll * 6);
>>> +	val &= ~(DPLL_CTRL1_HDMI_MODE(pll->id) | DPLL_CTRL1_SSC(pll->id) |
>>> +		 DPLL_CTRL1_LINK_RATE_MASK(pll->id));
>>> +	val |= pll->config.hw_state.ctrl1 << (pll->id * 6);
>>>  
>>>  	I915_WRITE(DPLL_CTRL1, val);
>>>  	POSTING_READ(DPLL_CTRL1);
>>> +}
>>> +
>>> +static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
>>> +			       struct intel_shared_dpll *pll)
>>> +{
>>> +	const struct skl_dpll_regs *regs = skl_dpll_regs;
>>> +
>>> +	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
>>> +
>>> +	skl_ddi_pll_write_ctrl1(dev_priv, pll);
>>>  
>>>  	I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
>>>  	I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
>>> @@ -834,8 +844,15 @@ static void skl_ddi_pll_enable(struct drm_i915_private
>>> *dev_priv,
>>>  	I915_WRITE(regs[pll->id].ctl,
>>>  		   I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
>>>  
>>> -	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
>>> -		DRM_ERROR("DPLL %d not locked\n", dpll);
>>> +	if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(pll->id), 5))
>>> +		DRM_ERROR("DPLL %d not locked\n", pll->id);
>>> +}
>>> +
>>> +static void skl_ddi_dpll0_enable(struct drm_i915_private *dev_priv,
>>> +				 struct intel_shared_dpll *pll)
>>> +{
>>> +	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
>>> +	skl_ddi_pll_write_ctrl1(dev_priv, pll);
>>>  }
>>>  
>>>  static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
>>> @@ -849,32 +866,35 @@ static void skl_ddi_pll_disable(struct
>>> drm_i915_private *dev_priv,
>>>  	POSTING_READ(regs[pll->id].ctl);
>>>  }
>>>  
>>> +static void skl_ddi_dpll0_disable(struct drm_i915_private *dev_priv,
>>> +				  struct intel_shared_dpll *pll)
>>> +{
>>> +}
>>> +
>>>  static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
>>>  				     struct intel_shared_dpll *pll,
>>>  				     struct intel_dpll_hw_state *hw_state)
>>>  {
>>>  	uint32_t val;
>>> -	unsigned int dpll;
>>>  	const struct skl_dpll_regs *regs = skl_dpll_regs;
>>>  	bool ret;
>>>  
>>> +	WARN_ON(pll->id == DPLL_ID_SKL_DPLL0);
>>> +
>>>  	if (!intel_display_power_get_if_enabled(dev_priv,
>>> POWER_DOMAIN_PLLS))
>>>  		return false;
>>>  
>>>  	ret = false;
>>>  
>>> -	/* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1
>>> */
>>> -	dpll = pll->id + 1;
>>> -
>>>  	val = I915_READ(regs[pll->id].ctl);
>>>  	if (!(val & LCPLL_PLL_ENABLE))
>>>  		goto out;
>>>  
>>>  	val = I915_READ(DPLL_CTRL1);
>>> -	hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
>>> +	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
>>>  
>>>  	/* avoid reading back stale values if HDMI mode is not enabled */
>>> -	if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
>>> +	if (val & DPLL_CTRL1_HDMI_MODE(pll->id)) {
>>>  		hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
>>>  		hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
>>>  	}
>>> @@ -886,6 +906,37 @@ out:
>>>  	return ret;
>>>  }
>>>  
>>> +static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv,
>>> +				       struct intel_shared_dpll *pll,
>>> +				       struct intel_dpll_hw_state
>>> *hw_state)
>>> +{
>>> +	uint32_t val;
>>> +	const struct skl_dpll_regs *regs = skl_dpll_regs;
>>> +	bool ret;
>>> +
>>> +	WARN_ON(pll->id != DPLL_ID_SKL_DPLL0);
>> I'm all for paranoia, but how can this ever happen?
>>
>> Seems pll0 has its own function pointers, so you'd have to do something like
>> pll1->funcs->get_hw_state(pll0);
>>
>> I don't think this will ever happen, so all the paranoia from these functions
>> that are called from the function pointer can be removed.
> I went a bit overboard. Will respin.
>
>>> +	if (!intel_display_power_get_if_enabled(dev_priv,
>>> POWER_DOMAIN_PLLS))
>>> +		return false;
>>> +
>>> +	ret = false;
>>> +
>>> +	/* DPLL0 is always enabled since it drives CDCLK */
>>> +	val = I915_READ(regs[pll->id].ctl);
>>> +	if (WARN_ON(!(val & LCPLL_PLL_ENABLE)))
>>> +		goto out;
>>> +
>>> +	val = I915_READ(DPLL_CTRL1);
>>> +	hw_state->ctrl1 = (val >> (pll->id * 6)) & 0x3f;
>>> +
>>> +	ret = true;
>>> +
>>> +out:
>>> +	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>>  struct skl_wrpll_context {
>>>  	uint64_t min_deviation;		/* current minimal deviation
>>> */
>>>  	uint64_t central_freq;		/* chosen central freq */
>>> @@ -1165,7 +1216,8 @@ skl_get_dpll(struct intel_crtc *crtc, struct
>>> intel_crtc_state *crtc_state,
>>>  			 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
>>>  			 wrpll_params.central_freq;
>>>  	} else if (encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
>>> -		   encoder->type == INTEL_OUTPUT_DP_MST) {
>>> +		   encoder->type == INTEL_OUTPUT_DP_MST ||
>>> +		   encoder->type == INTEL_OUTPUT_EDP) {
>>>  		switch (crtc_state->port_clock / 2) {
>>>  		case 81000:
>>>  			ctrl1 |=
>>> DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
>>> @@ -1176,6 +1228,19 @@ skl_get_dpll(struct intel_crtc *crtc, struct
>>> intel_crtc_state *crtc_state,
>>>  		case 270000:
>>>  			ctrl1 |=
>>> DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
>>>  			break;
>>> +		/* eDP 1.4 rates */
>>> +		case 162000:
>>> +			ctrl1 |=
>>> DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, 0);
>>> +			break;
>>> +		/* TBD: For DP link rates 2.16 GHz and 4.32 GHz, VCO is
>>> 8640 which
>>> +		results in CDCLK change. Need to handle the change of CDCLK
>>> by
>>> +		disabling pipes and re-enabling them */
>> Sounds like we really need to start supporting cdclk changes on SKL, if it's
>> based on this pll?
>> modeset_calc_cdclk and modeset_commit_cdclk.
> Clint Taylor has been working on it:
>
> https://lists.freedesktop.org/archives/intel-gfx/2016-February/087796.html
>
Ah indeed, that would definitely help with this TBD!
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/13] drm/i915: Refactor platform specifics out of intel_get_shared_dpll()
  2016-02-26 13:54 ` [PATCH 08/13] drm/i915: Refactor platform specifics out of intel_get_shared_dpll() Ander Conselvan de Oliveira
@ 2016-03-03 14:08   ` Maarten Lankhorst
  2016-03-04  6:36     ` Ander Conselvan De Oliveira
  2016-03-04  6:49     ` Ander Conselvan De Oliveira
  0 siblings, 2 replies; 31+ messages in thread
From: Maarten Lankhorst @ 2016-03-03 14:08 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx

Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
> The function intel_get_shared_dpll() had a more or less generic
> implementation with some platform specific checks to handle smaller
> differences between platforms. However, the minimalist approach forces
> bigger differences between platforms to be implemented outside of the
> shared dpll code (see the *_ddi_pll_select() functions in intel_ddi.c,
> for instance).
>
> This patch changes the implementation of intel_get_share_dpll() so that
> a completely platform specific version can be used, providing helpers to
> reduce code duplication. This should allow the code from the ddi pll
> select functions to be moved, and also make room for making more dplls
> managed by the shared dpll infrastructure.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h       |   1 +
>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 226 +++++++++++++++++++++-------------
>  drivers/gpu/drm/i915/intel_dpll_mgr.h |   2 +
>  3 files changed, 145 insertions(+), 84 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 6de93dc..b858801 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1802,6 +1802,7 @@ struct drm_i915_private {
>  	/* dpll and cdclk state is protected by connection_mutex */
>  	int num_shared_dpll;
>  	struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
> +	const struct intel_dpll_mgr *dpll_mgr;
>  
>  	unsigned int active_crtcs;
>  	unsigned int min_pixclk[I915_MAX_PIPES];
> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> index e88dc46..3553324 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> @@ -174,66 +174,20 @@ void intel_disable_shared_dpll(struct intel_crtc *crtc)
>  	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
>  }
>  
> -static enum intel_dpll_id
> -ibx_get_fixed_dpll(struct intel_crtc *crtc,
> -		   struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	struct intel_shared_dpll *pll;
> -	enum intel_dpll_id i;
> -
> -	/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
> -	i = (enum intel_dpll_id) crtc->pipe;
> -	pll = &dev_priv->shared_dplls[i];
> -
> -	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> -		      crtc->base.base.id, pll->name);
> -
> -	return i;
> -}
> -
> -static enum intel_dpll_id
> -bxt_get_fixed_dpll(struct intel_crtc *crtc,
> -		   struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	struct intel_encoder *encoder;
> -	struct intel_digital_port *intel_dig_port;
> -	struct intel_shared_dpll *pll;
> -	enum intel_dpll_id i;
> -
> -	/* PLL is attached to port in bxt */
> -	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
> -	if (WARN_ON(!encoder))
> -		return DPLL_ID_PRIVATE;
> -
> -	intel_dig_port = enc_to_dig_port(&encoder->base);
> -	/* 1:1 mapping between ports and PLLs */
> -	i = (enum intel_dpll_id)intel_dig_port->port;
> -	pll = &dev_priv->shared_dplls[i];
> -	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> -		crtc->base.base.id, pll->name);
> -
> -	return i;
> -}
> -
> -static enum intel_dpll_id
> +static struct intel_shared_dpll *
>  intel_find_shared_dpll(struct intel_crtc *crtc,
> -		       struct intel_crtc_state *crtc_state)
> +		       struct intel_crtc_state *crtc_state,
> +		       enum intel_dpll_id range_min,
> +		       enum intel_dpll_id range_max)
>  {
>  	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
>  	struct intel_shared_dpll *pll;
>  	struct intel_shared_dpll_config *shared_dpll;
>  	enum intel_dpll_id i;
> -	int max = dev_priv->num_shared_dpll;
> -
> -	if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
> -		/* Do not consider SPLL */
> -		max = 2;
>  
>  	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
>  
> -	for (i = 0; i < max; i++) {
> +	for (i = range_min; i <= range_max; i++) {
>  		pll = &dev_priv->shared_dplls[i];
>  
>  		/* Only want to check enabled timings first */
> @@ -247,49 +201,33 @@ intel_find_shared_dpll(struct intel_crtc *crtc,
>  				      crtc->base.base.id, pll->name,
>  				      shared_dpll[i].crtc_mask,
>  				      pll->active);
> -			return i;
> +			return pll;
>  		}
>  	}
>  
>  	/* Ok no matching timings, maybe there's a free one? */
> -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> +	for (i = range_min; i <= range_max; i++) {
>  		pll = &dev_priv->shared_dplls[i];
>  		if (shared_dpll[i].crtc_mask == 0) {
>  			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
>  				      crtc->base.base.id, pll->name);
> -			return i;
> +			return pll;
>  		}
>  	}
>  
> -	return DPLL_ID_PRIVATE;
> +	return NULL;
>  }
>  
> -struct intel_shared_dpll *
> -intel_get_shared_dpll(struct intel_crtc *crtc,
> -		      struct intel_crtc_state *crtc_state)
> +static void
> +intel_reference_shared_dpll(struct intel_shared_dpll *pll,
> +			    struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> -	struct intel_shared_dpll *pll;
>  	struct intel_shared_dpll_config *shared_dpll;
> -	enum intel_dpll_id i;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	enum intel_dpll_id i = pll->id;
>  
>  	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state->base.state);
>  
> -	if (HAS_PCH_IBX(dev_priv->dev)) {
> -		i = ibx_get_fixed_dpll(crtc, crtc_state);
> -		WARN_ON(shared_dpll[i].crtc_mask);
> -	} else if (IS_BROXTON(dev_priv->dev)) {
> -		i = bxt_get_fixed_dpll(crtc, crtc_state);
> -		WARN_ON(shared_dpll[i].crtc_mask);
> -	} else {
> -		i = intel_find_shared_dpll(crtc, crtc_state);
> -	}
> -
> -	if (i < 0)
> -		return NULL;
> -
> -	pll = &dev_priv->shared_dplls[i];
> -
>  	if (shared_dpll[i].crtc_mask == 0)
>  		shared_dpll[i].hw_state =
>  			crtc_state->dpll_hw_state;
> @@ -299,8 +237,6 @@ intel_get_shared_dpll(struct intel_crtc *crtc,
>  			 pipe_name(crtc->pipe));
>  
>  	intel_shared_dpll_config_get(shared_dpll, pll, crtc);
> -
> -	return pll;
>  }
>  
>  void intel_shared_dpll_commit(struct drm_atomic_state *state)
> @@ -398,6 +334,32 @@ static void ibx_pch_dpll_disable(struct drm_i915_private *dev_priv,
>  	udelay(200);
>  }
>  
> +static struct intel_shared_dpll *
> +ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	struct intel_shared_dpll *pll;
> +	enum intel_dpll_id i;
> +
> +	if (HAS_PCH_IBX(dev_priv)) {
> +		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
> +		i = (enum intel_dpll_id) crtc->pipe;
> +		pll = &dev_priv->shared_dplls[i];
> +
> +		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> +			      crtc->base.base.id, pll->name);
> +	} else {
> +		pll = intel_find_shared_dpll(crtc, crtc_state,
> +					     DPLL_ID_PCH_PLL_A,
> +					     DPLL_ID_PCH_PLL_B);
> +	}
> +
> +	/* reference the pll */
> +	intel_reference_shared_dpll(pll, crtc_state);
> +
> +	return pll;
> +}
> +
>  static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
>  	.mode_set = ibx_pch_dpll_mode_set,
>  	.enable = ibx_pch_dpll_enable,
> @@ -475,6 +437,19 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
>  	return val & SPLL_PLL_ENABLE;
>  }
>  
> +static struct intel_shared_dpll *
> +hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_shared_dpll *pll;
> +
> +	pll = intel_find_shared_dpll(crtc, crtc_state,
> +				     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
> +	if (pll)
> +		intel_reference_shared_dpll(pll, crtc_state);
> +
> +	return pll;
> +}
> +
>  
>  static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
>  	.enable = hsw_ddi_wrpll_enable,
> @@ -594,6 +569,19 @@ out:
>  	return ret;
>  }
>  
> +static struct intel_shared_dpll *
> +skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_shared_dpll *pll;
> +
> +	pll = intel_find_shared_dpll(crtc, crtc_state,
> +				     DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3);
> +	if (pll)
> +		intel_reference_shared_dpll(pll, crtc_state);
> +
> +	return pll;
> +}
> +
>  static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
>  	.enable = skl_ddi_pll_enable,
>  	.disable = skl_ddi_pll_disable,
> @@ -782,6 +770,32 @@ out:
>  	return ret;
>  }
>  
> +static struct intel_shared_dpll *
> +bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	struct intel_encoder *encoder;
> +	struct intel_digital_port *intel_dig_port;
> +	struct intel_shared_dpll *pll;
> +	enum intel_dpll_id i;
> +
> +	/* PLL is attached to port in bxt */
> +	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
> +	if (WARN_ON(!encoder))
> +		return NULL;
> +
> +	intel_dig_port = enc_to_dig_port(&encoder->base);
> +	/* 1:1 mapping between ports and PLLs */
> +	i = (enum intel_dpll_id)intel_dig_port->port;
> +	pll = &dev_priv->shared_dplls[i];
> +	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> +		crtc->base.base.id, pll->name);
> +
> +	intel_reference_shared_dpll(pll, crtc_state);
> +
> +	return pll;
> +}
> +
>  static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
>  	.enable = bxt_ddi_pll_enable,
>  	.disable = bxt_ddi_pll_disable,
> @@ -826,12 +840,24 @@ struct dpll_info {
>  	const struct intel_shared_dpll_funcs *funcs;
>  };
>  
> +struct intel_dpll_mgr {
> +	const struct dpll_info *dpll_info;
> +
> +	struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
> +					      struct intel_crtc_state *crtc_state);
> +};
> +
>  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 },
>  };
>  
> +static const struct intel_dpll_mgr pch_pll_mgr = {
> +	.dpll_info = pch_plls,
> +	.get_dpll = ibx_get_dpll,
> +};
> +
>  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 },
> @@ -839,6 +865,11 @@ static const struct dpll_info hsw_plls[] = {
>  	{ NULL, -1, NULL, },
>  };
>  
> +static const struct intel_dpll_mgr hsw_pll_mgr = {
> +	.dpll_info = hsw_plls,
> +	.get_dpll = hsw_get_dpll,
> +};
> +
>  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 },
> @@ -846,6 +877,11 @@ static const struct dpll_info skl_plls[] = {
>  	{ NULL, -1, NULL, },
>  };
>  
> +static const struct intel_dpll_mgr skl_pll_mgr = {
> +	.dpll_info = skl_plls,
> +	.get_dpll = skl_get_dpll,
> +};
> +
>  static const struct dpll_info bxt_plls[] = {
>  	{ "PORT PLL A", 0, &bxt_ddi_pll_funcs },
>  	{ "PORT PLL B", 1, &bxt_ddi_pll_funcs },
> @@ -853,26 +889,34 @@ static const struct dpll_info bxt_plls[] = {
>  	{ NULL, -1, NULL, },
>  };
>  
> +static const struct intel_dpll_mgr bxt_pll_mgr = {
> +	.dpll_info = bxt_plls,
> +	.get_dpll = bxt_get_dpll,
> +};
> +
>  void intel_shared_dpll_init(struct drm_device *dev)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	const struct dpll_info *dpll_info = NULL;
> +	const struct intel_dpll_mgr *dpll_mgr = NULL;
> +	const struct dpll_info *dpll_info;
>  	int i;
>  
>  	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
> -		dpll_info = skl_plls;
> +		dpll_mgr = &skl_pll_mgr;
>  	else if IS_BROXTON(dev)
> -		dpll_info = bxt_plls;
> +		dpll_mgr = &bxt_pll_mgr;
>  	else if (HAS_DDI(dev))
> -		dpll_info = hsw_plls;
> +		dpll_mgr = &hsw_pll_mgr;
>  	else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
> -		dpll_info = pch_plls;
> +		dpll_mgr = &pch_pll_mgr;
>  
> -	if (!dpll_info) {
> +	if (!dpll_mgr) {
>  		dev_priv->num_shared_dpll = 0;
>  		return;
>  	}
>  
> +	dpll_info = dpll_mgr->dpll_info;
> +
>  	for (i = 0; dpll_info[i].id >= 0; i++) {
>  		WARN_ON(i != dpll_info[i].id);
>  
> @@ -881,6 +925,7 @@ void intel_shared_dpll_init(struct drm_device *dev)
>  		dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
>  	}
>  
> +	dev_priv->dpll_mgr = dpll_mgr;
>  	dev_priv->num_shared_dpll = i;
>  
>  	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
> @@ -889,3 +934,16 @@ void intel_shared_dpll_init(struct drm_device *dev)
>  	if (HAS_DDI(dev))
>  		intel_ddi_pll_init(dev);
>  }
> +
> +struct intel_shared_dpll *
> +intel_get_shared_dpll(struct intel_crtc *crtc,
> +		      struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
> +
> +	if (dpll_mgr)
> +		return dpll_mgr->get_dpll(crtc, crtc_state);
> +	else
> +		return NULL;
> +}
should there be a WARN_ON here?

Rest looks good, so for patch 8...11/13:

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/13] drm/i915: Refactor platform specifics out of intel_get_shared_dpll()
  2016-03-03 14:08   ` Maarten Lankhorst
@ 2016-03-04  6:36     ` Ander Conselvan De Oliveira
  2016-03-04  6:49     ` Ander Conselvan De Oliveira
  1 sibling, 0 replies; 31+ messages in thread
From: Ander Conselvan De Oliveira @ 2016-03-04  6:36 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

On Thu, 2016-03-03 at 15:08 +0100, Maarten Lankhorst wrote:
> Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
> > The function intel_get_shared_dpll() had a more or less generic
> > implementation with some platform specific checks to handle smaller
> > differences between platforms. However, the minimalist approach forces
> > bigger differences between platforms to be implemented outside of the
> > shared dpll code (see the *_ddi_pll_select() functions in intel_ddi.c,
> > for instance).
> > 
> > This patch changes the implementation of intel_get_share_dpll() so that
> > a completely platform specific version can be used, providing helpers to
> > reduce code duplication. This should allow the code from the ddi pll
> > select functions to be moved, and also make room for making more dplls
> > managed by the shared dpll infrastructure.
> > 
> > Signed-off-by: Ander Conselvan de Oliveira <
> > ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h       |   1 +
> >  drivers/gpu/drm/i915/intel_dpll_mgr.c | 226 +++++++++++++++++++++----------
> > ---
> >  drivers/gpu/drm/i915/intel_dpll_mgr.h |   2 +
> >  3 files changed, 145 insertions(+), 84 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 6de93dc..b858801 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1802,6 +1802,7 @@ struct drm_i915_private {
> >  	/* dpll and cdclk state is protected by connection_mutex */
> >  	int num_shared_dpll;
> >  	struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
> > +	const struct intel_dpll_mgr *dpll_mgr;
> >  
> >  	unsigned int active_crtcs;
> >  	unsigned int min_pixclk[I915_MAX_PIPES];
> > diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > index e88dc46..3553324 100644
> > --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > @@ -174,66 +174,20 @@ void intel_disable_shared_dpll(struct intel_crtc
> > *crtc)
> >  	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
> >  }
> >  
> > -static enum intel_dpll_id
> > -ibx_get_fixed_dpll(struct intel_crtc *crtc,
> > -		   struct intel_crtc_state *crtc_state)
> > -{
> > -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > -	struct intel_shared_dpll *pll;
> > -	enum intel_dpll_id i;
> > -
> > -	/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
> > -	i = (enum intel_dpll_id) crtc->pipe;
> > -	pll = &dev_priv->shared_dplls[i];
> > -
> > -	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> > -		      crtc->base.base.id, pll->name);
> > -
> > -	return i;
> > -}
> > -
> > -static enum intel_dpll_id
> > -bxt_get_fixed_dpll(struct intel_crtc *crtc,
> > -		   struct intel_crtc_state *crtc_state)
> > -{
> > -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > -	struct intel_encoder *encoder;
> > -	struct intel_digital_port *intel_dig_port;
> > -	struct intel_shared_dpll *pll;
> > -	enum intel_dpll_id i;
> > -
> > -	/* PLL is attached to port in bxt */
> > -	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
> > -	if (WARN_ON(!encoder))
> > -		return DPLL_ID_PRIVATE;
> > -
> > -	intel_dig_port = enc_to_dig_port(&encoder->base);
> > -	/* 1:1 mapping between ports and PLLs */
> > -	i = (enum intel_dpll_id)intel_dig_port->port;
> > -	pll = &dev_priv->shared_dplls[i];
> > -	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> > -		crtc->base.base.id, pll->name);
> > -
> > -	return i;
> > -}
> > -
> > -static enum intel_dpll_id
> > +static struct intel_shared_dpll *
> >  intel_find_shared_dpll(struct intel_crtc *crtc,
> > -		       struct intel_crtc_state *crtc_state)
> > +		       struct intel_crtc_state *crtc_state,
> > +		       enum intel_dpll_id range_min,
> > +		       enum intel_dpll_id range_max)
> >  {
> >  	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> >  	struct intel_shared_dpll *pll;
> >  	struct intel_shared_dpll_config *shared_dpll;
> >  	enum intel_dpll_id i;
> > -	int max = dev_priv->num_shared_dpll;
> > -
> > -	if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
> > -		/* Do not consider SPLL */
> > -		max = 2;
> >  
> >  	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state
> > ->base.state);
> >  
> > -	for (i = 0; i < max; i++) {
> > +	for (i = range_min; i <= range_max; i++) {
> >  		pll = &dev_priv->shared_dplls[i];
> >  
> >  		/* Only want to check enabled timings first */
> > @@ -247,49 +201,33 @@ intel_find_shared_dpll(struct intel_crtc *crtc,
> >  				      crtc->base.base.id, pll->name,
> >  				      shared_dpll[i].crtc_mask,
> >  				      pll->active);
> > -			return i;
> > +			return pll;
> >  		}
> >  	}
> >  
> >  	/* Ok no matching timings, maybe there's a free one? */
> > -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> > +	for (i = range_min; i <= range_max; i++) {
> >  		pll = &dev_priv->shared_dplls[i];
> >  		if (shared_dpll[i].crtc_mask == 0) {
> >  			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
> >  				      crtc->base.base.id, pll->name);
> > -			return i;
> > +			return pll;
> >  		}
> >  	}
> >  
> > -	return DPLL_ID_PRIVATE;
> > +	return NULL;
> >  }
> >  
> > -struct intel_shared_dpll *
> > -intel_get_shared_dpll(struct intel_crtc *crtc,
> > -		      struct intel_crtc_state *crtc_state)
> > +static void
> > +intel_reference_shared_dpll(struct intel_shared_dpll *pll,
> > +			    struct intel_crtc_state *crtc_state)
> >  {
> > -	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > -	struct intel_shared_dpll *pll;
> >  	struct intel_shared_dpll_config *shared_dpll;
> > -	enum intel_dpll_id i;
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> > +	enum intel_dpll_id i = pll->id;
> >  
> >  	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state
> > ->base.state);
> >  
> > -	if (HAS_PCH_IBX(dev_priv->dev)) {
> > -		i = ibx_get_fixed_dpll(crtc, crtc_state);
> > -		WARN_ON(shared_dpll[i].crtc_mask);
> > -	} else if (IS_BROXTON(dev_priv->dev)) {
> > -		i = bxt_get_fixed_dpll(crtc, crtc_state);
> > -		WARN_ON(shared_dpll[i].crtc_mask);
> > -	} else {
> > -		i = intel_find_shared_dpll(crtc, crtc_state);
> > -	}
> > -
> > -	if (i < 0)
> > -		return NULL;
> > -
> > -	pll = &dev_priv->shared_dplls[i];
> > -
> >  	if (shared_dpll[i].crtc_mask == 0)
> >  		shared_dpll[i].hw_state =
> >  			crtc_state->dpll_hw_state;
> > @@ -299,8 +237,6 @@ intel_get_shared_dpll(struct intel_crtc *crtc,
> >  			 pipe_name(crtc->pipe));
> >  
> >  	intel_shared_dpll_config_get(shared_dpll, pll, crtc);
> > -
> > -	return pll;
> >  }
> >  
> >  void intel_shared_dpll_commit(struct drm_atomic_state *state)
> > @@ -398,6 +334,32 @@ static void ibx_pch_dpll_disable(struct
> > drm_i915_private *dev_priv,
> >  	udelay(200);
> >  }
> >  
> > +static struct intel_shared_dpll *
> > +ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	struct intel_shared_dpll *pll;
> > +	enum intel_dpll_id i;
> > +
> > +	if (HAS_PCH_IBX(dev_priv)) {
> > +		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
> > +		i = (enum intel_dpll_id) crtc->pipe;
> > +		pll = &dev_priv->shared_dplls[i];
> > +
> > +		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> > +			      crtc->base.base.id, pll->name);
> > +	} else {
> > +		pll = intel_find_shared_dpll(crtc, crtc_state,
> > +					     DPLL_ID_PCH_PLL_A,
> > +					     DPLL_ID_PCH_PLL_B);
> > +	}
> > +
> > +	/* reference the pll */
> > +	intel_reference_shared_dpll(pll, crtc_state);
> > +
> > +	return pll;
> > +}
> > +
> >  static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
> >  	.mode_set = ibx_pch_dpll_mode_set,
> >  	.enable = ibx_pch_dpll_enable,
> > @@ -475,6 +437,19 @@ static bool hsw_ddi_spll_get_hw_state(struct
> > drm_i915_private *dev_priv,
> >  	return val & SPLL_PLL_ENABLE;
> >  }
> >  
> > +static struct intel_shared_dpll *
> > +hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_shared_dpll *pll;
> > +
> > +	pll = intel_find_shared_dpll(crtc, crtc_state,
> > +				     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
> > +	if (pll)
> > +		intel_reference_shared_dpll(pll, crtc_state);
> > +
> > +	return pll;
> > +}
> > +
> >  
> >  static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
> >  	.enable = hsw_ddi_wrpll_enable,
> > @@ -594,6 +569,19 @@ out:
> >  	return ret;
> >  }
> >  
> > +static struct intel_shared_dpll *
> > +skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_shared_dpll *pll;
> > +
> > +	pll = intel_find_shared_dpll(crtc, crtc_state,
> > +				     DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3);
> > +	if (pll)
> > +		intel_reference_shared_dpll(pll, crtc_state);
> > +
> > +	return pll;
> > +}
> > +
> >  static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
> >  	.enable = skl_ddi_pll_enable,
> >  	.disable = skl_ddi_pll_disable,
> > @@ -782,6 +770,32 @@ out:
> >  	return ret;
> >  }
> >  
> > +static struct intel_shared_dpll *
> > +bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	struct intel_encoder *encoder;
> > +	struct intel_digital_port *intel_dig_port;
> > +	struct intel_shared_dpll *pll;
> > +	enum intel_dpll_id i;
> > +
> > +	/* PLL is attached to port in bxt */
> > +	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
> > +	if (WARN_ON(!encoder))
> > +		return NULL;
> > +
> > +	intel_dig_port = enc_to_dig_port(&encoder->base);
> > +	/* 1:1 mapping between ports and PLLs */
> > +	i = (enum intel_dpll_id)intel_dig_port->port;
> > +	pll = &dev_priv->shared_dplls[i];
> > +	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> > +		crtc->base.base.id, pll->name);
> > +
> > +	intel_reference_shared_dpll(pll, crtc_state);
> > +
> > +	return pll;
> > +}
> > +
> >  static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
> >  	.enable = bxt_ddi_pll_enable,
> >  	.disable = bxt_ddi_pll_disable,
> > @@ -826,12 +840,24 @@ struct dpll_info {
> >  	const struct intel_shared_dpll_funcs *funcs;
> >  };
> >  
> > +struct intel_dpll_mgr {
> > +	const struct dpll_info *dpll_info;
> > +
> > +	struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
> > +					      struct intel_crtc_state
> > *crtc_state);
> > +};
> > +
> >  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 },
> >  };
> >  
> > +static const struct intel_dpll_mgr pch_pll_mgr = {
> > +	.dpll_info = pch_plls,
> > +	.get_dpll = ibx_get_dpll,
> > +};
> > +
> >  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 },
> > @@ -839,6 +865,11 @@ static const struct dpll_info hsw_plls[] = {
> >  	{ NULL, -1, NULL, },
> >  };
> >  
> > +static const struct intel_dpll_mgr hsw_pll_mgr = {
> > +	.dpll_info = hsw_plls,
> > +	.get_dpll = hsw_get_dpll,
> > +};
> > +
> >  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 },
> > @@ -846,6 +877,11 @@ static const struct dpll_info skl_plls[] = {
> >  	{ NULL, -1, NULL, },
> >  };
> >  
> > +static const struct intel_dpll_mgr skl_pll_mgr = {
> > +	.dpll_info = skl_plls,
> > +	.get_dpll = skl_get_dpll,
> > +};
> > +
> >  static const struct dpll_info bxt_plls[] = {
> >  	{ "PORT PLL A", 0, &bxt_ddi_pll_funcs },
> >  	{ "PORT PLL B", 1, &bxt_ddi_pll_funcs },
> > @@ -853,26 +889,34 @@ static const struct dpll_info bxt_plls[] = {
> >  	{ NULL, -1, NULL, },
> >  };
> >  
> > +static const struct intel_dpll_mgr bxt_pll_mgr = {
> > +	.dpll_info = bxt_plls,
> > +	.get_dpll = bxt_get_dpll,
> > +};
> > +
> >  void intel_shared_dpll_init(struct drm_device *dev)
> >  {
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	const struct dpll_info *dpll_info = NULL;
> > +	const struct intel_dpll_mgr *dpll_mgr = NULL;
> > +	const struct dpll_info *dpll_info;
> >  	int i;
> >  
> >  	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
> > -		dpll_info = skl_plls;
> > +		dpll_mgr = &skl_pll_mgr;
> >  	else if IS_BROXTON(dev)
> > -		dpll_info = bxt_plls;
> > +		dpll_mgr = &bxt_pll_mgr;
> >  	else if (HAS_DDI(dev))
> > -		dpll_info = hsw_plls;
> > +		dpll_mgr = &hsw_pll_mgr;
> >  	else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
> > -		dpll_info = pch_plls;
> > +		dpll_mgr = &pch_pll_mgr;
> >  
> > -	if (!dpll_info) {
> > +	if (!dpll_mgr) {
> >  		dev_priv->num_shared_dpll = 0;
> >  		return;
> >  	}
> >  
> > +	dpll_info = dpll_mgr->dpll_info;
> > +
> >  	for (i = 0; dpll_info[i].id >= 0; i++) {
> >  		WARN_ON(i != dpll_info[i].id);
> >  
> > @@ -881,6 +925,7 @@ void intel_shared_dpll_init(struct drm_device *dev)
> >  		dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
> >  	}
> >  
> > +	dev_priv->dpll_mgr = dpll_mgr;
> >  	dev_priv->num_shared_dpll = i;
> >  
> >  	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
> > @@ -889,3 +934,16 @@ void intel_shared_dpll_init(struct drm_device *dev)
> >  	if (HAS_DDI(dev))
> >  		intel_ddi_pll_init(dev);
> >  }
> > +
> > +struct intel_shared_dpll *
> > +intel_get_shared_dpll(struct intel_crtc *crtc,
> > +		      struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
> > +
> > +	if (dpll_mgr)
> > +		return dpll_mgr->get_dpll(crtc, crtc_state);
> > +	else
> > +		return NULL;
> > +}
> should there be a WARN_ON here?
> 

Makes sense. I'll send v2.

Thanks,
Ander

> Rest looks good, so for patch 8...11/13:
> 
> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/13] drm/i915: Refactor platform specifics out of intel_get_shared_dpll()
  2016-03-03 14:08   ` Maarten Lankhorst
  2016-03-04  6:36     ` Ander Conselvan De Oliveira
@ 2016-03-04  6:49     ` Ander Conselvan De Oliveira
  2016-03-07  9:59       ` Maarten Lankhorst
  1 sibling, 1 reply; 31+ messages in thread
From: Ander Conselvan De Oliveira @ 2016-03-04  6:49 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

On Thu, 2016-03-03 at 15:08 +0100, Maarten Lankhorst wrote:
> Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
> > The function intel_get_shared_dpll() had a more or less generic
> > implementation with some platform specific checks to handle smaller
> > differences between platforms. However, the minimalist approach forces
> > bigger differences between platforms to be implemented outside of the
> > shared dpll code (see the *_ddi_pll_select() functions in intel_ddi.c,
> > for instance).
> > 
> > This patch changes the implementation of intel_get_share_dpll() so that
> > a completely platform specific version can be used, providing helpers to
> > reduce code duplication. This should allow the code from the ddi pll
> > select functions to be moved, and also make room for making more dplls
> > managed by the shared dpll infrastructure.
> > 
> > Signed-off-by: Ander Conselvan de Oliveira <
> > ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h       |   1 +
> >  drivers/gpu/drm/i915/intel_dpll_mgr.c | 226 +++++++++++++++++++++----------
> > ---
> >  drivers/gpu/drm/i915/intel_dpll_mgr.h |   2 +
> >  3 files changed, 145 insertions(+), 84 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 6de93dc..b858801 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -1802,6 +1802,7 @@ struct drm_i915_private {
> >  	/* dpll and cdclk state is protected by connection_mutex */
> >  	int num_shared_dpll;
> >  	struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
> > +	const struct intel_dpll_mgr *dpll_mgr;
> >  
> >  	unsigned int active_crtcs;
> >  	unsigned int min_pixclk[I915_MAX_PIPES];
> > diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > index e88dc46..3553324 100644
> > --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
> > @@ -174,66 +174,20 @@ void intel_disable_shared_dpll(struct intel_crtc
> > *crtc)
> >  	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
> >  }
> >  
> > -static enum intel_dpll_id
> > -ibx_get_fixed_dpll(struct intel_crtc *crtc,
> > -		   struct intel_crtc_state *crtc_state)
> > -{
> > -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > -	struct intel_shared_dpll *pll;
> > -	enum intel_dpll_id i;
> > -
> > -	/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
> > -	i = (enum intel_dpll_id) crtc->pipe;
> > -	pll = &dev_priv->shared_dplls[i];
> > -
> > -	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> > -		      crtc->base.base.id, pll->name);
> > -
> > -	return i;
> > -}
> > -
> > -static enum intel_dpll_id
> > -bxt_get_fixed_dpll(struct intel_crtc *crtc,
> > -		   struct intel_crtc_state *crtc_state)
> > -{
> > -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > -	struct intel_encoder *encoder;
> > -	struct intel_digital_port *intel_dig_port;
> > -	struct intel_shared_dpll *pll;
> > -	enum intel_dpll_id i;
> > -
> > -	/* PLL is attached to port in bxt */
> > -	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
> > -	if (WARN_ON(!encoder))
> > -		return DPLL_ID_PRIVATE;
> > -
> > -	intel_dig_port = enc_to_dig_port(&encoder->base);
> > -	/* 1:1 mapping between ports and PLLs */
> > -	i = (enum intel_dpll_id)intel_dig_port->port;
> > -	pll = &dev_priv->shared_dplls[i];
> > -	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> > -		crtc->base.base.id, pll->name);
> > -
> > -	return i;
> > -}
> > -
> > -static enum intel_dpll_id
> > +static struct intel_shared_dpll *
> >  intel_find_shared_dpll(struct intel_crtc *crtc,
> > -		       struct intel_crtc_state *crtc_state)
> > +		       struct intel_crtc_state *crtc_state,
> > +		       enum intel_dpll_id range_min,
> > +		       enum intel_dpll_id range_max)
> >  {
> >  	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> >  	struct intel_shared_dpll *pll;
> >  	struct intel_shared_dpll_config *shared_dpll;
> >  	enum intel_dpll_id i;
> > -	int max = dev_priv->num_shared_dpll;
> > -
> > -	if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
> > -		/* Do not consider SPLL */
> > -		max = 2;
> >  
> >  	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state
> > ->base.state);
> >  
> > -	for (i = 0; i < max; i++) {
> > +	for (i = range_min; i <= range_max; i++) {
> >  		pll = &dev_priv->shared_dplls[i];
> >  
> >  		/* Only want to check enabled timings first */
> > @@ -247,49 +201,33 @@ intel_find_shared_dpll(struct intel_crtc *crtc,
> >  				      crtc->base.base.id, pll->name,
> >  				      shared_dpll[i].crtc_mask,
> >  				      pll->active);
> > -			return i;
> > +			return pll;
> >  		}
> >  	}
> >  
> >  	/* Ok no matching timings, maybe there's a free one? */
> > -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> > +	for (i = range_min; i <= range_max; i++) {
> >  		pll = &dev_priv->shared_dplls[i];
> >  		if (shared_dpll[i].crtc_mask == 0) {
> >  			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
> >  				      crtc->base.base.id, pll->name);
> > -			return i;
> > +			return pll;
> >  		}
> >  	}
> >  
> > -	return DPLL_ID_PRIVATE;
> > +	return NULL;
> >  }
> >  
> > -struct intel_shared_dpll *
> > -intel_get_shared_dpll(struct intel_crtc *crtc,
> > -		      struct intel_crtc_state *crtc_state)
> > +static void
> > +intel_reference_shared_dpll(struct intel_shared_dpll *pll,
> > +			    struct intel_crtc_state *crtc_state)
> >  {
> > -	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
> > -	struct intel_shared_dpll *pll;
> >  	struct intel_shared_dpll_config *shared_dpll;
> > -	enum intel_dpll_id i;
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> > +	enum intel_dpll_id i = pll->id;
> >  
> >  	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state
> > ->base.state);
> >  
> > -	if (HAS_PCH_IBX(dev_priv->dev)) {
> > -		i = ibx_get_fixed_dpll(crtc, crtc_state);
> > -		WARN_ON(shared_dpll[i].crtc_mask);
> > -	} else if (IS_BROXTON(dev_priv->dev)) {
> > -		i = bxt_get_fixed_dpll(crtc, crtc_state);
> > -		WARN_ON(shared_dpll[i].crtc_mask);
> > -	} else {
> > -		i = intel_find_shared_dpll(crtc, crtc_state);
> > -	}
> > -
> > -	if (i < 0)
> > -		return NULL;
> > -
> > -	pll = &dev_priv->shared_dplls[i];
> > -
> >  	if (shared_dpll[i].crtc_mask == 0)
> >  		shared_dpll[i].hw_state =
> >  			crtc_state->dpll_hw_state;
> > @@ -299,8 +237,6 @@ intel_get_shared_dpll(struct intel_crtc *crtc,
> >  			 pipe_name(crtc->pipe));
> >  
> >  	intel_shared_dpll_config_get(shared_dpll, pll, crtc);
> > -
> > -	return pll;
> >  }
> >  
> >  void intel_shared_dpll_commit(struct drm_atomic_state *state)
> > @@ -398,6 +334,32 @@ static void ibx_pch_dpll_disable(struct
> > drm_i915_private *dev_priv,
> >  	udelay(200);
> >  }
> >  
> > +static struct intel_shared_dpll *
> > +ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	struct intel_shared_dpll *pll;
> > +	enum intel_dpll_id i;
> > +
> > +	if (HAS_PCH_IBX(dev_priv)) {
> > +		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
> > +		i = (enum intel_dpll_id) crtc->pipe;
> > +		pll = &dev_priv->shared_dplls[i];
> > +
> > +		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> > +			      crtc->base.base.id, pll->name);
> > +	} else {
> > +		pll = intel_find_shared_dpll(crtc, crtc_state,
> > +					     DPLL_ID_PCH_PLL_A,
> > +					     DPLL_ID_PCH_PLL_B);
> > +	}
> > +
> > +	/* reference the pll */
> > +	intel_reference_shared_dpll(pll, crtc_state);
> > +
> > +	return pll;
> > +}
> > +
> >  static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
> >  	.mode_set = ibx_pch_dpll_mode_set,
> >  	.enable = ibx_pch_dpll_enable,
> > @@ -475,6 +437,19 @@ static bool hsw_ddi_spll_get_hw_state(struct
> > drm_i915_private *dev_priv,
> >  	return val & SPLL_PLL_ENABLE;
> >  }
> >  
> > +static struct intel_shared_dpll *
> > +hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_shared_dpll *pll;
> > +
> > +	pll = intel_find_shared_dpll(crtc, crtc_state,
> > +				     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
> > +	if (pll)
> > +		intel_reference_shared_dpll(pll, crtc_state);
> > +
> > +	return pll;
> > +}
> > +
> >  
> >  static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
> >  	.enable = hsw_ddi_wrpll_enable,
> > @@ -594,6 +569,19 @@ out:
> >  	return ret;
> >  }
> >  
> > +static struct intel_shared_dpll *
> > +skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_shared_dpll *pll;
> > +
> > +	pll = intel_find_shared_dpll(crtc, crtc_state,
> > +				     DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3);
> > +	if (pll)
> > +		intel_reference_shared_dpll(pll, crtc_state);
> > +
> > +	return pll;
> > +}
> > +
> >  static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
> >  	.enable = skl_ddi_pll_enable,
> >  	.disable = skl_ddi_pll_disable,
> > @@ -782,6 +770,32 @@ out:
> >  	return ret;
> >  }
> >  
> > +static struct intel_shared_dpll *
> > +bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	struct intel_encoder *encoder;
> > +	struct intel_digital_port *intel_dig_port;
> > +	struct intel_shared_dpll *pll;
> > +	enum intel_dpll_id i;
> > +
> > +	/* PLL is attached to port in bxt */
> > +	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
> > +	if (WARN_ON(!encoder))
> > +		return NULL;
> > +
> > +	intel_dig_port = enc_to_dig_port(&encoder->base);
> > +	/* 1:1 mapping between ports and PLLs */
> > +	i = (enum intel_dpll_id)intel_dig_port->port;
> > +	pll = &dev_priv->shared_dplls[i];
> > +	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
> > +		crtc->base.base.id, pll->name);
> > +
> > +	intel_reference_shared_dpll(pll, crtc_state);
> > +
> > +	return pll;
> > +}
> > +
> >  static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
> >  	.enable = bxt_ddi_pll_enable,
> >  	.disable = bxt_ddi_pll_disable,
> > @@ -826,12 +840,24 @@ struct dpll_info {
> >  	const struct intel_shared_dpll_funcs *funcs;
> >  };
> >  
> > +struct intel_dpll_mgr {
> > +	const struct dpll_info *dpll_info;
> > +
> > +	struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
> > +					      struct intel_crtc_state
> > *crtc_state);
> > +};
> > +
> >  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 },
> >  };
> >  
> > +static const struct intel_dpll_mgr pch_pll_mgr = {
> > +	.dpll_info = pch_plls,
> > +	.get_dpll = ibx_get_dpll,
> > +};
> > +
> >  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 },
> > @@ -839,6 +865,11 @@ static const struct dpll_info hsw_plls[] = {
> >  	{ NULL, -1, NULL, },
> >  };
> >  
> > +static const struct intel_dpll_mgr hsw_pll_mgr = {
> > +	.dpll_info = hsw_plls,
> > +	.get_dpll = hsw_get_dpll,
> > +};
> > +
> >  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 },
> > @@ -846,6 +877,11 @@ static const struct dpll_info skl_plls[] = {
> >  	{ NULL, -1, NULL, },
> >  };
> >  
> > +static const struct intel_dpll_mgr skl_pll_mgr = {
> > +	.dpll_info = skl_plls,
> > +	.get_dpll = skl_get_dpll,
> > +};
> > +
> >  static const struct dpll_info bxt_plls[] = {
> >  	{ "PORT PLL A", 0, &bxt_ddi_pll_funcs },
> >  	{ "PORT PLL B", 1, &bxt_ddi_pll_funcs },
> > @@ -853,26 +889,34 @@ static const struct dpll_info bxt_plls[] = {
> >  	{ NULL, -1, NULL, },
> >  };
> >  
> > +static const struct intel_dpll_mgr bxt_pll_mgr = {
> > +	.dpll_info = bxt_plls,
> > +	.get_dpll = bxt_get_dpll,
> > +};
> > +
> >  void intel_shared_dpll_init(struct drm_device *dev)
> >  {
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	const struct dpll_info *dpll_info = NULL;
> > +	const struct intel_dpll_mgr *dpll_mgr = NULL;
> > +	const struct dpll_info *dpll_info;
> >  	int i;
> >  
> >  	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
> > -		dpll_info = skl_plls;
> > +		dpll_mgr = &skl_pll_mgr;
> >  	else if IS_BROXTON(dev)
> > -		dpll_info = bxt_plls;
> > +		dpll_mgr = &bxt_pll_mgr;
> >  	else if (HAS_DDI(dev))
> > -		dpll_info = hsw_plls;
> > +		dpll_mgr = &hsw_pll_mgr;
> >  	else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
> > -		dpll_info = pch_plls;
> > +		dpll_mgr = &pch_pll_mgr;
> >  
> > -	if (!dpll_info) {
> > +	if (!dpll_mgr) {
> >  		dev_priv->num_shared_dpll = 0;
> >  		return;
> >  	}
> >  
> > +	dpll_info = dpll_mgr->dpll_info;
> > +
> >  	for (i = 0; dpll_info[i].id >= 0; i++) {
> >  		WARN_ON(i != dpll_info[i].id);
> >  
> > @@ -881,6 +925,7 @@ void intel_shared_dpll_init(struct drm_device *dev)
> >  		dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
> >  	}
> >  
> > +	dev_priv->dpll_mgr = dpll_mgr;
> >  	dev_priv->num_shared_dpll = i;
> >  
> >  	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
> > @@ -889,3 +934,16 @@ void intel_shared_dpll_init(struct drm_device *dev)
> >  	if (HAS_DDI(dev))
> >  		intel_ddi_pll_init(dev);
> >  }
> > +
> > +struct intel_shared_dpll *
> > +intel_get_shared_dpll(struct intel_crtc *crtc,
> > +		      struct intel_crtc_state *crtc_state)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
> > +
> > +	if (dpll_mgr)
> > +		return dpll_mgr->get_dpll(crtc, crtc_state);
> > +	else
> > +		return NULL;
> > +}
> should there be a WARN_ON here?
> 
> Rest looks good, so for patch 8...11/13:

Did you have comments on patch 12? I seem to have missed it.

Ander
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 08/13] drm/i915: Refactor platform specifics out of intel_get_shared_dpll()
  2016-03-04  6:49     ` Ander Conselvan De Oliveira
@ 2016-03-07  9:59       ` Maarten Lankhorst
  0 siblings, 0 replies; 31+ messages in thread
From: Maarten Lankhorst @ 2016-03-07  9:59 UTC (permalink / raw)
  To: Ander Conselvan De Oliveira, intel-gfx

Op 04-03-16 om 07:49 schreef Ander Conselvan De Oliveira:
> On Thu, 2016-03-03 at 15:08 +0100, Maarten Lankhorst wrote:
>> Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
>>> The function intel_get_shared_dpll() had a more or less generic
>>> implementation with some platform specific checks to handle smaller
>>> differences between platforms. However, the minimalist approach forces
>>> bigger differences between platforms to be implemented outside of the
>>> shared dpll code (see the *_ddi_pll_select() functions in intel_ddi.c,
>>> for instance).
>>>
>>> This patch changes the implementation of intel_get_share_dpll() so that
>>> a completely platform specific version can be used, providing helpers to
>>> reduce code duplication. This should allow the code from the ddi pll
>>> select functions to be moved, and also make room for making more dplls
>>> managed by the shared dpll infrastructure.
>>>
>>> Signed-off-by: Ander Conselvan de Oliveira <
>>> ander.conselvan.de.oliveira@intel.com>
>>> ---
>>>  drivers/gpu/drm/i915/i915_drv.h       |   1 +
>>>  drivers/gpu/drm/i915/intel_dpll_mgr.c | 226 +++++++++++++++++++++----------
>>> ---
>>>  drivers/gpu/drm/i915/intel_dpll_mgr.h |   2 +
>>>  3 files changed, 145 insertions(+), 84 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h
>>> b/drivers/gpu/drm/i915/i915_drv.h
>>> index 6de93dc..b858801 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -1802,6 +1802,7 @@ struct drm_i915_private {
>>>  	/* dpll and cdclk state is protected by connection_mutex */
>>>  	int num_shared_dpll;
>>>  	struct intel_shared_dpll shared_dplls[I915_NUM_PLLS];
>>> +	const struct intel_dpll_mgr *dpll_mgr;
>>>  
>>>  	unsigned int active_crtcs;
>>>  	unsigned int min_pixclk[I915_MAX_PIPES];
>>> diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> b/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> index e88dc46..3553324 100644
>>> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c
>>> @@ -174,66 +174,20 @@ void intel_disable_shared_dpll(struct intel_crtc
>>> *crtc)
>>>  	intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
>>>  }
>>>  
>>> -static enum intel_dpll_id
>>> -ibx_get_fixed_dpll(struct intel_crtc *crtc,
>>> -		   struct intel_crtc_state *crtc_state)
>>> -{
>>> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>> -	struct intel_shared_dpll *pll;
>>> -	enum intel_dpll_id i;
>>> -
>>> -	/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
>>> -	i = (enum intel_dpll_id) crtc->pipe;
>>> -	pll = &dev_priv->shared_dplls[i];
>>> -
>>> -	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
>>> -		      crtc->base.base.id, pll->name);
>>> -
>>> -	return i;
>>> -}
>>> -
>>> -static enum intel_dpll_id
>>> -bxt_get_fixed_dpll(struct intel_crtc *crtc,
>>> -		   struct intel_crtc_state *crtc_state)
>>> -{
>>> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>> -	struct intel_encoder *encoder;
>>> -	struct intel_digital_port *intel_dig_port;
>>> -	struct intel_shared_dpll *pll;
>>> -	enum intel_dpll_id i;
>>> -
>>> -	/* PLL is attached to port in bxt */
>>> -	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
>>> -	if (WARN_ON(!encoder))
>>> -		return DPLL_ID_PRIVATE;
>>> -
>>> -	intel_dig_port = enc_to_dig_port(&encoder->base);
>>> -	/* 1:1 mapping between ports and PLLs */
>>> -	i = (enum intel_dpll_id)intel_dig_port->port;
>>> -	pll = &dev_priv->shared_dplls[i];
>>> -	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
>>> -		crtc->base.base.id, pll->name);
>>> -
>>> -	return i;
>>> -}
>>> -
>>> -static enum intel_dpll_id
>>> +static struct intel_shared_dpll *
>>>  intel_find_shared_dpll(struct intel_crtc *crtc,
>>> -		       struct intel_crtc_state *crtc_state)
>>> +		       struct intel_crtc_state *crtc_state,
>>> +		       enum intel_dpll_id range_min,
>>> +		       enum intel_dpll_id range_max)
>>>  {
>>>  	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
>>>  	struct intel_shared_dpll *pll;
>>>  	struct intel_shared_dpll_config *shared_dpll;
>>>  	enum intel_dpll_id i;
>>> -	int max = dev_priv->num_shared_dpll;
>>> -
>>> -	if (INTEL_INFO(dev_priv)->gen < 9 && HAS_DDI(dev_priv))
>>> -		/* Do not consider SPLL */
>>> -		max = 2;
>>>  
>>>  	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state
>>> ->base.state);
>>>  
>>> -	for (i = 0; i < max; i++) {
>>> +	for (i = range_min; i <= range_max; i++) {
>>>  		pll = &dev_priv->shared_dplls[i];
>>>  
>>>  		/* Only want to check enabled timings first */
>>> @@ -247,49 +201,33 @@ intel_find_shared_dpll(struct intel_crtc *crtc,
>>>  				      crtc->base.base.id, pll->name,
>>>  				      shared_dpll[i].crtc_mask,
>>>  				      pll->active);
>>> -			return i;
>>> +			return pll;
>>>  		}
>>>  	}
>>>  
>>>  	/* Ok no matching timings, maybe there's a free one? */
>>> -	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
>>> +	for (i = range_min; i <= range_max; i++) {
>>>  		pll = &dev_priv->shared_dplls[i];
>>>  		if (shared_dpll[i].crtc_mask == 0) {
>>>  			DRM_DEBUG_KMS("CRTC:%d allocated %s\n",
>>>  				      crtc->base.base.id, pll->name);
>>> -			return i;
>>> +			return pll;
>>>  		}
>>>  	}
>>>  
>>> -	return DPLL_ID_PRIVATE;
>>> +	return NULL;
>>>  }
>>>  
>>> -struct intel_shared_dpll *
>>> -intel_get_shared_dpll(struct intel_crtc *crtc,
>>> -		      struct intel_crtc_state *crtc_state)
>>> +static void
>>> +intel_reference_shared_dpll(struct intel_shared_dpll *pll,
>>> +			    struct intel_crtc_state *crtc_state)
>>>  {
>>> -	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
>>> -	struct intel_shared_dpll *pll;
>>>  	struct intel_shared_dpll_config *shared_dpll;
>>> -	enum intel_dpll_id i;
>>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>>> +	enum intel_dpll_id i = pll->id;
>>>  
>>>  	shared_dpll = intel_atomic_get_shared_dpll_state(crtc_state
>>> ->base.state);
>>>  
>>> -	if (HAS_PCH_IBX(dev_priv->dev)) {
>>> -		i = ibx_get_fixed_dpll(crtc, crtc_state);
>>> -		WARN_ON(shared_dpll[i].crtc_mask);
>>> -	} else if (IS_BROXTON(dev_priv->dev)) {
>>> -		i = bxt_get_fixed_dpll(crtc, crtc_state);
>>> -		WARN_ON(shared_dpll[i].crtc_mask);
>>> -	} else {
>>> -		i = intel_find_shared_dpll(crtc, crtc_state);
>>> -	}
>>> -
>>> -	if (i < 0)
>>> -		return NULL;
>>> -
>>> -	pll = &dev_priv->shared_dplls[i];
>>> -
>>>  	if (shared_dpll[i].crtc_mask == 0)
>>>  		shared_dpll[i].hw_state =
>>>  			crtc_state->dpll_hw_state;
>>> @@ -299,8 +237,6 @@ intel_get_shared_dpll(struct intel_crtc *crtc,
>>>  			 pipe_name(crtc->pipe));
>>>  
>>>  	intel_shared_dpll_config_get(shared_dpll, pll, crtc);
>>> -
>>> -	return pll;
>>>  }
>>>  
>>>  void intel_shared_dpll_commit(struct drm_atomic_state *state)
>>> @@ -398,6 +334,32 @@ static void ibx_pch_dpll_disable(struct
>>> drm_i915_private *dev_priv,
>>>  	udelay(200);
>>>  }
>>>  
>>> +static struct intel_shared_dpll *
>>> +ibx_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
>>> +{
>>> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>> +	struct intel_shared_dpll *pll;
>>> +	enum intel_dpll_id i;
>>> +
>>> +	if (HAS_PCH_IBX(dev_priv)) {
>>> +		/* Ironlake PCH has a fixed PLL->PCH pipe mapping. */
>>> +		i = (enum intel_dpll_id) crtc->pipe;
>>> +		pll = &dev_priv->shared_dplls[i];
>>> +
>>> +		DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
>>> +			      crtc->base.base.id, pll->name);
>>> +	} else {
>>> +		pll = intel_find_shared_dpll(crtc, crtc_state,
>>> +					     DPLL_ID_PCH_PLL_A,
>>> +					     DPLL_ID_PCH_PLL_B);
>>> +	}
>>> +
>>> +	/* reference the pll */
>>> +	intel_reference_shared_dpll(pll, crtc_state);
>>> +
>>> +	return pll;
>>> +}
>>> +
>>>  static const struct intel_shared_dpll_funcs ibx_pch_dpll_funcs = {
>>>  	.mode_set = ibx_pch_dpll_mode_set,
>>>  	.enable = ibx_pch_dpll_enable,
>>> @@ -475,6 +437,19 @@ static bool hsw_ddi_spll_get_hw_state(struct
>>> drm_i915_private *dev_priv,
>>>  	return val & SPLL_PLL_ENABLE;
>>>  }
>>>  
>>> +static struct intel_shared_dpll *
>>> +hsw_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
>>> +{
>>> +	struct intel_shared_dpll *pll;
>>> +
>>> +	pll = intel_find_shared_dpll(crtc, crtc_state,
>>> +				     DPLL_ID_WRPLL1, DPLL_ID_WRPLL2);
>>> +	if (pll)
>>> +		intel_reference_shared_dpll(pll, crtc_state);
>>> +
>>> +	return pll;
>>> +}
>>> +
>>>  
>>>  static const struct intel_shared_dpll_funcs hsw_ddi_wrpll_funcs = {
>>>  	.enable = hsw_ddi_wrpll_enable,
>>> @@ -594,6 +569,19 @@ out:
>>>  	return ret;
>>>  }
>>>  
>>> +static struct intel_shared_dpll *
>>> +skl_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
>>> +{
>>> +	struct intel_shared_dpll *pll;
>>> +
>>> +	pll = intel_find_shared_dpll(crtc, crtc_state,
>>> +				     DPLL_ID_SKL_DPLL1, DPLL_ID_SKL_DPLL3);
>>> +	if (pll)
>>> +		intel_reference_shared_dpll(pll, crtc_state);
>>> +
>>> +	return pll;
>>> +}
>>> +
>>>  static const struct intel_shared_dpll_funcs skl_ddi_pll_funcs = {
>>>  	.enable = skl_ddi_pll_enable,
>>>  	.disable = skl_ddi_pll_disable,
>>> @@ -782,6 +770,32 @@ out:
>>>  	return ret;
>>>  }
>>>  
>>> +static struct intel_shared_dpll *
>>> +bxt_get_dpll(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state)
>>> +{
>>> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>> +	struct intel_encoder *encoder;
>>> +	struct intel_digital_port *intel_dig_port;
>>> +	struct intel_shared_dpll *pll;
>>> +	enum intel_dpll_id i;
>>> +
>>> +	/* PLL is attached to port in bxt */
>>> +	encoder = intel_ddi_get_crtc_new_encoder(crtc_state);
>>> +	if (WARN_ON(!encoder))
>>> +		return NULL;
>>> +
>>> +	intel_dig_port = enc_to_dig_port(&encoder->base);
>>> +	/* 1:1 mapping between ports and PLLs */
>>> +	i = (enum intel_dpll_id)intel_dig_port->port;
>>> +	pll = &dev_priv->shared_dplls[i];
>>> +	DRM_DEBUG_KMS("CRTC:%d using pre-allocated %s\n",
>>> +		crtc->base.base.id, pll->name);
>>> +
>>> +	intel_reference_shared_dpll(pll, crtc_state);
>>> +
>>> +	return pll;
>>> +}
>>> +
>>>  static const struct intel_shared_dpll_funcs bxt_ddi_pll_funcs = {
>>>  	.enable = bxt_ddi_pll_enable,
>>>  	.disable = bxt_ddi_pll_disable,
>>> @@ -826,12 +840,24 @@ struct dpll_info {
>>>  	const struct intel_shared_dpll_funcs *funcs;
>>>  };
>>>  
>>> +struct intel_dpll_mgr {
>>> +	const struct dpll_info *dpll_info;
>>> +
>>> +	struct intel_shared_dpll *(*get_dpll)(struct intel_crtc *crtc,
>>> +					      struct intel_crtc_state
>>> *crtc_state);
>>> +};
>>> +
>>>  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 },
>>>  };
>>>  
>>> +static const struct intel_dpll_mgr pch_pll_mgr = {
>>> +	.dpll_info = pch_plls,
>>> +	.get_dpll = ibx_get_dpll,
>>> +};
>>> +
>>>  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 },
>>> @@ -839,6 +865,11 @@ static const struct dpll_info hsw_plls[] = {
>>>  	{ NULL, -1, NULL, },
>>>  };
>>>  
>>> +static const struct intel_dpll_mgr hsw_pll_mgr = {
>>> +	.dpll_info = hsw_plls,
>>> +	.get_dpll = hsw_get_dpll,
>>> +};
>>> +
>>>  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 },
>>> @@ -846,6 +877,11 @@ static const struct dpll_info skl_plls[] = {
>>>  	{ NULL, -1, NULL, },
>>>  };
>>>  
>>> +static const struct intel_dpll_mgr skl_pll_mgr = {
>>> +	.dpll_info = skl_plls,
>>> +	.get_dpll = skl_get_dpll,
>>> +};
>>> +
>>>  static const struct dpll_info bxt_plls[] = {
>>>  	{ "PORT PLL A", 0, &bxt_ddi_pll_funcs },
>>>  	{ "PORT PLL B", 1, &bxt_ddi_pll_funcs },
>>> @@ -853,26 +889,34 @@ static const struct dpll_info bxt_plls[] = {
>>>  	{ NULL, -1, NULL, },
>>>  };
>>>  
>>> +static const struct intel_dpll_mgr bxt_pll_mgr = {
>>> +	.dpll_info = bxt_plls,
>>> +	.get_dpll = bxt_get_dpll,
>>> +};
>>> +
>>>  void intel_shared_dpll_init(struct drm_device *dev)
>>>  {
>>>  	struct drm_i915_private *dev_priv = dev->dev_private;
>>> -	const struct dpll_info *dpll_info = NULL;
>>> +	const struct intel_dpll_mgr *dpll_mgr = NULL;
>>> +	const struct dpll_info *dpll_info;
>>>  	int i;
>>>  
>>>  	if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
>>> -		dpll_info = skl_plls;
>>> +		dpll_mgr = &skl_pll_mgr;
>>>  	else if IS_BROXTON(dev)
>>> -		dpll_info = bxt_plls;
>>> +		dpll_mgr = &bxt_pll_mgr;
>>>  	else if (HAS_DDI(dev))
>>> -		dpll_info = hsw_plls;
>>> +		dpll_mgr = &hsw_pll_mgr;
>>>  	else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
>>> -		dpll_info = pch_plls;
>>> +		dpll_mgr = &pch_pll_mgr;
>>>  
>>> -	if (!dpll_info) {
>>> +	if (!dpll_mgr) {
>>>  		dev_priv->num_shared_dpll = 0;
>>>  		return;
>>>  	}
>>>  
>>> +	dpll_info = dpll_mgr->dpll_info;
>>> +
>>>  	for (i = 0; dpll_info[i].id >= 0; i++) {
>>>  		WARN_ON(i != dpll_info[i].id);
>>>  
>>> @@ -881,6 +925,7 @@ void intel_shared_dpll_init(struct drm_device *dev)
>>>  		dev_priv->shared_dplls[i].funcs = *dpll_info[i].funcs;
>>>  	}
>>>  
>>> +	dev_priv->dpll_mgr = dpll_mgr;
>>>  	dev_priv->num_shared_dpll = i;
>>>  
>>>  	BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS);
>>> @@ -889,3 +934,16 @@ void intel_shared_dpll_init(struct drm_device *dev)
>>>  	if (HAS_DDI(dev))
>>>  		intel_ddi_pll_init(dev);
>>>  }
>>> +
>>> +struct intel_shared_dpll *
>>> +intel_get_shared_dpll(struct intel_crtc *crtc,
>>> +		      struct intel_crtc_state *crtc_state)
>>> +{
>>> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>> +	const struct intel_dpll_mgr *dpll_mgr = dev_priv->dpll_mgr;
>>> +
>>> +	if (dpll_mgr)
>>> +		return dpll_mgr->get_dpll(crtc, crtc_state);
>>> +	else
>>> +		return NULL;
>>> +}
>> should there be a WARN_ON here?
>>
>> Rest looks good, so for patch 8...11/13:
> Did you have comments on patch 12? I seem to have missed it.
>
No, I didn't get around to looking yet.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface
  2016-02-26 13:54 ` [PATCH 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface Ander Conselvan de Oliveira
  2016-02-29  9:08   ` [PATCH v2 " Ander Conselvan de Oliveira
@ 2016-03-08 11:05   ` Maarten Lankhorst
  2016-03-08 11:11     ` Conselvan De Oliveira, Ander
  1 sibling, 1 reply; 31+ messages in thread
From: Maarten Lankhorst @ 2016-03-08 11:05 UTC (permalink / raw)
  To: Ander Conselvan de Oliveira, intel-gfx

Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
> Manage the LCPLLs used with DisplayPort, so that all the HSW/BDW DPLLs
> are managed by the shared dpll code.
>
> Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c      | 18 ++++----
>  drivers/gpu/drm/i915/intel_display.c  | 35 ++++++++++++----
>  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 | 79 +++++++++++++++++++++++++++++++----
>  drivers/gpu/drm/i915/intel_dpll_mgr.h |  5 ++-
>  drivers/gpu/drm/i915/intel_drv.h      |  1 -
>  7 files changed, 110 insertions(+), 55 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;
>  }
Eventually the reliance on intel_encoder->type should end here, and based on the connector.
It would fix some kms tests, but that would be better to do in a future patch.
> ...
>
> +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)
> +{
> +	/*
> +	 * LC PLL is kept enabled all the time since it drives CDCLK. The
> +	 * state checker still expects it to be disabled when it is not used
> +	 * by any crtc. To avoid adding a case to LC PLL, just tell the
> +	 * state checker what it expects.
> +	 */
> +	if (pll->config.crtc_mask)
> +		return true;
> +	else
> +		return false;
> +}
Wouldn't it be better to return true or the real hardware state then, and set the ALWAYS_ON flag from the next patch?
> +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;
>  };
> @@ -1559,9 +1617,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 },
> +	{ "WRPLL 2",    DPLL_ID_WRPLL2,     &hsw_ddi_wrpll_funcs },
> +	{ "SPLL",       DPLL_ID_SPLL,       &hsw_ddi_spll_funcs },
> +	{ "LCPLL 810",  DPLL_ID_LCPLL_810,  &hsw_ddi_lcpll_funcs },
> +	{ "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs },
> +	{ "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs },
>  	{ 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..872878e 100644
> --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
> +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
> @@ -49,13 +49,16 @@ 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
>  
>  struct intel_dpll_hw_state {
>  	/* i9xx, pch plls */
> 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,

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface
  2016-03-08 11:05   ` [PATCH " Maarten Lankhorst
@ 2016-03-08 11:11     ` Conselvan De Oliveira, Ander
  2016-03-08 11:16       ` Ander Conselvan De Oliveira
  0 siblings, 1 reply; 31+ messages in thread
From: Conselvan De Oliveira, Ander @ 2016-03-08 11:11 UTC (permalink / raw)
  To: intel-gfx, maarten.lankhorst

On Tue, 2016-03-08 at 12:05 +0100, Maarten Lankhorst wrote:
> Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
> > Manage the LCPLLs used with DisplayPort, so that all the HSW/BDW DPLLs
> > are managed by the shared dpll code.
> > 
> > Signed-off-by: Ander Conselvan de Oliveira <
> > ander.conselvan.de.oliveira@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c      | 18 ++++----
> >  drivers/gpu/drm/i915/intel_display.c  | 35 ++++++++++++----
> >  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 | 79 +++++++++++++++++++++++++++++++-
> > ---
> >  drivers/gpu/drm/i915/intel_dpll_mgr.h |  5 ++-
> >  drivers/gpu/drm/i915/intel_drv.h      |  1 -
> >  7 files changed, 110 insertions(+), 55 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;
> >  }
> Eventually the reliance on intel_encoder->type should end here, and based on
> the connector.

Do you mean that the parameter to get_shared_dpll() should be connector instead
of encoder?

> It would fix some kms tests, but that would be better to do in a future patch.
> > ...
> > 
> > +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)
> > +{
> > +	/*
> > +	 * LC PLL is kept enabled all the time since it drives CDCLK. The
> > +	 * state checker still expects it to be disabled when it is not
> > used
> > +	 * by any crtc. To avoid adding a case to LC PLL, just tell the
> > +	 * state checker what it expects.
> > +	 */
> > +	if (pll->config.crtc_mask)
> > +		return true;
> > +	else
> > +		return false;
> > +}
> Wouldn't it be better to return true or the real hardware state then, and set
> the ALWAYS_ON flag from the next patch?

That's exactly what v2 of this patch does. :)

Ander

> > +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;
> >  };
> > @@ -1559,9 +1617,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 },
> > +	{ "WRPLL 2",    DPLL_ID_WRPLL2,     &hsw_ddi_wrpll_funcs },
> > +	{ "SPLL",       DPLL_ID_SPLL,       &hsw_ddi_spll_funcs },
> > +	{ "LCPLL 810",  DPLL_ID_LCPLL_810,  &hsw_ddi_lcpll_funcs },
> > +	{ "LCPLL 1350", DPLL_ID_LCPLL_1350, &hsw_ddi_lcpll_funcs },
> > +	{ "LCPLL 2700", DPLL_ID_LCPLL_2700, &hsw_ddi_lcpll_funcs },
> >  	{ 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..872878e 100644
> > --- a/drivers/gpu/drm/i915/intel_dpll_mgr.h
> > +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.h
> > @@ -49,13 +49,16 @@ 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
> >  
> >  struct intel_dpll_hw_state {
> >  	/* i9xx, pch plls */
> > 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,
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface
  2016-03-08 11:11     ` Conselvan De Oliveira, Ander
@ 2016-03-08 11:16       ` Ander Conselvan De Oliveira
  0 siblings, 0 replies; 31+ messages in thread
From: Ander Conselvan De Oliveira @ 2016-03-08 11:16 UTC (permalink / raw)
  To: intel-gfx, maarten.lankhorst

On Tue, 2016-03-08 at 11:11 +0000, Conselvan De Oliveira, Ander wrote:
> On Tue, 2016-03-08 at 12:05 +0100, Maarten Lankhorst wrote:
> > Op 26-02-16 om 14:54 schreef Ander Conselvan de Oliveira:
> > > Manage the LCPLLs used with DisplayPort, so that all the HSW/BDW DPLLs
> > > are managed by the shared dpll code.
> > > 
> > > Signed-off-by: Ander Conselvan de Oliveira <
> > > ander.conselvan.de.oliveira@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_ddi.c      | 18 ++++----
> > >  drivers/gpu/drm/i915/intel_display.c  | 35 ++++++++++++----
> > >  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 | 79
> > > +++++++++++++++++++++++++++++++-
> > > ---
> > >  drivers/gpu/drm/i915/intel_dpll_mgr.h |  5 ++-
> > >  drivers/gpu/drm/i915/intel_drv.h      |  1 -
> > >  7 files changed, 110 insertions(+), 55 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;
> > >  }
> > Eventually the reliance on intel_encoder->type should end here, and based on
> > the connector.
> 
> Do you mean that the parameter to get_shared_dpll() should be connector
> instead
> of encoder?
> 
> > It would fix some kms tests, but that would be better to do in a future
> > patch.
> > > ...
> > > 
> > > +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)
> > > +{
> > > +	/*
> > > +	 * LC PLL is kept enabled all the time since it drives CDCLK. The
> > > +	 * state checker still expects it to be disabled when it is not
> > > used
> > > +	 * by any crtc. To avoid adding a case to LC PLL, just tell the
> > > +	 * state checker what it expects.
> > > +	 */
> > > +	if (pll->config.crtc_mask)
> > > +		return true;
> > > +	else
> > > +		return false;
> > > +}
> > Wouldn't it be better to return true or the real hardware state then, and
> > set
> > the ALWAYS_ON flag from the next patch?
> 
> That's exactly what v2 of this patch does. :)

Well, actually, I think I fumbled git add or something, so I need to send a v3
of that patch. I also have a v3 of the SKL DPLL0 one, now that I managed to test
it. So I'll resend the series later today.

Ander

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2016-03-08 11:16 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-26 13:54 [PATCH 00/13] Shared pll improvements Ander Conselvan de Oliveira
2016-02-26 13:54 ` [PATCH 01/13] drm/i915: Move shared dpll code to a new file Ander Conselvan de Oliveira
2016-02-26 13:54 ` [PATCH 02/13] drm/i915: Move ddi shared dpll code to intel_dpll_mgr.c Ander Conselvan de Oliveira
2016-02-26 13:54 ` [PATCH 03/13] drm/i915: Split intel_get_shared_dpll() into smaller functions Ander Conselvan de Oliveira
2016-02-26 13:54 ` [PATCH 04/13] drm/i915: Store a direct pointer to shared dpll in intel_crtc_state Ander Conselvan de Oliveira
2016-02-26 13:54 ` [PATCH 05/13] drm/i915: Move shared dpll struct definitions to separate header file Ander Conselvan de Oliveira
2016-02-26 13:54 ` [PATCH 06/13] drm/i915: Move shared dpll function prototypes to intel_dpll_mgr.h Ander Conselvan de Oliveira
2016-03-02 14:56   ` Maarten Lankhorst
2016-02-26 13:54 ` [PATCH 07/13] drm/i915: Use a table to initilize shared dplls Ander Conselvan de Oliveira
2016-03-02 15:30   ` Maarten Lankhorst
2016-03-03 11:32     ` Ander Conselvan De Oliveira
2016-03-03 13:35       ` Maarten Lankhorst
2016-02-26 13:54 ` [PATCH 08/13] drm/i915: Refactor platform specifics out of intel_get_shared_dpll() Ander Conselvan de Oliveira
2016-03-03 14:08   ` Maarten Lankhorst
2016-03-04  6:36     ` Ander Conselvan De Oliveira
2016-03-04  6:49     ` Ander Conselvan De Oliveira
2016-03-07  9:59       ` Maarten Lankhorst
2016-02-26 13:54 ` [PATCH 09/13] drm/i915: Move HSW/BDW pll selection logic to intel_dpll_mgr.c Ander Conselvan de Oliveira
2016-02-26 13:54 ` [PATCH 10/13] drm/i915: Move SKL/KLB " Ander Conselvan de Oliveira
2016-02-26 13:54 ` [PATCH 11/13] drm/i915: Move BXT pll configuration " Ander Conselvan de Oliveira
2016-02-26 13:54 ` [PATCH 12/13] drm/i915: Manage HSW/BDW LCPLLs with the shared dpll interface Ander Conselvan de Oliveira
2016-02-29  9:08   ` [PATCH v2 " Ander Conselvan de Oliveira
2016-03-08 11:05   ` [PATCH " Maarten Lankhorst
2016-03-08 11:11     ` Conselvan De Oliveira, Ander
2016-03-08 11:16       ` Ander Conselvan De Oliveira
2016-02-26 13:54 ` [PATCH 13/13] drm/i915: Make SKL/KBL DPLL0 managed by the shared dpll code Ander Conselvan de Oliveira
2016-02-29  9:08   ` [PATCH v3 " Ander Conselvan de Oliveira
2016-03-03 13:33     ` Maarten Lankhorst
2016-03-03 13:40       ` Ander Conselvan De Oliveira
2016-03-03 13:51         ` Maarten Lankhorst
2016-02-26 14:27 ` ✗ Fi.CI.BAT: failure for Shared pll improvements Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.