All of lore.kernel.org
 help / color / mirror / Atom feed
* Vlv punit w/a (take two)
@ 2018-01-15  8:47 Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband Chris Wilson
                   ` (12 more replies)
  0 siblings, 13 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

I've incorporated Ville's feedback that this is highly unlikely to be a
general problem and tied the w/a to only the Valleyview punit. I kept
it reasonably open just in case we need to extend it, and for an
interface that makes for locking all sideband access convenient. (If we
make punit access very expensive, we don't want to be doing it too
often!)
-Chris

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

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

* [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-15 12:04   ` Mika Kuoppala
  2018-01-15  8:47 ` [PATCH v2 02/11] drm/i915: Lift acquiring the vlv punit magic to a common sb-get Chris Wilson
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx; +Cc: Hans de Goede

While we talk to the punit over its sideband, we need to prevent the cpu
from sleeping in order to prevent a potential machine hang.

Note that by itself, it appears that pm_qos_update_request (via
intel_idle) doesn't provide a sufficient barrier to ensure that all core
are indeed awake (out of Cstate) and that the package is awake. To do so,
we need to supplement the pm_qos with a manual ping on_each_cpu.

v2: Restrict the heavy-weight wakeup to just the ISOF_PORT_PUNIT, there
is insufficient evidence to implicate a wider problem atm. Similarly,
restrict the w/a to Valleyview, as Cherryview doesn't have an angry cadre
of users.

The working theory, courtesy of Ville and Hans, is the issue lies within
the power delivery and so is likely to be unit and board specific and
occurs when both the unit/fw require extra power at the same time as the
cpu package is changing its own power state.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=109051
References: https://bugs.freedesktop.org/show_bug.cgi?id=102657
References: https://bugzilla.kernel.org/show_bug.cgi?id=195255
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.c       |  6 +++
 drivers/gpu/drm/i915/i915_drv.h       |  1 +
 drivers/gpu/drm/i915/intel_sideband.c | 89 +++++++++++++++++++++++++++--------
 3 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6c8da9d20c33..d4b90cc0130b 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -902,6 +902,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
 	spin_lock_init(&dev_priv->uncore.lock);
 
 	mutex_init(&dev_priv->sb_lock);
+	pm_qos_add_request(&dev_priv->sb_qos,
+			   PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
+
 	mutex_init(&dev_priv->modeset_restore_lock);
 	mutex_init(&dev_priv->av_mutex);
 	mutex_init(&dev_priv->wm.wm_mutex);
@@ -953,6 +956,9 @@ static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
 	intel_irq_fini(dev_priv);
 	i915_workqueues_cleanup(dev_priv);
 	i915_engines_cleanup(dev_priv);
+
+	pm_qos_remove_request(&dev_priv->sb_qos);
+	mutex_destroy(&dev_priv->sb_lock);
 }
 
 static int i915_mmio_setup(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c42015b05b47..d95d8c3d04aa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1886,6 +1886,7 @@ struct drm_i915_private {
 
 	/* Sideband mailbox protection */
 	struct mutex sb_lock;
+	struct pm_qos_request sb_qos;
 
 	/** Cached value of IMR to avoid reads in updating the bitfield */
 	union {
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 75c872bb8cc9..d56eda33734e 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -22,6 +22,8 @@
  *
  */
 
+#include <asm/iosf_mbi.h>
+
 #include "i915_drv.h"
 #include "intel_drv.h"
 
@@ -39,18 +41,48 @@
 /* Private register write, double-word addressing, non-posted */
 #define SB_CRWRDA_NP	0x07
 
-static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
-			   u32 port, u32 opcode, u32 addr, u32 *val)
+static void ping(void *info)
 {
-	u32 cmd, be = 0xf, bar = 0;
-	bool is_read = (opcode == SB_MRD_NP || opcode == SB_CRRDDA_NP);
+}
 
-	cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
-		(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
-		(bar << IOSF_BAR_SHIFT);
+static void __vlv_punit_get(struct drm_i915_private *dev_priv)
+{
+	iosf_mbi_punit_acquire();
 
-	WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
+	/*
+	 * Prevent the cpu from sleeping while we use this sideband, otherwise
+	 * the punit may cause a machine hang. The issue appears to be isolated
+	 * with changing the power state of the CPU package while changing
+	 * the power state via the punit, and we have only observed it
+	 * reliably on 4-core Baytail systems suggesting the issue is in the
+	 * power delivery mechanism and likely to be be board/function
+	 * specific. Hence we presume the workaround needs only be applied
+	 * to the Valleyview P-unit and not all sideband communications.
+	 */
+	if (IS_VALLEYVIEW(dev_priv)) {
+		pm_qos_update_request(&dev_priv->sb_qos, 0);
+		on_each_cpu(ping, NULL, 1);
+	}
+}
+
+static void __vlv_punit_put(struct drm_i915_private *dev_priv)
+{
+	if (IS_VALLEYVIEW(dev_priv))
+		pm_qos_update_request(&dev_priv->sb_qos, PM_QOS_DEFAULT_VALUE);
 
+	iosf_mbi_punit_release();
+}
+
+static int vlv_sideband_rw(struct drm_i915_private *dev_priv,
+			   u32 devfn, u32 port, u32 opcode,
+			   u32 addr, u32 *val)
+{
+	const bool is_read = (opcode == SB_MRD_NP || opcode == SB_CRRDDA_NP);
+	int err;
+
+	lockdep_assert_held(&dev_priv->sb_lock);
+
+	/* Flush the previous comms, just in case it failed last time. */
 	if (intel_wait_for_register(dev_priv,
 				    VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
 				    5)) {
@@ -59,22 +91,33 @@ static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
 		return -EAGAIN;
 	}
 
-	I915_WRITE(VLV_IOSF_ADDR, addr);
-	I915_WRITE(VLV_IOSF_DATA, is_read ? 0 : *val);
-	I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
-
-	if (intel_wait_for_register(dev_priv,
-				    VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
-				    5)) {
+	preempt_disable();
+
+	I915_WRITE_FW(VLV_IOSF_ADDR, addr);
+	I915_WRITE_FW(VLV_IOSF_DATA, is_read ? 0 : *val);
+	I915_WRITE_FW(VLV_IOSF_DOORBELL_REQ,
+		      (devfn << IOSF_DEVFN_SHIFT) |
+		      (opcode << IOSF_OPCODE_SHIFT) |
+		      (port << IOSF_PORT_SHIFT) |
+		      (0xf << IOSF_BYTE_ENABLES_SHIFT) |
+		      (0 << IOSF_BAR_SHIFT) |
+		      IOSF_SB_BUSY);
+
+	if (__intel_wait_for_register_fw(dev_priv,
+					 VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
+					 10000, 0, NULL) == 0) {
+		if (is_read)
+			*val = I915_READ_FW(VLV_IOSF_DATA);
+		err = 0;
+	} else {
 		DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
 				 is_read ? "read" : "write");
-		return -ETIMEDOUT;
+		err = -ETIMEDOUT;
 	}
 
-	if (is_read)
-		*val = I915_READ(VLV_IOSF_DATA);
+	preempt_enable();
 
-	return 0;
+	return err;
 }
 
 u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
@@ -84,8 +127,12 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
 	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
 
 	mutex_lock(&dev_priv->sb_lock);
+	__vlv_punit_get(dev_priv);
+
 	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
 			SB_CRRDDA_NP, addr, &val);
+
+	__vlv_punit_put(dev_priv);
 	mutex_unlock(&dev_priv->sb_lock);
 
 	return val;
@@ -98,8 +145,12 @@ int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
 	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
 
 	mutex_lock(&dev_priv->sb_lock);
+	__vlv_punit_get(dev_priv);
+
 	err = vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
 			      SB_CRWRDA_NP, addr, &val);
+
+	__vlv_punit_put(dev_priv);
 	mutex_unlock(&dev_priv->sb_lock);
 
 	return err;
-- 
2.15.1

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

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

* [PATCH v2 02/11] drm/i915: Lift acquiring the vlv punit magic to a common sb-get
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-15 10:36   ` Mika Kuoppala
  2018-01-15  8:47 ` [PATCH v2 03/11] drm/i915: Lift sideband locking for vlv_punit_(read|write) Chris Wilson
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

As we now employ a very heavy pm_qos around the punit access, we want to
minimise the number of synchronous requests by performing one for the
whole punit sequence rather than around individual accesses. The
sideband lock is used for this, so push the pm_qos into the sideband
lock acquisition and release, moving it from the lowlevel punit rw
routine to the callers. In the first step, we move the punit magic into
the common sideband lock so that we can acquire a bunch of ports
simultaneously, and if need be extend the workaround protection later.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.h         |  44 ++++++++++--
 drivers/gpu/drm/i915/intel_cdclk.c      |   6 +-
 drivers/gpu/drm/i915/intel_display.c    |  37 +++++-----
 drivers/gpu/drm/i915/intel_dp.c         |   4 +-
 drivers/gpu/drm/i915/intel_dpio_phy.c   |  37 +++++-----
 drivers/gpu/drm/i915/intel_dsi.c        |   8 +--
 drivers/gpu/drm/i915/intel_dsi_pll.c    |  14 ++--
 drivers/gpu/drm/i915/intel_dsi_vbt.c    |   8 +--
 drivers/gpu/drm/i915/intel_hdmi.c       |   4 +-
 drivers/gpu/drm/i915/intel_pm.c         |   4 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c |   8 +--
 drivers/gpu/drm/i915/intel_sideband.c   | 115 +++++++++++++++++++++++++++-----
 12 files changed, 207 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d95d8c3d04aa..80280f27601e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3723,25 +3723,61 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 		      u32 reply_mask, u32 reply, int timeout_base_ms);
 
 /* intel_sideband.c */
+
+enum {
+	VLV_IOSF_SB_BUNIT,
+	VLV_IOSF_SB_CCK,
+	VLV_IOSF_SB_CCU,
+	VLV_IOSF_SB_DPIO,
+	VLV_IOSF_SB_FLISDSI,
+	VLV_IOSF_SB_GPIO,
+	VLV_IOSF_SB_NC,
+	VLV_IOSF_SB_PUNIT,
+};
+
+void vlv_iosf_sb_get(struct drm_i915_private *dev_priv, unsigned long ports);
+u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg);
+void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, u8 port, u32 reg, u32 val);
+void vlv_iosf_sb_put(struct drm_i915_private *dev_priv, unsigned long ports);
+
+void vlv_punit_get(struct drm_i915_private *dev_priv);
 u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
 int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val);
+void vlv_punit_put(struct drm_i915_private *dev_priv);
+
+void vlv_nc_get(struct drm_i915_private *dev_priv);
 u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
-u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg);
-void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, u8 port, u32 reg, u32 val);
+void vlv_nc_put(struct drm_i915_private *dev_priv);
+
+void vlv_cck_get(struct drm_i915_private *dev_priv);
 u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
 void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+void vlv_cck_put(struct drm_i915_private *dev_priv);
+
+void vlv_ccu_get(struct drm_i915_private *dev_priv);
 u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
 void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+void vlv_ccu_put(struct drm_i915_private *dev_priv);
+
+void vlv_bunit_get(struct drm_i915_private *dev_priv);
 u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg);
 void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+void vlv_bunit_put(struct drm_i915_private *dev_priv);
+
+void vlv_dpio_get(struct drm_i915_private *dev_priv);
 u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg);
 void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val);
+void vlv_dpio_put(struct drm_i915_private *dev_priv);
+
+void vlv_flisdsi_get(struct drm_i915_private *dev_priv);
+u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+void vlv_flisdsi_put(struct drm_i915_private *dev_priv);
+
 u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
 		   enum intel_sbi_destination destination);
 void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
 		     enum intel_sbi_destination destination);
-u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
 
 /* intel_dpio_phy.c */
 void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index ca36321eafac..177bb79beee7 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -552,7 +552,8 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 	}
 	mutex_unlock(&dev_priv->pcu_lock);
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_iosf_sb_get(dev_priv,
+		       	BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_BUNIT));
 
 	if (cdclk == 400000) {
 		u32 divider;
@@ -586,7 +587,8 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 		val |= 3000 / 250; /* 3.0 usec */
 	vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_iosf_sb_put(dev_priv,
+		       	BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_BUNIT));
 
 	intel_update_cdclk(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 221e3a183d36..5f0b9f66c8d8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -165,10 +165,10 @@ int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
 	int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
 
 	/* Obtain SKU information */
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_cck_get(dev_priv);
 	hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
 		CCK_FUSE_HPLL_FREQ_MASK;
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_cck_put(dev_priv);
 
 	return vco_freq[hpll_freq] * 1000;
 }
@@ -179,9 +179,9 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
 	u32 val;
 	int divider;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_cck_get(dev_priv);
 	val = vlv_cck_read(dev_priv, reg);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_cck_put(dev_priv);
 
 	divider = val & CCK_FREQUENCY_VALUES;
 
@@ -1078,9 +1078,9 @@ void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
 	u32 val;
 	bool cur_state;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_cck_get(dev_priv);
 	val = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_cck_put(dev_priv);
 
 	cur_state = val & DSI_PLL_VCO_EN;
 	I915_STATE_WARN(cur_state != state,
@@ -1428,14 +1428,14 @@ static void _chv_enable_pll(struct intel_crtc *crtc,
 	enum dpio_channel port = vlv_pipe_to_channel(pipe);
 	u32 tmp;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* Enable back the 10bit clock to display controller */
 	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
 	tmp |= DPIO_DCLKP_EN;
 	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 
 	/*
 	 * Need to wait > 100ns between dclkp clock enable bit and PLL enable.
@@ -1620,14 +1620,14 @@ static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
 	I915_WRITE(DPLL(pipe), val);
 	POSTING_READ(DPLL(pipe));
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* Disable 10bit clock to display controller */
 	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
 	val &= ~DPIO_DCLKP_EN;
 	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 }
 
 void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
@@ -6638,7 +6638,7 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
 	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
 		return;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	bestn = pipe_config->dpll.n;
 	bestm1 = pipe_config->dpll.m1;
@@ -6715,7 +6715,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
 
 	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
-	mutex_unlock(&dev_priv->sb_lock);
+
+	vlv_dpio_put(dev_priv);
 }
 
 static void chv_prepare_pll(struct intel_crtc *crtc,
@@ -6748,7 +6749,7 @@ static void chv_prepare_pll(struct intel_crtc *crtc,
 	dpio_val = 0;
 	loopfilter = 0;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* p1 and p2 divider */
 	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
@@ -6820,7 +6821,7 @@ static void chv_prepare_pll(struct intel_crtc *crtc,
 			vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
 			DPIO_AFC_RECAL);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 }
 
 /**
@@ -7422,9 +7423,9 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
 	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
 		return;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 	mdiv = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW3(pipe));
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 
 	clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
 	clock.m2 = mdiv & DPIO_M2DIV_MASK;
@@ -7524,13 +7525,13 @@ static void chv_crtc_clock_get(struct intel_crtc *crtc,
 	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
 		return;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 	cmn_dw13 = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW13(port));
 	pll_dw0 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW0(port));
 	pll_dw1 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW1(port));
 	pll_dw2 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW2(port));
 	pll_dw3 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 
 	clock.m1 = (pll_dw1 & 0x7) == DPIO_CHV_M1_DIV_BY_2 ? 2 : 0;
 	clock.m2 = (pll_dw0 & 0xff) << 22;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 68229f53d5b8..168f2c0de1b6 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2771,12 +2771,12 @@ static void chv_post_disable_dp(struct intel_encoder *encoder,
 
 	intel_dp_link_down(encoder, old_crtc_state);
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* Assert data lane reset */
 	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c
index 76473e9836c6..662d71cd501f 100644
--- a/drivers/gpu/drm/i915/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/intel_dpio_phy.c
@@ -645,7 +645,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 	u32 val;
 	int i;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* Clear calc init */
 	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
@@ -726,8 +726,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
 	}
 
-	mutex_unlock(&dev_priv->sb_lock);
-
+	vlv_dpio_put(dev_priv);
 }
 
 void chv_data_lane_soft_reset(struct intel_encoder *encoder,
@@ -797,7 +796,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
 
 	chv_phy_powergate_lanes(encoder, true, lane_mask);
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* Assert data lane reset */
 	chv_data_lane_soft_reset(encoder, crtc_state, true);
@@ -852,7 +851,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
 		val |= CHV_CMN_USEDCLKCHANNEL;
 	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 }
 
 void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
@@ -867,7 +866,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
 	int data, i, stagger;
 	u32 val;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* allow hardware to manage TX FIFO reset source */
 	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
@@ -932,7 +931,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
 	/* Deassert data lane reset */
 	chv_data_lane_soft_reset(encoder, crtc_state, false);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 }
 
 void chv_phy_release_cl2_override(struct intel_encoder *encoder)
@@ -953,7 +952,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
 	enum pipe pipe = to_intel_crtc(old_crtc_state->base.crtc)->pipe;
 	u32 val;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* disable left/right clock distribution */
 	if (pipe != PIPE_B) {
@@ -966,7 +965,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
 		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
 	}
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 
 	/*
 	 * Leave the power down bit cleared for at least one
@@ -990,7 +989,8 @@ void vlv_set_phy_signal_level(struct intel_encoder *encoder,
 	enum dpio_channel port = vlv_dport_to_channel(dport);
 	enum pipe pipe = intel_crtc->pipe;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
+
 	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
 	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
 	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
@@ -1003,7 +1003,8 @@ void vlv_set_phy_signal_level(struct intel_encoder *encoder,
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
 	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN);
-	mutex_unlock(&dev_priv->sb_lock);
+
+	vlv_dpio_put(dev_priv);
 }
 
 void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
@@ -1016,7 +1017,8 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
 	enum pipe pipe = crtc->pipe;
 
 	/* Program Tx lane resets to default */
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
+
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port),
 			 DPIO_PCS_TX_LANE2_RESET |
 			 DPIO_PCS_TX_LANE1_RESET);
@@ -1030,7 +1032,8 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00);
 	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500);
 	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000);
-	mutex_unlock(&dev_priv->sb_lock);
+
+	vlv_dpio_put(dev_priv);
 }
 
 void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
@@ -1044,7 +1047,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
 	enum pipe pipe = crtc->pipe;
 	u32 val;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* Enable clock channels for this port */
 	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port));
@@ -1060,7 +1063,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018);
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 }
 
 void vlv_phy_reset_lanes(struct intel_encoder *encoder,
@@ -1072,8 +1075,8 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder,
 	enum dpio_channel port = vlv_dport_to_channel(dport);
 	enum pipe pipe = crtc->pipe;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), 0x00000000);
 	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port), 0x00e00060);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 }
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index f67d321376e4..0b503b6971ff 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -278,7 +278,7 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs,
 
 static void band_gap_reset(struct drm_i915_private *dev_priv)
 {
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_flisdsi_get(dev_priv);
 
 	vlv_flisdsi_write(dev_priv, 0x08, 0x0001);
 	vlv_flisdsi_write(dev_priv, 0x0F, 0x0005);
@@ -287,7 +287,7 @@ static void band_gap_reset(struct drm_i915_private *dev_priv)
 	vlv_flisdsi_write(dev_priv, 0x0F, 0x0000);
 	vlv_flisdsi_write(dev_priv, 0x08, 0x0000);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_flisdsi_put(dev_priv);
 }
 
 static inline bool is_vid_mode(struct intel_dsi *intel_dsi)
@@ -509,11 +509,11 @@ static void vlv_dsi_device_ready(struct intel_encoder *encoder)
 
 	DRM_DEBUG_KMS("\n");
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_flisdsi_get(dev_priv);
 	/* program rcomp for compliance, reduce from 50 ohms to 45 ohms
 	 * needed everytime after power gate */
 	vlv_flisdsi_write(dev_priv, 0x04, 0x0004);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_flisdsi_put(dev_priv);
 
 	/* bandgap reset is needed after everytime we do power gate */
 	band_gap_reset(dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
index 2ff2ee7f3b78..b73336e7dcd2 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -149,7 +149,7 @@ static void vlv_enable_dsi_pll(struct intel_encoder *encoder,
 
 	DRM_DEBUG_KMS("\n");
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_cck_get(dev_priv);
 
 	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
 	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, config->dsi_pll.div);
@@ -166,11 +166,11 @@ static void vlv_enable_dsi_pll(struct intel_encoder *encoder,
 	if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) &
 						DSI_PLL_LOCK, 20)) {
 
-		mutex_unlock(&dev_priv->sb_lock);
+		vlv_cck_put(dev_priv);
 		DRM_ERROR("DSI PLL lock failed\n");
 		return;
 	}
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_cck_put(dev_priv);
 
 	DRM_DEBUG_KMS("DSI PLL locked\n");
 }
@@ -182,14 +182,14 @@ static void vlv_disable_dsi_pll(struct intel_encoder *encoder)
 
 	DRM_DEBUG_KMS("\n");
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_cck_get(dev_priv);
 
 	tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
 	tmp &= ~DSI_PLL_VCO_EN;
 	tmp |= DSI_PLL_LDO_GATE;
 	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_cck_put(dev_priv);
 }
 
 static bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv)
@@ -274,10 +274,10 @@ static u32 vlv_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp,
 
 	DRM_DEBUG_KMS("\n");
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_cck_get(dev_priv);
 	pll_ctl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
 	pll_div = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_DIVIDER);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_cck_put(dev_priv);
 
 	config->dsi_pll.ctrl = pll_ctl & ~DSI_PLL_LOCK;
 	config->dsi_pll.div = pll_div;
diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c
index 91c07b0c8db9..f1168b6e8592 100644
--- a/drivers/gpu/drm/i915/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c
@@ -234,7 +234,7 @@ static void vlv_exec_gpio(struct drm_i915_private *dev_priv,
 	pconf0 = VLV_GPIO_PCONF0(map->base_offset);
 	padval = VLV_GPIO_PAD_VAL(map->base_offset);
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_GPIO));
 	if (!map->init) {
 		/* FIXME: remove constant below */
 		vlv_iosf_sb_write(dev_priv, port, pconf0, 0x2000CC00);
@@ -243,7 +243,7 @@ static void vlv_exec_gpio(struct drm_i915_private *dev_priv,
 
 	tmp = 0x4 | value;
 	vlv_iosf_sb_write(dev_priv, port, padval, tmp);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
 }
 
 static void chv_exec_gpio(struct drm_i915_private *dev_priv,
@@ -289,12 +289,12 @@ static void chv_exec_gpio(struct drm_i915_private *dev_priv,
 	cfg0 = CHV_GPIO_PAD_CFG0(family_num, gpio_index);
 	cfg1 = CHV_GPIO_PAD_CFG1(family_num, gpio_index);
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_GPIO));
 	vlv_iosf_sb_write(dev_priv, port, cfg1, 0);
 	vlv_iosf_sb_write(dev_priv, port, cfg0,
 			  CHV_GPIO_GPIOEN | CHV_GPIO_GPIOCFG_GPO |
 			  CHV_GPIO_GPIOTXSTATE(value));
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
 }
 
 static void bxt_exec_gpio(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 691f15b59124..2b5b7d4f73d7 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1995,12 +1995,12 @@ static void chv_hdmi_post_disable(struct intel_encoder *encoder,
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* Assert data lane reset */
 	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 }
 
 static void chv_hdmi_pre_enable(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1db79a860b96..60c666424d65 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -7173,9 +7173,9 @@ static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
 
 	vlv_init_gpll_ref_freq(dev_priv);
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_cck_get(dev_priv);
 	val = vlv_cck_read(dev_priv, CCK_FUSE_REG);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_cck_put(dev_priv);
 
 	switch ((val >> 2) & 0x7) {
 	case 3:
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 4996c4ea8a80..34ffa2dd3996 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -1182,7 +1182,7 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
 				    1))
 		DRM_ERROR("Display PHY %d is not power up\n", phy);
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 
 	/* Enable dynamic power down */
 	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW28);
@@ -1205,7 +1205,7 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
 		vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, tmp);
 	}
 
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 
 	dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy);
 	I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control);
@@ -1268,9 +1268,9 @@ static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpi
 	else
 		reg = _CHV_CMN_DW6_CH1;
 
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_dpio_get(dev_priv);
 	val = vlv_dpio_read(dev_priv, pipe, reg);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_dpio_put(dev_priv);
 
 	/*
 	 * This assumes !override is only used when the port is disabled.
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index d56eda33734e..3d7c5917b97c 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -73,6 +73,22 @@ static void __vlv_punit_put(struct drm_i915_private *dev_priv)
 	iosf_mbi_punit_release();
 }
 
+void vlv_iosf_sb_get(struct drm_i915_private *dev_priv, unsigned long ports)
+{
+	if (ports & BIT(VLV_IOSF_SB_PUNIT))
+		__vlv_punit_get(dev_priv);
+
+	mutex_lock(&dev_priv->sb_lock);
+}
+
+void vlv_iosf_sb_put(struct drm_i915_private *dev_priv, unsigned long ports)
+{
+	mutex_unlock(&dev_priv->sb_lock);
+
+	if (ports & BIT(VLV_IOSF_SB_PUNIT))
+		__vlv_punit_put(dev_priv);
+}
+
 static int vlv_sideband_rw(struct drm_i915_private *dev_priv,
 			   u32 devfn, u32 port, u32 opcode,
 			   u32 addr, u32 *val)
@@ -81,6 +97,8 @@ static int vlv_sideband_rw(struct drm_i915_private *dev_priv,
 	int err;
 
 	lockdep_assert_held(&dev_priv->sb_lock);
+	if (port == IOSF_PORT_PUNIT)
+		iosf_mbi_assert_punit_acquired();
 
 	/* Flush the previous comms, just in case it failed last time. */
 	if (intel_wait_for_register(dev_priv,
@@ -124,16 +142,14 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
 {
 	u32 val = 0;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
+	lockdep_assert_held(&dev_priv->pcu_lock);
 
-	mutex_lock(&dev_priv->sb_lock);
-	__vlv_punit_get(dev_priv);
+	vlv_punit_get(dev_priv);
 
 	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
 			SB_CRRDDA_NP, addr, &val);
 
-	__vlv_punit_put(dev_priv);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_punit_put(dev_priv);
 
 	return val;
 }
@@ -142,20 +158,28 @@ int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
 {
 	int err;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
+	lockdep_assert_held(&dev_priv->pcu_lock);
 
-	mutex_lock(&dev_priv->sb_lock);
-	__vlv_punit_get(dev_priv);
+	vlv_punit_get(dev_priv);
 
 	err = vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
 			      SB_CRWRDA_NP, addr, &val);
 
-	__vlv_punit_put(dev_priv);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_punit_put(dev_priv);
 
 	return err;
 }
 
+void vlv_punit_get(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_PUNIT));
+}
+
+void vlv_punit_put(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_PUNIT));
+}
+
 u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
 {
 	u32 val = 0;
@@ -172,20 +196,38 @@ void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
 			SB_CRWRDA_NP, reg, &val);
 }
 
+void vlv_bunit_get(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_BUNIT));
+}
+
+void vlv_bunit_put(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_BUNIT));
+}
+
 u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
 {
 	u32 val = 0;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
-
-	mutex_lock(&dev_priv->sb_lock);
+	vlv_nc_get(dev_priv);
 	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC,
 			SB_CRRDDA_NP, addr, &val);
-	mutex_unlock(&dev_priv->sb_lock);
+	vlv_nc_put(dev_priv);
 
 	return val;
 }
 
+void vlv_nc_get(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_NC));
+}
+
+void vlv_nc_put(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_NC));
+}
+
 u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg)
 {
 	u32 val = 0;
@@ -215,6 +257,16 @@ void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
 			SB_CRWRDA_NP, reg, &val);
 }
 
+void vlv_cck_get(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_CCK));
+}
+
+void vlv_cck_put(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_CCK));
+}
+
 u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg)
 {
 	u32 val = 0;
@@ -229,6 +281,16 @@ void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
 			SB_CRWRDA_NP, reg, &val);
 }
 
+void vlv_ccu_get(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_CCU));
+}
+
+void vlv_ccu_put(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_CCU));
+}
+
 u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg)
 {
 	u32 val = 0;
@@ -252,12 +314,23 @@ void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg,
 			SB_MWR_NP, reg, &val);
 }
 
+void vlv_dpio_get(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_DPIO));
+}
+
+void vlv_dpio_put(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_DPIO));
+}
+
 /* SBI access */
 u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
 		   enum intel_sbi_destination destination)
 {
 	u32 value = 0;
-	WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
+
+	lockdep_assert_held(&dev_priv->sb_lock);
 
 	if (intel_wait_for_register(dev_priv,
 				    SBI_CTL_STAT, SBI_BUSY, 0,
@@ -297,7 +370,7 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
 {
 	u32 tmp;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
+	lockdep_assert_held(&dev_priv->sb_lock);
 
 	if (intel_wait_for_register(dev_priv,
 				    SBI_CTL_STAT, SBI_BUSY, 0,
@@ -344,3 +417,13 @@ void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
 	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI, SB_CRWRDA_NP,
 			reg, &val);
 }
+
+void vlv_flisdsi_get(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_FLISDSI));
+}
+
+void vlv_flisdsi_put(struct drm_i915_private *dev_priv)
+{
+	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_FLISDSI));
+}
-- 
2.15.1

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

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

* [PATCH v2 03/11] drm/i915: Lift sideband locking for vlv_punit_(read|write)
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 02/11] drm/i915: Lift acquiring the vlv punit magic to a common sb-get Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 04/11] drm/i915: Reduce RPS update frequency on Valleyview/Cherryview Chris Wilson
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

Lift the sideband acquisition for vlv_punit_read and vlv_punit_write
into their callers, so that we can lock the sideband once for a sequence
of operations, rather than perform the heavyweight acquisition on each
request.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c     |  3 +++
 drivers/gpu/drm/i915/i915_sysfs.c       | 14 +++++-----
 drivers/gpu/drm/i915/intel_cdclk.c      | 24 +++++++++++++----
 drivers/gpu/drm/i915/intel_display.c    | 16 +++++++-----
 drivers/gpu/drm/i915/intel_pm.c         | 46 +++++++++++++++++++++++++++------
 drivers/gpu/drm/i915/intel_runtime_pm.c |  8 ++++++
 drivers/gpu/drm/i915/intel_sideband.c   | 18 ++-----------
 7 files changed, 86 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index cc659b4b2a45..28062bd60793 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1033,7 +1033,10 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 			   yesno((rpmodectl & GEN6_RP_MEDIA_MODE_MASK) ==
 				  GEN6_RP_MEDIA_SW_MODE));
 
+		vlv_punit_get(dev_priv);
 		freq_sts = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
+		vlv_punit_put(dev_priv);
+
 		seq_printf(m, "PUNIT_REG_GPU_FREQ_STS: 0x%08x\n", freq_sts);
 		seq_printf(m, "DDR freq: %d MHz\n", dev_priv->mem_freq);
 
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index c74a20b80182..0475a13d751b 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -258,25 +258,25 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev,
 				    struct device_attribute *attr, char *buf)
 {
 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
-	int ret;
+	u32 freq;
 
 	intel_runtime_pm_get(dev_priv);
 
 	mutex_lock(&dev_priv->pcu_lock);
 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-		u32 freq;
+		vlv_punit_get(dev_priv);
 		freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
-		ret = intel_gpu_freq(dev_priv, (freq >> 8) & 0xff);
+		vlv_punit_put(dev_priv);
+
+		freq = (freq >> 8) & 0xff;
 	} else {
-		ret = intel_gpu_freq(dev_priv,
-				     intel_get_cagf(dev_priv,
-						    I915_READ(GEN6_RPSTAT1)));
+		freq = intel_get_cagf(dev_priv, I915_READ(GEN6_RPSTAT1));
 	}
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_runtime_pm_put(dev_priv);
 
-	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+	return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, freq));
 }
 
 static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index 177bb79beee7..fd6aa8da373f 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -461,13 +461,19 @@ static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
 {
 	u32 val;
 
+	mutex_lock(&dev_priv->pcu_lock);
+	vlv_iosf_sb_get(dev_priv,
+			BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
+
 	cdclk_state->vco = vlv_get_hpll_vco(dev_priv);
 	cdclk_state->cdclk = vlv_get_cck_clock(dev_priv, "cdclk",
 					       CCK_DISPLAY_CLOCK_CONTROL,
 					       cdclk_state->vco);
 
-	mutex_lock(&dev_priv->pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
+
+	vlv_iosf_sb_put(dev_priv,
+			BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (IS_VALLEYVIEW(dev_priv))
@@ -540,6 +546,11 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 	 */
 	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
 
+	vlv_iosf_sb_get(dev_priv,
+			BIT(VLV_IOSF_SB_CCK) |
+			BIT(VLV_IOSF_SB_BUNIT) |
+			BIT(VLV_IOSF_SB_PUNIT));
+
 	mutex_lock(&dev_priv->pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK;
@@ -552,9 +563,6 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 	}
 	mutex_unlock(&dev_priv->pcu_lock);
 
-	vlv_iosf_sb_get(dev_priv,
-		       	BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_BUNIT));
-
 	if (cdclk == 400000) {
 		u32 divider;
 
@@ -588,7 +596,9 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 	vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
 
 	vlv_iosf_sb_put(dev_priv,
-		       	BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_BUNIT));
+			BIT(VLV_IOSF_SB_CCK) |
+			BIT(VLV_IOSF_SB_BUNIT) |
+			BIT(VLV_IOSF_SB_PUNIT));
 
 	intel_update_cdclk(dev_priv);
 
@@ -623,6 +633,8 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
 
 	mutex_lock(&dev_priv->pcu_lock);
+	vlv_punit_get(dev_priv);
+
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK_CHV;
 	val |= (cmd << DSPFREQGUAR_SHIFT_CHV);
@@ -632,6 +644,8 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 		     50)) {
 		DRM_ERROR("timed out waiting for CDclk change\n");
 	}
+
+	vlv_punit_put(dev_priv);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_update_cdclk(dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5f0b9f66c8d8..9e082c6e9364 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -165,10 +165,8 @@ int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
 	int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
 
 	/* Obtain SKU information */
-	vlv_cck_get(dev_priv);
 	hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
 		CCK_FUSE_HPLL_FREQ_MASK;
-	vlv_cck_put(dev_priv);
 
 	return vco_freq[hpll_freq] * 1000;
 }
@@ -179,10 +177,7 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
 	u32 val;
 	int divider;
 
-	vlv_cck_get(dev_priv);
 	val = vlv_cck_read(dev_priv, reg);
-	vlv_cck_put(dev_priv);
-
 	divider = val & CCK_FREQUENCY_VALUES;
 
 	WARN((val & CCK_FREQUENCY_STATUS) !=
@@ -195,11 +190,18 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
 int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
 			   const char *name, u32 reg)
 {
+	int hpll;
+
+	vlv_cck_get(dev_priv);
+
 	if (dev_priv->hpll_freq == 0)
 		dev_priv->hpll_freq = vlv_get_hpll_vco(dev_priv);
 
-	return vlv_get_cck_clock(dev_priv, name, reg,
-				 dev_priv->hpll_freq);
+	hpll = vlv_get_cck_clock(dev_priv, name, reg, dev_priv->hpll_freq);
+
+	vlv_cck_put(dev_priv);
+
+	return hpll;
 }
 
 static void intel_update_czclk(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 60c666424d65..83eef5d04592 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -311,6 +311,7 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable)
 	u32 val;
 
 	mutex_lock(&dev_priv->pcu_lock);
+	vlv_punit_get(dev_priv);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
 	if (enable)
@@ -325,6 +326,7 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable)
 		      FORCE_DDR_FREQ_REQ_ACK) == 0, 3))
 		DRM_ERROR("timed out waiting for Punit DDR DVFS request\n");
 
+	vlv_punit_put(dev_priv);
 	mutex_unlock(&dev_priv->pcu_lock);
 }
 
@@ -333,6 +335,7 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable)
 	u32 val;
 
 	mutex_lock(&dev_priv->pcu_lock);
+	vlv_punit_get(dev_priv);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	if (enable)
@@ -341,6 +344,7 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable)
 		val &= ~DSP_MAXFIFO_PM5_ENABLE;
 	vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
 
+	vlv_punit_put(dev_priv);
 	mutex_unlock(&dev_priv->pcu_lock);
 }
 
@@ -5636,6 +5640,7 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
 
 	if (IS_CHERRYVIEW(dev_priv)) {
 		mutex_lock(&dev_priv->pcu_lock);
+		vlv_punit_get(dev_priv);
 
 		val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 		if (val & DSP_MAXFIFO_PM5_ENABLE)
@@ -5665,6 +5670,7 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
 				wm->level = VLV_WM_LEVEL_DDR_DVFS;
 		}
 
+		vlv_punit_put(dev_priv);
 		mutex_unlock(&dev_priv->pcu_lock);
 	}
 
@@ -6211,7 +6217,9 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val)
 	I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
 
 	if (val != dev_priv->gt_pm.rps.cur_freq) {
+		vlv_punit_get(dev_priv);
 		err = vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
+		vlv_punit_put(dev_priv);
 		if (err)
 			return err;
 
@@ -7125,6 +7133,11 @@ static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv)
 
 	valleyview_setup_pctx(dev_priv);
 
+	vlv_iosf_sb_get(dev_priv,
+			BIT(VLV_IOSF_SB_PUNIT) |
+			BIT(VLV_IOSF_SB_NC) |
+			BIT(VLV_IOSF_SB_CCK));
+
 	vlv_init_gpll_ref_freq(dev_priv);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
@@ -7162,6 +7175,11 @@ static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv)
 	DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
 			 intel_gpu_freq(dev_priv, rps->min_freq),
 			 rps->min_freq);
+
+	vlv_iosf_sb_put(dev_priv,
+			BIT(VLV_IOSF_SB_PUNIT) |
+			BIT(VLV_IOSF_SB_NC) |
+			BIT(VLV_IOSF_SB_CCK));
 }
 
 static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
@@ -7171,11 +7189,14 @@ static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
 
 	cherryview_setup_pctx(dev_priv);
 
+	vlv_iosf_sb_get(dev_priv,
+			BIT(VLV_IOSF_SB_PUNIT) |
+			BIT(VLV_IOSF_SB_NC) |
+			BIT(VLV_IOSF_SB_CCK));
+
 	vlv_init_gpll_ref_freq(dev_priv);
 
-	vlv_cck_get(dev_priv);
 	val = vlv_cck_read(dev_priv, CCK_FUSE_REG);
-	vlv_cck_put(dev_priv);
 
 	switch ((val >> 2) & 0x7) {
 	case 3:
@@ -7208,6 +7229,11 @@ static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
 			 intel_gpu_freq(dev_priv, rps->min_freq),
 			 rps->min_freq);
 
+	vlv_iosf_sb_put(dev_priv,
+			BIT(VLV_IOSF_SB_PUNIT) |
+			BIT(VLV_IOSF_SB_NC) |
+			BIT(VLV_IOSF_SB_CCK));
+
 	WARN_ONCE((rps->max_freq | rps->efficient_freq | rps->rp1_freq |
 		   rps->min_freq) & 1,
 		  "Odd GPU freq values\n");
@@ -7295,13 +7321,15 @@ static void cherryview_enable_rps(struct drm_i915_private *dev_priv)
 		   GEN6_RP_DOWN_IDLE_AVG);
 
 	/* Setting Fixed Bias */
-	val = VLV_OVERRIDE_EN |
-		  VLV_SOC_TDP_EN |
-		  CHV_BIAS_CPU_50_SOC_50;
+	vlv_punit_get(dev_priv);
+
+	val = VLV_OVERRIDE_EN | VLV_SOC_TDP_EN | CHV_BIAS_CPU_50_SOC_50;
 	vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
 
+	vlv_punit_put(dev_priv);
+
 	/* RPS code assumes GPLL is used */
 	WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n");
 
@@ -7378,14 +7406,16 @@ static void valleyview_enable_rps(struct drm_i915_private *dev_priv)
 		   GEN6_RP_UP_BUSY_AVG |
 		   GEN6_RP_DOWN_IDLE_CONT);
 
+	vlv_punit_get(dev_priv);
+
 	/* Setting Fixed Bias */
-	val = VLV_OVERRIDE_EN |
-		  VLV_SOC_TDP_EN |
-		  VLV_BIAS_CPU_125_SOC_875;
+	val = VLV_OVERRIDE_EN | VLV_SOC_TDP_EN | VLV_BIAS_CPU_125_SOC_875;
 	vlv_punit_write(dev_priv, VLV_TURBO_SOC_OVERRIDE, val);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
 
+	vlv_punit_put(dev_priv);
+
 	/* RPS code assumes GPLL is used */
 	WARN_ONCE((val & GPLLENABLE) == 0, "GPLL not enabled\n");
 
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 34ffa2dd3996..d41972087cb7 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -799,6 +799,7 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv,
 			 PUNIT_PWRGT_PWR_GATE(power_well_id);
 
 	mutex_lock(&dev_priv->pcu_lock);
+	vlv_punit_get(dev_priv);
 
 #define COND \
 	((vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask) == state)
@@ -819,6 +820,7 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv,
 #undef COND
 
 out:
+	vlv_punit_put(dev_priv);
 	mutex_unlock(&dev_priv->pcu_lock);
 }
 
@@ -847,6 +849,7 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
 	ctrl = PUNIT_PWRGT_PWR_ON(power_well_id);
 
 	mutex_lock(&dev_priv->pcu_lock);
+	vlv_punit_get(dev_priv);
 
 	state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
 	/*
@@ -865,6 +868,7 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
 	ctrl = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_CTRL) & mask;
 	WARN_ON(ctrl != state);
 
+	vlv_punit_put(dev_priv);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	return enabled;
@@ -1378,6 +1382,7 @@ static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv,
 	u32 state, ctrl;
 
 	mutex_lock(&dev_priv->pcu_lock);
+	vlv_punit_get(dev_priv);
 
 	state = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe);
 	/*
@@ -1394,6 +1399,7 @@ static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv,
 	ctrl = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSC_MASK(pipe);
 	WARN_ON(ctrl << 16 != state);
 
+	vlv_punit_put(dev_priv);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	return enabled;
@@ -1410,6 +1416,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv,
 	state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe);
 
 	mutex_lock(&dev_priv->pcu_lock);
+	vlv_punit_get(dev_priv);
 
 #define COND \
 	((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe)) == state)
@@ -1430,6 +1437,7 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv,
 #undef COND
 
 out:
+	vlv_punit_put(dev_priv);
 	mutex_unlock(&dev_priv->pcu_lock);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 3d7c5917b97c..dc3b491b4d00 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -144,30 +144,18 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
 
 	lockdep_assert_held(&dev_priv->pcu_lock);
 
-	vlv_punit_get(dev_priv);
-
 	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
 			SB_CRRDDA_NP, addr, &val);
 
-	vlv_punit_put(dev_priv);
-
 	return val;
 }
 
 int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
 {
-	int err;
-
 	lockdep_assert_held(&dev_priv->pcu_lock);
 
-	vlv_punit_get(dev_priv);
-
-	err = vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
-			      SB_CRWRDA_NP, addr, &val);
-
-	vlv_punit_put(dev_priv);
-
-	return err;
+	return vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
+			       SB_CRWRDA_NP, addr, &val);
 }
 
 void vlv_punit_get(struct drm_i915_private *dev_priv)
@@ -210,10 +198,8 @@ u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
 {
 	u32 val = 0;
 
-	vlv_nc_get(dev_priv);
 	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC,
 			SB_CRRDDA_NP, addr, &val);
-	vlv_nc_put(dev_priv);
 
 	return val;
 }
-- 
2.15.1

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

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

* [PATCH v2 04/11] drm/i915: Reduce RPS update frequency on Valleyview/Cherryview
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (2 preceding siblings ...)
  2018-01-15  8:47 ` [PATCH v2 03/11] drm/i915: Lift sideband locking for vlv_punit_(read|write) Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 05/11] Revert "drm/i915: Avoid tweaking evaluation thresholds on Baytrail v3" Chris Wilson
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

