All of lore.kernel.org
 help / color / mirror / Atom feed
From: ville.syrjala@linux.intel.com
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 08/14] drm/i915: Compute DSI PLL parameters during .compute_config()
Date: Thu,  3 Sep 2015 21:50:10 +0300	[thread overview]
Message-ID: <1441306216-6581-9-git-send-email-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <1441306216-6581-1-git-send-email-ville.syrjala@linux.intel.com>

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Compute the DSI PLL parameters during .compute_config() rather than
.pre_pll_enable() so that we can fail gracefully if we can't find
suitable parameters.

In order to do that we need to store the DSI PLL parameters in
pipe_config.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |  3 ++
 drivers/gpu/drm/i915/intel_drv.h     |  5 ++++
 drivers/gpu/drm/i915/intel_dsi.c     | 16 +++++++----
 drivers/gpu/drm/i915/intel_dsi.h     |  8 ++++--
 drivers/gpu/drm/i915/intel_dsi_pll.c | 56 +++++++++++++++++++++---------------
 5 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1ec39b0..9a77ca5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12488,6 +12488,9 @@ intel_pipe_config_compare(struct drm_device *dev,
 	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
 	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
 
+	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
+	PIPE_CONF_CHECK_X(dsi_pll.div);
+
 	if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
 		PIPE_CONF_CHECK_I(pipe_bpp);
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index cf971ef..8bb74eb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -407,6 +407,11 @@ struct intel_crtc_state {
 	/* Actual register state of the dpll, for shared dpll cross-checking. */
 	struct intel_dpll_hw_state dpll_hw_state;
 
+	/* DSI PLL registers */
+	struct {
+		u32 ctrl, div;
+	} dsi_pll;
+
 	int pipe_bpp;
 	struct intel_link_m_n dp_m_n;
 
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index e0ccaf1..4cf6c0d 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -270,6 +270,7 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder,
 	struct intel_connector *intel_connector = intel_dsi->attached_connector;
 	struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
 	struct drm_display_mode *adjusted_mode = &config->base.adjusted_mode;
+	int ret;
 
 	DRM_DEBUG_KMS("\n");
 
@@ -279,10 +280,10 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder,
 	/* DSI uses short packets for sync events, so clear mode flags for DSI */
 	adjusted_mode->flags = 0;
 
-	/*
-	 * FIXME move the DSI PLL calc from vlv_enable_dsi_pll()
-	 * to .compute_config().
-	 */
+	ret = vlv_compute_dsi_pll(encoder, config);
+	if (ret)
+		return false;
+
 	config->clock_set = true;
 
 	return true;
@@ -629,7 +630,8 @@ static void intel_dsi_get_config(struct intel_encoder *encoder,
 	u32 pclk;
 	DRM_DEBUG_KMS("\n");
 
-	pclk = vlv_get_dsi_pclk(encoder, pipe_config->pipe_bpp);
+	pclk = vlv_get_dsi_pclk(encoder, pipe_config->pipe_bpp,
+				pipe_config);
 	if (!pclk)
 		return;
 
@@ -900,6 +902,8 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder)
 
 static void intel_dsi_pre_pll_enable(struct intel_encoder *encoder)
 {
+	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
+
 	DRM_DEBUG_KMS("\n");
 
 	intel_dsi_prepare(encoder);
@@ -909,7 +913,7 @@ static void intel_dsi_pre_pll_enable(struct intel_encoder *encoder)
 	 * lock. It needs to be fully powered down to fix it.
 	 */
 	vlv_disable_dsi_pll(encoder);
-	vlv_enable_dsi_pll(encoder);
+	vlv_enable_dsi_pll(encoder, intel_crtc->config);
 }
 
 static enum drm_connector_status
diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h
index 42a6859..58c39b4 100644
--- a/drivers/gpu/drm/i915/intel_dsi.h
+++ b/drivers/gpu/drm/i915/intel_dsi.h
@@ -124,9 +124,13 @@ static inline struct intel_dsi *enc_to_intel_dsi(struct drm_encoder *encoder)
 	return container_of(encoder, struct intel_dsi, base.base);
 }
 
-extern void vlv_enable_dsi_pll(struct intel_encoder *encoder);
+extern int vlv_compute_dsi_pll(struct intel_encoder *encoder,
+			       struct intel_crtc_state *config);
+extern void vlv_enable_dsi_pll(struct intel_encoder *encoder,
+			       const struct intel_crtc_state *config);
 extern void vlv_disable_dsi_pll(struct intel_encoder *encoder);
-extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp);
+extern u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp,
+			    struct intel_crtc_state *config);
 
 struct drm_panel *vbt_panel_init(struct intel_dsi *intel_dsi, u16 panel_id);
 
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
index c6a8975..79c18a0 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -59,10 +59,6 @@ static int dsi_pixel_format_bpp(int pixel_format)
 	return bpp;
 }
 
