All of lore.kernel.org
 help / color / mirror / Atom feed
From: ville.syrjala@linux.intel.com
To: intel-gfx@lists.freedesktop.org
Cc: "Deepak S"@freedesktop.org, deepak.s@intel.com
Subject: [PATCH 09/15] drm/i915: Trick CL2 into life on CHV when using pipe B with port B
Date: Wed,  8 Jul 2015 23:45:55 +0300	[thread overview]
Message-ID: <1436388361-11130-10-git-send-email-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <1436388361-11130-1-git-send-email-ville.syrjala@linux.intel.com>

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

Normmally the common lane in a PHY channel gets powered up when some
of the data lanes get powered up. But when we're driving port B with
pipe B we don't want to enabled any of the data lanes, and just want
the DPLL in the common lane to be active.

To make that happens we have to temporarily enable some data lanes
after which we can access the DPLL registers in the common lane. Once
the pipe is up and running we can drop the power override on the data
lanes allowing them to shut down. From this point forward the common
lane will in fact stay powered on until the data lanes in the other
channel get powered down.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c         | 23 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h        |  3 +++
 drivers/gpu/drm/i915/intel_hdmi.c       | 23 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_runtime_pm.c | 29 +++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 6058129..8d088f3 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2865,6 +2865,12 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
 	mutex_unlock(&dev_priv->sb_lock);
 
 	intel_enable_dp(encoder);
+
+	/* Second common lane will stay alive on its own now */
+	if (dport->release_cl2_override) {
+		chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, false);
+		dport->release_cl2_override = false;
+	}
 }
 
 static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
@@ -2882,6 +2888,14 @@ static void chv_dp_pre_pll_enable(struct intel_encoder *encoder)
 
 	intel_dp_prepare(encoder);
 
+	/*
+	 * Must trick the second common lane into life.
+	 * Otherwise we can't even access the PLL.
+	 */
+	if (ch == DPIO_CH0 && pipe == PIPE_B)
+		dport->release_cl2_override =
+			!chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, true);
+
 	chv_phy_powergate_lanes(encoder, true, lane_mask);
 
 	mutex_lock(&dev_priv->sb_lock);
@@ -2960,6 +2974,15 @@ static void chv_dp_post_pll_disable(struct intel_encoder *encoder)
 
 	mutex_unlock(&dev_priv->sb_lock);
 
+	/*
+	 * Leave the power down bit cleared for at least one
+	 * lane so that chv_powergate_phy_ch() will power
+	 * on something when the channel is otherwise unused.
+	 * When the port is off and the override is removed
+	 * the lanes power down anyway, so otherwise it doesn't
+	 * really matter what the state of power down bits is
+	 * after this.
+	 */
 	chv_phy_powergate_lanes(encoder, false, 0x0);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f8a16dc..6133a98 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -782,6 +782,7 @@ struct intel_digital_port {
 	struct intel_dp dp;
 	struct intel_hdmi hdmi;
 	enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool);
+	bool release_cl2_override;
 };
 
 struct intel_dp_mst_encoder {
@@ -1372,6 +1373,8 @@ void intel_display_set_init_power(struct drm_i915_private *dev, bool enable);
 
 void chv_phy_powergate_lanes(struct intel_encoder *encoder,
 			     bool override, unsigned int mask);
+bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
+			  enum dpio_channel ch, bool override);
 
 
 /* intel_pm.c */
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index b3f6c9f..4b604ee 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1625,6 +1625,14 @@ static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
 
 	intel_hdmi_prepare(encoder);
 
+	/*
+	 * Must trick the second common lane into life.
+	 * Otherwise we can't even access the PLL.
+	 */
+	if (ch == DPIO_CH0 && pipe == PIPE_B)
+		dport->release_cl2_override =
+			!chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, true);
+
 	chv_phy_powergate_lanes(encoder, true, 0x0);
 
 	mutex_lock(&dev_priv->sb_lock);
@@ -1701,6 +1709,15 @@ static void chv_hdmi_post_pll_disable(struct intel_encoder *encoder)
 
 	mutex_unlock(&dev_priv->sb_lock);
 
+	/*
+	 * Leave the power down bit cleared for at least one
+	 * lane so that chv_powergate_phy_ch() will power
+	 * on something when the channel is otherwise unused.
+	 * When the port is off and the override is removed
+	 * the lanes power down anyway, so otherwise it doesn't
+	 * really matter what the state of power down bits is
+	 * after this.
+	 */
 	chv_phy_powergate_lanes(encoder, false, 0x0);
 }
 
@@ -1922,6 +1939,12 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
 	g4x_enable_hdmi(encoder);
 
 	vlv_wait_port_ready(dev_priv, dport, 0x0);
+
+	/* Second common lane will stay alive on its own now */
+	if (dport->release_cl2_override) {
+		chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, false);
+		dport->release_cl2_override = false;
+	}
 }
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 506a8cc..551cf08 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -1016,6 +1016,35 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
 		      phy, dev_priv->chv_phy_control);
 }
 
+bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
+			  enum dpio_channel ch, bool override)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	bool was_override;
+
+	mutex_lock(&power_domains->lock);
+
+	was_override = dev_priv->chv_phy_control & PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
+
+	if (override == was_override)
+		goto out;
+
+	if (override)
+		dev_priv->chv_phy_control |= PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
+	else
+		dev_priv->chv_phy_control &= ~PHY_CH_POWER_DOWN_OVRD_EN(phy, ch);
+
+	I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control);
+
+	DRM_DEBUG_KMS("Power gating DPIO PHY%d CH%d (DPIO_PHY_CONTROL=0x%08x)\n",
+		      phy, ch, dev_priv->chv_phy_control);
+
+out:
+	mutex_unlock(&power_domains->lock);
+
+	return was_override;
+}
+
 void chv_phy_powergate_lanes(struct intel_encoder *encoder,
 			     bool override, unsigned int mask)
 {
-- 
2.3.6

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

  parent reply	other threads:[~2015-07-08 20:46 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-08 20:45 [PATCH 00/15] drm/i915: CHV DPIO power gating, take two ville.syrjala
2015-07-08 20:45 ` [PATCH 01/15] drm/i915: Always program m2 fractional value on CHV ville.syrjala
2015-08-17  2:19   ` Deepak
2015-08-17 11:45     ` Ville Syrjälä
2015-08-26  8:11       ` Deepak
2015-07-08 20:45 ` [PATCH 02/15] drm/i915: Always program unique transition scale for CHV ville.syrjala
2015-08-17  2:31   ` Deepak
2015-07-08 20:45 ` [PATCH 03/15] drm/i915: Add encoder->post_pll_disable() hooks and move CHV clock buffer disables there ville.syrjala
2015-08-17  4:16   ` Deepak
2015-08-17 11:53     ` Ville Syrjälä
2015-08-26  8:14       ` Deepak
2015-07-08 20:45 ` [PATCH 04/15] drm/i915: Move DPIO port init earlier ville.syrjala
2015-08-17  4:18   ` Deepak
2015-07-08 20:45 ` [PATCH 05/15] drm/i915: Add locking around chv_phy_control_init() ville.syrjala
2015-08-17  4:23   ` Deepak
2015-07-08 20:45 ` [PATCH 06/15] drm/i915: Move VLV/CHV prepare_pll later ville.syrjala
2015-08-17  4:36   ` Deepak
2015-08-17  4:39   ` Deepak
2015-07-08 20:45 ` [PATCH 07/15] drm/i915: Add vlv_dport_to_phy() ville.syrjala
2015-08-17  4:56   ` Deepak
2015-08-26  8:24   ` Daniel Vetter
2015-07-08 20:45 ` [PATCH 08/15] drm/i915: Implement PHY lane power gating for CHV ville.syrjala
2015-08-19  1:48   ` Deepak
2015-08-26  8:27   ` Daniel Vetter
2015-07-08 20:45 ` ville.syrjala [this message]
2015-08-19  2:17   ` [PATCH 09/15] drm/i915: Trick CL2 into life on CHV when using pipe B with port B Deepak
2015-08-19 11:29     ` Ville Syrjälä
2015-08-26 12:36       ` Daniel Vetter
2015-07-08 20:45 ` [PATCH 10/15] drm/i915: Force common lane on for the PPS kick on CHV ville.syrjala
2015-07-10  7:56   ` [PATCH v2 " ville.syrjala
2015-08-19  2:21   ` [PATCH " Deepak
2015-08-19 11:32     ` Ville Syrjälä
2015-07-08 20:45 ` [PATCH 11/15] drm/i915: Enable DPIO SUS clock gating " ville.syrjala
2015-08-19 13:09   ` Deepak
2015-07-08 20:45 ` [PATCH 12/15] drm/i915: Force CL2 off in CHV x1 PHY ville.syrjala
2015-08-19 13:22   ` Deepak
2015-08-19 13:39     ` Ville Syrjälä
2015-08-26 12:38       ` Daniel Vetter
2015-07-08 20:45 ` [PATCH 13/15] drm/i915: Clean up CHV lane soft reset programming ville.syrjala
2015-07-09 16:27   ` Daniel Vetter
2015-07-09 17:14   ` [PATCH v2 " ville.syrjala
2015-08-27  4:25   ` [PATCH " Deepak
2015-07-08 20:46 ` [PATCH 14/15] drm/i915: Add some CHV DPIO lane power state asserts ville.syrjala
2015-08-27  4:36   ` Deepak
2015-08-27 11:02     ` Ville Syrjälä
2015-08-31 10:47       ` Deepak
2015-07-08 20:46 ` [PATCH 15/15] drm/i915: Add CHV PHY LDO power sanity checks ville.syrjala
2015-08-27  4:39   ` Deepak
2015-09-01  9:45     ` Daniel Vetter
2015-07-09 13:24 ` [PATCH 00/15] drm/i915: CHV DPIO power gating, take two Deepak

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=1436388361-11130-10-git-send-email-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc="Deepak S"@freedesktop.org \
    --cc=deepak.s@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.