Valleyview and Cherryview update the GPU frequency via the punit, which
is very expensive as we have to ensure the cores do not sleep during the
comms. If we perform frequent RPS evaluations, the frequent punit
requests cause measurable system overhead for little benefit, so
increase the evaluation intervals to reduce the number of times we try
and change frequency.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_pm.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 83eef5d04592..b2a7cff044cb 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6119,6 +6119,19 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 		break;
 	}
 
+	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+		/*
+		 * Baytrail and Braswell control the gpu frequency via the
+		 * punit, which is very slow and expensive to communicate with,
+		 * as we synchronously force the package to C0. If we try and
+		 * update the gpufreq too often we cause measurable system
+		 * load for little benefit (effectively stealing CPU time for
+		 * the GPU, negatively impacting overall throughput).
+		 */
+		ei_up <<= 2;
+		ei_down <<= 2;
+	}
+
 	/* When byt can survive without system hang with dynamic
 	 * sw freq adjustments, this restriction can be lifted.
 	 */
-- 
2.15.1

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

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

* [PATCH v2 05/11] Revert "drm/i915: Avoid tweaking evaluation thresholds on Baytrail v3"
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (3 preceding siblings ...)
  2018-01-15  8:47 ` [PATCH v2 04/11] drm/i915: Reduce RPS update frequency on Valleyview/Cherryview Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 06/11] drm/i915: Replace pcu_lock with sb_lock Chris Wilson
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx; +Cc: Len Brown, Jani Nikula, Daniel Vetter, fritsch

With the vlv sideband fixed to avoid sleeping while we talk to the
punit, the system should be much more stable and be able to utilise the
punit without risk.

This reverts commit 6067a27d1f01 ("drm/i915: Avoid tweaking evaluation
thresholds on Baytrail v3")

References: 6067a27d1f01 ("drm/i915: Avoid tweaking evaluation thresholds on Baytrail v3")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Len Brown <len.brown@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: fritsch@xbmc.org
---
 drivers/gpu/drm/i915/intel_pm.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index b2a7cff044cb..d88ceea031de 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6132,12 +6132,6 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 		ei_down <<= 2;
 	}
 
-	/* When byt can survive without system hang with dynamic
-	 * sw freq adjustments, this restriction can be lifted.
-	 */
-	if (IS_VALLEYVIEW(dev_priv))
-		goto skip_hw_write;
-
 	I915_WRITE(GEN6_RP_UP_EI,
 		   GT_INTERVAL_FROM_US(dev_priv, ei_up));
 	I915_WRITE(GEN6_RP_UP_THRESHOLD,
@@ -6158,7 +6152,6 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
 		   GEN6_RP_UP_BUSY_AVG |
 		   GEN6_RP_DOWN_IDLE_AVG);
 
-skip_hw_write:
 	rps->power = new_power;
 	rps->up_threshold = threshold_up;
 	rps->down_threshold = threshold_down;
-- 
2.15.1

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

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

* [PATCH v2 06/11] drm/i915: Replace pcu_lock with sb_lock
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (4 preceding siblings ...)
  2018-01-15  8:47 ` [PATCH v2 05/11] Revert "drm/i915: Avoid tweaking evaluation thresholds on Baytrail v3" Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 07/11] drm/i915: Separate sideband declarations to intel_sideband.h Chris Wilson
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

We now have two locks for sideband access. The general one covering
sideband access across all generation, sb_lock, and a specific one
covering sideband access via the punit on vlv/chv. After lifting the
sb_lock around the punit into the callers, the pcu_lock is now redudant
and can be separated from its other use to regulate RPS (essentially
giving RPS a lock all of its own).

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c     |  52 +++++---------
 drivers/gpu/drm/i915/i915_drv.h         |  10 +--
 drivers/gpu/drm/i915/i915_irq.c         |   4 +-
 drivers/gpu/drm/i915/i915_sysfs.c       |  40 +++++------
 drivers/gpu/drm/i915/intel_cdclk.c      |  24 -------
 drivers/gpu/drm/i915/intel_display.c    |   6 --
 drivers/gpu/drm/i915/intel_hdcp.c       |   2 -
 drivers/gpu/drm/i915/intel_pm.c         | 120 +++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_runtime_pm.c |   8 ---
 drivers/gpu/drm/i915/intel_sideband.c   |   4 --
 10 files changed, 97 insertions(+), 173 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 28062bd60793..044f74726a6f 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1022,8 +1022,6 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 	} else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
 		u32 rpmodectl, freq_sts;
 
-		mutex_lock(&dev_priv->pcu_lock);
-
 		rpmodectl = I915_READ(GEN6_RP_CONTROL);
 		seq_printf(m, "Video Turbo Mode: %s\n",
 			   yesno(rpmodectl & GEN6_RP_MEDIA_TURBO));
@@ -1058,7 +1056,6 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 		seq_printf(m,
 			   "efficient (RPe) frequency: %d MHz\n",
 			   intel_gpu_freq(dev_priv, rps->efficient_freq));
-		mutex_unlock(&dev_priv->pcu_lock);
 	} else if (INTEL_GEN(dev_priv) >= 6) {
 		u32 rp_state_limits;
 		u32 gt_perf_status;
@@ -1486,9 +1483,7 @@ static int gen6_drpc_info(struct seq_file *m)
 		gen9_powergate_status = I915_READ(GEN9_PWRGT_DOMAIN_STATUS);
 	}
 
-	mutex_lock(&dev_priv->pcu_lock);
 	sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids);
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	seq_printf(m, "RC1e Enabled: %s\n",
 		   yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE));
@@ -1754,30 +1749,24 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
-	int ret = 0;
 	int gpu_freq, ia_freq;
 	unsigned int max_gpu_freq, min_gpu_freq;
 
 	if (!HAS_LLC(dev_priv))
 		return -ENODEV;
 
-	intel_runtime_pm_get(dev_priv);
-
-	ret = mutex_lock_interruptible(&dev_priv->pcu_lock);
-	if (ret)
-		goto out;
+	min_gpu_freq = rps->min_freq;
+	max_gpu_freq = rps->max_freq;
 
 	if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
 		/* Convert GT frequency to 50 HZ units */
-		min_gpu_freq = rps->min_freq_softlimit / GEN9_FREQ_SCALER;
-		max_gpu_freq = rps->max_freq_softlimit / GEN9_FREQ_SCALER;
-	} else {
-		min_gpu_freq = rps->min_freq_softlimit;
-		max_gpu_freq = rps->max_freq_softlimit;
+		min_gpu_freq /= GEN9_FREQ_SCALER;
+		max_gpu_freq /= GEN9_FREQ_SCALER;
 	}
 
 	seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n");
 
+	intel_runtime_pm_get(dev_priv);
 	for (gpu_freq = min_gpu_freq; gpu_freq <= max_gpu_freq; gpu_freq++) {
 		ia_freq = gpu_freq;
 		sandybridge_pcode_read(dev_priv,
@@ -1791,12 +1780,9 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
 			   ((ia_freq >> 0) & 0xff) * 100,
 			   ((ia_freq >> 8) & 0xff) * 100);
 	}
