All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paulo Zanoni <przanoni@gmail.com>
To: intel-gfx@lists.freedesktop.org
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Subject: [RFC 02/30] drm/i915: disable DDI pipes and ports when initializing
Date: Tue, 28 Aug 2012 19:06:33 -0300	[thread overview]
Message-ID: <1346191621-12996-3-git-send-email-przanoni@gmail.com> (raw)
In-Reply-To: <1346191621-12996-1-git-send-email-przanoni@gmail.com>

From: Paulo Zanoni <paulo.r.zanoni@intel.com>

This is required to prevent hanging the machine on Haswell. We need to
disable everything so when we start using we only enable/disable
exactly what we are using.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      |  2 +
 drivers/gpu/drm/i915/intel_ddi.c     | 74 ++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_display.c |  7 ++--
 drivers/gpu/drm/i915/intel_drv.h     |  4 ++
 drivers/gpu/drm/i915/intel_sprite.c  |  6 +--
 5 files changed, 86 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2eed9d4..ee70588 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4375,6 +4375,7 @@
 #define  PIPE_DDI_FUNC_ENABLE		(1<<31)
 /* Those bits are ignored by pipe EDP since it can only connect to DDI A */
 #define  PIPE_DDI_PORT_MASK		(7<<28)
+#define  PIPE_DDI_PORT_NONE		(0<<28)
 #define  PIPE_DDI_SELECT_PORT(x)	((x)<<28)
 #define  PIPE_DDI_MODE_SELECT_MASK	(7<<24)
 #define  PIPE_DDI_MODE_SELECT_HDMI	(0<<24)
@@ -4503,6 +4504,7 @@
 #define  PORT_CLK_SEL_SPLL		(3<<29)
 #define  PORT_CLK_SEL_WRPLL1		(4<<29)
 #define  PORT_CLK_SEL_WRPLL2		(5<<29)
+#define  PORT_CLK_SEL_NONE		(7<<29)
 
 /* Pipe clock selection */
 #define PIPE_CLK_SEL_A			0x46140
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 18ebf15..b8b7670 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -751,6 +751,20 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
 	intel_hdmi->set_infoframes(encoder, adjusted_mode);
 }
 
+static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
+				    enum port port)
+{
+	uint32_t reg = DDI_BUF_CTL(port);
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		udelay(1);
+		if (I915_READ(reg) & DDI_BUF_IS_IDLE)
+			return;
+	}
+	DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
+}
+
 void intel_ddi_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
@@ -775,11 +789,71 @@ void intel_ddi_dpms(struct drm_encoder *encoder, int mode)
 			temp);
 }
 
+static void intel_ddi_disable_pipe(struct drm_i915_private *dev_priv,
+				   enum pipe pipe)
+{
+	uint32_t temp;
+
+	temp = I915_READ(DDI_FUNC_CTL(pipe));
+	temp &= ~(PIPE_DDI_FUNC_ENABLE | PIPE_DDI_PORT_MASK);
+	temp |= PIPE_DDI_PORT_NONE;
+	I915_WRITE(DDI_FUNC_CTL(pipe), temp);
+
+	I915_WRITE(PIPE_CLK_SEL(pipe), PIPE_CLK_SEL_DISABLED);
+}
+
+static void intel_ddi_disable_port(struct drm_i915_private *dev_priv,
+				   enum port port)
+{
+	uint32_t reg, val;
+
+	reg = DDI_BUF_CTL(port);
+	val = I915_READ(reg);
+	if (val & DDI_BUF_CTL_ENABLE) {
+		val &= ~DDI_BUF_CTL_ENABLE;
+		I915_WRITE(reg, val);
+		intel_wait_ddi_buf_idle(dev_priv, port);
+	}
+
+	switch (I915_READ(PORT_CLK_SEL(port))) {
+	case PORT_CLK_SEL_WRPLL1:
+		reg = WRPLL_CTL1;
+		val = I915_READ(reg) & ~WRPLL_PLL_ENABLE;
+		break;
+	case PORT_CLK_SEL_WRPLL2:
+		reg = WRPLL_CTL2;
+		val = I915_READ(reg) & ~WRPLL_PLL_ENABLE;
+		break;
+	case PORT_CLK_SEL_SPLL:
+		reg = SPLL_CTL;
+		val = I915_READ(reg) & ~SPLL_PLL_ENABLE;
+		break;
+	default: /* LCPLL or none or reserved */
+		reg = 0;
+	}
+
+	if (reg)
+		I915_WRITE(reg, val);
+
+	I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
+}
+
 void intel_ddi_pll_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint32_t lcpll_val, clk_val, temp;
 	bool lcpll_needs_change = false;