-struct dsi_mnp {
-	u32 dsi_pll_ctrl;
-	u32 dsi_pll_div;
-};
 
 static const u32 lfsr_converts[] = {
 	426, 469, 234, 373, 442, 221, 110, 311, 411,		/* 62 - 70 */
@@ -158,7 +154,8 @@ static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count)
 #endif
 
 static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
-			struct dsi_mnp *dsi_mnp, int target_dsi_clk)
+			struct intel_crtc_state *config,
+			int target_dsi_clk)
 {
 	unsigned int calc_m = 0, calc_p = 0;
 	unsigned int m_min, m_max, p_min = 2, p_max = 6;
@@ -204,8 +201,8 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
 	/* register has log2(N1), this works fine for powers of two */
 	n = ffs(n) - 1;
 	m_seed = lfsr_converts[calc_m - 62];
-	dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
-	dsi_mnp->dsi_pll_div = n << DSI_PLL_N1_DIV_SHIFT |
+	config->dsi_pll.ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
+	config->dsi_pll.div = n << DSI_PLL_N1_DIV_SHIFT |
 		m_seed << DSI_PLL_M1_DIV_SHIFT;
 
 	return 0;
@@ -215,54 +212,63 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
  * XXX: The muxing and gating is hard coded for now. Need to add support for
  * sharing PLLs with two DSI outputs.
  */
-static void vlv_configure_dsi_pll(struct intel_encoder *encoder)
+int vlv_compute_dsi_pll(struct intel_encoder *encoder,
+			struct intel_crtc_state *config)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 	int ret;
-	struct dsi_mnp dsi_mnp;
 	u32 dsi_clk;
 
 	dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
 				    intel_dsi->lane_count);
 
-	ret = dsi_calc_mnp(dev_priv, &dsi_mnp, dsi_clk);
+	ret = dsi_calc_mnp(dev_priv, config, dsi_clk);
 	if (ret) {
 		DRM_DEBUG_KMS("dsi_calc_mnp failed\n");
-		return;
+		return ret;
 	}
 
 	if (intel_dsi->ports & (1 << PORT_A))
-		dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
+		config->dsi_pll.ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
 
 	if (intel_dsi->ports & (1 << PORT_C))
-		dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL;
+		config->dsi_pll.ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL;
+
+	config->dsi_pll.ctrl |= DSI_PLL_VCO_EN;
 
 	DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n",
-		      dsi_mnp.dsi_pll_div, dsi_mnp.dsi_pll_ctrl);
+		      config->dsi_pll.div, config->dsi_pll.ctrl);
+
+	return 0;
+}
+
+static void vlv_configure_dsi_pll(struct intel_encoder *encoder,
+				  const struct intel_crtc_state *config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 
 	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
-	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, dsi_mnp.dsi_pll_div);
-	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_mnp.dsi_pll_ctrl);
+	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, config->dsi_pll.div);
+	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL,
+		      config->dsi_pll.ctrl & ~DSI_PLL_VCO_EN);
 }
 