-
-	mutex_unlock(&dev_priv->pcu_lock);
-
-out:
 	intel_runtime_pm_put(dev_priv);
-	return ret;
+
+	return 0;
 }
 
 static int i915_opregion(struct seq_file *m, void *unused)
@@ -4135,7 +4121,7 @@ i915_max_freq_set(void *data, u64 val)
 
 	DRM_DEBUG_DRIVER("Manually setting max freq to %llu\n", val);
 
-	ret = mutex_lock_interruptible(&dev_priv->pcu_lock);
+	ret = mutex_lock_interruptible(&rps->lock);
 	if (ret)
 		return ret;
 
@@ -4148,8 +4134,8 @@ i915_max_freq_set(void *data, u64 val)
 	hw_min = rps->min_freq;
 
 	if (val < hw_min || val > hw_max || val < rps->min_freq_softlimit) {
-		mutex_unlock(&dev_priv->pcu_lock);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto unlock;
 	}
 
 	rps->max_freq_softlimit = val;
@@ -4157,9 +4143,9 @@ i915_max_freq_set(void *data, u64 val)
 	if (intel_set_rps(dev_priv, val))
 		DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n");
 
-	mutex_unlock(&dev_priv->pcu_lock);
-
-	return 0;
+unlock:
+	mutex_unlock(&rps->lock);
+	return ret;
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(i915_max_freq_fops,
@@ -4191,7 +4177,7 @@ i915_min_freq_set(void *data, u64 val)
 
 	DRM_DEBUG_DRIVER("Manually setting min freq to %llu\n", val);
 
-	ret = mutex_lock_interruptible(&dev_priv->pcu_lock);
+	ret = mutex_lock_interruptible(&rps->lock);
 	if (ret)
 		return ret;
 
@@ -4205,8 +4191,8 @@ i915_min_freq_set(void *data, u64 val)
 
 	if (val < hw_min ||
 	    val > hw_max || val > rps->max_freq_softlimit) {
-		mutex_unlock(&dev_priv->pcu_lock);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto unlock;
 	}
 
 	rps->min_freq_softlimit = val;
@@ -4214,9 +4200,9 @@ i915_min_freq_set(void *data, u64 val)
 	if (intel_set_rps(dev_priv, val))
 		DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n");
 
-	mutex_unlock(&dev_priv->pcu_lock);
-
-	return 0;
+unlock:
+	mutex_unlock(&rps->lock);
+	return ret;
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(i915_min_freq_fops,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 80280f27601e..6e4e30397997 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -891,6 +891,8 @@ struct intel_rps_ei {
 };
 
 struct intel_rps {
+	struct mutex lock;
+
 	/*
 	 * work, interrupts_enabled and pm_iir are protected by
 	 * dev_priv->irq_lock
@@ -2033,14 +2035,6 @@ struct drm_i915_private {
 	/* Cannot be determined by PCIID. You must always read a register. */
 	u32 edram_cap;
 
-	/*
-	 * Protects RPS/RC6 register access and PCU communication.
-	 * Must be taken after struct_mutex if nested. Note that
-	 * this lock may be held for long periods of time when
-	 * talking to hw - so only take it when talking to hw!
-	 */
-	struct mutex pcu_lock;
-
 	/* gen6+ GT PM state */
 	struct intel_gen6_power_mgmt gt_pm;
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 3517c6548e2c..2aee867e5cfa 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1191,7 +1191,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
 	if ((pm_iir & dev_priv->pm_rps_events) == 0 && !client_boost)
 		goto out;
 
-	mutex_lock(&dev_priv->pcu_lock);
+	mutex_lock(&rps->lock);
 
 	pm_iir |= vlv_wa_c0_ei(dev_priv, pm_iir);
 
@@ -1245,7 +1245,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
 		rps->last_adj = 0;
 	}
 
-	mutex_unlock(&dev_priv->pcu_lock);
+	mutex_unlock(&rps->lock);
 
 out:
 	/* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 0475a13d751b..4ed1af6f8920 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -262,7 +262,6 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev,
 
 	intel_runtime_pm_get(dev_priv);
 
-	mutex_lock(&dev_priv->pcu_lock);
 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
 		vlv_punit_get(dev_priv);
 		freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
@@ -272,7 +271,6 @@ static ssize_t gt_act_freq_mhz_show(struct device *kdev,
 	} else {
 		freq = intel_get_cagf(dev_priv, I915_READ(GEN6_RPSTAT1));
 	}
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_runtime_pm_put(dev_priv);
 
@@ -304,6 +302,7 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
 {
 	struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
+	bool boost = false;
 	u32 val;
 	ssize_t ret;
 
@@ -316,9 +315,14 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
 	if (val < rps->min_freq || val > rps->max_freq)
 		return -EINVAL;
 
-	mutex_lock(&dev_priv->pcu_lock);
-	rps->boost_freq = val;
-	mutex_unlock(&dev_priv->pcu_lock);
+	mutex_lock(&rps->lock);
+	if (val != rps->boost_freq) {
+		rps->boost_freq = val;
+		boost = atomic_read(&rps->num_waiters);
+	}
+	mutex_unlock(&rps->lock);
+	if (boost)
+		schedule_work(&rps->work);
 
 	return count;
 }
@@ -356,17 +360,14 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
 		return ret;
 
 	intel_runtime_pm_get(dev_priv);
-
-	mutex_lock(&dev_priv->pcu_lock);
+	mutex_lock(&rps->lock);
 
 	val = intel_freq_opcode(dev_priv, val);
-
 	if (val < rps->min_freq ||
 	    val > rps->max_freq ||
 	    val < rps->min_freq_softlimit) {
-		mutex_unlock(&dev_priv->pcu_lock);
-		intel_runtime_pm_put(dev_priv);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto unlock;
 	}
 
 	if (val > rps->rp0_freq)
@@ -384,8 +385,8 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
 	 * frequency request may be unchanged. */
 	ret = intel_set_rps(dev_priv, val);
 
-	mutex_unlock(&dev_priv->pcu_lock);
-
+unlock:
+	mutex_unlock(&rps->lock);
 	intel_runtime_pm_put(dev_priv);
 
 	return ret ?: count;
@@ -414,17 +415,14 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
 		return ret;
 
 	intel_runtime_pm_get(dev_priv);
-
-	mutex_lock(&dev_priv->pcu_lock);
+	mutex_lock(&rps->lock);
 
 	val = intel_freq_opcode(dev_priv, val);
-
 	if (val < rps->min_freq ||
 	    val > rps->max_freq ||
 	    val > rps->max_freq_softlimit) {
-		mutex_unlock(&dev_priv->pcu_lock);
-		intel_runtime_pm_put(dev_priv);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto unlock;
 	}
 
 	rps->min_freq_softlimit = val;
@@ -438,8 +436,8 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
 	 * frequency request may be unchanged. */
 	ret = intel_set_rps(dev_priv, val);
 
-	mutex_unlock(&dev_priv->pcu_lock);
-
+unlock:
+	mutex_unlock(&rps->lock);
 	intel_runtime_pm_put(dev_priv);
 
 	return ret ?: count;
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index fd6aa8da373f..f471b3d2c0eb 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -461,7 +461,6 @@ static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
 {
 	u32 val;
 
-	mutex_lock(&dev_priv->pcu_lock);
 	vlv_iosf_sb_get(dev_priv,
 			BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
 
@@ -474,7 +473,6 @@ static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
 
 	vlv_iosf_sb_put(dev_priv,
 			BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (IS_VALLEYVIEW(dev_priv))
 		cdclk_state->voltage_level = (val & DSPFREQGUAR_MASK) >>
@@ -551,7 +549,6 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 			BIT(VLV_IOSF_SB_BUNIT) |
 			BIT(VLV_IOSF_SB_PUNIT));
 
-	mutex_lock(&dev_priv->pcu_lock);
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
 	val &= ~DSPFREQGUAR_MASK;
 	val |= (cmd << DSPFREQGUAR_SHIFT);
@@ -561,7 +558,6 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
 		     50)) {
 		DRM_ERROR("timed out waiting for CDclk change\n");
 	}
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (cdclk == 400000) {
 		u32 divider;
@@ -632,7 +628,6 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 	 */
 	intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
 
-	mutex_lock(&dev_priv->pcu_lock);
 	vlv_punit_get(dev_priv);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
@@ -646,7 +641,6 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
 	}
 
 	vlv_punit_put(dev_priv);
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_update_cdclk(dev_priv);
 
@@ -724,10 +718,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 		 "trying to change cdclk frequency with cdclk not enabled\n"))
 		return;
 
-	mutex_lock(&dev_priv->pcu_lock);
 	ret = sandybridge_pcode_write(dev_priv,
 				      BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
-	mutex_unlock(&dev_priv->pcu_lock);
 	if (ret) {
 		DRM_ERROR("failed to inform pcode about cdclk change\n");
 		return;
@@ -776,10 +768,8 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
 			LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
 		DRM_ERROR("Switching back to LCPLL failed\n");
 
-	mutex_lock(&dev_priv->pcu_lock);
 	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
 				cdclk_state->voltage_level);
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
 
@@ -1007,12 +997,10 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 	u32 freq_select, cdclk_ctl;
 	int ret;
 
-	mutex_lock(&dev_priv->pcu_lock);
 	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
 				SKL_CDCLK_PREPARE_FOR_CHANGE,
 				SKL_CDCLK_READY_FOR_CHANGE,
 				SKL_CDCLK_READY_FOR_CHANGE, 3);
-	mutex_unlock(&dev_priv->pcu_lock);
 	if (ret) {
 		DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
 			  ret);
@@ -1076,10 +1064,8 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
 	POSTING_READ(CDCLK_CTL);
 
 	/* inform PCU of the change */
-	mutex_lock(&dev_priv->pcu_lock);
 	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
 				cdclk_state->voltage_level);
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_update_cdclk(dev_priv);
 }
@@ -1387,11 +1373,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 	}
 
 	/* Inform power controller of upcoming frequency change */
-	mutex_lock(&dev_priv->pcu_lock);
 	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
 				      0x80000000);
-	mutex_unlock(&dev_priv->pcu_lock);
-
 	if (ret) {
 		DRM_ERROR("PCode CDCLK freq change notify failed (err %d, freq %d)\n",
 			  ret, cdclk);
@@ -1419,11 +1402,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
 	I915_WRITE(CDCLK_CTL, val);
 
-	mutex_lock(&dev_priv->pcu_lock);
 	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
 				      cdclk_state->voltage_level);
-	mutex_unlock(&dev_priv->pcu_lock);
-
 	if (ret) {
 		DRM_ERROR("PCode CDCLK freq set failed, (err %d, freq %d)\n",
 			  ret, cdclk);
@@ -1661,12 +1641,10 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 	u32 val, divider;
 	int ret;
 
-	mutex_lock(&dev_priv->pcu_lock);
 	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
 				SKL_CDCLK_PREPARE_FOR_CHANGE,
 				SKL_CDCLK_READY_FOR_CHANGE,
 				SKL_CDCLK_READY_FOR_CHANGE, 3);
-	mutex_unlock(&dev_priv->pcu_lock);
 	if (ret) {
 		DRM_ERROR("Failed to inform PCU about cdclk change (%d)\n",
 			  ret);
@@ -1703,10 +1681,8 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv,
 	I915_WRITE(CDCLK_CTL, val);
 
 	/* inform PCU of the change */
-	mutex_lock(&dev_priv->pcu_lock);
 	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
 				cdclk_state->voltage_level);
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	intel_update_cdclk(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 9e082c6e9364..bd9f7fcec20a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4858,10 +4858,8 @@ void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
 	WARN_ON(!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
 
 	if (IS_BROADWELL(dev_priv)) {
-		mutex_lock(&dev_priv->pcu_lock);
 		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL,
 						IPS_ENABLE | IPS_PCODE_CONTROL));
-		mutex_unlock(&dev_priv->pcu_lock);
 		/* Quoting Art Runyan: "its not safe to expect any particular
 		 * value in IPS_CTL bit 31 after enabling IPS through the
 		 * mailbox." Moreover, the mailbox may return a bogus state,
@@ -4891,9 +4889,7 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
 		return;
 
 	if (IS_BROADWELL(dev_priv)) {
-		mutex_lock(&dev_priv->pcu_lock);
 		WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
-		mutex_unlock(&dev_priv->pcu_lock);
 		/* wait for pcode to finish disabling IPS, which may take up to 42ms */
 		if (intel_wait_for_register(dev_priv,
 					    IPS_CTL, IPS_ENABLE, 0,
@@ -8733,11 +8729,9 @@ static uint32_t hsw_read_dcomp(struct drm_i915_private *dev_priv)
 static void hsw_write_dcomp(struct drm_i915_private *dev_priv, uint32_t val)
 {
 	if (IS_HASWELL(dev_priv)) {
-		mutex_lock(&dev_priv->pcu_lock);
 		if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP,
 					    val))
 			DRM_DEBUG_KMS("Failed to write to D_COMP\n");
-		mutex_unlock(&dev_priv->pcu_lock);
 	} else {
 		I915_WRITE(D_COMP_BDW, val);
 		POSTING_READ(D_COMP_BDW);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 827cab22f191..d0e97172b8ed 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -50,9 +50,7 @@ static int intel_hdcp_load_keys(struct drm_i915_private *dev_priv)
 	u32 val;
 
 	/* Initiate loading the HDCP key from fuses */
-	mutex_lock(&dev_priv->pcu_lock);
 	ret = sandybridge_pcode_write(dev_priv, SKL_PCODE_LOAD_HDCP_KEYS, 1);
-	mutex_unlock(&dev_priv->pcu_lock);
 	if (ret) {
 		DRM_ERROR("Failed to initiate HDCP key load (%d)\n", ret);
 		return ret;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d88ceea031de..5af07ba96b30 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -310,7 +310,6 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable)
 {
 	u32 val;
 
-	mutex_lock(&dev_priv->pcu_lock);
 	vlv_punit_get(dev_priv);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
@@ -327,14 +326,12 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable)
 		DRM_ERROR("timed out waiting for Punit DDR DVFS request\n");
 
 	vlv_punit_put(dev_priv);
-	mutex_unlock(&dev_priv->pcu_lock);
 }
 
 static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable)
 {
 	u32 val;
 
-	mutex_lock(&dev_priv->pcu_lock);
 	vlv_punit_get(dev_priv);
 
 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
@@ -345,7 +342,6 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable)
 	vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val);
 
 	vlv_punit_put(dev_priv);
-	mutex_unlock(&dev_priv->pcu_lock);
 }
 
 #define FW_WM(value, plane) \
@@ -2809,11 +2805,9 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
 
 		/* read the first set of memory latencies[0:3] */
 		val = 0; /* data0 to be programmed to 0 for first set */
-		mutex_lock(&dev_priv->pcu_lock);
 		ret = sandybridge_pcode_read(dev_priv,
 					     GEN9_PCODE_READ_MEM_LATENCY,
 					     &val);
-		mutex_unlock(&dev_priv->pcu_lock);
 
 		if (ret) {
 			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
@@ -2830,11 +2824,9 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
 
 		/* read the second set of memory latencies[4:7] */
 		val = 1; /* data0 to be programmed to 1 for second set */
-		mutex_lock(&dev_priv->pcu_lock);
 		ret = sandybridge_pcode_read(dev_priv,
 					     GEN9_PCODE_READ_MEM_LATENCY,
 					     &val);
-		mutex_unlock(&dev_priv->pcu_lock);
 		if (ret) {
 			DRM_ERROR("SKL Mailbox read error = %d\n", ret);
 			return;
@@ -3625,13 +3617,10 @@ intel_enable_sagv(struct drm_i915_private *dev_priv)
 		return 0;
 
 	DRM_DEBUG_KMS("Enabling the SAGV\n");
-	mutex_lock(&dev_priv->pcu_lock);
-
 	ret = sandybridge_pcode_write(dev_priv, GEN9_PCODE_SAGV_CONTROL,
 				      GEN9_SAGV_ENABLE);
 
 	/* We don't need to wait for the SAGV when enabling */
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	/*
 	 * Some skl systems, pre-release machines in particular,
@@ -3662,15 +3651,11 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
 		return 0;
 
 	DRM_DEBUG_KMS("Disabling the SAGV\n");
-	mutex_lock(&dev_priv->pcu_lock);
-
 	/* bspec says to keep retrying for at least 1 ms */
 	ret = skl_pcode_request(dev_priv, GEN9_PCODE_SAGV_CONTROL,
 				GEN9_SAGV_DISABLE,
 				GEN9_SAGV_IS_DISABLED, GEN9_SAGV_IS_DISABLED,
 				1);
-	mutex_unlock(&dev_priv->pcu_lock);
-
 	/*
 	 * Some skl systems, pre-release machines in particular,
 	 * don't actually have an SAGV.
@@ -5639,7 +5624,6 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
 	wm->level = VLV_WM_LEVEL_PM2;
 
 	if (IS_CHERRYVIEW(dev_priv)) {
-		mutex_lock(&dev_priv->pcu_lock);
 		vlv_punit_get(dev_priv);
 
 		val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ);
@@ -5671,7 +5655,6 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
 		}
 
 		vlv_punit_put(dev_priv);
-		mutex_unlock(&dev_priv->pcu_lock);
 	}
 
 	for_each_intel_crtc(dev, crtc) {
@@ -6278,7 +6261,7 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv)
 {
 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
 
-	mutex_lock(&dev_priv->pcu_lock);
+	mutex_lock(&rps->lock);
 	if (rps->enabled) {
 		u8 freq;
 
@@ -6301,7 +6284,7 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv)
 					rps->max_freq_softlimit)))
 			DRM_DEBUG_DRIVER("Failed to set idle frequency\n");
 	}
-	mutex_unlock(&dev_priv->pcu_lock);
+	mutex_unlock(&rps->lock);
 }
 
 void gen6_rps_idle(struct drm_i915_private *dev_priv)
@@ -6315,7 +6298,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
 	 */
 	gen6_disable_rps_interrupts(dev_priv);
 
-	mutex_lock(&dev_priv->pcu_lock);
+	mutex_lock(&rps->lock);
 	if (rps->enabled) {
 		if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
 			vlv_set_rps_idle(dev_priv);
@@ -6325,7 +6308,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
 		I915_WRITE(GEN6_PMINTRMSK,
 			   gen6_sanitize_rps_pm_mask(dev_priv, ~0));
 	}
-	mutex_unlock(&dev_priv->pcu_lock);
+	mutex_unlock(&rps->lock);
 }
 
 void gen6_rps_boost(struct drm_i915_gem_request *rq,
@@ -6363,7 +6346,7 @@ int intel_set_rps(struct drm_i915_private *dev_priv, u8 val)
 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
 	int err;
 
-	lockdep_assert_held(&dev_priv->pcu_lock);
+	lockdep_assert_held(&rps->lock);
 	GEM_BUG_ON(val > rps->max_freq);
 	GEM_BUG_ON(val < rps->min_freq);
 
@@ -6842,7 +6825,7 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
 	int scaling_factor = 180;
 	struct cpufreq_policy *policy;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
+	lockdep_assert_held(&rps->lock);
 
 	policy = cpufreq_cpu_get(0);
 	if (policy) {
@@ -7919,7 +7902,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 		intel_runtime_pm_get(dev_priv);
 	}
 
-	mutex_lock(&dev_priv->pcu_lock);
+	mutex_lock(&rps->lock);
 
 	/* Initialize RPS limits (for userspace) */
 	if (IS_CHERRYVIEW(dev_priv))
@@ -7959,7 +7942,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
 	/* Finally allow us to boost to max by default */
 	rps->boost_freq = rps->max_freq;
 
-	mutex_unlock(&dev_priv->pcu_lock);
+	mutex_unlock(&rps->lock);
 }
 
 void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
@@ -7998,7 +7981,7 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
 
 static inline void intel_disable_llc_pstate(struct drm_i915_private *i915)
 {
-	lockdep_assert_held(&i915->pcu_lock);
+	lockdep_assert_held(&i915->gt_pm.rps.lock);
 
 	if (!i915->gt_pm.llc_pstate.enabled)
 		return;
@@ -8010,7 +7993,7 @@ static inline void intel_disable_llc_pstate(struct drm_i915_private *i915)
 
 static void intel_disable_rc6(struct drm_i915_private *dev_priv)
 {
-	lockdep_assert_held(&dev_priv->pcu_lock);
+	lockdep_assert_held(&dev_priv->gt_pm.rps.lock);
 
 	if (!dev_priv->gt_pm.rc6.enabled)
 		return;
@@ -8029,7 +8012,7 @@ static void intel_disable_rc6(struct drm_i915_private *dev_priv)
 
 static void intel_disable_rps(struct drm_i915_private *dev_priv)
 {
-	lockdep_assert_held(&dev_priv->pcu_lock);
+	lockdep_assert_held(&dev_priv->gt_pm.rps.lock);
 
 	if (!dev_priv->gt_pm.rps.enabled)
 		return;
@@ -8050,19 +8033,19 @@ static void intel_disable_rps(struct drm_i915_private *dev_priv)
 
 void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
 {
-	mutex_lock(&dev_priv->pcu_lock);
+	mutex_lock(&dev_priv->gt_pm.rps.lock);
 
 	intel_disable_rc6(dev_priv);
 	intel_disable_rps(dev_priv);
 	if (HAS_LLC(dev_priv))
 		intel_disable_llc_pstate(dev_priv);
 
-	mutex_unlock(&dev_priv->pcu_lock);
+	mutex_unlock(&dev_priv->gt_pm.rps.lock);
 }
 
 static inline void intel_enable_llc_pstate(struct drm_i915_private *i915)
 {
-	lockdep_assert_held(&i915->pcu_lock);
+	lockdep_assert_held(&i915->gt_pm.rps.lock);
 
 	if (i915->gt_pm.llc_pstate.enabled)
 		return;
@@ -8074,7 +8057,7 @@ static inline void intel_enable_llc_pstate(struct drm_i915_private *i915)
 
 static void intel_enable_rc6(struct drm_i915_private *dev_priv)
 {
-	lockdep_assert_held(&dev_priv->pcu_lock);
+	lockdep_assert_held(&dev_priv->gt_pm.rps.lock);
 
 	if (dev_priv->gt_pm.rc6.enabled)
 		return;
@@ -8097,7 +8080,7 @@ static void intel_enable_rps(struct drm_i915_private *dev_priv)
 {
 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
 
-	lockdep_assert_held(&dev_priv->pcu_lock);
+	lockdep_assert_held(&rps->lock);
 
 	if (rps->enabled)
 		return;
@@ -8132,7 +8115,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 	if (intel_vgpu_active(dev_priv))
 		return;
 
-	mutex_lock(&dev_priv->pcu_lock);
+	mutex_lock(&dev_priv->gt_pm.rps.lock);
 
 	if (HAS_RC6(dev_priv))
 		intel_enable_rc6(dev_priv);
@@ -8140,7 +8123,7 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
 	if (HAS_LLC(dev_priv))
 		intel_enable_llc_pstate(dev_priv);
 
-	mutex_unlock(&dev_priv->pcu_lock);
+	mutex_unlock(&dev_priv->gt_pm.rps.lock);
 }
 
 static void ibx_init_clock_gating(struct drm_i915_private *dev_priv)
@@ -9139,22 +9122,19 @@ static inline int gen7_check_mailbox_status(struct drm_i915_private *dev_priv)
 	}
 }
 
-int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val)
+static int __sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val)
 {
 	int status;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
+	lockdep_assert_held(&dev_priv->sb_lock);
 
 	/* GEN6_PCODE_* are outside of the forcewake domain, we can
 	 * use te fw I915_READ variants to reduce the amount of work
 	 * required when reading/writing.
 	 */
 
-	if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
-		DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps\n",
-				 mbox, __builtin_return_address(0));
+	if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
 		return -EAGAIN;
-	}
 
 	I915_WRITE_FW(GEN6_PCODE_DATA, *val);
 	I915_WRITE_FW(GEN6_PCODE_DATA1, 0);
@@ -9162,11 +9142,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
 
 	if (__intel_wait_for_register_fw(dev_priv,
 					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
-					 500, 0, NULL)) {
-		DRM_ERROR("timeout waiting for pcode read (from mbox %x) to finish for %ps\n",
-			  mbox, __builtin_return_address(0));
+					 500, 0, NULL))
 		return -ETIMEDOUT;
-	}
 
 	*val = I915_READ_FW(GEN6_PCODE_DATA);
 	I915_WRITE_FW(GEN6_PCODE_DATA, 0);
@@ -9176,32 +9153,37 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
 	else
 		status = gen6_check_mailbox_status(dev_priv);
 
+	return status;
+}
+
+int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val)
+{
+	int status;
+
+	mutex_lock(&dev_priv->sb_lock);
+	status = __sandybridge_pcode_read(dev_priv, mbox, val);
+	mutex_unlock(&dev_priv->sb_lock);
+
 	if (status) {
 		DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n",
 				 mbox, __builtin_return_address(0), status);
-		return status;
 	}
 
-	return 0;
+	return status;
 }
 
-int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
-			    u32 mbox, u32 val)
+static int __sandybridge_pcode_write(struct drm_i915_private *dev_priv,
+				     u32 mbox, u32 val)
 {
 	int status;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
-
 	/* GEN6_PCODE_* are outside of the forcewake domain, we can
 	 * use te fw I915_READ variants to reduce the amount of work
 	 * required when reading/writing.
 	 */
 
-	if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) {
-		DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps\n",
-				 val, mbox, __builtin_return_address(0));
+	if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
 		return -EAGAIN;