+	int i;
+
+	/* Reset all pipe clocks and ports so we don't hang the machine later */
+	for (i = PIPE_A; i <= PIPE_C; i++) {
+		intel_disable_plane(dev_priv, i, i);
+		intel_disable_pipe(dev_priv, i);
+		intel_ddi_disable_pipe(dev_priv, i);
+	}
+
+	for (i = PORT_A; i <= PORT_E; i++)
+		intel_ddi_disable_port(dev_priv, i);
 
 	/* Check the LCPLL state and fix it if needed. */
 	lcpll_val = I915_READ(LCPLL_CTL);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 11687d2..33eebcb 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1773,8 +1773,7 @@ static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
  *
  * Will wait until the pipe has shut down before returning.
  */
-static void intel_disable_pipe(struct drm_i915_private *dev_priv,
-			       enum pipe pipe)
+void intel_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
 {
 	int reg;
 	u32 val;
@@ -1844,8 +1843,8 @@ static void intel_enable_plane(struct drm_i915_private *dev_priv,
  *
  * Disable @plane; should be an independent operation.
  */
-static void intel_disable_plane(struct drm_i915_private *dev_priv,
-				enum plane plane, enum pipe pipe)
+void intel_disable_plane(struct drm_i915_private *dev_priv,
+			 enum plane plane, enum pipe pipe)
 {
 	int reg;
 	u32 val;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index cf9a1ad..2578158 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -390,6 +390,10 @@ extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
 extern int intel_plane_init(struct drm_device *dev, enum pipe pipe);
 extern void intel_flush_display_plane(struct drm_i915_private *dev_priv,
 				      enum plane plane);
+extern void intel_disable_plane(struct drm_i915_private *dev_priv,
+				enum plane plane, enum pipe pipe);
+extern void intel_disable_pipe(struct drm_i915_private *dev_priv,
+			       enum pipe pipe);
 
 /* intel_panel.c */
 extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index cc8df4d..4737303 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -531,7 +531,7 @@ out:
 }
 
 static int
-intel_disable_plane(struct drm_plane *plane)
+intel_disable_drm_plane(struct drm_plane *plane)
 {
 	struct drm_device *dev = plane->dev;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -556,7 +556,7 @@ out:
 static void intel_destroy_plane(struct drm_plane *plane)
 {
 	struct intel_plane *intel_plane = to_intel_plane(plane);
-	intel_disable_plane(plane);
+	intel_disable_drm_plane(plane);
 	drm_plane_cleanup(plane);
 	kfree(intel_plane);
 }
@@ -625,7 +625,7 @@ out_unlock:
 
 static const struct drm_plane_funcs intel_plane_funcs = {
 	.update_plane = intel_update_plane,
-	.disable_plane = intel_disable_plane,
+	.disable_plane = intel_disable_drm_plane,
 	.destroy = intel_destroy_plane,
 };
 
-- 
1.7.11.2

  parent reply	other threads:[~2012-08-28 22:07 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-28 22:06 [RFC 00/30] Haswell clocking+HDMI+DP+eDP fixes Paulo Zanoni
2012-08-28 22:06 ` [RFC 01/30] drm/i915: rewrite the LCPLL code Paulo Zanoni
2012-08-28 22:06 ` Paulo Zanoni [this message]
2012-08-28 22:06 ` [RFC 03/30] drm/i915: wait for idle DDI_BUF_CTL after disabling it Paulo Zanoni
2012-08-28 22:06 ` [RFC 04/30] drm/i915: implement DDI disable function Paulo Zanoni
2012-08-28 22:06 ` [RFC 05/30] drm/i915: implement intel_ddi_pll_mode_set Paulo Zanoni
2012-08-28 22:06 ` [RFC 06/30] drm/i915: extract intel_ddi_enable pipe from intel_ddi_mode_set Paulo Zanoni
2012-08-28 22:06 ` [RFC 07/30] drm/i915: make intel_ddi_enable_pipe work on DP Paulo Zanoni
2012-08-28 22:06 ` [RFC 08/30] drm/i915: don't sleep after selecting the DDI pipe clock Paulo Zanoni
2012-08-28 22:06 ` [RFC 09/30] drm/i915: add DP support to intel_ddi_pll_mode_set Paulo Zanoni
2012-08-28 22:06 ` [RFC 10/30] drm/i915: add DP support to intel_ddi_disable_port Paulo Zanoni
2012-08-28 22:06 ` [RFC 11/30] drm/i915: add DP support to intel_ddi_mode_set Paulo Zanoni
2012-08-28 22:06 ` [RFC 12/30] drm/i915: add basic Haswell DP link train bits Paulo Zanoni
2012-08-28 22:06 ` [RFC 13/30] drm/i915: add intel_ddi_commit Paulo Zanoni
2012-08-28 22:06 ` [RFC 14/30] drm/i915: fix Haswell M/N registers Paulo Zanoni
2012-08-28 22:06 ` [RFC 15/30] drm/i915: fix DP AUX register definitions on Haswell Paulo Zanoni
2012-08-28 22:06 ` [RFC 16/30] drm/i915: disable DDI on intel_dp_link_down Paulo Zanoni
2012-08-28 22:06 ` [RFC 17/30] drm/i915: add intel_ddi_prepare_link_retrain Paulo Zanoni
2012-08-28 22:06 ` [RFC 18/30] drm/i915: add DP support to intel_ddi_disable Paulo Zanoni
2012-08-28 22:06 ` [RFC 19/30] drm/i915: add Haswell DP encoder_helper function definitions Paulo Zanoni
2012-08-28 22:06 ` [RFC 20/30] drm/i915: add TRANSCODER_EDP Paulo Zanoni
2012-08-28 22:06 ` [RFC 21/30] drm/i915: enable eDP on Haswell Paulo Zanoni
2012-08-28 22:06 ` [RFC 22/30] drm/i915: don't run PCH code on non-PCH ports Paulo Zanoni
2012-08-28 22:06 ` [RFC 23/30] drm/i915: init DP on port B Paulo Zanoni
2012-08-28 22:06 ` [RFC 24/30] drm/i915: simplify assignments inside intel_dp.c Paulo Zanoni
2012-08-28 22:06 ` [RFC 25/30] drm/i915: add intel_dp_to_dev and intel_hdmi_to_dev Paulo Zanoni
2012-08-28 22:06 ` [RFC 26/30] drm/i915: create intel_digital_port and use it Paulo Zanoni
2012-08-28 22:06 ` [RFC 27/30] drm/i915: remove encoder args from intel_{dp, hdmi}_add_properties Paulo Zanoni
2012-08-28 22:06 ` [RFC 28/30] drm/i915: split intel_hdmi_init into encoder and connector pieces Paulo Zanoni
2012-08-28 22:07 ` [RFC 29/30] drm/i915: split intel_dp_commit " Paulo Zanoni
2012-08-28 22:07 ` [RFC 30/30] drm/i915: make DDI an encoder Paulo Zanoni

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=1346191621-12996-3-git-send-email-przanoni@gmail.com \
    --to=przanoni@gmail.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=paulo.r.zanoni@intel.com \
    /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.