-void vlv_enable_dsi_pll(struct intel_encoder *encoder)
+void vlv_enable_dsi_pll(struct intel_encoder *encoder,
+			const struct intel_crtc_state *config)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
-	u32 tmp;
 
 	DRM_DEBUG_KMS("\n");
 
 	mutex_lock(&dev_priv->sb_lock);
 
-	vlv_configure_dsi_pll(encoder);
+	vlv_configure_dsi_pll(encoder, config);
 
 	/* wait at least 0.5 us after ungating before enabling VCO */
 	usleep_range(1, 10);
 
-	tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
-	tmp |= DSI_PLL_VCO_EN;
-	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
+	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, config->dsi_pll.ctrl);
 
 	if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) &
 						DSI_PLL_LOCK, 20)) {
@@ -302,7 +308,8 @@ static void assert_bpp_mismatch(int pixel_format, int pipe_bpp)
 	     bpp, pipe_bpp);
 }
 
-u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
+u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp,
+		     struct intel_crtc_state *config)
 {
 	struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
@@ -319,6 +326,9 @@ u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
 	pll_div = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_DIVIDER);
 	mutex_unlock(&dev_priv->sb_lock);
 
+	config->dsi_pll.ctrl = pll_ctl & ~DSI_PLL_LOCK;
+	config->dsi_pll.div = pll_div;
+
 	/* mask out other bits and extract the P1 divisor */
 	pll_ctl &= DSI_PLL_P1_POST_DIV_MASK;
 	pll_ctl = pll_ctl >> (DSI_PLL_P1_POST_DIV_SHIFT - 2);
-- 
2.4.6

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

  parent reply	other threads:[~2015-09-03 18:51 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-03 18:50 [PATCH 00/14] drm/i915: VLV/CHV DPLL and DSI stuff ville.syrjala
2015-09-03 18:50 ` [PATCH v2 01/14] drm/i915: Make {vlv, chv}_{disable, update}_pll() more similar ville.syrjala
2015-09-03 18:50 ` [PATCH 02/14] drm/i915: Implement WaPixelRepeatModeFixForC0:chv ville.syrjala
2015-09-03 18:50 ` [PATCH 03/14] drm/i915: Power down the DSI PLL before reconfiguring it ville.syrjala
2015-09-03 18:50 ` [PATCH 04/14] drm/i915: Add a local pipe variable to vlv_enable_pll() ville.syrjala
2015-09-03 18:50 ` [PATCH 05/14] drm/i915: assert_panel_unlocked() in chv_enable_pll() ville.syrjala
2015-09-03 18:50 ` [PATCH 06/14] drm/i915: Remove the "three times for luck" trick from vlv_enable_pll() ville.syrjala
2015-09-03 18:50 ` [PATCH 07/14] drm/i915: Setup DPLL/DPLLMD for DSI too on VLV/CHV ville.syrjala
2015-09-03 18:50 ` ville.syrjala [this message]
2015-09-03 18:50 ` [PATCH 09/14] drm/i915: Fix CHV DSI PLL refclk during state readout ville.syrjala
2015-09-03 18:50 ` [PATCH 10/14] drm/i915: Change lfsr_converts[] to u16 ville.syrjala
2015-09-03 18:50 ` [PATCH 11/14] drm/i915: Throw out BUGs from DPLL/PCH functions ville.syrjala
2015-09-03 18:50 ` [PATCH 12/14] drm/i915: Hook up pfit for DSI ville.syrjala
2015-09-03 18:50 ` [PATCH 13/14] drm/i915: Reject 'Center' scaling mode for eDP/DSI on GMCH platforms ville.syrjala
2015-09-03 18:50 ` [PATCH 14/14] drm/i915: Dump pfit state as hex ville.syrjala
2015-09-04  8:34   ` Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1441306216-6581-9-git-send-email-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.