-	}
 
 	I915_WRITE_FW(GEN6_PCODE_DATA, val);
 	I915_WRITE_FW(GEN6_PCODE_DATA1, 0);
@@ -9209,11 +9191,8 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
 
 	if (__intel_wait_for_register_fw(dev_priv,
 					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
-					 500, 0, NULL)) {
-		DRM_ERROR("timeout waiting for pcode write of 0x%08x to mbox %x to finish for %ps\n",
-			  val, mbox, __builtin_return_address(0));
+					 500, 0, NULL))
 		return -ETIMEDOUT;
-	}
 
 	I915_WRITE_FW(GEN6_PCODE_DATA, 0);
 
@@ -9222,13 +9201,24 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
 	else
 		status = gen6_check_mailbox_status(dev_priv);
 
+	return status;
+}
+
+int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
+			    u32 mbox, u32 val)
+{
+	int status;
+
+	mutex_lock(&dev_priv->sb_lock);
+	status = __sandybridge_pcode_write(dev_priv, mbox, val);
+	mutex_unlock(&dev_priv->sb_lock);
+
 	if (status) {
 		DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n",
 				 val, mbox, __builtin_return_address(0), status);
-		return status;
 	}
 
-	return 0;
+	return status;
 }
 
 static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
@@ -9237,7 +9227,7 @@ static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
 {
 	u32 val = request;
 
-	*status = sandybridge_pcode_read(dev_priv, mbox, &val);
+	*status = __sandybridge_pcode_read(dev_priv, mbox, &val);
 
 	return *status || ((val & reply_mask) == reply);
 }
@@ -9267,7 +9257,7 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 	u32 status;
 	int ret;
 
-	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
+	mutex_lock(&dev_priv->sb_lock);
 
 #define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \
 				   &status)
@@ -9303,6 +9293,7 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 	preempt_enable();
 
 out:
+	mutex_unlock(&dev_priv->sb_lock);
 	return ret ? ret : status;
 #undef COND
 }
@@ -9372,8 +9363,7 @@ int intel_freq_opcode(struct drm_i915_private *dev_priv, int val)
 
 void intel_pm_setup(struct drm_i915_private *dev_priv)
 {
-	mutex_init(&dev_priv->pcu_lock);
-
+	mutex_init(&dev_priv->gt_pm.rps.lock);
 	atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0);
 
 	dev_priv->runtime_pm.suspended = false;
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index d41972087cb7..5faa938ab052 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -798,7 +798,6 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv,
 	state = enable ? PUNIT_PWRGT_PWR_ON(power_well_id) :
 			 PUNIT_PWRGT_PWR_GATE(power_well_id);
 
-	mutex_lock(&dev_priv->pcu_lock);
 	vlv_punit_get(dev_priv);
 
 #define COND \
@@ -821,7 +820,6 @@ static void vlv_set_power_well(struct drm_i915_private *dev_priv,
 
 out:
 	vlv_punit_put(dev_priv);
-	mutex_unlock(&dev_priv->pcu_lock);
 }
 
 static void vlv_power_well_enable(struct drm_i915_private *dev_priv,
@@ -848,7 +846,6 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
 	mask = PUNIT_PWRGT_MASK(power_well_id);
 	ctrl = PUNIT_PWRGT_PWR_ON(power_well_id);
 
-	mutex_lock(&dev_priv->pcu_lock);
 	vlv_punit_get(dev_priv);
 
 	state = vlv_punit_read(dev_priv, PUNIT_REG_PWRGT_STATUS) & mask;
@@ -869,7 +866,6 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
 	WARN_ON(ctrl != state);
 
 	vlv_punit_put(dev_priv);
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	return enabled;
 }
@@ -1381,7 +1377,6 @@ static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv,
 	bool enabled;
 	u32 state, ctrl;
 
-	mutex_lock(&dev_priv->pcu_lock);
 	vlv_punit_get(dev_priv);
 
 	state = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & DP_SSS_MASK(pipe);
@@ -1400,7 +1395,6 @@ static bool chv_pipe_power_well_enabled(struct drm_i915_private *dev_priv,
 	WARN_ON(ctrl << 16 != state);
 
 	vlv_punit_put(dev_priv);
-	mutex_unlock(&dev_priv->pcu_lock);
 
 	return enabled;
 }
@@ -1415,7 +1409,6 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv,
 
 	state = enable ? DP_SSS_PWR_ON(pipe) : DP_SSS_PWR_GATE(pipe);
 
-	mutex_lock(&dev_priv->pcu_lock);
 	vlv_punit_get(dev_priv);
 
 #define COND \
@@ -1438,7 +1431,6 @@ static void chv_set_pipe_power_well(struct drm_i915_private *dev_priv,
 
 out:
 	vlv_punit_put(dev_priv);
-	mutex_unlock(&dev_priv->pcu_lock);
 }
 
 static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index dc3b491b4d00..2d4e48e9e1d5 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -142,8 +142,6 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
 {
 	u32 val = 0;
 
-	lockdep_assert_held(&dev_priv->pcu_lock);
-
 	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
 			SB_CRRDDA_NP, addr, &val);
 
@@ -152,8 +150,6 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
 
 int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
 {
-	lockdep_assert_held(&dev_priv->pcu_lock);
-
 	return vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
 			       SB_CRWRDA_NP, addr, &val);
 }
-- 
2.15.1

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

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

* [PATCH v2 07/11] drm/i915: Separate sideband declarations to intel_sideband.h
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (5 preceding siblings ...)
  2018-01-15  8:47 ` [PATCH v2 06/11] drm/i915: Replace pcu_lock with sb_lock Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 08/11] drm/i915: Merge sbi read/write into a single accessor Chris Wilson
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

Split the sideback declarations out of the ginormous i915_drv.h

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c     |  2 +
 drivers/gpu/drm/i915/i915_drv.h         | 62 ----------------------------
 drivers/gpu/drm/i915/i915_sysfs.c       |  2 +
 drivers/gpu/drm/i915/intel_cdclk.c      |  1 +
 drivers/gpu/drm/i915/intel_display.c    | 19 +++++----
 drivers/gpu/drm/i915/intel_dp.c         |  6 ++-
 drivers/gpu/drm/i915/intel_dpio_phy.c   |  1 +
 drivers/gpu/drm/i915/intel_dsi.c        |  7 +++-
 drivers/gpu/drm/i915/intel_dsi_pll.c    |  4 +-
 drivers/gpu/drm/i915/intel_dsi_vbt.c    | 11 +++--
 drivers/gpu/drm/i915/intel_hdmi.c       |  5 ++-
 drivers/gpu/drm/i915/intel_pm.c         |  7 +++-
 drivers/gpu/drm/i915/intel_runtime_pm.c |  1 +
 drivers/gpu/drm/i915/intel_sideband.c   |  2 +
 drivers/gpu/drm/i915/intel_sideband.h   | 71 +++++++++++++++++++++++++++++++++
 15 files changed, 121 insertions(+), 80 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_sideband.h

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 044f74726a6f..921fc969491e 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -29,8 +29,10 @@
 #include <linux/debugfs.h>
 #include <linux/sort.h>
 #include <linux/sched/mm.h>
+
 #include "intel_drv.h"
 #include "intel_guc_submission.h"
+#include "intel_sideband.h"
 
 static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
 {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6e4e30397997..4d9e9741ed8f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -785,11 +785,6 @@ enum intel_pch {
 	PCH_NOP,
 };
 
-enum intel_sbi_destination {
-	SBI_ICLK,
-	SBI_MPHY,
-};
-
 #define QUIRK_LVDS_SSC_DISABLE (1<<1)
 #define QUIRK_INVERT_BRIGHTNESS (1<<2)
 #define QUIRK_BACKLIGHT_PRESENT (1<<3)
@@ -3716,63 +3711,6 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val
 int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 		      u32 reply_mask, u32 reply, int timeout_base_ms);
 
-/* intel_sideband.c */
-
-enum {
-	VLV_IOSF_SB_BUNIT,
-	VLV_IOSF_SB_CCK,
-	VLV_IOSF_SB_CCU,
-	VLV_IOSF_SB_DPIO,
-	VLV_IOSF_SB_FLISDSI,
-	VLV_IOSF_SB_GPIO,
-	VLV_IOSF_SB_NC,
-	VLV_IOSF_SB_PUNIT,
-};
-
-void vlv_iosf_sb_get(struct drm_i915_private *dev_priv, unsigned long ports);
-u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg);
-void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, u8 port, u32 reg, u32 val);
-void vlv_iosf_sb_put(struct drm_i915_private *dev_priv, unsigned long ports);
-
-void vlv_punit_get(struct drm_i915_private *dev_priv);
-u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
-int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val);
-void vlv_punit_put(struct drm_i915_private *dev_priv);
-
-void vlv_nc_get(struct drm_i915_private *dev_priv);
-u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
-void vlv_nc_put(struct drm_i915_private *dev_priv);
-
-void vlv_cck_get(struct drm_i915_private *dev_priv);
-u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
-void vlv_cck_put(struct drm_i915_private *dev_priv);
-
-void vlv_ccu_get(struct drm_i915_private *dev_priv);
-u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
-void vlv_ccu_put(struct drm_i915_private *dev_priv);
-
-void vlv_bunit_get(struct drm_i915_private *dev_priv);
-u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
-void vlv_bunit_put(struct drm_i915_private *dev_priv);
-
-void vlv_dpio_get(struct drm_i915_private *dev_priv);
-u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg);
-void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val);
-void vlv_dpio_put(struct drm_i915_private *dev_priv);
-
-void vlv_flisdsi_get(struct drm_i915_private *dev_priv);
-u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
-void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
-void vlv_flisdsi_put(struct drm_i915_private *dev_priv);
-
-u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
-		   enum intel_sbi_destination destination);
-void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
-		     enum intel_sbi_destination destination);
-
 /* intel_dpio_phy.c */
 void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
 			     enum dpio_phy *phy, enum dpio_channel *ch);
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c
index 4ed1af6f8920..290e2a29fb89 100644
--- a/drivers/gpu/drm/i915/i915_sysfs.c
+++ b/drivers/gpu/drm/i915/i915_sysfs.c
@@ -29,7 +29,9 @@
 #include <linux/module.h>
 #include <linux/stat.h>
 #include <linux/sysfs.h>
+
 #include "intel_drv.h"
+#include "intel_sideband.h"
 #include "i915_drv.h"
 
 static inline struct drm_i915_private *kdev_minor_to_i915(struct device *kdev)
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index f471b3d2c0eb..afb8ffbb7258 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -22,6 +22,7 @@
  */
 
 #include "intel_drv.h"
+#include "intel_sideband.h"
 
 /**
  * DOC: CDCLK / RAWCLK
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bd9f7fcec20a..89a927a3a506 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -31,23 +31,26 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/vgaarb.h>
+#include <linux/dma_remapping.h>
+#include <linux/reservation.h>
+
 #include <drm/drm_edid.h>
 #include <drm/drmP.h>
-#include "intel_drv.h"
-#include "intel_frontbuffer.h"
 #include <drm/i915_drm.h>
-#include "i915_drv.h"
-#include "i915_gem_clflush.h"
-#include "intel_dsi.h"
-#include "i915_trace.h"
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_plane_helper.h>
 #include <drm/drm_rect.h>
-#include <linux/dma_remapping.h>
-#include <linux/reservation.h>
+
+#include "i915_drv.h"
+#include "i915_gem_clflush.h"
+#include "i915_trace.h"
+#include "intel_dsi.h"
+#include "intel_drv.h"
+#include "intel_frontbuffer.h"
+#include "intel_sideband.h"
 
 /* Primary plane formats for gen <= 3 */
 static const uint32_t i8xx_primary_formats[] = {
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 168f2c0de1b6..9c92a7fd620c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -31,7 +31,9 @@
 #include <linux/types.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
+
 #include <asm/byteorder.h>
+
 #include <drm/drmP.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
@@ -39,9 +41,11 @@
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_hdcp.h>
-#include "intel_drv.h"
 #include <drm/i915_drm.h>
+
 #include "i915_drv.h"
+#include "intel_drv.h"
+#include "intel_sideband.h"
 
 #define DP_LINK_CHECK_TIMEOUT	(10 * 1000)
 #define DP_DPRX_ESI_LEN 14
diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c
index 662d71cd501f..a4c4bcba3679 100644
--- a/drivers/gpu/drm/i915/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/intel_dpio_phy.c
@@ -22,6 +22,7 @@
  */
 
 #include "intel_drv.h"
+#include "intel_sideband.h"
 
 /**
  * DOC: DPIO
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index 0b503b6971ff..2740056018c3 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -23,17 +23,20 @@
  * Author: Jani Nikula <jani.nikula@intel.com>
  */
 
+#include <linux/slab.h>
+#include <linux/gpio/consumer.h>
+
 #include <drm/drmP.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include <drm/i915_drm.h>
 #include <drm/drm_mipi_dsi.h>
-#include <linux/slab.h>
-#include <linux/gpio/consumer.h>
+
 #include "i915_drv.h"
 #include "intel_drv.h"
 #include "intel_dsi.h"
+#include "intel_sideband.h"
 
 /* return pixels in terms of txbyteclkhs */
 static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count,
diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
index b73336e7dcd2..ebb3dba75d06 100644
--- a/drivers/gpu/drm/i915/intel_dsi_pll.c
+++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
@@ -26,9 +26,11 @@
  */
 
 #include <linux/kernel.h>
-#include "intel_drv.h"
+
 #include "i915_drv.h"
+#include "intel_drv.h"
 #include "intel_dsi.h"
+#include "intel_sideband.h"
 
 static const u16 lfsr_converts[] = {
 	426, 469, 234, 373, 442, 221, 110, 311, 411,		/* 62 - 70 */
diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c
index f1168b6e8592..752a6afecca2 100644
--- a/drivers/gpu/drm/i915/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c
@@ -24,18 +24,23 @@
  *
  */
 
+#include <linux/gpio/consumer.h>
+#include <linux/slab.h>
+
+#include <asm/intel-mid.h>
+
 #include <drm/drmP.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include <drm/i915_drm.h>
-#include <linux/gpio/consumer.h>
-#include <linux/slab.h>
+
 #include <video/mipi_display.h>
-#include <asm/intel-mid.h>
 #include <video/mipi_display.h>
+
 #include "i915_drv.h"
 #include "intel_drv.h"
 #include "intel_dsi.h"
+#include "intel_sideband.h"
 
 #define MIPI_TRANSFER_MODE_SHIFT	0
 #define MIPI_VIRTUAL_CHANNEL_SHIFT	1
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 2b5b7d4f73d7..9e34054f9746 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -30,16 +30,19 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/hdmi.h>
+
 #include <drm/drmP.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_hdcp.h>
 #include <drm/drm_scdc_helper.h>
-#include "intel_drv.h"
 #include <drm/i915_drm.h>
 #include <drm/intel_lpe_audio.h>
+
 #include "i915_drv.h"
+#include "intel_drv.h"
+#include "intel_sideband.h"
 
 static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
 {
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5af07ba96b30..7e66917a6564 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -26,12 +26,15 @@
  */
 
 #include <linux/cpufreq.h>
+#include <linux/module.h>
+
+#include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
+
 #include "i915_drv.h"
 #include "intel_drv.h"
+#include "intel_sideband.h"
 #include "../../../platform/x86/intel_ips.h"
-#include <linux/module.h>
-#include <drm/drm_atomic_helper.h>
 
 /**
  * DOC: RC6
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 5faa938ab052..6012fdbe3ea7 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -31,6 +31,7 @@
 
 #include "i915_drv.h"
 #include "intel_drv.h"
+#include "intel_sideband.h"
 
 /**
  * DOC: runtime pm
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 2d4e48e9e1d5..87e34787939b 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -24,6 +24,8 @@
 
 #include <asm/iosf_mbi.h>
 
+#include "intel_sideband.h"
+
 #include "i915_drv.h"
 #include "intel_drv.h"
 
diff --git a/drivers/gpu/drm/i915/intel_sideband.h b/drivers/gpu/drm/i915/intel_sideband.h
new file mode 100644
index 000000000000..46e917dd3973
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_sideband.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: MIT */
+
+#ifndef _INTEL_SIDEBAND_H_
+#define _INTEL_SIDEBAND_H_
+
+#include <linux/types.h>
+
+struct drm_i915_private;
+enum pipe;
+
+enum {
+	VLV_IOSF_SB_BUNIT,
+	VLV_IOSF_SB_CCK,
+	VLV_IOSF_SB_CCU,
+	VLV_IOSF_SB_DPIO,
+	VLV_IOSF_SB_FLISDSI,
+	VLV_IOSF_SB_GPIO,
+	VLV_IOSF_SB_NC,
+	VLV_IOSF_SB_PUNIT,
+};
+
+void vlv_iosf_sb_get(struct drm_i915_private *dev_priv, unsigned long ports);
+u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg);
+void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, u8 port, u32 reg, u32 val);
+void vlv_iosf_sb_put(struct drm_i915_private *dev_priv, unsigned long ports);
+
+void vlv_punit_get(struct drm_i915_private *dev_priv);
+u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
+int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val);
+void vlv_punit_put(struct drm_i915_private *dev_priv);
+
+void vlv_nc_get(struct drm_i915_private *dev_priv);
+u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
+void vlv_nc_put(struct drm_i915_private *dev_priv);
+
+void vlv_cck_get(struct drm_i915_private *dev_priv);
+u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+void vlv_cck_put(struct drm_i915_private *dev_priv);
+
+void vlv_ccu_get(struct drm_i915_private *dev_priv);
+u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+void vlv_ccu_put(struct drm_i915_private *dev_priv);
+
+void vlv_bunit_get(struct drm_i915_private *dev_priv);
+u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+void vlv_bunit_put(struct drm_i915_private *dev_priv);
+
+void vlv_dpio_get(struct drm_i915_private *dev_priv);
+u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg);
+void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val);
+void vlv_dpio_put(struct drm_i915_private *dev_priv);
+
+void vlv_flisdsi_get(struct drm_i915_private *dev_priv);
+u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
+void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+void vlv_flisdsi_put(struct drm_i915_private *dev_priv);
+
+enum intel_sbi_destination {
+	SBI_ICLK,
+	SBI_MPHY,
+};
+
+u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
+		   enum intel_sbi_destination destination);
+void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
+		     enum intel_sbi_destination destination);
+
+#endif /* _INTEL_SIDEBAND_H */
-- 
2.15.1

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

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

* [PATCH v2 08/11] drm/i915: Merge sbi read/write into a single accessor
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (6 preceding siblings ...)
  2018-01-15  8:47 ` [PATCH v2 07/11] drm/i915: Separate sideband declarations to intel_sideband.h Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 09/11] drm/i915: Merge sandybride_pcode_(read|write) Chris Wilson
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

Since intel_sideband_read and intel_sideband_write differ by only a
couple of lines (depending on whether we feed the value in or out),
merge the two into a single common accessor.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_sideband.c | 92 ++++++++++++-----------------------
 1 file changed, 32 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 87e34787939b..6815be9e5b7c 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -309,91 +309,63 @@ void vlv_dpio_put(struct drm_i915_private *dev_priv)
 }
 
 /* SBI access */
-u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
-		   enum intel_sbi_destination destination)
+static int intel_sbi_rw(struct drm_i915_private *dev_priv, u16 reg,
+			enum intel_sbi_destination destination,
+			u32 *val, bool is_read)
 {
-	u32 value = 0;
+	u32 cmd;
 
 	lockdep_assert_held(&dev_priv->sb_lock);
 
-	if (intel_wait_for_register(dev_priv,
-				    SBI_CTL_STAT, SBI_BUSY, 0,
-				    100)) {
+	if (intel_wait_for_register_fw(dev_priv,
+				       SBI_CTL_STAT, SBI_BUSY, 0,
+				       100)) {
 		DRM_ERROR("timeout waiting for SBI to become ready\n");
-		return 0;
+		return -EBUSY;
 	}
 
-	I915_WRITE(SBI_ADDR, (reg << 16));
-	I915_WRITE(SBI_DATA, 0);
+	I915_WRITE_FW(SBI_ADDR, reg << 16);
+	I915_WRITE_FW(SBI_DATA, is_read ? 0 : *val);
 
 	if (destination == SBI_ICLK)
-		value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
+		cmd = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
 	else
-		value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
-	I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
+		cmd = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
+	I915_WRITE_FW(SBI_CTL_STAT, cmd | SBI_BUSY);
+
+	if (__intel_wait_for_register_fw(dev_priv,
+					 SBI_CTL_STAT, SBI_BUSY, 0,
+					 100, 100, &cmd)) {
 
-	if (intel_wait_for_register(dev_priv,
-				    SBI_CTL_STAT,
-				    SBI_BUSY,
-				    0,
-				    100)) {
 		DRM_ERROR("timeout waiting for SBI to complete read\n");
-		return 0;
+		return -ETIMEDOUT;
 	}
 
-	if (I915_READ(SBI_CTL_STAT) & SBI_RESPONSE_FAIL) {
+	if (cmd & SBI_RESPONSE_FAIL) {
 		DRM_ERROR("error during SBI read of reg %x\n", reg);
-		return 0;
+		return -ENXIO;
 	}
 
-	return I915_READ(SBI_DATA);
+	if (is_read)
+		*val = I915_READ_FW(SBI_DATA);
+
+	return 0;
 }
 
-void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
-		     enum intel_sbi_destination destination)
+u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
+		   enum intel_sbi_destination destination)
 {
-	u32 tmp;
+	u32 result = 0;
 
-	lockdep_assert_held(&dev_priv->sb_lock);
+	intel_sbi_rw(dev_priv, reg, destination, &result, true);
 
-	if (intel_wait_for_register(dev_priv,
-				    SBI_CTL_STAT, SBI_BUSY, 0,
-				    100)) {
-		DRM_ERROR("timeout waiting for SBI to become ready\n");
-		return;
-	}
-
-	I915_WRITE(SBI_ADDR, (reg << 16));
-	I915_WRITE(SBI_DATA, value);
-
-	if (destination == SBI_ICLK)
-		tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
-	else
-		tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
-	I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
-
-	if (intel_wait_for_register(dev_priv,
-				    SBI_CTL_STAT,
-				    SBI_BUSY,
-				    0,
-				    100)) {
-		DRM_ERROR("timeout waiting for SBI to complete write\n");
-		return;
-	}
-
-	if (I915_READ(SBI_CTL_STAT) & SBI_RESPONSE_FAIL) {
-		DRM_ERROR("error during SBI write of %x to reg %x\n",
-			  value, reg);
-		return;
-	}
+	return result;
 }
 
-u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg)
+void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
+		     enum intel_sbi_destination destination)
 {
-	u32 val = 0;
-	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI, SB_CRRDDA_NP,
-			reg, &val);
-	return val;
+	intel_sbi_rw(dev_priv, reg, destination, &value, false);
 }
 
 void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
-- 
2.15.1

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

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

* [PATCH v2 09/11] drm/i915: Merge sandybride_pcode_(read|write)
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (7 preceding siblings ...)
  2018-01-15  8:47 ` [PATCH v2 08/11] drm/i915: Merge sbi read/write into a single accessor Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-15  8:47 ` [PATCH v2 10/11] drm/i915: Move sandybride pcode access to intel_sideband.c Chris Wilson
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

These routines are identical except in the nature of the value parameter.
For writes it is a pure in-param, but for a read, we need an out-param.
Since they differ in a single line, merge the two routines into one.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_pm.c | 51 ++++++++---------------------------------
 1 file changed, 10 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 7e66917a6564..18945264b835 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -9125,13 +9125,15 @@ static inline int gen7_check_mailbox_status(struct drm_i915_private *dev_priv)
 	}
 }
 
-static int __sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val)
+static int __sandybridge_pcode_rw(struct drm_i915_private *dev_priv,
+				  u32 mbox, u32 *val, bool is_read)
 {
 	int status;
 
 	lockdep_assert_held(&dev_priv->sb_lock);
 
-	/* GEN6_PCODE_* are outside of the forcewake domain, we can
+	/*
+	 * GEN6_PCODE_* are outside of the forcewake domain, we can
 	 * use te fw I915_READ variants to reduce the amount of work
 	 * required when reading/writing.
 	 */
@@ -9148,7 +9150,8 @@ static int __sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox,
 					 500, 0, NULL))
 		return -ETIMEDOUT;
 
-	*val = I915_READ_FW(GEN6_PCODE_DATA);
+	if (is_read)
+		*val = I915_READ_FW(GEN6_PCODE_DATA);
 	I915_WRITE_FW(GEN6_PCODE_DATA, 0);
 
 	if (INTEL_GEN(dev_priv) > 6)
@@ -9164,7 +9167,7 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
 	int status;
 
 	mutex_lock(&dev_priv->sb_lock);
-	status = __sandybridge_pcode_read(dev_priv, mbox, val);
+	status = __sandybridge_pcode_rw(dev_priv, mbox, val, true);
 	mutex_unlock(&dev_priv->sb_lock);
 
 	if (status) {
@@ -9175,45 +9178,13 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
 	return status;
 }
 
-static int __sandybridge_pcode_write(struct drm_i915_private *dev_priv,
-				     u32 mbox, u32 val)
-{
-	int status;
-
-	/* GEN6_PCODE_* are outside of the forcewake domain, we can
-	 * use te fw I915_READ variants to reduce the amount of work
-	 * required when reading/writing.
-	 */
-
-	if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
-		return -EAGAIN;
-
-	I915_WRITE_FW(GEN6_PCODE_DATA, val);
-	I915_WRITE_FW(GEN6_PCODE_DATA1, 0);
-	I915_WRITE_FW(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
-
-	if (__intel_wait_for_register_fw(dev_priv,
-					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
-					 500, 0, NULL))
-		return -ETIMEDOUT;
-
-	I915_WRITE_FW(GEN6_PCODE_DATA, 0);
-
-	if (INTEL_GEN(dev_priv) > 6)
-		status = gen7_check_mailbox_status(dev_priv);
-	else
-		status = gen6_check_mailbox_status(dev_priv);
-
-	return status;
-}
-
 int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
 			    u32 mbox, u32 val)
 {
 	int status;
 
 	mutex_lock(&dev_priv->sb_lock);
-	status = __sandybridge_pcode_write(dev_priv, mbox, val);
+	status = __sandybridge_pcode_rw(dev_priv, mbox, &val, false);
 	mutex_unlock(&dev_priv->sb_lock);
 
 	if (status) {
@@ -9228,11 +9199,9 @@ static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
 				  u32 request, u32 reply_mask, u32 reply,
 				  u32 *status)
 {
-	u32 val = request;
-
-	*status = __sandybridge_pcode_read(dev_priv, mbox, &val);
+	*status = __sandybridge_pcode_rw(dev_priv, mbox, &request, true);
 
-	return *status || ((val & reply_mask) == reply);
+	return *status || ((request & reply_mask) == reply);
 }
 
 /**
-- 
2.15.1

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

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

* [PATCH v2 10/11] drm/i915: Move sandybride pcode access to intel_sideband.c
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (8 preceding siblings ...)
  2018-01-15  8:47 ` [PATCH v2 09/11] drm/i915: Merge sandybride_pcode_(read|write) Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-19  8:21   ` Mika Kuoppala
  2018-01-15  8:47 ` [PATCH v2 11/11] drm/i915: Avoid waitboosting on the active request Chris Wilson
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

sandybride_pcode is another sideband, so move it to their new home.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.h       |   5 -
 drivers/gpu/drm/i915/intel_hdcp.c     |   3 +-
 drivers/gpu/drm/i915/intel_pm.c       | 190 ----------------------------------
 drivers/gpu/drm/i915/intel_sideband.c | 190 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_sideband.h |   5 +
 5 files changed, 197 insertions(+), 196 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4d9e9741ed8f..a0bb0f018a76 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3706,11 +3706,6 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv);
 extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
 					    struct intel_display_error_state *error);
 
-int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
-int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
-int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
-		      u32 reply_mask, u32 reply, int timeout_base_ms);
-
 /* intel_dpio_phy.c */
 void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
 			     enum dpio_phy *phy, enum dpio_channel *ch);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index d0e97172b8ed..1afae93707a1 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -11,8 +11,9 @@
 #include <linux/i2c.h>
 #include <linux/random.h>
 
-#include "intel_drv.h"
 #include "i915_reg.h"
+#include "intel_drv.h"
+#include "intel_sideband.h"
 
 #define KEY_LOAD_TRIES	5
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 18945264b835..a69b742147f7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -9080,196 +9080,6 @@ void intel_init_pm(struct drm_i915_private *dev_priv)
 	}
 }
 
-static inline int gen6_check_mailbox_status(struct drm_i915_private *dev_priv)
-{
-	uint32_t flags =
-		I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK;
-
-	switch (flags) {
-	case GEN6_PCODE_SUCCESS:
-		return 0;
-	case GEN6_PCODE_UNIMPLEMENTED_CMD:
-		return -ENODEV;
-	case GEN6_PCODE_ILLEGAL_CMD:
-		return -ENXIO;
-	case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
-	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
-		return -EOVERFLOW;
-	case GEN6_PCODE_TIMEOUT:
-		return -ETIMEDOUT;
-	default:
-		MISSING_CASE(flags);
-		return 0;
-	}
-}
-
-static inline int gen7_check_mailbox_status(struct drm_i915_private *dev_priv)
-{
-	uint32_t flags =
-		I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK;
-
-	switch (flags) {
-	case GEN6_PCODE_SUCCESS:
-		return 0;
-	case GEN6_PCODE_ILLEGAL_CMD:
-		return -ENXIO;
-	case GEN7_PCODE_TIMEOUT:
-		return -ETIMEDOUT;
-	case GEN7_PCODE_ILLEGAL_DATA:
-		return -EINVAL;
-	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
-		return -EOVERFLOW;
-	default:
-		MISSING_CASE(flags);
-		return 0;
-	}
-}
-
-static int __sandybridge_pcode_rw(struct drm_i915_private *dev_priv,
-				  u32 mbox, u32 *val, bool is_read)
-{
-	int status;
-
-	lockdep_assert_held(&dev_priv->sb_lock);
-
-	/*
-	 * GEN6_PCODE_* are outside of the forcewake domain, we can
-	 * use te fw I915_READ variants to reduce the amount of work
-	 * required when reading/writing.
-	 */
-
-	if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
-		return -EAGAIN;
-
-	I915_WRITE_FW(GEN6_PCODE_DATA, *val);
-	I915_WRITE_FW(GEN6_PCODE_DATA1, 0);
-	I915_WRITE_FW(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
-
-	if (__intel_wait_for_register_fw(dev_priv,
-					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
-					 500, 0, NULL))
-		return -ETIMEDOUT;
-
-	if (is_read)
-		*val = I915_READ_FW(GEN6_PCODE_DATA);
-	I915_WRITE_FW(GEN6_PCODE_DATA, 0);
-
-	if (INTEL_GEN(dev_priv) > 6)
-		status = gen7_check_mailbox_status(dev_priv);
-	else
-		status = gen6_check_mailbox_status(dev_priv);
-
-	return status;
-}
-
-int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val)
-{
-	int status;
-
-	mutex_lock(&dev_priv->sb_lock);
-	status = __sandybridge_pcode_rw(dev_priv, mbox, val, true);
-	mutex_unlock(&dev_priv->sb_lock);
-
-	if (status) {
-		DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n",
-				 mbox, __builtin_return_address(0), status);
-	}
-
-	return status;
-}
-
-int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
-			    u32 mbox, u32 val)
-{
-	int status;
-
-	mutex_lock(&dev_priv->sb_lock);
-	status = __sandybridge_pcode_rw(dev_priv, mbox, &val, false);
-	mutex_unlock(&dev_priv->sb_lock);
-
-	if (status) {
-		DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n",
-				 val, mbox, __builtin_return_address(0), status);
-	}
-
-	return status;
-}
-
-static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
-				  u32 request, u32 reply_mask, u32 reply,
-				  u32 *status)
-{
-	*status = __sandybridge_pcode_rw(dev_priv, mbox, &request, true);
-
-	return *status || ((request & reply_mask) == reply);
-}
-
-/**
- * skl_pcode_request - send PCODE request until acknowledgment
- * @dev_priv: device private
- * @mbox: PCODE mailbox ID the request is targeted for
- * @request: request ID
- * @reply_mask: mask used to check for request acknowledgment
- * @reply: value used to check for request acknowledgment
- * @timeout_base_ms: timeout for polling with preemption enabled
- *
- * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE
- * reports an error or an overall timeout of @timeout_base_ms+50 ms expires.
- * The request is acknowledged once the PCODE reply dword equals @reply after
- * applying @reply_mask. Polling is first attempted with preemption enabled
- * for @timeout_base_ms and if this times out for another 50 ms with
- * preemption disabled.
- *
- * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some
- * other error as reported by PCODE.
- */
-int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
-		      u32 reply_mask, u32 reply, int timeout_base_ms)
-{
-	u32 status;
-	int ret;
-
-	mutex_lock(&dev_priv->sb_lock);
-
-#define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \
-				   &status)
-
-	/*
-	 * Prime the PCODE by doing a request first. Normally it guarantees
-	 * that a subsequent request, at most @timeout_base_ms later, succeeds.
-	 * _wait_for() doesn't guarantee when its passed condition is evaluated
-	 * first, so send the first request explicitly.
-	 */
-	if (COND) {
-		ret = 0;
-		goto out;
-	}
-	ret = _wait_for(COND, timeout_base_ms * 1000, 10, 10);
-	if (!ret)
-		goto out;
-
-	/*
-	 * The above can time out if the number of requests was low (2 in the
-	 * worst case) _and_ PCODE was busy for some reason even after a
-	 * (queued) request and @timeout_base_ms delay. As a workaround retry
-	 * the poll with preemption disabled to maximize the number of
-	 * requests. Increase the timeout from @timeout_base_ms to 50ms to
-	 * account for interrupts that could reduce the number of these
-	 * requests, and for any quirks of the PCODE firmware that delays
-	 * the request completion.
-	 */
-	DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n");
-	WARN_ON_ONCE(timeout_base_ms > 3);
-	preempt_disable();
-	ret = wait_for_atomic(COND, 50);
-	preempt_enable();
-
-out:
-	mutex_unlock(&dev_priv->sb_lock);
-	return ret ? ret : status;
-#undef COND
-}
-
 static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
 {
 	struct intel_rps *rps = &dev_priv->gt_pm.rps;
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 6815be9e5b7c..a9ba378bf9fc 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -383,3 +383,193 @@ void vlv_flisdsi_put(struct drm_i915_private *dev_priv)
 {
 	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_FLISDSI));
 }
+
+static inline int gen6_check_mailbox_status(struct drm_i915_private *dev_priv)
+{
+	uint32_t flags =
+		I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK;
+
+	switch (flags) {
+	case GEN6_PCODE_SUCCESS:
+		return 0;
+	case GEN6_PCODE_UNIMPLEMENTED_CMD:
+		return -ENODEV;
+	case GEN6_PCODE_ILLEGAL_CMD:
+		return -ENXIO;
+	case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
+	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
+		return -EOVERFLOW;
+	case GEN6_PCODE_TIMEOUT:
+		return -ETIMEDOUT;
+	default:
+		MISSING_CASE(flags);
+		return 0;
+	}
+}
+
+static inline int gen7_check_mailbox_status(struct drm_i915_private *dev_priv)
+{
+	uint32_t flags =
+		I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK;
+
+	switch (flags) {
+	case GEN6_PCODE_SUCCESS:
+		return 0;
+	case GEN6_PCODE_ILLEGAL_CMD:
+		return -ENXIO;
+	case GEN7_PCODE_TIMEOUT:
+		return -ETIMEDOUT;
+	case GEN7_PCODE_ILLEGAL_DATA:
+		return -EINVAL;
+	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
+		return -EOVERFLOW;
+	default:
+		MISSING_CASE(flags);
+		return 0;
+	}
+}
+
+static int __sandybridge_pcode_rw(struct drm_i915_private *dev_priv,
+				  u32 mbox, u32 *val, bool is_read)
+{
+	int status;
+
+	lockdep_assert_held(&dev_priv->sb_lock);
+
+	/*
+	 * GEN6_PCODE_* are outside of the forcewake domain, we can
+	 * use te fw I915_READ variants to reduce the amount of work
+	 * required when reading/writing.
+	 */
+
+	if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
+		return -EAGAIN;
+
+	I915_WRITE_FW(GEN6_PCODE_DATA, *val);
+	I915_WRITE_FW(GEN6_PCODE_DATA1, 0);
+	I915_WRITE_FW(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
+
+	if (__intel_wait_for_register_fw(dev_priv,
+					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
+					 500, 0, NULL))
+		return -ETIMEDOUT;
+
+	if (is_read)
+		*val = I915_READ_FW(GEN6_PCODE_DATA);
+	I915_WRITE_FW(GEN6_PCODE_DATA, 0);
+
+	if (INTEL_GEN(dev_priv) > 6)
+		status = gen7_check_mailbox_status(dev_priv);
+	else
+		status = gen6_check_mailbox_status(dev_priv);
+
+	return status;
+}
+
+int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val)
+{
+	int status;
+
+	mutex_lock(&dev_priv->sb_lock);
+	status = __sandybridge_pcode_rw(dev_priv, mbox, val, true);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	if (status) {
+		DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n",
+				 mbox, __builtin_return_address(0), status);
+	}
+
+	return status;
+}
+
+int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
+			    u32 mbox, u32 val)
+{
+	int status;
+
+	mutex_lock(&dev_priv->sb_lock);
+	status = __sandybridge_pcode_rw(dev_priv, mbox, &val, false);
+	mutex_unlock(&dev_priv->sb_lock);
+
+	if (status) {
+		DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n",
+				 val, mbox, __builtin_return_address(0), status);
+	}
+
+	return status;
+}
+
+static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
+				  u32 request, u32 reply_mask, u32 reply,
+				  u32 *status)
+{
+	*status = __sandybridge_pcode_rw(dev_priv, mbox, &request, true);
+
+	return *status || ((request & reply_mask) == reply);
+}
+
+/**
+ * skl_pcode_request - send PCODE request until acknowledgment
+ * @dev_priv: device private
+ * @mbox: PCODE mailbox ID the request is targeted for
+ * @request: request ID
+ * @reply_mask: mask used to check for request acknowledgment
+ * @reply: value used to check for request acknowledgment
+ * @timeout_base_ms: timeout for polling with preemption enabled
+ *
+ * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE
+ * reports an error or an overall timeout of @timeout_base_ms+50 ms expires.
+ * The request is acknowledged once the PCODE reply dword equals @reply after
+ * applying @reply_mask. Polling is first attempted with preemption enabled
+ * for @timeout_base_ms and if this times out for another 50 ms with
+ * preemption disabled.
+ *
+ * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some
+ * other error as reported by PCODE.
+ */
+int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
+		      u32 reply_mask, u32 reply, int timeout_base_ms)
+{
+	u32 status;
+	int ret;
+
+	mutex_lock(&dev_priv->sb_lock);
+
+#define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \
+				   &status)
+
+	/*
+	 * Prime the PCODE by doing a request first. Normally it guarantees
+	 * that a subsequent request, at most @timeout_base_ms later, succeeds.
+	 * _wait_for() doesn't guarantee when its passed condition is evaluated
+	 * first, so send the first request explicitly.
+	 */
+	if (COND) {
+		ret = 0;
+		goto out;
+	}
+	ret = _wait_for(COND, timeout_base_ms * 1000, 10, 10);
+	if (!ret)
+		goto out;
+
+	/*
+	 * The above can time out if the number of requests was low (2 in the
+	 * worst case) _and_ PCODE was busy for some reason even after a
+	 * (queued) request and @timeout_base_ms delay. As a workaround retry
+	 * the poll with preemption disabled to maximize the number of
+	 * requests. Increase the timeout from @timeout_base_ms to 50ms to
+	 * account for interrupts that could reduce the number of these
+	 * requests, and for any quirks of the PCODE firmware that delays
+	 * the request completion.
+	 */
+	DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n");
+	WARN_ON_ONCE(timeout_base_ms > 3);
+	preempt_disable();
+	ret = wait_for_atomic(COND, 50);
+	preempt_enable();
+
+out:
+	mutex_unlock(&dev_priv->sb_lock);
+	return ret ? ret : status;
+#undef COND
+}
diff --git a/drivers/gpu/drm/i915/intel_sideband.h b/drivers/gpu/drm/i915/intel_sideband.h
index 46e917dd3973..999c1da2cd93 100644
--- a/drivers/gpu/drm/i915/intel_sideband.h
+++ b/drivers/gpu/drm/i915/intel_sideband.h
@@ -68,4 +68,9 @@ u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
 void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
 		     enum intel_sbi_destination destination);
 
+int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
+int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
+int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
+		      u32 reply_mask, u32 reply, int timeout_base_ms);
+
 #endif /* _INTEL_SIDEBAND_H */
-- 
2.15.1

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

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

* [PATCH v2 11/11] drm/i915: Avoid waitboosting on the active request
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (9 preceding siblings ...)
  2018-01-15  8:47 ` [PATCH v2 10/11] drm/i915: Move sandybride pcode access to intel_sideband.c Chris Wilson
@ 2018-01-15  8:47 ` Chris Wilson
  2018-01-18  9:49   ` Joonas Lahtinen
  2018-01-15  9:19 ` ✓ Fi.CI.BAT: success for series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband Patchwork
  2018-01-15 10:23 ` ✗ Fi.CI.IGT: failure " Patchwork
  12 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-01-15  8:47 UTC (permalink / raw)
  To: intel-gfx

Watching a light workload on Baytrail (running glxgears and a 1080p
decode), instead of the system remaining at low frequency, the glxgears
would regularly trigger waitboosting after which it would have to spend
a few seconds throttling back down. In this case, the waitboosting is
counter productive as the minimal wait for glxgears doesn't prevent it
from functioning correctly and delivering frames on time. In this case,
glxgears happens to almost always be waiting on the current request,
which we already expect to complete quickly (see i915_spin_request) and
so avoiding the waitboost on the active request and spinning instead
provides the best latency without overcommitting to upclocking.
However, if the system falls behind we still force the waitboost.
Similarly, we will also trigger upclocking if we detect the system is
not delivering frames on time - again using a mechanism that tries to
detect a miss and not preemptively upclock.

v2: Also skip boosting for after missed vblank if the desired request is
already active.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c         |  7 +++----
 drivers/gpu/drm/i915/i915_gem_request.h | 13 +++++++++++++
 drivers/gpu/drm/i915/intel_display.c    |  8 +++++++-
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1135a77b383a..b3517676b417 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -369,7 +369,8 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
 	if (i915_gem_request_completed(rq))
 		goto out;
 
-	/* This client is about to stall waiting for the GPU. In many cases
+	/*
+	 * This client is about to stall waiting for the GPU. In many cases
 	 * this is undesirable and limits the throughput of the system, as
 	 * many clients cannot continue processing user input/output whilst
 	 * blocked. RPS autotuning may take tens of milliseconds to respond
@@ -384,11 +385,9 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
 	 * forcing the clocks too high for the whole system, we only allow
 	 * each client to waitboost once in a busy period.
 	 */
-	if (rps_client) {
+	if (rps_client && !i915_gem_request_started(rq)) {
 		if (INTEL_GEN(rq->i915) >= 6)
 			gen6_rps_boost(rq, rps_client);
-		else
-			rps_client = NULL;
 	}
 
 	timeout = i915_wait_request(rq, flags, timeout);
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index 6c607f8dbf92..2236e9188c5c 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -329,6 +329,19 @@ i915_gem_request_completed(const struct drm_i915_gem_request *req)
 	return __i915_gem_request_completed(req, seqno);
 }
 
+static inline bool
+i915_gem_request_started(const struct drm_i915_gem_request *req)
+{
+	u32 seqno;
+
+	seqno = i915_gem_request_global_seqno(req);
+	if (!seqno)
+		return false;
+
+	return i915_seqno_passed(intel_engine_get_seqno(req->engine),
+				 seqno - 1);
+}
+
 static inline bool i915_priotree_signaled(const struct i915_priotree *pt)
 {
 	const struct drm_i915_gem_request *rq =
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 89a927a3a506..4d4db7486f70 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12519,7 +12519,13 @@ static int do_rps_boost(struct wait_queue_entry *_wait,
 	struct wait_rps_boost *wait = container_of(_wait, typeof(*wait), wait);
 	struct drm_i915_gem_request *rq = wait->request;
 
-	gen6_rps_boost(rq, NULL);
+	/*
+	 * If we missed the vblank, but the request is already running it
+	 * is reasonable to assume that it will complete before the next
+	 * vblank without our intervention, so leave RPS alone.
+	 */
+	if (!i915_gem_request_started(rq))
+		gen6_rps_boost(rq, NULL);
 	i915_gem_request_put(rq);
 
 	drm_crtc_vblank_put(wait->crtc);
-- 
2.15.1

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

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

* ✓ Fi.CI.BAT: success for series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (10 preceding siblings ...)
  2018-01-15  8:47 ` [PATCH v2 11/11] drm/i915: Avoid waitboosting on the active request Chris Wilson
@ 2018-01-15  9:19 ` Patchwork
  2018-01-15 10:23 ` ✗ Fi.CI.IGT: failure " Patchwork
  12 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2018-01-15  9:19 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
URL   : https://patchwork.freedesktop.org/series/36469/
State : success

== Summary ==

Series 36469v1 series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
https://patchwork.freedesktop.org/api/1.0/series/36469/revisions/1/mbox/

Test gem_exec_suspend:
        Subgroup basic-s3:
                pass       -> INCOMPLETE (fi-hsw-4770) fdo#103375
Test gem_mmap_gtt:
        Subgroup basic-small-bo-tiledx:
                fail       -> PASS       (fi-gdg-551) fdo#102575
Test gem_ringfill:
        Subgroup basic-default:
                skip       -> PASS       (fi-bsw-n3050)
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-a:
                pass       -> DMESG-WARN (fi-kbl-r) fdo#104172 +1
        Subgroup suspend-read-crc-pipe-c:
                incomplete -> PASS       (fi-skl-6600u) fdo#104108

fdo#103375 https://bugs.freedesktop.org/show_bug.cgi?id=103375
fdo#102575 https://bugs.freedesktop.org/show_bug.cgi?id=102575
fdo#104172 https://bugs.freedesktop.org/show_bug.cgi?id=104172
fdo#104108 https://bugs.freedesktop.org/show_bug.cgi?id=104108

fi-bdw-5557u     total:288  pass:267  dwarn:0   dfail:0   fail:0   skip:21  time:418s
fi-bdw-gvtdvm    total:288  pass:264  dwarn:0   dfail:0   fail:0   skip:24  time:428s
fi-blb-e6850     total:288  pass:223  dwarn:1   dfail:0   fail:0   skip:64  time:372s
fi-bsw-n3050     total:288  pass:242  dwarn:0   dfail:0   fail:0   skip:46  time:495s
fi-bwr-2160      total:288  pass:183  dwarn:0   dfail:0   fail:0   skip:105 time:286s
fi-bxt-dsi       total:288  pass:258  dwarn:0   dfail:0   fail:0   skip:30  time:486s
fi-bxt-j4205     total:288  pass:259  dwarn:0   dfail:0   fail:0   skip:29  time:491s
fi-byt-j1900     total:288  pass:253  dwarn:0   dfail:0   fail:0   skip:35  time:468s
fi-byt-n2820     total:288  pass:249  dwarn:0   dfail:0   fail:0   skip:39  time:452s
fi-elk-e7500     total:224  pass:168  dwarn:10  dfail:0   fail:0   skip:45 
fi-gdg-551       total:288  pass:180  dwarn:0   dfail:0   fail:0   skip:108 time:275s
fi-glk-1         total:288  pass:260  dwarn:0   dfail:0   fail:0   skip:28  time:519s
fi-hsw-4770      total:108  pass:99   dwarn:0   dfail:0   fail:0   skip:8  
fi-hsw-4770r     total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:399s
fi-ilk-650       total:288  pass:228  dwarn:0   dfail:0   fail:0   skip:60  time:415s
fi-ivb-3520m     total:288  pass:259  dwarn:0   dfail:0   fail:0   skip:29  time:459s
fi-ivb-3770      total:288  pass:255  dwarn:0   dfail:0   fail:0   skip:33  time:418s
fi-kbl-7560u     total:288  pass:269  dwarn:0   dfail:0   fail:0   skip:19  time:496s
fi-kbl-7567u     total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:456s
fi-kbl-r         total:288  pass:260  dwarn:1   dfail:0   fail:0   skip:27  time:499s
fi-pnv-d510      total:288  pass:222  dwarn:1   dfail:0   fail:0   skip:65  time:589s
fi-skl-6260u     total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:428s
fi-skl-6600u     total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:505s
fi-skl-6700hq    total:288  pass:262  dwarn:0   dfail:0   fail:0   skip:26  time:526s
fi-skl-6700k2    total:288  pass:264  dwarn:0   dfail:0   fail:0   skip:24  time:491s
fi-skl-6770hq    total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:489s
fi-snb-2520m     total:288  pass:248  dwarn:0   dfail:0   fail:0   skip:40  time:532s
fi-snb-2600      total:288  pass:248  dwarn:0   dfail:0   fail:0   skip:40  time:397s
Blacklisted hosts:
fi-cfl-s2        total:288  pass:262  dwarn:0   dfail:0   fail:0   skip:26  time:571s
fi-glk-dsi       total:288  pass:258  dwarn:0   dfail:0   fail:0   skip:30  time:475s
fi-kbl-7500u failed to connect after reboot
fi-skl-gvtdvm failed to connect after reboot

e96cbac0c1751d045065a49bf20ea134739e2dbb drm-tip: 2018y-01m-15d-05h-55m-36s UTC integration manifest
f251b4f992fc drm/i915: Avoid waitboosting on the active request
05d0730fe5df drm/i915: Move sandybride pcode access to intel_sideband.c
58f58438df5a drm/i915: Merge sandybride_pcode_(read|write)
6b059d094d81 drm/i915: Merge sbi read/write into a single accessor
9a06bb07fd36 drm/i915: Separate sideband declarations to intel_sideband.h
899fa0a613f6 drm/i915: Replace pcu_lock with sb_lock
9db2b07c3487 Revert "drm/i915: Avoid tweaking evaluation thresholds on Baytrail v3"
06e5546d1735 drm/i915: Reduce RPS update frequency on Valleyview/Cherryview
6ae54df1e024 drm/i915: Lift sideband locking for vlv_punit_(read|write)
7ec136be1971 drm/i915: Lift acquiring the vlv punit magic to a common sb-get
6ba4ecbcc1aa drm/i915: Disable preemption and sleeping while using the punit sideband

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7665/issues.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✗ Fi.CI.IGT: failure for series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
                   ` (11 preceding siblings ...)
  2018-01-15  9:19 ` ✓ Fi.CI.BAT: success for series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband Patchwork
@ 2018-01-15 10:23 ` Patchwork
  2018-01-15 10:27   ` Chris Wilson
  12 siblings, 1 reply; 26+ messages in thread
From: Patchwork @ 2018-01-15 10:23 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

== Series Details ==

Series: series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
URL   : https://patchwork.freedesktop.org/series/36469/
State : failure

== Summary ==

Test kms_flip:
        Subgroup flip-vs-absolute-wf_vblank-interruptible:
                pass       -> DMESG-WARN (shard-hsw) fdo#100368 +2
        Subgroup bo-too-big-interruptible:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup vblank-vs-dpms-suspend:
                pass       -> INCOMPLETE (shard-hsw) fdo#103540 +9
        Subgroup blt-wf_vblank-vs-modeset:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup blocking-absolute-wf_vblank-interruptible:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup modeset-vs-vblank-race:
                pass       -> DMESG-WARN (shard-hsw) fdo#103060 +2
        Subgroup flip-vs-dpms-interruptible:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup vblank-vs-modeset-rpm-interruptible:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup wf_vblank-interruptible:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup flip-vs-fences-interruptible:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup plain-flip-interruptible:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup vblank-vs-modeset-suspend:
                pass       -> INCOMPLETE (shard-hsw)
Test kms_cursor_crc:
        Subgroup cursor-256x85-onscreen:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-64x64-onscreen:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-128x42-random:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-64x21-sliding:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-256x256-sliding:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-128x128-random:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-256x85-sliding:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-256x256-offscreen:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-64x64-offscreen:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-128x42-offscreen:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_frontbuffer_tracking:
        Subgroup fbc-rgb101010-draw-blt:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup fbc-farfromfence:
                pass       -> DMESG-WARN (shard-hsw) fdo#101623 +10
        Subgroup fbc-rgb565-draw-mmap-gtt:
                pass       -> DMESG-WARN (shard-hsw) fdo#103167 +4
        Subgroup fbc-1p-primscrn-cur-indfb-draw-mmap-wc:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup fbc-rgb565-draw-mmap-cpu:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_atomic:
        Subgroup plane_invalid_params:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup test_only:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup plane_overlay_legacy:
                pass       -> DMESG-WARN (shard-hsw)
Test pm_rpm:
        Subgroup system-suspend-modeset:
                pass       -> INCOMPLETE (shard-hsw)
        Subgroup system-suspend-execbuf:
                pass       -> INCOMPLETE (shard-hsw) fdo#103375 +7
        Subgroup modeset-non-lpsp-stress:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup gem-idle:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup legacy-planes:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup modeset-non-lpsp:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup basic-pci-d3-state:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pm-caching:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup sysfs-read:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pm-tiling:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup debugfs-forcewake-user:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup gem-execbuf:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup gem-mmap-gtt:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup fences-dpms:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup gem-evict-pwrite:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup gem-mmap-cpu:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup cursor-dpms:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup i2c:
                pass       -> DMESG-WARN (shard-hsw)
Test gem_eio:
        Subgroup suspend:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_chv_cursor_fail:
        Subgroup pipe-b-256x256-top-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-a-128x128-top-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-a-256x256-right-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-a-256x256-bottom-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-c-128x128-top-edge:
                pass       -> DMESG-WARN (shard-hsw) fdo#104152
        Subgroup pipe-c-256x256-left-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-c-128x128-right-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-b-256x256-bottom-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-a-64x64-top-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-b-256x256-left-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-a-64x64-bottom-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-a-64x64-right-edge:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-c-256x256-bottom-edge:
                pass       -> DMESG-WARN (shard-hsw)
Test gem_tiled_swapping:
        Subgroup non-threaded:
                incomplete -> PASS       (shard-hsw) fdo#104218
Test drv_module_reload:
        Subgroup basic-reload:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup basic-reload-inject:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup basic-no-display:
                pass       -> DMESG-WARN (shard-hsw)
Test drv_suspend:
        Subgroup sysfs-reader:
                pass       -> INCOMPLETE (shard-hsw)
        Subgroup debugfs-reader:
                pass       -> INCOMPLETE (shard-hsw)
Test kms_concurrent:
        Subgroup pipe-a:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-b:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup pipe-c:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_universal_plane:
        Subgroup disable-primary-vs-flip-pipe-c:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup universal-plane-pipe-b-functional:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup universal-plane-pipe-b-sanity:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup universal-plane-pipe-a-sanity:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup universal-plane-pipe-c-sanity:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_plane_multiple:
        Subgroup legacy-pipe-c-tiling-none:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup atomic-pipe-b-tiling-none:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup atomic-pipe-c-tiling-none:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup atomic-pipe-c-tiling-x:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_atomic_transition:
        Subgroup plane-all-transition-nonblocking:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup plane-all-transition-fencing:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup plane-toggle-modeset-transition:
                pass       -> DMESG-WARN (shard-hsw) fdo#102614 +6
        Subgroup plane-primary-toggle-with-vblank-wait:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup plane-use-after-nonblocking-unbind:
                pass       -> DMESG-WARN (shard-hsw)
Test pm_rps:
        Subgroup reset:
                pass       -> FAIL       (shard-snb)
                pass       -> FAIL       (shard-hsw)
        Subgroup waitboost:
                pass       -> FAIL       (shard-snb)
                pass       -> FAIL       (shard-hsw)
Test kms_vblank:
        Subgroup wait-busy:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup accuracy-idle:
                pass       -> DMESG-WARN (shard-hsw) fdo#102583
        Subgroup query-forked:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_plane:
        Subgroup plane-position-hole-pipe-c-planes:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup plane-panning-bottom-right-suspend-pipe-b-planes:
                pass       -> INCOMPLETE (shard-hsw)
        Subgroup plane-panning-top-left-pipe-a-planes:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup plane-panning-bottom-right-pipe-c-planes:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup plane-panning-bottom-right-pipe-a-planes:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_properties:
        Subgroup crtc-properties-atomic:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup connector-properties-atomic:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup plane-properties-atomic:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_busy:
        Subgroup basic-flip-a:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup basic-modeset-c:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup extended-modeset-hang-oldfb-with-reset-render-b:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup extended-modeset-hang-newfb-with-reset-render-c:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup extended-pageflip-hang-oldfb-render-b:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup extended-pageflip-modeset-hang-oldfb-render-b:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_atomic_interruptible:
        Subgroup legacy-pageflip:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup universal-setplane-primary:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_plane_lowres:
        Subgroup pipe-c-tiling-none:
                pass       -> INCOMPLETE (shard-hsw)
        Subgroup pipe-c-tiling-x:
                pass       -> INCOMPLETE (shard-hsw)
        Subgroup pipe-a-tiling-x:
                pass       -> INCOMPLETE (shard-hsw)
Test kms_pipe_crc_basic:
        Subgroup read-crc-pipe-c-frame-sequence:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup hang-read-crc-pipe-c:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_rotation_crc:
        Subgroup sprite-rotation-180-flip:
                pass       -> DMESG-WARN (shard-hsw)
        Subgroup primary-rotation-180-flip:
                pass       -> DMESG-WARN (shard-hsw)
Test debugfs_test:
        Subgroup read_all_entries_display_off:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_pwrite_crc:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_invalid_dotclock:
                pass       -> DMESG-WARN (shard-hsw)
Test testdisplay:
                pass       -> DMESG-WARN (shard-hsw)
Test kms_setmode:
        Subgroup basic:
                fail       -> DMESG-FAIL (shard-hsw) fdo#99912
Test gem_exec_suspend:
        Subgroup basic-s3-devices:
                pass       -> INCOMPLETE (shard-hsw)

fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368
fdo#103540 https://bugs.freedesktop.org/show_bug.cgi?id=103540
fdo#103060 https://bugs.freedesktop.org/show_bug.cgi?id=103060
fdo#101623 https://bugs.freedesktop.org/show_bug.cgi?id=101623
fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
fdo#103375 https://bugs.freedesktop.org/show_bug.cgi?id=103375
fdo#104152 https://bugs.freedesktop.org/show_bug.cgi?id=104152
fdo#104218 https://bugs.freedesktop.org/show_bug.cgi?id=104218
fdo#102614 https://bugs.freedesktop.org/show_bug.cgi?id=102614
fdo#102583 https://bugs.freedesktop.org/show_bug.cgi?id=102583
fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912

shard-hsw        total:1674 pass:806  dwarn:129 dfail:3   fail:4   skip:710 time:2743s
shard-snb        total:2713 pass:1308 dwarn:1   dfail:0   fail:13  skip:1391 time:7882s
Blacklisted hosts:
shard-apl        total:2713 pass:1686 dwarn:1   dfail:0   fail:25  skip:1001 time:13651s
shard-kbl        total:2713 pass:1724 dwarn:39  dfail:2   fail:23  skip:925 time:10317s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_7665/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: ✗ Fi.CI.IGT: failure for series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15 10:23 ` ✗ Fi.CI.IGT: failure " Patchwork
@ 2018-01-15 10:27   ` Chris Wilson
  0 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15 10:27 UTC (permalink / raw)
  To: Patchwork; +Cc: intel-gfx

Quoting Patchwork (2018-01-15 10:23:17)
> == Series Details ==
> 
> Series: series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
> URL   : https://patchwork.freedesktop.org/series/36469/
> State : failure
> 
> == Summary ==
> 
> Test kms_flip:
>         Subgroup flip-vs-absolute-wf_vblank-interruptible:
>                 pass       -> DMESG-WARN (shard-hsw) fdo#100368 +2

Hmm, be back after a quick^w slow bisection.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 02/11] drm/i915: Lift acquiring the vlv punit magic to a common sb-get
  2018-01-15  8:47 ` [PATCH v2 02/11] drm/i915: Lift acquiring the vlv punit magic to a common sb-get Chris Wilson
@ 2018-01-15 10:36   ` Mika Kuoppala
  0 siblings, 0 replies; 26+ messages in thread
From: Mika Kuoppala @ 2018-01-15 10:36 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

Chris Wilson <chris@chris-wilson.co.uk> writes:

> As we now employ a very heavy pm_qos around the punit access, we want to
> minimise the number of synchronous requests by performing one for the
> whole punit sequence rather than around individual accesses. The
> sideband lock is used for this, so push the pm_qos into the sideband
> lock acquisition and release, moving it from the lowlevel punit rw
> routine to the callers. In the first step, we move the punit magic into
> the common sideband lock so that we can acquire a bunch of ports
> simultaneously, and if need be extend the workaround protection later.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/i915_drv.h         |  44 ++++++++++--
>  drivers/gpu/drm/i915/intel_cdclk.c      |   6 +-
>  drivers/gpu/drm/i915/intel_display.c    |  37 +++++-----
>  drivers/gpu/drm/i915/intel_dp.c         |   4 +-
>  drivers/gpu/drm/i915/intel_dpio_phy.c   |  37 +++++-----
>  drivers/gpu/drm/i915/intel_dsi.c        |   8 +--
>  drivers/gpu/drm/i915/intel_dsi_pll.c    |  14 ++--
>  drivers/gpu/drm/i915/intel_dsi_vbt.c    |   8 +--
>  drivers/gpu/drm/i915/intel_hdmi.c       |   4 +-
>  drivers/gpu/drm/i915/intel_pm.c         |   4 +-
>  drivers/gpu/drm/i915/intel_runtime_pm.c |   8 +--
>  drivers/gpu/drm/i915/intel_sideband.c   | 115 +++++++++++++++++++++++++++-----
>  12 files changed, 207 insertions(+), 82 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index d95d8c3d04aa..80280f27601e 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3723,25 +3723,61 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
>  		      u32 reply_mask, u32 reply, int timeout_base_ms);
>  
>  /* intel_sideband.c */
> +
> +enum {
> +	VLV_IOSF_SB_BUNIT,
> +	VLV_IOSF_SB_CCK,
> +	VLV_IOSF_SB_CCU,
> +	VLV_IOSF_SB_DPIO,
> +	VLV_IOSF_SB_FLISDSI,
> +	VLV_IOSF_SB_GPIO,
> +	VLV_IOSF_SB_NC,
> +	VLV_IOSF_SB_PUNIT,
> +};
> +
> +void vlv_iosf_sb_get(struct drm_i915_private *dev_priv, unsigned long ports);
> +u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg);
> +void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, u8 port, u32 reg, u32 val);
> +void vlv_iosf_sb_put(struct drm_i915_private *dev_priv, unsigned long ports);
> +
> +void vlv_punit_get(struct drm_i915_private *dev_priv);
>  u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr);
>  int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val);
> +void vlv_punit_put(struct drm_i915_private *dev_priv);
> +
> +void vlv_nc_get(struct drm_i915_private *dev_priv);
>  u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
> -u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg);
> -void vlv_iosf_sb_write(struct drm_i915_private *dev_priv, u8 port, u32 reg, u32 val);
> +void vlv_nc_put(struct drm_i915_private *dev_priv);
> +
> +void vlv_cck_get(struct drm_i915_private *dev_priv);
>  u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
>  void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
> +void vlv_cck_put(struct drm_i915_private *dev_priv);
> +
> +void vlv_ccu_get(struct drm_i915_private *dev_priv);
>  u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
>  void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
> +void vlv_ccu_put(struct drm_i915_private *dev_priv);
> +
> +void vlv_bunit_get(struct drm_i915_private *dev_priv);
>  u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg);
>  void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
> +void vlv_bunit_put(struct drm_i915_private *dev_priv);
> +
> +void vlv_dpio_get(struct drm_i915_private *dev_priv);
>  u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg);
>  void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val);
> +void vlv_dpio_put(struct drm_i915_private *dev_priv);
> +
> +void vlv_flisdsi_get(struct drm_i915_private *dev_priv);
> +u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
> +void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
> +void vlv_flisdsi_put(struct drm_i915_private *dev_priv);
> +
>  u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
>  		   enum intel_sbi_destination destination);
>  void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
>  		     enum intel_sbi_destination destination);
> -u32 vlv_flisdsi_read(struct drm_i915_private *dev_priv, u32 reg);
> -void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
>  
>  /* intel_dpio_phy.c */
>  void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
> diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
> index ca36321eafac..177bb79beee7 100644
> --- a/drivers/gpu/drm/i915/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/intel_cdclk.c
> @@ -552,7 +552,8 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
>  	}
>  	mutex_unlock(&dev_priv->pcu_lock);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_iosf_sb_get(dev_priv,
> +		       	BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_BUNIT));
>

git am complained about spaces before tab in above..

>  	if (cdclk == 400000) {
>  		u32 divider;
> @@ -586,7 +587,8 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
>  		val |= 3000 / 250; /* 3.0 usec */
>  	vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_iosf_sb_put(dev_priv,
> +		       	BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_BUNIT));
>

and in here.

-Mika

>  	intel_update_cdclk(dev_priv);
>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 221e3a183d36..5f0b9f66c8d8 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -165,10 +165,10 @@ int vlv_get_hpll_vco(struct drm_i915_private *dev_priv)
>  	int hpll_freq, vco_freq[] = { 800, 1600, 2000, 2400 };
>  
>  	/* Obtain SKU information */
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_cck_get(dev_priv);
>  	hpll_freq = vlv_cck_read(dev_priv, CCK_FUSE_REG) &
>  		CCK_FUSE_HPLL_FREQ_MASK;
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_cck_put(dev_priv);
>  
>  	return vco_freq[hpll_freq] * 1000;
>  }
> @@ -179,9 +179,9 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
>  	u32 val;
>  	int divider;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_cck_get(dev_priv);
>  	val = vlv_cck_read(dev_priv, reg);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_cck_put(dev_priv);
>  
>  	divider = val & CCK_FREQUENCY_VALUES;
>  
> @@ -1078,9 +1078,9 @@ void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
>  	u32 val;
>  	bool cur_state;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_cck_get(dev_priv);
>  	val = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_cck_put(dev_priv);
>  
>  	cur_state = val & DSI_PLL_VCO_EN;
>  	I915_STATE_WARN(cur_state != state,
> @@ -1428,14 +1428,14 @@ static void _chv_enable_pll(struct intel_crtc *crtc,
>  	enum dpio_channel port = vlv_pipe_to_channel(pipe);
>  	u32 tmp;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* Enable back the 10bit clock to display controller */
>  	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
>  	tmp |= DPIO_DCLKP_EN;
>  	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), tmp);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  
>  	/*
>  	 * Need to wait > 100ns between dclkp clock enable bit and PLL enable.
> @@ -1620,14 +1620,14 @@ static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
>  	I915_WRITE(DPLL(pipe), val);
>  	POSTING_READ(DPLL(pipe));
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* Disable 10bit clock to display controller */
>  	val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port));
>  	val &= ~DPIO_DCLKP_EN;
>  	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW14(port), val);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
> @@ -6638,7 +6638,7 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
>  	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
>  		return;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	bestn = pipe_config->dpll.n;
>  	bestm1 = pipe_config->dpll.m1;
> @@ -6715,7 +6715,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
>  	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW7(pipe), coreclk);
>  
>  	vlv_dpio_write(dev_priv, pipe, VLV_PLL_DW11(pipe), 0x87871000);
> -	mutex_unlock(&dev_priv->sb_lock);
> +
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  static void chv_prepare_pll(struct intel_crtc *crtc,
> @@ -6748,7 +6749,7 @@ static void chv_prepare_pll(struct intel_crtc *crtc,
>  	dpio_val = 0;
>  	loopfilter = 0;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* p1 and p2 divider */
>  	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW13(port),
> @@ -6820,7 +6821,7 @@ static void chv_prepare_pll(struct intel_crtc *crtc,
>  			vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW14(port)) |
>  			DPIO_AFC_RECAL);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  /**
> @@ -7422,9 +7423,9 @@ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
>  	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
>  		return;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  	mdiv = vlv_dpio_read(dev_priv, pipe, VLV_PLL_DW3(pipe));
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  
>  	clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
>  	clock.m2 = mdiv & DPIO_M2DIV_MASK;
> @@ -7524,13 +7525,13 @@ static void chv_crtc_clock_get(struct intel_crtc *crtc,
>  	if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
>  		return;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  	cmn_dw13 = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW13(port));
>  	pll_dw0 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW0(port));
>  	pll_dw1 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW1(port));
>  	pll_dw2 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW2(port));
>  	pll_dw3 = vlv_dpio_read(dev_priv, pipe, CHV_PLL_DW3(port));
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  
>  	clock.m1 = (pll_dw1 & 0x7) == DPIO_CHV_M1_DIV_BY_2 ? 2 : 0;
>  	clock.m2 = (pll_dw0 & 0xff) << 22;
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 68229f53d5b8..168f2c0de1b6 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -2771,12 +2771,12 @@ static void chv_post_disable_dp(struct intel_encoder *encoder,
>  
>  	intel_dp_link_down(encoder, old_crtc_state);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* Assert data lane reset */
>  	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  static void
> diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c
> index 76473e9836c6..662d71cd501f 100644
> --- a/drivers/gpu/drm/i915/intel_dpio_phy.c
> +++ b/drivers/gpu/drm/i915/intel_dpio_phy.c
> @@ -645,7 +645,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
>  	u32 val;
>  	int i;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* Clear calc init */
>  	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW10(ch));
> @@ -726,8 +726,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
>  		vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val);
>  	}
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> -
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  void chv_data_lane_soft_reset(struct intel_encoder *encoder,
> @@ -797,7 +796,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
>  
>  	chv_phy_powergate_lanes(encoder, true, lane_mask);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* Assert data lane reset */
>  	chv_data_lane_soft_reset(encoder, crtc_state, true);
> @@ -852,7 +851,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
>  		val |= CHV_CMN_USEDCLKCHANNEL;
>  	vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW19(ch), val);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
> @@ -867,7 +866,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
>  	int data, i, stagger;
>  	u32 val;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* allow hardware to manage TX FIFO reset source */
>  	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW11(ch));
> @@ -932,7 +931,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
>  	/* Deassert data lane reset */
>  	chv_data_lane_soft_reset(encoder, crtc_state, false);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  void chv_phy_release_cl2_override(struct intel_encoder *encoder)
> @@ -953,7 +952,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
>  	enum pipe pipe = to_intel_crtc(old_crtc_state->base.crtc)->pipe;
>  	u32 val;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* disable left/right clock distribution */
>  	if (pipe != PIPE_B) {
> @@ -966,7 +965,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
>  		vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val);
>  	}
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  
>  	/*
>  	 * Leave the power down bit cleared for at least one
> @@ -990,7 +989,8 @@ void vlv_set_phy_signal_level(struct intel_encoder *encoder,
>  	enum dpio_channel port = vlv_dport_to_channel(dport);
>  	enum pipe pipe = intel_crtc->pipe;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
> +
>  	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
>  	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
>  	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
> @@ -1003,7 +1003,8 @@ void vlv_set_phy_signal_level(struct intel_encoder *encoder,
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
>  	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN);
> -	mutex_unlock(&dev_priv->sb_lock);
> +
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
> @@ -1016,7 +1017,8 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
>  	enum pipe pipe = crtc->pipe;
>  
>  	/* Program Tx lane resets to default */
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
> +
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port),
>  			 DPIO_PCS_TX_LANE2_RESET |
>  			 DPIO_PCS_TX_LANE1_RESET);
> @@ -1030,7 +1032,8 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00);
>  	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500);
>  	vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000);
> -	mutex_unlock(&dev_priv->sb_lock);
> +
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
> @@ -1044,7 +1047,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
>  	enum pipe pipe = crtc->pipe;
>  	u32 val;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* Enable clock channels for this port */
>  	val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port));
> @@ -1060,7 +1063,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018);
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  void vlv_phy_reset_lanes(struct intel_encoder *encoder,
> @@ -1072,8 +1075,8 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder,
>  	enum dpio_channel port = vlv_dport_to_channel(dport);
>  	enum pipe pipe = crtc->pipe;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port), 0x00000000);
>  	vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port), 0x00e00060);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  }
> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
> index f67d321376e4..0b503b6971ff 100644
> --- a/drivers/gpu/drm/i915/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/intel_dsi.c
> @@ -278,7 +278,7 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs,
>  
>  static void band_gap_reset(struct drm_i915_private *dev_priv)
>  {
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_flisdsi_get(dev_priv);
>  
>  	vlv_flisdsi_write(dev_priv, 0x08, 0x0001);
>  	vlv_flisdsi_write(dev_priv, 0x0F, 0x0005);
> @@ -287,7 +287,7 @@ static void band_gap_reset(struct drm_i915_private *dev_priv)
>  	vlv_flisdsi_write(dev_priv, 0x0F, 0x0000);
>  	vlv_flisdsi_write(dev_priv, 0x08, 0x0000);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_flisdsi_put(dev_priv);
>  }
>  
>  static inline bool is_vid_mode(struct intel_dsi *intel_dsi)
> @@ -509,11 +509,11 @@ static void vlv_dsi_device_ready(struct intel_encoder *encoder)
>  
>  	DRM_DEBUG_KMS("\n");
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_flisdsi_get(dev_priv);
>  	/* program rcomp for compliance, reduce from 50 ohms to 45 ohms
>  	 * needed everytime after power gate */
>  	vlv_flisdsi_write(dev_priv, 0x04, 0x0004);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_flisdsi_put(dev_priv);
>  
>  	/* bandgap reset is needed after everytime we do power gate */
>  	band_gap_reset(dev_priv);
> diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c
> index 2ff2ee7f3b78..b73336e7dcd2 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_pll.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c
> @@ -149,7 +149,7 @@ static void vlv_enable_dsi_pll(struct intel_encoder *encoder,
>  
>  	DRM_DEBUG_KMS("\n");
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_cck_get(dev_priv);
>  
>  	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
>  	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, config->dsi_pll.div);
> @@ -166,11 +166,11 @@ static void vlv_enable_dsi_pll(struct intel_encoder *encoder,
>  	if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) &
>  						DSI_PLL_LOCK, 20)) {
>  
> -		mutex_unlock(&dev_priv->sb_lock);
> +		vlv_cck_put(dev_priv);
>  		DRM_ERROR("DSI PLL lock failed\n");
>  		return;
>  	}
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_cck_put(dev_priv);
>  
>  	DRM_DEBUG_KMS("DSI PLL locked\n");
>  }
> @@ -182,14 +182,14 @@ static void vlv_disable_dsi_pll(struct intel_encoder *encoder)
>  
>  	DRM_DEBUG_KMS("\n");
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_cck_get(dev_priv);
>  
>  	tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
>  	tmp &= ~DSI_PLL_VCO_EN;
>  	tmp |= DSI_PLL_LDO_GATE;
>  	vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_cck_put(dev_priv);
>  }
>  
>  static bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv)
> @@ -274,10 +274,10 @@ static u32 vlv_dsi_get_pclk(struct intel_encoder *encoder, int pipe_bpp,
>  
>  	DRM_DEBUG_KMS("\n");
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_cck_get(dev_priv);
>  	pll_ctl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
>  	pll_div = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_DIVIDER);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_cck_put(dev_priv);
>  
>  	config->dsi_pll.ctrl = pll_ctl & ~DSI_PLL_LOCK;
>  	config->dsi_pll.div = pll_div;
> diff --git a/drivers/gpu/drm/i915/intel_dsi_vbt.c b/drivers/gpu/drm/i915/intel_dsi_vbt.c
> index 91c07b0c8db9..f1168b6e8592 100644
> --- a/drivers/gpu/drm/i915/intel_dsi_vbt.c
> +++ b/drivers/gpu/drm/i915/intel_dsi_vbt.c
> @@ -234,7 +234,7 @@ static void vlv_exec_gpio(struct drm_i915_private *dev_priv,
>  	pconf0 = VLV_GPIO_PCONF0(map->base_offset);
>  	padval = VLV_GPIO_PAD_VAL(map->base_offset);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_GPIO));
>  	if (!map->init) {
>  		/* FIXME: remove constant below */
>  		vlv_iosf_sb_write(dev_priv, port, pconf0, 0x2000CC00);
> @@ -243,7 +243,7 @@ static void vlv_exec_gpio(struct drm_i915_private *dev_priv,
>  
>  	tmp = 0x4 | value;
>  	vlv_iosf_sb_write(dev_priv, port, padval, tmp);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
>  }
>  
>  static void chv_exec_gpio(struct drm_i915_private *dev_priv,
> @@ -289,12 +289,12 @@ static void chv_exec_gpio(struct drm_i915_private *dev_priv,
>  	cfg0 = CHV_GPIO_PAD_CFG0(family_num, gpio_index);
>  	cfg1 = CHV_GPIO_PAD_CFG1(family_num, gpio_index);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_GPIO));
>  	vlv_iosf_sb_write(dev_priv, port, cfg1, 0);
>  	vlv_iosf_sb_write(dev_priv, port, cfg0,
>  			  CHV_GPIO_GPIOEN | CHV_GPIO_GPIOCFG_GPO |
>  			  CHV_GPIO_GPIOTXSTATE(value));
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_GPIO));
>  }
>  
>  static void bxt_exec_gpio(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> index 691f15b59124..2b5b7d4f73d7 100644
> --- a/drivers/gpu/drm/i915/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> @@ -1995,12 +1995,12 @@ static void chv_hdmi_post_disable(struct intel_encoder *encoder,
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* Assert data lane reset */
>  	chv_data_lane_soft_reset(encoder, old_crtc_state, true);
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  }
>  
>  static void chv_hdmi_pre_enable(struct intel_encoder *encoder,
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 1db79a860b96..60c666424d65 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -7173,9 +7173,9 @@ static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
>  
>  	vlv_init_gpll_ref_freq(dev_priv);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_cck_get(dev_priv);
>  	val = vlv_cck_read(dev_priv, CCK_FUSE_REG);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_cck_put(dev_priv);
>  
>  	switch ((val >> 2) & 0x7) {
>  	case 3:
> diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> index 4996c4ea8a80..34ffa2dd3996 100644
> --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> @@ -1182,7 +1182,7 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
>  				    1))
>  		DRM_ERROR("Display PHY %d is not power up\n", phy);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  
>  	/* Enable dynamic power down */
>  	tmp = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW28);
> @@ -1205,7 +1205,7 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
>  		vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, tmp);
>  	}
>  
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  
>  	dev_priv->chv_phy_control |= PHY_COM_LANE_RESET_DEASSERT(phy);
>  	I915_WRITE(DISPLAY_PHY_CONTROL, dev_priv->chv_phy_control);
> @@ -1268,9 +1268,9 @@ static void assert_chv_phy_powergate(struct drm_i915_private *dev_priv, enum dpi
>  	else
>  		reg = _CHV_CMN_DW6_CH1;
>  
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_dpio_get(dev_priv);
>  	val = vlv_dpio_read(dev_priv, pipe, reg);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_dpio_put(dev_priv);
>  
>  	/*
>  	 * This assumes !override is only used when the port is disabled.
> diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
> index d56eda33734e..3d7c5917b97c 100644
> --- a/drivers/gpu/drm/i915/intel_sideband.c
> +++ b/drivers/gpu/drm/i915/intel_sideband.c
> @@ -73,6 +73,22 @@ static void __vlv_punit_put(struct drm_i915_private *dev_priv)
>  	iosf_mbi_punit_release();
>  }
>  
> +void vlv_iosf_sb_get(struct drm_i915_private *dev_priv, unsigned long ports)
> +{
> +	if (ports & BIT(VLV_IOSF_SB_PUNIT))
> +		__vlv_punit_get(dev_priv);
> +
> +	mutex_lock(&dev_priv->sb_lock);
> +}
> +
> +void vlv_iosf_sb_put(struct drm_i915_private *dev_priv, unsigned long ports)
> +{
> +	mutex_unlock(&dev_priv->sb_lock);
> +
> +	if (ports & BIT(VLV_IOSF_SB_PUNIT))
> +		__vlv_punit_put(dev_priv);
> +}
> +
>  static int vlv_sideband_rw(struct drm_i915_private *dev_priv,
>  			   u32 devfn, u32 port, u32 opcode,
>  			   u32 addr, u32 *val)
> @@ -81,6 +97,8 @@ static int vlv_sideband_rw(struct drm_i915_private *dev_priv,
>  	int err;
>  
>  	lockdep_assert_held(&dev_priv->sb_lock);
> +	if (port == IOSF_PORT_PUNIT)
> +		iosf_mbi_assert_punit_acquired();
>  
>  	/* Flush the previous comms, just in case it failed last time. */
>  	if (intel_wait_for_register(dev_priv,
> @@ -124,16 +142,14 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
>  {
>  	u32 val = 0;
>  
> -	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
> +	lockdep_assert_held(&dev_priv->pcu_lock);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> -	__vlv_punit_get(dev_priv);
> +	vlv_punit_get(dev_priv);
>  
>  	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
>  			SB_CRRDDA_NP, addr, &val);
>  
> -	__vlv_punit_put(dev_priv);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_punit_put(dev_priv);
>  
>  	return val;
>  }
> @@ -142,20 +158,28 @@ int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
>  {
>  	int err;
>  
> -	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
> +	lockdep_assert_held(&dev_priv->pcu_lock);
>  
> -	mutex_lock(&dev_priv->sb_lock);
> -	__vlv_punit_get(dev_priv);
> +	vlv_punit_get(dev_priv);
>  
>  	err = vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
>  			      SB_CRWRDA_NP, addr, &val);
>  
> -	__vlv_punit_put(dev_priv);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_punit_put(dev_priv);
>  
>  	return err;
>  }
>  
> +void vlv_punit_get(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_PUNIT));
> +}
> +
> +void vlv_punit_put(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_PUNIT));
> +}
> +
>  u32 vlv_bunit_read(struct drm_i915_private *dev_priv, u32 reg)
>  {
>  	u32 val = 0;
> @@ -172,20 +196,38 @@ void vlv_bunit_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
>  			SB_CRWRDA_NP, reg, &val);
>  }
>  
> +void vlv_bunit_get(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_BUNIT));
> +}
> +
> +void vlv_bunit_put(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_BUNIT));
> +}
> +
>  u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr)
>  {
>  	u32 val = 0;
>  
> -	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
> -
> -	mutex_lock(&dev_priv->sb_lock);
> +	vlv_nc_get(dev_priv);
>  	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_NC,
>  			SB_CRRDDA_NP, addr, &val);
> -	mutex_unlock(&dev_priv->sb_lock);
> +	vlv_nc_put(dev_priv);
>  
>  	return val;
>  }
>  
> +void vlv_nc_get(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_NC));
> +}
> +
> +void vlv_nc_put(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_NC));
> +}
> +
>  u32 vlv_iosf_sb_read(struct drm_i915_private *dev_priv, u8 port, u32 reg)
>  {
>  	u32 val = 0;
> @@ -215,6 +257,16 @@ void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
>  			SB_CRWRDA_NP, reg, &val);
>  }
>  
> +void vlv_cck_get(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_CCK));
> +}
> +
> +void vlv_cck_put(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_CCK));
> +}
> +
>  u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg)
>  {
>  	u32 val = 0;
> @@ -229,6 +281,16 @@ void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
>  			SB_CRWRDA_NP, reg, &val);
>  }
>  
> +void vlv_ccu_get(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_CCU));
> +}
> +
> +void vlv_ccu_put(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_CCU));
> +}
> +
>  u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg)
>  {
>  	u32 val = 0;
> @@ -252,12 +314,23 @@ void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg,
>  			SB_MWR_NP, reg, &val);
>  }
>  
> +void vlv_dpio_get(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_DPIO));
> +}
> +
> +void vlv_dpio_put(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_DPIO));
> +}
> +
>  /* SBI access */
>  u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
>  		   enum intel_sbi_destination destination)
>  {
>  	u32 value = 0;
> -	WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
> +
> +	lockdep_assert_held(&dev_priv->sb_lock);
>  
>  	if (intel_wait_for_register(dev_priv,
>  				    SBI_CTL_STAT, SBI_BUSY, 0,
> @@ -297,7 +370,7 @@ void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
>  {
>  	u32 tmp;
>  
> -	WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
> +	lockdep_assert_held(&dev_priv->sb_lock);
>  
>  	if (intel_wait_for_register(dev_priv,
>  				    SBI_CTL_STAT, SBI_BUSY, 0,
> @@ -344,3 +417,13 @@ void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val)
>  	vlv_sideband_rw(dev_priv, DPIO_DEVFN, IOSF_PORT_FLISDSI, SB_CRWRDA_NP,
>  			reg, &val);
>  }
> +
> +void vlv_flisdsi_get(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_get(dev_priv, BIT(VLV_IOSF_SB_FLISDSI));
> +}
> +
> +void vlv_flisdsi_put(struct drm_i915_private *dev_priv)
> +{
> +	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_FLISDSI));
> +}
> -- 
> 2.15.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15  8:47 ` [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband Chris Wilson
@ 2018-01-15 12:04   ` Mika Kuoppala
  2018-01-15 12:13     ` Chris Wilson
                       ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Mika Kuoppala @ 2018-01-15 12:04 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx; +Cc: Hans de Goede

Chris Wilson <chris@chris-wilson.co.uk> writes:

> While we talk to the punit over its sideband, we need to prevent the cpu
> from sleeping in order to prevent a potential machine hang.
>
> Note that by itself, it appears that pm_qos_update_request (via
> intel_idle) doesn't provide a sufficient barrier to ensure that all core
> are indeed awake (out of Cstate) and that the package is awake. To do so,
> we need to supplement the pm_qos with a manual ping on_each_cpu.
>
> v2: Restrict the heavy-weight wakeup to just the ISOF_PORT_PUNIT, there
> is insufficient evidence to implicate a wider problem atm. Similarly,
> restrict the w/a to Valleyview, as Cherryview doesn't have an angry cadre
> of users.
>

One datapoint about the v1 of this patch with the cpu ping in it.
The j1900 byt did end up with system hang during weekend with
drm-tip + v1.

:(
-Mika

> The working theory, courtesy of Ville and Hans, is the issue lies within
> the power delivery and so is likely to be unit and board specific and
> occurs when both the unit/fw require extra power at the same time as the
> cpu package is changing its own power state.
>
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=109051
> References: https://bugs.freedesktop.org/show_bug.cgi?id=102657
> References: https://bugzilla.kernel.org/show_bug.cgi?id=195255
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> Cc: Hans de Goede <hdegoede@redhat.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.c       |  6 +++
>  drivers/gpu/drm/i915/i915_drv.h       |  1 +
>  drivers/gpu/drm/i915/intel_sideband.c | 89 +++++++++++++++++++++++++++--------
>  3 files changed, 77 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 6c8da9d20c33..d4b90cc0130b 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -902,6 +902,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
>  	spin_lock_init(&dev_priv->uncore.lock);
>  
>  	mutex_init(&dev_priv->sb_lock);
> +	pm_qos_add_request(&dev_priv->sb_qos,
> +			   PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
> +
>  	mutex_init(&dev_priv->modeset_restore_lock);
>  	mutex_init(&dev_priv->av_mutex);
>  	mutex_init(&dev_priv->wm.wm_mutex);
> @@ -953,6 +956,9 @@ static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
>  	intel_irq_fini(dev_priv);
>  	i915_workqueues_cleanup(dev_priv);
>  	i915_engines_cleanup(dev_priv);
> +
> +	pm_qos_remove_request(&dev_priv->sb_qos);
> +	mutex_destroy(&dev_priv->sb_lock);
>  }
>  
>  static int i915_mmio_setup(struct drm_i915_private *dev_priv)
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index c42015b05b47..d95d8c3d04aa 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1886,6 +1886,7 @@ struct drm_i915_private {
>  
>  	/* Sideband mailbox protection */
>  	struct mutex sb_lock;
> +	struct pm_qos_request sb_qos;
>  
>  	/** Cached value of IMR to avoid reads in updating the bitfield */
>  	union {
> diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
> index 75c872bb8cc9..d56eda33734e 100644
> --- a/drivers/gpu/drm/i915/intel_sideband.c
> +++ b/drivers/gpu/drm/i915/intel_sideband.c
> @@ -22,6 +22,8 @@
>   *
>   */
>  
> +#include <asm/iosf_mbi.h>
> +
>  #include "i915_drv.h"
>  #include "intel_drv.h"
>  
> @@ -39,18 +41,48 @@
>  /* Private register write, double-word addressing, non-posted */
>  #define SB_CRWRDA_NP	0x07
>  
> -static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
> -			   u32 port, u32 opcode, u32 addr, u32 *val)
> +static void ping(void *info)
>  {
> -	u32 cmd, be = 0xf, bar = 0;
> -	bool is_read = (opcode == SB_MRD_NP || opcode == SB_CRRDDA_NP);
> +}
>  
> -	cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
> -		(port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
> -		(bar << IOSF_BAR_SHIFT);
> +static void __vlv_punit_get(struct drm_i915_private *dev_priv)
> +{
> +	iosf_mbi_punit_acquire();
>  
> -	WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
> +	/*
> +	 * Prevent the cpu from sleeping while we use this sideband, otherwise
> +	 * the punit may cause a machine hang. The issue appears to be isolated
> +	 * with changing the power state of the CPU package while changing
> +	 * the power state via the punit, and we have only observed it
> +	 * reliably on 4-core Baytail systems suggesting the issue is in the
> +	 * power delivery mechanism and likely to be be board/function
> +	 * specific. Hence we presume the workaround needs only be applied
> +	 * to the Valleyview P-unit and not all sideband communications.
> +	 */
> +	if (IS_VALLEYVIEW(dev_priv)) {
> +		pm_qos_update_request(&dev_priv->sb_qos, 0);
> +		on_each_cpu(ping, NULL, 1);
> +	}
> +}
> +
> +static void __vlv_punit_put(struct drm_i915_private *dev_priv)
> +{
> +	if (IS_VALLEYVIEW(dev_priv))
> +		pm_qos_update_request(&dev_priv->sb_qos, PM_QOS_DEFAULT_VALUE);
>  
> +	iosf_mbi_punit_release();
> +}
> +
> +static int vlv_sideband_rw(struct drm_i915_private *dev_priv,
> +			   u32 devfn, u32 port, u32 opcode,
> +			   u32 addr, u32 *val)
> +{
> +	const bool is_read = (opcode == SB_MRD_NP || opcode == SB_CRRDDA_NP);
> +	int err;
> +
> +	lockdep_assert_held(&dev_priv->sb_lock);
> +
> +	/* Flush the previous comms, just in case it failed last time. */
>  	if (intel_wait_for_register(dev_priv,
>  				    VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
>  				    5)) {
> @@ -59,22 +91,33 @@ static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
>  		return -EAGAIN;
>  	}
>  
> -	I915_WRITE(VLV_IOSF_ADDR, addr);
> -	I915_WRITE(VLV_IOSF_DATA, is_read ? 0 : *val);
> -	I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
> -
> -	if (intel_wait_for_register(dev_priv,
> -				    VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
> -				    5)) {
> +	preempt_disable();
> +
> +	I915_WRITE_FW(VLV_IOSF_ADDR, addr);
> +	I915_WRITE_FW(VLV_IOSF_DATA, is_read ? 0 : *val);
> +	I915_WRITE_FW(VLV_IOSF_DOORBELL_REQ,
> +		      (devfn << IOSF_DEVFN_SHIFT) |
> +		      (opcode << IOSF_OPCODE_SHIFT) |
> +		      (port << IOSF_PORT_SHIFT) |
> +		      (0xf << IOSF_BYTE_ENABLES_SHIFT) |
> +		      (0 << IOSF_BAR_SHIFT) |
> +		      IOSF_SB_BUSY);
> +
> +	if (__intel_wait_for_register_fw(dev_priv,
> +					 VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
> +					 10000, 0, NULL) == 0) {
> +		if (is_read)
> +			*val = I915_READ_FW(VLV_IOSF_DATA);
> +		err = 0;
> +	} else {
>  		DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
>  				 is_read ? "read" : "write");
> -		return -ETIMEDOUT;
> +		err = -ETIMEDOUT;
>  	}
>  
> -	if (is_read)
> -		*val = I915_READ(VLV_IOSF_DATA);
> +	preempt_enable();
>  
> -	return 0;
> +	return err;
>  }
>  
>  u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
> @@ -84,8 +127,12 @@ u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
>  	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
>  
>  	mutex_lock(&dev_priv->sb_lock);
> +	__vlv_punit_get(dev_priv);
> +
>  	vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
>  			SB_CRRDDA_NP, addr, &val);
> +
> +	__vlv_punit_put(dev_priv);
>  	mutex_unlock(&dev_priv->sb_lock);
>  
>  	return val;
> @@ -98,8 +145,12 @@ int vlv_punit_write(struct drm_i915_private *dev_priv, u32 addr, u32 val)
>  	WARN_ON(!mutex_is_locked(&dev_priv->pcu_lock));
>  
>  	mutex_lock(&dev_priv->sb_lock);
> +	__vlv_punit_get(dev_priv);
> +
>  	err = vlv_sideband_rw(dev_priv, PCI_DEVFN(0, 0), IOSF_PORT_PUNIT,
>  			      SB_CRWRDA_NP, addr, &val);
> +
> +	__vlv_punit_put(dev_priv);
>  	mutex_unlock(&dev_priv->sb_lock);
>  
>  	return err;
> -- 
> 2.15.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15 12:04   ` Mika Kuoppala
@ 2018-01-15 12:13     ` Chris Wilson
  2018-01-16 15:27       ` Mika Kuoppala
  2018-01-15 12:21     ` Chris Wilson
  2018-01-22 12:54     ` Chris Wilson
  2 siblings, 1 reply; 26+ messages in thread
From: Chris Wilson @ 2018-01-15 12:13 UTC (permalink / raw)
  To: Mika Kuoppala, intel-gfx; +Cc: Hans de Goede

Quoting Mika Kuoppala (2018-01-15 12:04:40)
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > While we talk to the punit over its sideband, we need to prevent the cpu
> > from sleeping in order to prevent a potential machine hang.
> >
> > Note that by itself, it appears that pm_qos_update_request (via
> > intel_idle) doesn't provide a sufficient barrier to ensure that all core
> > are indeed awake (out of Cstate) and that the package is awake. To do so,
> > we need to supplement the pm_qos with a manual ping on_each_cpu.
> >
> > v2: Restrict the heavy-weight wakeup to just the ISOF_PORT_PUNIT, there
> > is insufficient evidence to implicate a wider problem atm. Similarly,
> > restrict the w/a to Valleyview, as Cherryview doesn't have an angry cadre
> > of users.
> >
> 
> One datapoint about the v1 of this patch with the cpu ping in it.
> The j1900 byt did end up with system hang during weekend with
> drm-tip + v1.

Not much different (supposedly in v2, especially if we ignore the bits
after the revert), and v2 ran most of Fri-Mon without incident. (Most
because I tested a few other things as well, such as eliminating the
waitboosting for glxgears in the reproducer.)

1 hang in 100 hours across 2 machines. Certainly the best we've achieved
so far (while allowing RPS to frequently adjust gpufreq). Any fresh ideas?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15 12:04   ` Mika Kuoppala
  2018-01-15 12:13     ` Chris Wilson
@ 2018-01-15 12:21     ` Chris Wilson
  2018-01-15 13:07       ` Hans de Goede
  2018-01-15 13:43       ` Mika Kuoppala
  2018-01-22 12:54     ` Chris Wilson
  2 siblings, 2 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-15 12:21 UTC (permalink / raw)
  To: Mika Kuoppala, intel-gfx; +Cc: Hans de Goede

Quoting Mika Kuoppala (2018-01-15 12:04:40)
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > While we talk to the punit over its sideband, we need to prevent the cpu
> > from sleeping in order to prevent a potential machine hang.
> >
> > Note that by itself, it appears that pm_qos_update_request (via
> > intel_idle) doesn't provide a sufficient barrier to ensure that all core
> > are indeed awake (out of Cstate) and that the package is awake. To do so,
> > we need to supplement the pm_qos with a manual ping on_each_cpu.
> >
> > v2: Restrict the heavy-weight wakeup to just the ISOF_PORT_PUNIT, there
> > is insufficient evidence to implicate a wider problem atm. Similarly,
> > restrict the w/a to Valleyview, as Cherryview doesn't have an angry cadre
> > of users.
> >
> 
> One datapoint about the v1 of this patch with the cpu ping in it.
> The j1900 byt did end up with system hang during weekend with
> drm-tip + v1.

Question: did you set CONFIG_I2C_DESIGNWARE_BAYTRAIL=y?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15 12:21     ` Chris Wilson
@ 2018-01-15 13:07       ` Hans de Goede
  2018-01-15 13:43       ` Mika Kuoppala
  1 sibling, 0 replies; 26+ messages in thread
From: Hans de Goede @ 2018-01-15 13:07 UTC (permalink / raw)
  To: Chris Wilson, Mika Kuoppala, intel-gfx

Hi,

On 15-01-18 13:21, Chris Wilson wrote:
> Quoting Mika Kuoppala (2018-01-15 12:04:40)
>> Chris Wilson <chris@chris-wilson.co.uk> writes:
>>
>>> While we talk to the punit over its sideband, we need to prevent the cpu
>>> from sleeping in order to prevent a potential machine hang.
>>>
>>> Note that by itself, it appears that pm_qos_update_request (via
>>> intel_idle) doesn't provide a sufficient barrier to ensure that all core
>>> are indeed awake (out of Cstate) and that the package is awake. To do so,
>>> we need to supplement the pm_qos with a manual ping on_each_cpu.
>>>
>>> v2: Restrict the heavy-weight wakeup to just the ISOF_PORT_PUNIT, there
>>> is insufficient evidence to implicate a wider problem atm. Similarly,
>>> restrict the w/a to Valleyview, as Cherryview doesn't have an angry cadre
>>> of users.
>>>
>>
>> One datapoint about the v1 of this patch with the cpu ping in it.
>> The j1900 byt did end up with system hang during weekend with
>> drm-tip + v1.
> 
> Question: did you set CONFIG_I2C_DESIGNWARE_BAYTRAIL=y?

Note this only matters (AFAIK) on a board with an AXP288 PMIC, on
other boards the i2c-bus is not shared between the kernel and the
punit, so no synchronization is happening (or necessary). I'm not
aware of any J1900 boards with the AXP288 (which does not mean
they do not exist).

If you have CONFIG_I2C_DESIGNWARE_BAYTRAIL enabled and you've an
affected PMIC then dmesg should contain:

"I2C bus managed by PUNIT"

Chris, are you seeing actual testing differences on a system
without a PUNIT manages I2C bus ? If so then the only reason
I can think of this is because the iosf_mbi_punit_acquire()
call will synchronize punit sideband accesses with
intel_uncore_forcewake_reset() calls, since both take the
mutex behind it, which is otherwise unused on systems without
the "I2C bus managed by PUNIT" thingie. But that would be strange
as I would not expect intel_uncore_forcewake_reset() calls
to happen during normal use (except for suspend/resume).

So if you do not have that message; and you do see different
testing results from adding the iosf_mbi_punit_acquire(), then
that suggests that we need to make sure no punit sideband
accesses are happening while changing forcewake settings.

iosf_mbi_punit_acquire() is not a complete solution here,
the i2c-designware-baytrail code also calls a notifier
(iosf_mbi_call_pmic_bus_access_notifier_chain) before doing
a PMIC access over the shared i2c bus, i915 code listens to
that notifier and gets all forcewake bits before before
the notifier call returns, so that we can be sure there will
be no forcewake gets/puts happening while an i2c bus access
is active on the PMIC i2c bus shared with the PUNIT.

The notifier approach is used here because the forcewake
gets may happen from non-sleeping contexts, so we just make
sure that everything is active beforehand.

With all this said I still think that doing the
iosf_mbi_punit_acquire() is a good idea, so that we block
i2c transfers on the PMIC i2c bus shared with the PUNIT
while we are talking to the PUNIT.

Regards,

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

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

* Re: [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15 12:21     ` Chris Wilson
  2018-01-15 13:07       ` Hans de Goede
@ 2018-01-15 13:43       ` Mika Kuoppala
  1 sibling, 0 replies; 26+ messages in thread
From: Mika Kuoppala @ 2018-01-15 13:43 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx; +Cc: Hans de Goede

Chris Wilson <chris@chris-wilson.co.uk> writes:

> Quoting Mika Kuoppala (2018-01-15 12:04:40)
>> Chris Wilson <chris@chris-wilson.co.uk> writes:
>> 
>> > While we talk to the punit over its sideband, we need to prevent the cpu
>> > from sleeping in order to prevent a potential machine hang.
>> >
>> > Note that by itself, it appears that pm_qos_update_request (via
>> > intel_idle) doesn't provide a sufficient barrier to ensure that all core
>> > are indeed awake (out of Cstate) and that the package is awake. To do so,
>> > we need to supplement the pm_qos with a manual ping on_each_cpu.
>> >
>> > v2: Restrict the heavy-weight wakeup to just the ISOF_PORT_PUNIT, there
>> > is insufficient evidence to implicate a wider problem atm. Similarly,
>> > restrict the w/a to Valleyview, as Cherryview doesn't have an angry cadre
>> > of users.
>> >
>> 
>> One datapoint about the v1 of this patch with the cpu ping in it.
>> The j1900 byt did end up with system hang during weekend with
>> drm-tip + v1.
>
> Question: did you set CONFIG_I2C_DESIGNWARE_BAYTRAIL=y?

I do have:
CONFIG_I2C_DESIGNWARE_BAYTRAIL=y

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

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

* Re: [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15 12:13     ` Chris Wilson
@ 2018-01-16 15:27       ` Mika Kuoppala
  0 siblings, 0 replies; 26+ messages in thread
From: Mika Kuoppala @ 2018-01-16 15:27 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx; +Cc: Hans de Goede

Chris Wilson <chris@chris-wilson.co.uk> writes:

> Quoting Mika Kuoppala (2018-01-15 12:04:40)
>> Chris Wilson <chris@chris-wilson.co.uk> writes:
>> 
>> > While we talk to the punit over its sideband, we need to prevent the cpu
>> > from sleeping in order to prevent a potential machine hang.
>> >
>> > Note that by itself, it appears that pm_qos_update_request (via
>> > intel_idle) doesn't provide a sufficient barrier to ensure that all core
>> > are indeed awake (out of Cstate) and that the package is awake. To do so,
>> > we need to supplement the pm_qos with a manual ping on_each_cpu.
>> >
>> > v2: Restrict the heavy-weight wakeup to just the ISOF_PORT_PUNIT, there
>> > is insufficient evidence to implicate a wider problem atm. Similarly,
>> > restrict the w/a to Valleyview, as Cherryview doesn't have an angry cadre
>> > of users.
>> >
>> 
>> One datapoint about the v1 of this patch with the cpu ping in it.
>> The j1900 byt did end up with system hang during weekend with
>> drm-tip + v1.
>
> Not much different (supposedly in v2, especially if we ignore the bits
> after the revert), and v2 ran most of Fri-Mon without incident. (Most
> because I tested a few other things as well, such as eliminating the
> waitboosting for glxgears in the reproducer.)
>
> 1 hang in 100 hours across 2 machines. Certainly the best we've achieved
> so far (while allowing RPS to frequently adjust gpufreq). Any fresh ideas?

Since you asked, I tried to express one idea with a fresh patch:
20180116152116.17900-1-mika.kuoppala@linux.intel.com

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

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

* Re: [PATCH v2 11/11] drm/i915: Avoid waitboosting on the active request
  2018-01-15  8:47 ` [PATCH v2 11/11] drm/i915: Avoid waitboosting on the active request Chris Wilson
@ 2018-01-18  9:49   ` Joonas Lahtinen
  0 siblings, 0 replies; 26+ messages in thread
From: Joonas Lahtinen @ 2018-01-18  9:49 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On Mon, 2018-01-15 at 08:47 +0000, Chris Wilson wrote:
> Watching a light workload on Baytrail (running glxgears and a 1080p
> decode), instead of the system remaining at low frequency, the glxgears
> would regularly trigger waitboosting after which it would have to spend
> a few seconds throttling back down. In this case, the waitboosting is
> counter productive as the minimal wait for glxgears doesn't prevent it
> from functioning correctly and delivering frames on time. In this case,
> glxgears happens to almost always be waiting on the current request,
> which we already expect to complete quickly (see i915_spin_request) and
> so avoiding the waitboost on the active request and spinning instead
> provides the best latency without overcommitting to upclocking.
> However, if the system falls behind we still force the waitboost.
> Similarly, we will also trigger upclocking if we detect the system is
> not delivering frames on time - again using a mechanism that tries to
> detect a miss and not preemptively upclock.
> 
> v2: Also skip boosting for after missed vblank if the desired request is
> already active.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
-- 
Joonas Lahtinen
Open Source Technology Center
Intel Corporation
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 10/11] drm/i915: Move sandybride pcode access to intel_sideband.c
  2018-01-15  8:47 ` [PATCH v2 10/11] drm/i915: Move sandybride pcode access to intel_sideband.c Chris Wilson
@ 2018-01-19  8:21   ` Mika Kuoppala
  2018-01-19  8:33     ` Chris Wilson
  0 siblings, 1 reply; 26+ messages in thread
From: Mika Kuoppala @ 2018-01-19  8:21 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

Chris Wilson <chris@chris-wilson.co.uk> writes:

> sandybride_pcode is another sideband, so move it to their new home.
>

Up to this patch, omitting the waitboosting. Uptime 41min till
system hang on j1900.

With waitboosting patch it did survive without system hangs
for 24h+ but the frequency seemed to remain constant.

-Mika


> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/i915_drv.h       |   5 -
>  drivers/gpu/drm/i915/intel_hdcp.c     |   3 +-
>  drivers/gpu/drm/i915/intel_pm.c       | 190 ----------------------------------
>  drivers/gpu/drm/i915/intel_sideband.c | 190 ++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_sideband.h |   5 +
>  5 files changed, 197 insertions(+), 196 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 4d9e9741ed8f..a0bb0f018a76 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -3706,11 +3706,6 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv);
>  extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
>  					    struct intel_display_error_state *error);
>  
> -int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
> -int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
> -int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
> -		      u32 reply_mask, u32 reply, int timeout_base_ms);
> -
>  /* intel_dpio_phy.c */
>  void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
>  			     enum dpio_phy *phy, enum dpio_channel *ch);
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> index d0e97172b8ed..1afae93707a1 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -11,8 +11,9 @@
>  #include <linux/i2c.h>
>  #include <linux/random.h>
>  
> -#include "intel_drv.h"
>  #include "i915_reg.h"
> +#include "intel_drv.h"
> +#include "intel_sideband.h"
>  
>  #define KEY_LOAD_TRIES	5
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 18945264b835..a69b742147f7 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -9080,196 +9080,6 @@ void intel_init_pm(struct drm_i915_private *dev_priv)
>  	}
>  }
>  
> -static inline int gen6_check_mailbox_status(struct drm_i915_private *dev_priv)
> -{
> -	uint32_t flags =
> -		I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK;
> -
> -	switch (flags) {
> -	case GEN6_PCODE_SUCCESS:
> -		return 0;
> -	case GEN6_PCODE_UNIMPLEMENTED_CMD:
> -		return -ENODEV;
> -	case GEN6_PCODE_ILLEGAL_CMD:
> -		return -ENXIO;
> -	case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
> -	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
> -		return -EOVERFLOW;
> -	case GEN6_PCODE_TIMEOUT:
> -		return -ETIMEDOUT;
> -	default:
> -		MISSING_CASE(flags);
> -		return 0;
> -	}
> -}
> -
> -static inline int gen7_check_mailbox_status(struct drm_i915_private *dev_priv)
> -{
> -	uint32_t flags =
> -		I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK;
> -
> -	switch (flags) {
> -	case GEN6_PCODE_SUCCESS:
> -		return 0;
> -	case GEN6_PCODE_ILLEGAL_CMD:
> -		return -ENXIO;
> -	case GEN7_PCODE_TIMEOUT:
> -		return -ETIMEDOUT;
> -	case GEN7_PCODE_ILLEGAL_DATA:
> -		return -EINVAL;
> -	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
> -		return -EOVERFLOW;
> -	default:
> -		MISSING_CASE(flags);
> -		return 0;
> -	}
> -}
> -
> -static int __sandybridge_pcode_rw(struct drm_i915_private *dev_priv,
> -				  u32 mbox, u32 *val, bool is_read)
> -{
> -	int status;
> -
> -	lockdep_assert_held(&dev_priv->sb_lock);
> -
> -	/*
> -	 * GEN6_PCODE_* are outside of the forcewake domain, we can
> -	 * use te fw I915_READ variants to reduce the amount of work
> -	 * required when reading/writing.
> -	 */
> -
> -	if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
> -		return -EAGAIN;
> -
> -	I915_WRITE_FW(GEN6_PCODE_DATA, *val);
> -	I915_WRITE_FW(GEN6_PCODE_DATA1, 0);
> -	I915_WRITE_FW(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
> -
> -	if (__intel_wait_for_register_fw(dev_priv,
> -					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
> -					 500, 0, NULL))
> -		return -ETIMEDOUT;
> -
> -	if (is_read)
> -		*val = I915_READ_FW(GEN6_PCODE_DATA);
> -	I915_WRITE_FW(GEN6_PCODE_DATA, 0);
> -
> -	if (INTEL_GEN(dev_priv) > 6)
> -		status = gen7_check_mailbox_status(dev_priv);
> -	else
> -		status = gen6_check_mailbox_status(dev_priv);
> -
> -	return status;
> -}
> -
> -int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val)
> -{
> -	int status;
> -
> -	mutex_lock(&dev_priv->sb_lock);
> -	status = __sandybridge_pcode_rw(dev_priv, mbox, val, true);
> -	mutex_unlock(&dev_priv->sb_lock);
> -
> -	if (status) {
> -		DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n",
> -				 mbox, __builtin_return_address(0), status);
> -	}
> -
> -	return status;
> -}
> -
> -int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
> -			    u32 mbox, u32 val)
> -{
> -	int status;
> -
> -	mutex_lock(&dev_priv->sb_lock);
> -	status = __sandybridge_pcode_rw(dev_priv, mbox, &val, false);
> -	mutex_unlock(&dev_priv->sb_lock);
> -
> -	if (status) {
> -		DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n",
> -				 val, mbox, __builtin_return_address(0), status);
> -	}
> -
> -	return status;
> -}
> -
> -static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
> -				  u32 request, u32 reply_mask, u32 reply,
> -				  u32 *status)
> -{
> -	*status = __sandybridge_pcode_rw(dev_priv, mbox, &request, true);
> -
> -	return *status || ((request & reply_mask) == reply);
> -}
> -
> -/**
> - * skl_pcode_request - send PCODE request until acknowledgment
> - * @dev_priv: device private
> - * @mbox: PCODE mailbox ID the request is targeted for
> - * @request: request ID
> - * @reply_mask: mask used to check for request acknowledgment
> - * @reply: value used to check for request acknowledgment
> - * @timeout_base_ms: timeout for polling with preemption enabled
> - *
> - * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE
> - * reports an error or an overall timeout of @timeout_base_ms+50 ms expires.
> - * The request is acknowledged once the PCODE reply dword equals @reply after
> - * applying @reply_mask. Polling is first attempted with preemption enabled
> - * for @timeout_base_ms and if this times out for another 50 ms with
> - * preemption disabled.
> - *
> - * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some
> - * other error as reported by PCODE.
> - */
> -int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
> -		      u32 reply_mask, u32 reply, int timeout_base_ms)
> -{
> -	u32 status;
> -	int ret;
> -
> -	mutex_lock(&dev_priv->sb_lock);
> -
> -#define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \
> -				   &status)
> -
> -	/*
> -	 * Prime the PCODE by doing a request first. Normally it guarantees
> -	 * that a subsequent request, at most @timeout_base_ms later, succeeds.
> -	 * _wait_for() doesn't guarantee when its passed condition is evaluated
> -	 * first, so send the first request explicitly.
> -	 */
> -	if (COND) {
> -		ret = 0;
> -		goto out;
> -	}
> -	ret = _wait_for(COND, timeout_base_ms * 1000, 10, 10);
> -	if (!ret)
> -		goto out;
> -
> -	/*
> -	 * The above can time out if the number of requests was low (2 in the
> -	 * worst case) _and_ PCODE was busy for some reason even after a
> -	 * (queued) request and @timeout_base_ms delay. As a workaround retry
> -	 * the poll with preemption disabled to maximize the number of
> -	 * requests. Increase the timeout from @timeout_base_ms to 50ms to
> -	 * account for interrupts that could reduce the number of these
> -	 * requests, and for any quirks of the PCODE firmware that delays
> -	 * the request completion.
> -	 */
> -	DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n");
> -	WARN_ON_ONCE(timeout_base_ms > 3);
> -	preempt_disable();
> -	ret = wait_for_atomic(COND, 50);
> -	preempt_enable();
> -
> -out:
> -	mutex_unlock(&dev_priv->sb_lock);
> -	return ret ? ret : status;
> -#undef COND
> -}
> -
>  static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
>  {
>  	struct intel_rps *rps = &dev_priv->gt_pm.rps;
> diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
> index 6815be9e5b7c..a9ba378bf9fc 100644
> --- a/drivers/gpu/drm/i915/intel_sideband.c
> +++ b/drivers/gpu/drm/i915/intel_sideband.c
> @@ -383,3 +383,193 @@ void vlv_flisdsi_put(struct drm_i915_private *dev_priv)
>  {
>  	vlv_iosf_sb_put(dev_priv, BIT(VLV_IOSF_SB_FLISDSI));
>  }
> +
> +static inline int gen6_check_mailbox_status(struct drm_i915_private *dev_priv)
> +{
> +	uint32_t flags =
> +		I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK;
> +
> +	switch (flags) {
> +	case GEN6_PCODE_SUCCESS:
> +		return 0;
> +	case GEN6_PCODE_UNIMPLEMENTED_CMD:
> +		return -ENODEV;
> +	case GEN6_PCODE_ILLEGAL_CMD:
> +		return -ENXIO;
> +	case GEN6_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
> +	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
> +		return -EOVERFLOW;
> +	case GEN6_PCODE_TIMEOUT:
> +		return -ETIMEDOUT;
> +	default:
> +		MISSING_CASE(flags);
> +		return 0;
> +	}
> +}
> +
> +static inline int gen7_check_mailbox_status(struct drm_i915_private *dev_priv)
> +{
> +	uint32_t flags =
> +		I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_ERROR_MASK;
> +
> +	switch (flags) {
> +	case GEN6_PCODE_SUCCESS:
> +		return 0;
> +	case GEN6_PCODE_ILLEGAL_CMD:
> +		return -ENXIO;
> +	case GEN7_PCODE_TIMEOUT:
> +		return -ETIMEDOUT;
> +	case GEN7_PCODE_ILLEGAL_DATA:
> +		return -EINVAL;
> +	case GEN7_PCODE_MIN_FREQ_TABLE_GT_RATIO_OUT_OF_RANGE:
> +		return -EOVERFLOW;
> +	default:
> +		MISSING_CASE(flags);
> +		return 0;
> +	}
> +}
> +
> +static int __sandybridge_pcode_rw(struct drm_i915_private *dev_priv,
> +				  u32 mbox, u32 *val, bool is_read)
> +{
> +	int status;
> +
> +	lockdep_assert_held(&dev_priv->sb_lock);
> +
> +	/*
> +	 * GEN6_PCODE_* are outside of the forcewake domain, we can
> +	 * use te fw I915_READ variants to reduce the amount of work
> +	 * required when reading/writing.
> +	 */
> +
> +	if (I915_READ_FW(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY)
> +		return -EAGAIN;
> +
> +	I915_WRITE_FW(GEN6_PCODE_DATA, *val);
> +	I915_WRITE_FW(GEN6_PCODE_DATA1, 0);
> +	I915_WRITE_FW(GEN6_PCODE_MAILBOX, GEN6_PCODE_READY | mbox);
> +
> +	if (__intel_wait_for_register_fw(dev_priv,
> +					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
> +					 500, 0, NULL))
> +		return -ETIMEDOUT;
> +
> +	if (is_read)
> +		*val = I915_READ_FW(GEN6_PCODE_DATA);
> +	I915_WRITE_FW(GEN6_PCODE_DATA, 0);
> +
> +	if (INTEL_GEN(dev_priv) > 6)
> +		status = gen7_check_mailbox_status(dev_priv);
> +	else
> +		status = gen6_check_mailbox_status(dev_priv);
> +
> +	return status;
> +}
> +
> +int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val)
> +{
> +	int status;
> +
> +	mutex_lock(&dev_priv->sb_lock);
> +	status = __sandybridge_pcode_rw(dev_priv, mbox, val, true);
> +	mutex_unlock(&dev_priv->sb_lock);
> +
> +	if (status) {
> +		DRM_DEBUG_DRIVER("warning: pcode (read from mbox %x) mailbox access failed for %ps: %d\n",
> +				 mbox, __builtin_return_address(0), status);
> +	}
> +
> +	return status;
> +}
> +
> +int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
> +			    u32 mbox, u32 val)
> +{
> +	int status;
> +
> +	mutex_lock(&dev_priv->sb_lock);
> +	status = __sandybridge_pcode_rw(dev_priv, mbox, &val, false);
> +	mutex_unlock(&dev_priv->sb_lock);
> +
> +	if (status) {
> +		DRM_DEBUG_DRIVER("warning: pcode (write of 0x%08x to mbox %x) mailbox access failed for %ps: %d\n",
> +				 val, mbox, __builtin_return_address(0), status);
> +	}
> +
> +	return status;
> +}
> +
> +static bool skl_pcode_try_request(struct drm_i915_private *dev_priv, u32 mbox,
> +				  u32 request, u32 reply_mask, u32 reply,
> +				  u32 *status)
> +{
> +	*status = __sandybridge_pcode_rw(dev_priv, mbox, &request, true);
> +
> +	return *status || ((request & reply_mask) == reply);
> +}
> +
> +/**
> + * skl_pcode_request - send PCODE request until acknowledgment
> + * @dev_priv: device private
> + * @mbox: PCODE mailbox ID the request is targeted for
> + * @request: request ID
> + * @reply_mask: mask used to check for request acknowledgment
> + * @reply: value used to check for request acknowledgment
> + * @timeout_base_ms: timeout for polling with preemption enabled
> + *
> + * Keep resending the @request to @mbox until PCODE acknowledges it, PCODE
> + * reports an error or an overall timeout of @timeout_base_ms+50 ms expires.
> + * The request is acknowledged once the PCODE reply dword equals @reply after
> + * applying @reply_mask. Polling is first attempted with preemption enabled
> + * for @timeout_base_ms and if this times out for another 50 ms with
> + * preemption disabled.
> + *
> + * Returns 0 on success, %-ETIMEDOUT in case of a timeout, <0 in case of some
> + * other error as reported by PCODE.
> + */
> +int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
> +		      u32 reply_mask, u32 reply, int timeout_base_ms)
> +{
> +	u32 status;
> +	int ret;
> +
> +	mutex_lock(&dev_priv->sb_lock);
> +
> +#define COND skl_pcode_try_request(dev_priv, mbox, request, reply_mask, reply, \
> +				   &status)
> +
> +	/*
> +	 * Prime the PCODE by doing a request first. Normally it guarantees
> +	 * that a subsequent request, at most @timeout_base_ms later, succeeds.
> +	 * _wait_for() doesn't guarantee when its passed condition is evaluated
> +	 * first, so send the first request explicitly.
> +	 */
> +	if (COND) {
> +		ret = 0;
> +		goto out;
> +	}
> +	ret = _wait_for(COND, timeout_base_ms * 1000, 10, 10);
> +	if (!ret)
> +		goto out;
> +
> +	/*
> +	 * The above can time out if the number of requests was low (2 in the
> +	 * worst case) _and_ PCODE was busy for some reason even after a
> +	 * (queued) request and @timeout_base_ms delay. As a workaround retry
> +	 * the poll with preemption disabled to maximize the number of
> +	 * requests. Increase the timeout from @timeout_base_ms to 50ms to
> +	 * account for interrupts that could reduce the number of these
> +	 * requests, and for any quirks of the PCODE firmware that delays
> +	 * the request completion.
> +	 */
> +	DRM_DEBUG_KMS("PCODE timeout, retrying with preemption disabled\n");
> +	WARN_ON_ONCE(timeout_base_ms > 3);
> +	preempt_disable();
> +	ret = wait_for_atomic(COND, 50);
> +	preempt_enable();
> +
> +out:
> +	mutex_unlock(&dev_priv->sb_lock);
> +	return ret ? ret : status;
> +#undef COND
> +}
> diff --git a/drivers/gpu/drm/i915/intel_sideband.h b/drivers/gpu/drm/i915/intel_sideband.h
> index 46e917dd3973..999c1da2cd93 100644
> --- a/drivers/gpu/drm/i915/intel_sideband.h
> +++ b/drivers/gpu/drm/i915/intel_sideband.h
> @@ -68,4 +68,9 @@ u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
>  void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
>  		     enum intel_sbi_destination destination);
>  
> +int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
> +int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
> +int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
> +		      u32 reply_mask, u32 reply, int timeout_base_ms);
> +
>  #endif /* _INTEL_SIDEBAND_H */
> -- 
> 2.15.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 10/11] drm/i915: Move sandybride pcode access to intel_sideband.c
  2018-01-19  8:21   ` Mika Kuoppala
@ 2018-01-19  8:33     ` Chris Wilson
  0 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-19  8:33 UTC (permalink / raw)
  To: Mika Kuoppala, intel-gfx

Quoting Mika Kuoppala (2018-01-19 08:21:31)
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > sandybride_pcode is another sideband, so move it to their new home.
> >
> 
> Up to this patch, omitting the waitboosting. Uptime 41min till
> system hang on j1900.

Still weird, my system is still surviving with its spiky frequency
graph. Starting to suspect the old test case just doesn't cut it any
more.
 
> With waitboosting patch it did survive without system hangs
> for 24h+ but the frequency seemed to remain constant.

Sorry for breaking your testcase :-p
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband
  2018-01-15 12:04   ` Mika Kuoppala
  2018-01-15 12:13     ` Chris Wilson
  2018-01-15 12:21     ` Chris Wilson
@ 2018-01-22 12:54     ` Chris Wilson
  2 siblings, 0 replies; 26+ messages in thread
From: Chris Wilson @ 2018-01-22 12:54 UTC (permalink / raw)
  To: Mika Kuoppala, intel-gfx; +Cc: Hans de Goede

Quoting Mika Kuoppala (2018-01-15 12:04:40)
> Chris Wilson <chris@chris-wilson.co.uk> writes:
> 
> > While we talk to the punit over its sideband, we need to prevent the cpu
> > from sleeping in order to prevent a potential machine hang.
> >
> > Note that by itself, it appears that pm_qos_update_request (via
> > intel_idle) doesn't provide a sufficient barrier to ensure that all core
> > are indeed awake (out of Cstate) and that the package is awake. To do so,
> > we need to supplement the pm_qos with a manual ping on_each_cpu.
> >
> > v2: Restrict the heavy-weight wakeup to just the ISOF_PORT_PUNIT, there
> > is insufficient evidence to implicate a wider problem atm. Similarly,
> > restrict the w/a to Valleyview, as Cherryview doesn't have an angry cadre
> > of users.
> >
> 
> One datapoint about the v1 of this patch with the cpu ping in it.
> The j1900 byt did end up with system hang during weekend with
> drm-tip + v1.

Fwiw, I've reproduced a scenario that triggers j1900 death:
gem_exec_load/pulse.

So far so good with essentially this patchset on drm-tip. Does that
testcase trigger the bug for you?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2018-01-22 12:54 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-15  8:47 Vlv punit w/a (take two) Chris Wilson
2018-01-15  8:47 ` [PATCH v2 01/11] drm/i915: Disable preemption and sleeping while using the punit sideband Chris Wilson
2018-01-15 12:04   ` Mika Kuoppala
2018-01-15 12:13     ` Chris Wilson
2018-01-16 15:27       ` Mika Kuoppala
2018-01-15 12:21     ` Chris Wilson
2018-01-15 13:07       ` Hans de Goede
2018-01-15 13:43       ` Mika Kuoppala
2018-01-22 12:54     ` Chris Wilson
2018-01-15  8:47 ` [PATCH v2 02/11] drm/i915: Lift acquiring the vlv punit magic to a common sb-get Chris Wilson
2018-01-15 10:36   ` Mika Kuoppala
2018-01-15  8:47 ` [PATCH v2 03/11] drm/i915: Lift sideband locking for vlv_punit_(read|write) Chris Wilson
2018-01-15  8:47 ` [PATCH v2 04/11] drm/i915: Reduce RPS update frequency on Valleyview/Cherryview Chris Wilson
2018-01-15  8:47 ` [PATCH v2 05/11] Revert "drm/i915: Avoid tweaking evaluation thresholds on Baytrail v3" Chris Wilson
2018-01-15  8:47 ` [PATCH v2 06/11] drm/i915: Replace pcu_lock with sb_lock Chris Wilson
2018-01-15  8:47 ` [PATCH v2 07/11] drm/i915: Separate sideband declarations to intel_sideband.h Chris Wilson
2018-01-15  8:47 ` [PATCH v2 08/11] drm/i915: Merge sbi read/write into a single accessor Chris Wilson
2018-01-15  8:47 ` [PATCH v2 09/11] drm/i915: Merge sandybride_pcode_(read|write) Chris Wilson
2018-01-15  8:47 ` [PATCH v2 10/11] drm/i915: Move sandybride pcode access to intel_sideband.c Chris Wilson
2018-01-19  8:21   ` Mika Kuoppala
2018-01-19  8:33     ` Chris Wilson
2018-01-15  8:47 ` [PATCH v2 11/11] drm/i915: Avoid waitboosting on the active request Chris Wilson
2018-01-18  9:49   ` Joonas Lahtinen
2018-01-15  9:19 ` ✓ Fi.CI.BAT: success for series starting with [v2,01/11] drm/i915: Disable preemption and sleeping while using the punit sideband Patchwork
2018-01-15 10:23 ` ✗ Fi.CI.IGT: failure " Patchwork
2018-01-15 10:27   ` Chris Wilson

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.