All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake
@ 2014-12-08 18:27 Mika Kuoppala
  2014-12-08 18:27 ` [PATCH 2/8] drm/i915: Assert that runtime pm is active on user fw access Mika Kuoppala
                   ` (8 more replies)
  0 siblings, 9 replies; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-08 18:27 UTC (permalink / raw
  To: intel-gfx; +Cc: Daniel Vetter, miku, Paulo Zanoni

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

Calling intel_runtime_pm_put() is illegal from a soft-irq context, so
revert the crude hack

commit aa0b3b5bb8768c1a6a6788869d9c7015eae7e80c
Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
Date:   Tue Apr 1 14:55:07 2014 -0300

    drm/i915: don't schedule force_wake_timer at gen6_read

and apply the single line corrective instead.

References: https://bugs.freedesktop.org/show_bug.cgi?id=80913
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.c     |  1 +
 drivers/gpu/drm/i915/intel_uncore.c | 18 ++++++------------
 2 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 71be3c9..706b122 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1402,6 +1402,7 @@ static int intel_runtime_suspend(struct device *device)
 	}
 
 	del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
+	intel_uncore_forcewake_reset(dev, false);
 	dev_priv->pm.suspended = true;
 
 	/*
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 46de8d7..38ac389 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -449,8 +449,6 @@ static void gen6_force_wake_timer(unsigned long arg)
 	if (--dev_priv->uncore.forcewake_count == 0)
 		dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-
-	intel_runtime_pm_put(dev_priv);
 }
 
 void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
@@ -586,7 +584,6 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 {
 	unsigned long irqflags;
-	bool delayed = false;
 
 	if (!dev_priv->uncore.funcs.force_wake_put)
 		return;
@@ -603,21 +600,19 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 		goto out;
 	}
 
-
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 	WARN_ON(!dev_priv->uncore.forcewake_count);
 
 	if (--dev_priv->uncore.forcewake_count == 0) {
 		dev_priv->uncore.forcewake_count++;
-		delayed = true;
 		mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
 				 jiffies + 1);
 	}
+
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 
 out:
-	if (!delayed)
-		intel_runtime_pm_put(dev_priv);
+	intel_runtime_pm_put(dev_priv);
 }
 
 void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
@@ -777,12 +772,11 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
 		dev_priv->uncore.funcs.force_wake_get(dev_priv, \
 						      FORCEWAKE_ALL); \
-		val = __raw_i915_read##x(dev_priv, reg); \
-		dev_priv->uncore.funcs.force_wake_put(dev_priv, \
-						      FORCEWAKE_ALL); \
-	} else { \
-		val = __raw_i915_read##x(dev_priv, reg); \
+		dev_priv->uncore.forcewake_count++; \
+		mod_timer_pinned(&dev_priv->uncore.force_wake_timer, \
+				 jiffies + 1); \
 	} \
+	val = __raw_i915_read##x(dev_priv, reg); \
 	hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
 	REG_READ_FOOTER; \
 }
-- 
1.9.1

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

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

* [PATCH 2/8] drm/i915: Assert that runtime pm is active on user fw access
  2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
@ 2014-12-08 18:27 ` Mika Kuoppala
  2014-12-12 11:39   ` Deepak S
  2014-12-08 18:27 ` [PATCH 3/8] drm/i915: Skip uncore lock on earlier gens Mika Kuoppala
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-08 18:27 UTC (permalink / raw
  To: intel-gfx; +Cc: miku

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

On user forcewake access, assert that runtime pm reference is held.
Fix and cleanup the callsites accordingly.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c  |  2 +
 drivers/gpu/drm/i915/intel_display.c | 19 +--------
 drivers/gpu/drm/i915/intel_lrc.c     | 53 ++-----------------------
 drivers/gpu/drm/i915/intel_uncore.c  | 76 ++++++++++++------------------------
 4 files changed, 31 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index d0e445e..e142629 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4250,6 +4250,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
 	if (INTEL_INFO(dev)->gen < 6)
 		return 0;
 
+	intel_runtime_pm_get(dev_priv);
 	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
 	return 0;
@@ -4264,6 +4265,7 @@ static int i915_forcewake_release(struct inode *inode, struct file *file)
 		return 0;
 
 	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_runtime_pm_put(dev_priv);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d5153a4..86c2885 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7862,19 +7862,8 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
 	/*
 	 * Make sure we're not on PC8 state before disabling PC8, otherwise
 	 * we'll hang the machine. To prevent PC8 state, just enable force_wake.
-	 *
-	 * The other problem is that hsw_restore_lcpll() is called as part of
-	 * the runtime PM resume sequence, so we can't just call
-	 * gen6_gt_force_wake_get() because that function calls
-	 * intel_runtime_pm_get(), and we can't change the runtime PM refcount
-	 * while we are on the resume sequence. So to solve this problem we have
-	 * to call special forcewake code that doesn't touch runtime PM and
-	 * doesn't enable the forcewake delayed work.
 	 */
-	spin_lock_irq(&dev_priv->uncore.lock);
-	if (dev_priv->uncore.forcewake_count++ == 0)
-		dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL);
-	spin_unlock_irq(&dev_priv->uncore.lock);
+	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
 	if (val & LCPLL_POWER_DOWN_ALLOW) {
 		val &= ~LCPLL_POWER_DOWN_ALLOW;
@@ -7904,11 +7893,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
 			DRM_ERROR("Switching back to LCPLL failed\n");
 	}
 
-	/* See the big comment above. */
-	spin_lock_irq(&dev_priv->uncore.lock);
-	if (--dev_priv->uncore.forcewake_count == 0)
-		dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
-	spin_unlock_irq(&dev_priv->uncore.lock);
+	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index a82020e..fcb5140 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -284,7 +284,6 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	uint64_t temp = 0;
 	uint32_t desc[4];
-	unsigned long flags;
 
 	/* XXX: You must always write both descriptors in the order below. */
 	if (ctx_obj1)
@@ -298,63 +297,17 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
 	desc[3] = (u32)(temp >> 32);
 	desc[2] = (u32)temp;
 
-	/* Set Force Wakeup bit to prevent GT from entering C6 while ELSP writes
-	 * are in progress.
-	 *
-	 * The other problem is that we can't just call gen6_gt_force_wake_get()
-	 * because that function calls intel_runtime_pm_get(), which might sleep.
-	 * Instead, we do the runtime_pm_get/put when creating/destroying requests.
-	 */
-	spin_lock_irqsave(&dev_priv->uncore.lock, flags);
-	if (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen >= 9) {
-		if (dev_priv->uncore.fw_rendercount++ == 0)
-			dev_priv->uncore.funcs.force_wake_get(dev_priv,
-							      FORCEWAKE_RENDER);
-		if (dev_priv->uncore.fw_mediacount++ == 0)
-			dev_priv->uncore.funcs.force_wake_get(dev_priv,
-							      FORCEWAKE_MEDIA);
-		if (INTEL_INFO(dev)->gen >= 9) {
-			if (dev_priv->uncore.fw_blittercount++ == 0)
-				dev_priv->uncore.funcs.force_wake_get(dev_priv,
-							FORCEWAKE_BLITTER);
-		}
-	} else {
-		if (dev_priv->uncore.forcewake_count++ == 0)
-			dev_priv->uncore.funcs.force_wake_get(dev_priv,
-							      FORCEWAKE_ALL);
-	}
-	spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
-
+	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 	I915_WRITE(RING_ELSP(ring), desc[1]);
 	I915_WRITE(RING_ELSP(ring), desc[0]);
 	I915_WRITE(RING_ELSP(ring), desc[3]);
+
 	/* The context is automatically loaded after the following */
 	I915_WRITE(RING_ELSP(ring), desc[2]);
 
 	/* ELSP is a wo register, so use another nearby reg for posting instead */
 	POSTING_READ(RING_EXECLIST_STATUS(ring));
-
-	/* Release Force Wakeup (see the big comment above). */
-	spin_lock_irqsave(&dev_priv->uncore.lock, flags);
-	if (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen >= 9) {
-		if (--dev_priv->uncore.fw_rendercount == 0)
-			dev_priv->uncore.funcs.force_wake_put(dev_priv,
-							      FORCEWAKE_RENDER);
-		if (--dev_priv->uncore.fw_mediacount == 0)
-			dev_priv->uncore.funcs.force_wake_put(dev_priv,
-							      FORCEWAKE_MEDIA);
-		if (INTEL_INFO(dev)->gen >= 9) {
-			if (--dev_priv->uncore.fw_blittercount == 0)
-				dev_priv->uncore.funcs.force_wake_put(dev_priv,
-							FORCEWAKE_BLITTER);
-		}
-	} else {
-		if (--dev_priv->uncore.forcewake_count == 0)
-			dev_priv->uncore.funcs.force_wake_put(dev_priv,
-							      FORCEWAKE_ALL);
-	}
-
-	spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
+	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 static int execlists_update_context(struct drm_i915_gem_object *ctx_obj,
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 38ac389..a1ceb92 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -24,6 +24,8 @@
 #include "i915_drv.h"
 #include "intel_drv.h"
 
+#include <linux/pm_runtime.h>
+
 #define FORCEWAKE_ACK_TIMEOUT_MS 2
 
 #define __raw_i915_read8(dev_priv__, reg__) readb((dev_priv__)->regs + (reg__))
@@ -247,10 +249,6 @@ static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
 
 static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 {
-	unsigned long irqflags;
-
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
 	if (fw_engine & FORCEWAKE_RENDER &&
 	    dev_priv->uncore.fw_rendercount++ != 0)
 		fw_engine &= ~FORCEWAKE_RENDER;
@@ -260,16 +258,10 @@ static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 
 	if (fw_engine)
 		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine);
-
-	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 {
-	unsigned long irqflags;
-
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
 	if (fw_engine & FORCEWAKE_RENDER) {
 		WARN_ON(!dev_priv->uncore.fw_rendercount);
 		if (--dev_priv->uncore.fw_rendercount != 0)
@@ -284,8 +276,6 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 
 	if (fw_engine)
 		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw_engine);
-
-	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
@@ -380,10 +370,6 @@ __gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 static void
 gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 {
-	unsigned long irqflags;
-
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
 	if (FORCEWAKE_RENDER & fw_engine) {
 		if (dev_priv->uncore.fw_rendercount++ == 0)
 			dev_priv->uncore.funcs.force_wake_get(dev_priv,
@@ -401,17 +387,11 @@ gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 			dev_priv->uncore.funcs.force_wake_get(dev_priv,
 							FORCEWAKE_BLITTER);
 	}
-
-	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void
 gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 {
-	unsigned long irqflags;
-
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
 	if (FORCEWAKE_RENDER & fw_engine) {
 		WARN_ON(dev_priv->uncore.fw_rendercount == 0);
 		if (--dev_priv->uncore.fw_rendercount == 0)
@@ -432,8 +412,6 @@ gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 			dev_priv->uncore.funcs.force_wake_put(dev_priv,
 							FORCEWAKE_BLITTER);
 	}
-
-	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void gen6_force_wake_timer(unsigned long arg)
@@ -564,17 +542,20 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 
 	intel_runtime_pm_get(dev_priv);
 
-	/* Redirect to Gen9 specific routine */
-	if (IS_GEN9(dev_priv->dev))
-		return gen9_force_wake_get(dev_priv, fw_engine);
-
-	/* Redirect to VLV specific routine */
-	if (IS_VALLEYVIEW(dev_priv->dev))
-		return vlv_force_wake_get(dev_priv, fw_engine);
+	WARN_ON(!pm_runtime_active(&dev_priv->dev->pdev->dev));
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-	if (dev_priv->uncore.forcewake_count++ == 0)
-		dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL);
+
+	if (IS_GEN9(dev_priv->dev)) {
+		gen9_force_wake_get(dev_priv, fw_engine);
+	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
+		vlv_force_wake_get(dev_priv, fw_engine);
+	} else {
+		if (dev_priv->uncore.forcewake_count++ == 0)
+			dev_priv->uncore.funcs.force_wake_get(dev_priv,
+							      FORCEWAKE_ALL);
+	}
+
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
@@ -588,31 +569,22 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 	if (!dev_priv->uncore.funcs.force_wake_put)
 		return;
 
-	/* Redirect to Gen9 specific routine */
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
 	if (IS_GEN9(dev_priv->dev)) {
 		gen9_force_wake_put(dev_priv, fw_engine);
-		goto out;
-	}
-
-	/* Redirect to VLV specific routine */
-	if (IS_VALLEYVIEW(dev_priv->dev)) {
+	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
 		vlv_force_wake_put(dev_priv, fw_engine);
-		goto out;
-	}
-
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-	WARN_ON(!dev_priv->uncore.forcewake_count);
-
-	if (--dev_priv->uncore.forcewake_count == 0) {
-		dev_priv->uncore.forcewake_count++;
-		mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
-				 jiffies + 1);
+	} else {
+		WARN_ON(!dev_priv->uncore.forcewake_count);
+		if (--dev_priv->uncore.forcewake_count == 0) {
+			dev_priv->uncore.forcewake_count++;
+			mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
+					 jiffies + 1);
+		}
 	}
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-
-out:
-	intel_runtime_pm_put(dev_priv);
 }
 
 void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
-- 
1.9.1

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

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

* [PATCH 3/8] drm/i915: Skip uncore lock on earlier gens
  2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
  2014-12-08 18:27 ` [PATCH 2/8] drm/i915: Assert that runtime pm is active on user fw access Mika Kuoppala
@ 2014-12-08 18:27 ` Mika Kuoppala
  2014-12-12 11:57   ` Deepak S
  2014-12-08 18:27 ` [PATCH 4/8] drm/i915: Reduce duplicated forcewake logic Mika Kuoppala
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-08 18:27 UTC (permalink / raw
  To: intel-gfx; +Cc: miku

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

With gen < 6 we don't need to take uncore lock as we
don't have anything to protect from concurrent access.

v2: rebase and account for gen9 changes

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c | 158 +++++++++++++++++++++---------------
 1 file changed, 91 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index a1ceb92..069fe7a 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -707,38 +707,61 @@ hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv)
 	}
 }
 
-#define REG_READ_HEADER(x) \
-	unsigned long irqflags; \
+#define GEN2_READ_HEADER(x) \
 	u##x val = 0; \
-	assert_device_not_suspended(dev_priv); \
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
+	assert_device_not_suspended(dev_priv);
 
-#define REG_READ_FOOTER \
-	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
+#define GEN2_READ_FOOTER \
 	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
 	return val
 
-#define __gen4_read(x) \
+#define __gen2_read(x) \
 static u##x \
-gen4_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
-	REG_READ_HEADER(x); \
+gen2_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
+	GEN2_READ_HEADER(x); \
 	val = __raw_i915_read##x(dev_priv, reg); \
-	REG_READ_FOOTER; \
+	GEN2_READ_FOOTER; \
 }
 
 #define __gen5_read(x) \
 static u##x \
 gen5_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
-	REG_READ_HEADER(x); \
+	GEN2_READ_HEADER(x); \
 	ilk_dummy_write(dev_priv); \
 	val = __raw_i915_read##x(dev_priv, reg); \
-	REG_READ_FOOTER; \
+	GEN2_READ_FOOTER; \
 }
 
+__gen5_read(8)
+__gen5_read(16)
+__gen5_read(32)
+__gen5_read(64)
+__gen2_read(8)
+__gen2_read(16)
+__gen2_read(32)
+__gen2_read(64)
+
+#undef __gen5_read
+#undef __gen2_read
+
+#undef GEN2_READ_FOOTER
+#undef GEN2_READ_HEADER
+
+#define GEN6_READ_HEADER(x) \
+	unsigned long irqflags; \
+	u##x val = 0; \
+	assert_device_not_suspended(dev_priv); \
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
+
+#define GEN6_READ_FOOTER \
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
+	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
+	return val
+
 #define __gen6_read(x) \
 static u##x \
 gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
-	REG_READ_HEADER(x); \
+	GEN6_READ_HEADER(x); \
 	hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \
 	if (dev_priv->uncore.forcewake_count == 0 && \
 	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
@@ -750,14 +773,14 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 	} \
 	val = __raw_i915_read##x(dev_priv, reg); \
 	hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
-	REG_READ_FOOTER; \
+	GEN6_READ_FOOTER; \
 }
 
 #define __vlv_read(x) \
 static u##x \
 vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 	unsigned fwengine = 0; \
-	REG_READ_HEADER(x); \
+	GEN6_READ_HEADER(x); \
 	if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \
 		if (dev_priv->uncore.fw_rendercount == 0) \
 			fwengine = FORCEWAKE_RENDER; \
@@ -770,14 +793,14 @@ vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 	val = __raw_i915_read##x(dev_priv, reg); \
 	if (fwengine) \
 		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
-	REG_READ_FOOTER; \
+	GEN6_READ_FOOTER; \
 }
 
 #define __chv_read(x) \
 static u##x \
 chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 	unsigned fwengine = 0; \
-	REG_READ_HEADER(x); \
+	GEN6_READ_HEADER(x); \
 	if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
 		if (dev_priv->uncore.fw_rendercount == 0) \
 			fwengine = FORCEWAKE_RENDER; \
@@ -795,7 +818,7 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 	val = __raw_i915_read##x(dev_priv, reg); \
 	if (fwengine) \
 		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
-	REG_READ_FOOTER; \
+	GEN6_READ_FOOTER; \
 }
 
 #define SKL_NEEDS_FORCE_WAKE(dev_priv, reg)	\
@@ -804,7 +827,7 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 #define __gen9_read(x) \
 static u##x \
 gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
-	REG_READ_HEADER(x); \
+	GEN6_READ_HEADER(x); \
 	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
 		val = __raw_i915_read##x(dev_priv, reg); \
 	} else { \
@@ -830,7 +853,7 @@ gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 		if (fwengine) \
 			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
 	} \
-	REG_READ_FOOTER; \
+	GEN6_READ_FOOTER; \
 }
 
 __gen9_read(8)
@@ -849,55 +872,66 @@ __gen6_read(8)
 __gen6_read(16)
 __gen6_read(32)
 __gen6_read(64)
-__gen5_read(8)
-__gen5_read(16)
-__gen5_read(32)
-__gen5_read(64)
-__gen4_read(8)
-__gen4_read(16)
-__gen4_read(32)
-__gen4_read(64)
 
 #undef __gen9_read
 #undef __chv_read
 #undef __vlv_read
 #undef __gen6_read
-#undef __gen5_read
-#undef __gen4_read
-#undef REG_READ_FOOTER
-#undef REG_READ_HEADER
+#undef GEN6_READ_FOOTER
+#undef GEN6_READ_HEADER
 
-#define REG_WRITE_HEADER \
-	unsigned long irqflags; \
+#define GEN2_WRITE_HEADER \
 	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
 	assert_device_not_suspended(dev_priv); \
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
 
-#define REG_WRITE_FOOTER \
-	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags)
+#define GEN2_WRITE_FOOTER
 
-#define __gen4_write(x) \
+#define __gen2_write(x) \
 static void \
-gen4_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
-	REG_WRITE_HEADER; \
+gen2_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
+	GEN2_WRITE_HEADER; \
 	__raw_i915_write##x(dev_priv, reg, val); \
-	REG_WRITE_FOOTER; \
+	GEN2_WRITE_FOOTER; \
 }
 
 #define __gen5_write(x) \
 static void \
 gen5_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
-	REG_WRITE_HEADER; \
+	GEN2_WRITE_HEADER; \
 	ilk_dummy_write(dev_priv); \
 	__raw_i915_write##x(dev_priv, reg, val); \
-	REG_WRITE_FOOTER; \
+	GEN2_WRITE_FOOTER; \
 }
 
+__gen5_write(8)
+__gen5_write(16)
+__gen5_write(32)
+__gen5_write(64)
+__gen2_write(8)
+__gen2_write(16)
+__gen2_write(32)
+__gen2_write(64)
+
+#undef __gen5_write
+#undef __gen2_write
+
+#undef GEN2_WRITE_FOOTER
+#undef GEN2_WRITE_HEADER
+
+#define GEN6_WRITE_HEADER \
+	unsigned long irqflags; \
+	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
+	assert_device_not_suspended(dev_priv); \
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
+
+#define GEN6_WRITE_FOOTER \
+	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags)
+
 #define __gen6_write(x) \
 static void \
 gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
 	u32 __fifo_ret = 0; \
-	REG_WRITE_HEADER; \
+	GEN6_WRITE_HEADER; \
 	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
 		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
 	} \
@@ -905,14 +939,14 @@ gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
 	if (unlikely(__fifo_ret)) { \
 		gen6_gt_check_fifodbg(dev_priv); \
 	} \
-	REG_WRITE_FOOTER; \
+	GEN6_WRITE_FOOTER; \
 }
 
 #define __hsw_write(x) \
 static void \
 hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
 	u32 __fifo_ret = 0; \
-	REG_WRITE_HEADER; \
+	GEN6_WRITE_HEADER; \
 	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
 		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
 	} \
@@ -923,7 +957,7 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
 	} \
 	hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
 	hsw_unclaimed_reg_detect(dev_priv); \
-	REG_WRITE_FOOTER; \
+	GEN6_WRITE_FOOTER; \
 }
 
 static const u32 gen8_shadowed_regs[] = {
@@ -950,7 +984,7 @@ static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, u32 reg)
 #define __gen8_write(x) \
 static void \
 gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
-	REG_WRITE_HEADER; \
+	GEN6_WRITE_HEADER; \
 	hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
 	if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) { \
 		if (dev_priv->uncore.forcewake_count == 0) \
@@ -965,7 +999,7 @@ gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
 	} \
 	hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
 	hsw_unclaimed_reg_detect(dev_priv); \
-	REG_WRITE_FOOTER; \
+	GEN6_WRITE_FOOTER; \
 }
 
 #define __chv_write(x) \
@@ -973,7 +1007,7 @@ static void \
 chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
 	unsigned fwengine = 0; \
 	bool shadowed = is_gen8_shadowed(dev_priv, reg); \
-	REG_WRITE_HEADER; \
+	GEN6_WRITE_HEADER; \
 	if (!shadowed) { \
 		if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
 			if (dev_priv->uncore.fw_rendercount == 0) \
@@ -993,7 +1027,7 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
 	__raw_i915_write##x(dev_priv, reg, val); \
 	if (fwengine) \
 		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
-	REG_WRITE_FOOTER; \
+	GEN6_WRITE_FOOTER; \
 }
 
 static const u32 gen9_shadowed_regs[] = {
@@ -1023,7 +1057,7 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
 static void \
 gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
 		bool trace) { \
-	REG_WRITE_HEADER; \
+	GEN6_WRITE_HEADER; \
 	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
 			is_gen9_shadowed(dev_priv, reg)) { \
 		__raw_i915_write##x(dev_priv, reg, val); \
@@ -1052,7 +1086,7 @@ gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
 			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
 					fwengine); \
 	} \
-	REG_WRITE_FOOTER; \
+	GEN6_WRITE_FOOTER; \
 }
 
 __gen9_write(8)
@@ -1075,24 +1109,14 @@ __gen6_write(8)
 __gen6_write(16)
 __gen6_write(32)
 __gen6_write(64)
-__gen5_write(8)
-__gen5_write(16)
-__gen5_write(32)
-__gen5_write(64)
-__gen4_write(8)
-__gen4_write(16)
-__gen4_write(32)
-__gen4_write(64)
 
 #undef __gen9_write
 #undef __chv_write
 #undef __gen8_write
 #undef __hsw_write
 #undef __gen6_write
-#undef __gen5_write
-#undef __gen4_write
-#undef REG_WRITE_FOOTER
-#undef REG_WRITE_HEADER
+#undef GEN6_WRITE_FOOTER
+#undef GEN6_WRITE_HEADER
 
 #define ASSIGN_WRITE_MMIO_VFUNCS(x) \
 do { \
@@ -1205,8 +1229,8 @@ void intel_uncore_init(struct drm_device *dev)
 	case 4:
 	case 3:
 	case 2:
-		ASSIGN_WRITE_MMIO_VFUNCS(gen4);
-		ASSIGN_READ_MMIO_VFUNCS(gen4);
+		ASSIGN_WRITE_MMIO_VFUNCS(gen2);
+		ASSIGN_READ_MMIO_VFUNCS(gen2);
 		break;
 	}
 
-- 
1.9.1

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

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

* [PATCH 4/8] drm/i915: Reduce duplicated forcewake logic
  2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
  2014-12-08 18:27 ` [PATCH 2/8] drm/i915: Assert that runtime pm is active on user fw access Mika Kuoppala
  2014-12-08 18:27 ` [PATCH 3/8] drm/i915: Skip uncore lock on earlier gens Mika Kuoppala
@ 2014-12-08 18:27 ` Mika Kuoppala
  2014-12-12 12:48   ` Deepak S
  2014-12-08 18:27 ` [PATCH 5/8] drm/i915: Consolidate forcewake code Mika Kuoppala
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-08 18:27 UTC (permalink / raw
  To: intel-gfx; +Cc: miku

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

Introduce a structure to track the individual forcewake domains and use
that to eliminate duplicate logic.

v2: - Rebase on latest dinq (Mika)
    - for_each_fw_domain macro (Mika)
    - Handle reset atomically, keeping the timer running (Mika)
    - for_each_fw_domain parameter ordering (Chris)
    - defer timer on new register access (Mika)

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c |  65 +++---
 drivers/gpu/drm/i915/i915_drv.h     |  54 +++--
 drivers/gpu/drm/i915/intel_uncore.c | 410 +++++++++++++-----------------------
 3 files changed, 208 insertions(+), 321 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index e142629..5cc838b 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1235,14 +1235,36 @@ static int ironlake_drpc_info(struct seq_file *m)
 	return 0;
 }
 
-static int vlv_drpc_info(struct seq_file *m)
+static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
 {
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_uncore_forcewake_domain *fw_domain;
+	const char *domain_names[] = {
+		"render",
+		"blitter",
+		"media",
+	};
+	int i;
+
+	spin_lock_irq(&dev_priv->uncore.lock);
+	for_each_fw_domain(fw_domain, dev_priv, i) {
+		seq_printf(m, "%s.wake_count = %u\n",
+			   domain_names[i],
+			   fw_domain->wake_count);
+	}
+	spin_unlock_irq(&dev_priv->uncore.lock);
 
+	return 0;
+}
+
+static int vlv_drpc_info(struct seq_file *m)
+{
 	struct drm_info_node *node = m->private;
 	struct drm_device *dev = node->minor->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	u32 rpmodectl1, rcctl1, pw_status;
-	unsigned fw_rendercount = 0, fw_mediacount = 0;
 
 	intel_runtime_pm_get(dev_priv);
 
@@ -1274,22 +1296,11 @@ static int vlv_drpc_info(struct seq_file *m)
 	seq_printf(m, "Media RC6 residency since boot: %u\n",
 		   I915_READ(VLV_GT_MEDIA_RC6));
 
-	spin_lock_irq(&dev_priv->uncore.lock);
-	fw_rendercount = dev_priv->uncore.fw_rendercount;
-	fw_mediacount = dev_priv->uncore.fw_mediacount;
-	spin_unlock_irq(&dev_priv->uncore.lock);
-
-	seq_printf(m, "Forcewake Render Count = %u\n", fw_rendercount);
-	seq_printf(m, "Forcewake Media Count = %u\n", fw_mediacount);
-
-
-	return 0;
+	return i915_gen6_forcewake_count_info(m, NULL);
 }
 
-
 static int gen6_drpc_info(struct seq_file *m)
 {
-
 	struct drm_info_node *node = m->private;
 	struct drm_device *dev = node->minor->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1303,7 +1314,7 @@ static int gen6_drpc_info(struct seq_file *m)
 	intel_runtime_pm_get(dev_priv);
 
 	spin_lock_irq(&dev_priv->uncore.lock);
-	forcewake_count = dev_priv->uncore.forcewake_count;
+	forcewake_count = dev_priv->uncore.fw_domain[FW_DOMAIN_ID_RENDER].wake_count;
 	spin_unlock_irq(&dev_priv->uncore.lock);
 
 	if (forcewake_count) {
@@ -1931,30 +1942,6 @@ static int i915_execlists(struct seq_file *m, void *data)
 	return 0;
 }
 
-static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = m->private;
-	struct drm_device *dev = node->minor->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	unsigned forcewake_count = 0, fw_rendercount = 0, fw_mediacount = 0;
-
-	spin_lock_irq(&dev_priv->uncore.lock);
-	if (IS_VALLEYVIEW(dev)) {
-		fw_rendercount = dev_priv->uncore.fw_rendercount;
-		fw_mediacount = dev_priv->uncore.fw_mediacount;
-	} else
-		forcewake_count = dev_priv->uncore.forcewake_count;
-	spin_unlock_irq(&dev_priv->uncore.lock);
-
-	if (IS_VALLEYVIEW(dev)) {
-		seq_printf(m, "fw_rendercount = %u\n", fw_rendercount);
-		seq_printf(m, "fw_mediacount = %u\n", fw_mediacount);
-	} else
-		seq_printf(m, "forcewake count = %u\n", forcewake_count);
-
-	return 0;
-}
-
 static const char *swizzle_string(unsigned swizzle)
 {
 	switch (swizzle) {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 95dfa2d..410558a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -554,20 +554,45 @@ struct intel_uncore_funcs {
 				uint64_t val, bool trace);
 };
 
+enum {
+	FW_DOMAIN_ID_RENDER = 0,
+	FW_DOMAIN_ID_BLITTER,
+	FW_DOMAIN_ID_MEDIA,
+
+	FW_DOMAIN_ID_COUNT
+};
+
 struct intel_uncore {
 	spinlock_t lock; /** lock is also taken in irq contexts. */
 
 	struct intel_uncore_funcs funcs;
 
 	unsigned fifo_count;
-	unsigned forcewake_count;
-
-	unsigned fw_rendercount;
-	unsigned fw_mediacount;
-	unsigned fw_blittercount;
-
-	struct timer_list force_wake_timer;
-};
+	unsigned fw_domains;
+
+	struct intel_uncore_forcewake_domain {
+		struct drm_i915_private *i915;
+		int id;
+		unsigned wake_count;
+		struct timer_list timer;
+	} fw_domain[FW_DOMAIN_ID_COUNT];
+#define FORCEWAKE_RENDER	(1 << FW_DOMAIN_ID_RENDER)
+#define FORCEWAKE_BLITTER	(1 << FW_DOMAIN_ID_BLITTER)
+#define FORCEWAKE_MEDIA		(1 << FW_DOMAIN_ID_MEDIA)
+#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | \
+				 FORCEWAKE_BLITTER | \
+				 FORCEWAKE_MEDIA)
+};
+
+/* Iterate over initialised fw domains */
+#define for_each_fw_domain_mask(domain__, mask__, dev_priv__, i__) \
+	for ((i__) = 0, (domain__) = &(dev_priv__)->uncore.fw_domain[0]; \
+	     (i__) < FW_DOMAIN_ID_COUNT; \
+	     (i__)++, (domain__) = &(dev_priv__)->uncore.fw_domain[i__]) \
+		if (((mask__) & (dev_priv__)->uncore.fw_domains) & (1 << (i__)))
+
+#define for_each_fw_domain(domain__, dev_priv__, i__) \
+	for_each_fw_domain_mask(domain__, FORCEWAKE_ALL, dev_priv__, i__)
 
 #define DEV_INFO_FOR_EACH_FLAG(func, sep) \
 	func(is_mobile) sep \
@@ -2998,8 +3023,10 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
  * must be set to prevent GT core from power down and stale values being
  * returned.
  */
-void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine);
-void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine);
+void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
+			    unsigned fw_domains);
+void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
+			    unsigned fw_domains);
 void assert_force_wake_inactive(struct drm_i915_private *dev_priv);
 
 int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
@@ -3031,13 +3058,6 @@ void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
 int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val);
 int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
 
-#define FORCEWAKE_RENDER	(1 << 0)
-#define FORCEWAKE_MEDIA		(1 << 1)
-#define FORCEWAKE_BLITTER	(1 << 2)
-#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
-					FORCEWAKE_BLITTER)
-
-
 #define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
 #define I915_WRITE8(reg, val)	dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
 
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 069fe7a..85e46b0 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -67,7 +67,7 @@ static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv)
 }
 
 static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
-							int fw_engine)
+				     int fw_engine)
 {
 	if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0,
 			    FORCEWAKE_ACK_TIMEOUT_MS))
@@ -93,7 +93,7 @@ static void __gen7_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
 }
 
 static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv,
-							int fw_engine)
+					int fw_engine)
 {
 	u32 forcewake_ack;
 
@@ -129,7 +129,7 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
 }
 
 static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
-							int fw_engine)
+				     int fw_engine)
 {
 	__raw_i915_write32(dev_priv, FORCEWAKE, 0);
 	/* something from same cacheline, but !FORCEWAKE */
@@ -138,7 +138,7 @@ static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
 }
 
 static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv,
-							int fw_engine)
+					int fw_engine)
 {
 	__raw_i915_write32(dev_priv, FORCEWAKE_MT,
 			   _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
@@ -187,7 +187,7 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
 }
 
 static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
-						int fw_engine)
+				 int fw_engine)
 {
 	/* Check for Render Engine */
 	if (FORCEWAKE_RENDER & fw_engine) {
@@ -227,9 +227,8 @@ static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
 }
 
 static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
-					int fw_engine)
+				 int fw_engine)
 {
-
 	/* Check for Render Engine */
 	if (FORCEWAKE_RENDER & fw_engine)
 		__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
@@ -247,37 +246,6 @@ static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
 		gen6_gt_check_fifodbg(dev_priv);
 }
 
-static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
-{
-	if (fw_engine & FORCEWAKE_RENDER &&
-	    dev_priv->uncore.fw_rendercount++ != 0)
-		fw_engine &= ~FORCEWAKE_RENDER;
-	if (fw_engine & FORCEWAKE_MEDIA &&
-	    dev_priv->uncore.fw_mediacount++ != 0)
-		fw_engine &= ~FORCEWAKE_MEDIA;
-
-	if (fw_engine)
-		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine);
-}
-
-static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
-{
-	if (fw_engine & FORCEWAKE_RENDER) {
-		WARN_ON(!dev_priv->uncore.fw_rendercount);
-		if (--dev_priv->uncore.fw_rendercount != 0)
-			fw_engine &= ~FORCEWAKE_RENDER;
-	}
-
-	if (fw_engine & FORCEWAKE_MEDIA) {
-		WARN_ON(!dev_priv->uncore.fw_mediacount);
-		if (--dev_priv->uncore.fw_mediacount != 0)
-			fw_engine &= ~FORCEWAKE_MEDIA;
-	}
-
-	if (fw_engine)
-		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw_engine);
-}
-
 static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
 {
 	__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
@@ -367,80 +335,40 @@ __gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
 }
 
-static void
-gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
-{
-	if (FORCEWAKE_RENDER & fw_engine) {
-		if (dev_priv->uncore.fw_rendercount++ == 0)
-			dev_priv->uncore.funcs.force_wake_get(dev_priv,
-							FORCEWAKE_RENDER);
-	}
-
-	if (FORCEWAKE_MEDIA & fw_engine) {
-		if (dev_priv->uncore.fw_mediacount++ == 0)
-			dev_priv->uncore.funcs.force_wake_get(dev_priv,
-							FORCEWAKE_MEDIA);
-	}
-
-	if (FORCEWAKE_BLITTER & fw_engine) {
-		if (dev_priv->uncore.fw_blittercount++ == 0)
-			dev_priv->uncore.funcs.force_wake_get(dev_priv,
-							FORCEWAKE_BLITTER);
-	}
-}
-
-static void
-gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
-{
-	if (FORCEWAKE_RENDER & fw_engine) {
-		WARN_ON(dev_priv->uncore.fw_rendercount == 0);
-		if (--dev_priv->uncore.fw_rendercount == 0)
-			dev_priv->uncore.funcs.force_wake_put(dev_priv,
-							FORCEWAKE_RENDER);
-	}
-
-	if (FORCEWAKE_MEDIA & fw_engine) {
-		WARN_ON(dev_priv->uncore.fw_mediacount == 0);
-		if (--dev_priv->uncore.fw_mediacount == 0)
-			dev_priv->uncore.funcs.force_wake_put(dev_priv,
-							FORCEWAKE_MEDIA);
-	}
-
-	if (FORCEWAKE_BLITTER & fw_engine) {
-		WARN_ON(dev_priv->uncore.fw_blittercount == 0);
-		if (--dev_priv->uncore.fw_blittercount == 0)
-			dev_priv->uncore.funcs.force_wake_put(dev_priv,
-							FORCEWAKE_BLITTER);
-	}
-}
-
 static void gen6_force_wake_timer(unsigned long arg)
 {
-	struct drm_i915_private *dev_priv = (void *)arg;
+	struct intel_uncore_forcewake_domain *domain = (void *)arg;
 	unsigned long irqflags;
 
-	assert_device_not_suspended(dev_priv);
+	assert_device_not_suspended(domain->i915);
 
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-	WARN_ON(!dev_priv->uncore.forcewake_count);
+	spin_lock_irqsave(&domain->i915->uncore.lock, irqflags);
+	WARN_ON(!domain->wake_count);
 
-	if (--dev_priv->uncore.forcewake_count == 0)
-		dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
-	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+	if (--domain->wake_count == 0)
+		domain->i915->uncore.funcs.force_wake_put(domain->i915,
+							  1 << domain->id);
+	spin_unlock_irqrestore(&domain->i915->uncore.lock, irqflags);
 }
 
 void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	unsigned long irqflags;
-
-	if (del_timer_sync(&dev_priv->uncore.force_wake_timer))
-		gen6_force_wake_timer((unsigned long)dev_priv);
+	unsigned long irqflags, fw = 0;
+	struct intel_uncore_forcewake_domain *domain;
+	int id;
 
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 	/* Hold uncore.lock across reset to prevent any register access
 	 * with forcewake not set correctly
 	 */
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+
+	for_each_fw_domain(domain, dev_priv, id)
+		if (domain->wake_count)
+			fw |= 1 << id;
+
+	if (fw)
+		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw);
 
 	if (IS_VALLEYVIEW(dev))
 		vlv_force_wake_reset(dev_priv);
@@ -454,28 +382,6 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 		__gen9_gt_force_wake_mt_reset(dev_priv);
 
 	if (restore) { /* If reset with a user forcewake, try to restore */
-		unsigned fw = 0;
-
-		if (IS_VALLEYVIEW(dev)) {
-			if (dev_priv->uncore.fw_rendercount)
-				fw |= FORCEWAKE_RENDER;
-
-			if (dev_priv->uncore.fw_mediacount)
-				fw |= FORCEWAKE_MEDIA;
-		} else if (IS_GEN9(dev)) {
-			if (dev_priv->uncore.fw_rendercount)
-				fw |= FORCEWAKE_RENDER;
-
-			if (dev_priv->uncore.fw_mediacount)
-				fw |= FORCEWAKE_MEDIA;
-
-			if (dev_priv->uncore.fw_blittercount)
-				fw |= FORCEWAKE_BLITTER;
-		} else {
-			if (dev_priv->uncore.forcewake_count)
-				fw = FORCEWAKE_ALL;
-		}
-
 		if (fw)
 			dev_priv->uncore.funcs.force_wake_get(dev_priv, fw);
 
@@ -533,28 +439,28 @@ void intel_uncore_sanitize(struct drm_device *dev)
  * be called at the beginning of the sequence followed by a call to
  * gen6_gt_force_wake_put() at the end of the sequence.
  */
-void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
+void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
+			    unsigned fw_domains)
 {
 	unsigned long irqflags;
+	struct intel_uncore_forcewake_domain *domain;
+	int id;
 
 	if (!dev_priv->uncore.funcs.force_wake_get)
 		return;
 
-	intel_runtime_pm_get(dev_priv);
-
 	WARN_ON(!pm_runtime_active(&dev_priv->dev->pdev->dev));
 
+	fw_domains &= dev_priv->uncore.fw_domains;
+
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
-	if (IS_GEN9(dev_priv->dev)) {
-		gen9_force_wake_get(dev_priv, fw_engine);
-	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
-		vlv_force_wake_get(dev_priv, fw_engine);
-	} else {
-		if (dev_priv->uncore.forcewake_count++ == 0)
-			dev_priv->uncore.funcs.force_wake_get(dev_priv,
-							      FORCEWAKE_ALL);
-	}
+	for_each_fw_domain_mask(domain, fw_domains, dev_priv, id)
+		if (domain->wake_count++)
+			fw_domains &= ~(1 << id);
+
+	if (fw_domains)
+		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -562,26 +468,27 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
 /*
  * see gen6_gt_force_wake_get()
  */
-void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
+void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
+			    unsigned fw_domains)
 {
 	unsigned long irqflags;
+	struct intel_uncore_forcewake_domain *domain;
+	int id;
 
 	if (!dev_priv->uncore.funcs.force_wake_put)
 		return;
 
+	fw_domains &= dev_priv->uncore.fw_domains;
+
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
-	if (IS_GEN9(dev_priv->dev)) {
-		gen9_force_wake_put(dev_priv, fw_engine);
-	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
-		vlv_force_wake_put(dev_priv, fw_engine);
-	} else {
-		WARN_ON(!dev_priv->uncore.forcewake_count);
-		if (--dev_priv->uncore.forcewake_count == 0) {
-			dev_priv->uncore.forcewake_count++;
-			mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
-					 jiffies + 1);
-		}
+	for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
+		WARN_ON(!domain->wake_count);
+		if (--domain->wake_count)
+			continue;
+
+		domain->wake_count++;
+		mod_timer_pinned(&domain->timer, jiffies + 1);
 	}
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
@@ -589,10 +496,14 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
 
 void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
 {
+	struct intel_uncore_forcewake_domain *domain;
+	int i;
+
 	if (!dev_priv->uncore.funcs.force_wake_get)
 		return;
 
-	WARN_ON(dev_priv->uncore.forcewake_count > 0);
+	for_each_fw_domain(domain, dev_priv, i)
+		WARN_ON(domain->wake_count);
 }
 
 /* We give fast paths for the really cool registers */
@@ -758,19 +669,36 @@ __gen2_read(64)
 	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
 	return val
 
+static inline void __force_wake_get(struct drm_i915_private *dev_priv,
+				    unsigned fw_domains)
+{
+	struct intel_uncore_forcewake_domain *domain;
+	int i;
+
+	if (WARN_ON(!fw_domains))
+		return;
+
+	/* Ideally GCC would be constant-fold and eliminate this loop */
+	for_each_fw_domain_mask(domain, fw_domains, dev_priv, i) {
+		if (domain->wake_count)
+			fw_domains &= ~(1 << i);
+		else
+			domain->wake_count++;
+
+		mod_timer_pinned(&domain->timer, jiffies + 1);
+	}
+
+	if (fw_domains)
+		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
+}
+
 #define __gen6_read(x) \
 static u##x \
 gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 	GEN6_READ_HEADER(x); \
 	hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \
-	if (dev_priv->uncore.forcewake_count == 0 && \
-	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
-		dev_priv->uncore.funcs.force_wake_get(dev_priv, \
-						      FORCEWAKE_ALL); \
-		dev_priv->uncore.forcewake_count++; \
-		mod_timer_pinned(&dev_priv->uncore.force_wake_timer, \
-				 jiffies + 1); \
-	} \
+	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) \
+		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
 	val = __raw_i915_read##x(dev_priv, reg); \
 	hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
 	GEN6_READ_FOOTER; \
@@ -779,45 +707,27 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 #define __vlv_read(x) \
 static u##x \
 vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
-	unsigned fwengine = 0; \
 	GEN6_READ_HEADER(x); \
-	if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \
-		if (dev_priv->uncore.fw_rendercount == 0) \
-			fwengine = FORCEWAKE_RENDER; \
-	} else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) { \
-		if (dev_priv->uncore.fw_mediacount == 0) \
-			fwengine = FORCEWAKE_MEDIA; \
-	}  \
-	if (fwengine) \
-		dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
+	if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) \
+		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
+	else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) \
+		__force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
 	val = __raw_i915_read##x(dev_priv, reg); \
-	if (fwengine) \
-		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
 	GEN6_READ_FOOTER; \
 }
 
 #define __chv_read(x) \
 static u##x \
 chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
-	unsigned fwengine = 0; \
 	GEN6_READ_HEADER(x); \
-	if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
-		if (dev_priv->uncore.fw_rendercount == 0) \
-			fwengine = FORCEWAKE_RENDER; \
-	} else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
-		if (dev_priv->uncore.fw_mediacount == 0) \
-			fwengine = FORCEWAKE_MEDIA; \
-	} else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
-		if (dev_priv->uncore.fw_rendercount == 0) \
-			fwengine |= FORCEWAKE_RENDER; \
-		if (dev_priv->uncore.fw_mediacount == 0) \
-			fwengine |= FORCEWAKE_MEDIA; \
-	} \
-	if (fwengine) \
-		dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
+	if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) \
+		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
+	else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) \
+		__force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
+	else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) \
+		__force_wake_get(dev_priv, \
+				 FORCEWAKE_RENDER | FORCEWAKE_MEDIA); \
 	val = __raw_i915_read##x(dev_priv, reg); \
-	if (fwengine) \
-		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
 	GEN6_READ_FOOTER; \
 }
 
@@ -827,32 +737,21 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 #define __gen9_read(x) \
 static u##x \
 gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
+	unsigned fw_engine; \
 	GEN6_READ_HEADER(x); \
-	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
-		val = __raw_i915_read##x(dev_priv, reg); \
-	} else { \
-		unsigned fwengine = 0; \
-		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
-			if (dev_priv->uncore.fw_rendercount == 0) \
-				fwengine = FORCEWAKE_RENDER; \
-		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
-			if (dev_priv->uncore.fw_mediacount == 0) \
-				fwengine = FORCEWAKE_MEDIA; \
-		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
-			if (dev_priv->uncore.fw_rendercount == 0) \
-				fwengine |= FORCEWAKE_RENDER; \
-			if (dev_priv->uncore.fw_mediacount == 0) \
-				fwengine |= FORCEWAKE_MEDIA; \
-		} else { \
-			if (dev_priv->uncore.fw_blittercount == 0) \
-				fwengine = FORCEWAKE_BLITTER; \
-		} \
-		if (fwengine) \
-			dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
-		val = __raw_i915_read##x(dev_priv, reg); \
-		if (fwengine) \
-			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
-	} \
+	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)))	\
+		fw_engine = 0; \
+	else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg))	\
+		fw_engine = FORCEWAKE_RENDER; \
+	else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \
+		fw_engine = FORCEWAKE_MEDIA; \
+	else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) \
+		fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
+	else \
+		fw_engine = FORCEWAKE_BLITTER; \
+	if (fw_engine) \
+		__force_wake_get(dev_priv, fw_engine); \
+	val = __raw_i915_read##x(dev_priv, reg); \
 	GEN6_READ_FOOTER; \
 }
 
@@ -986,17 +885,9 @@ static void \
 gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
 	GEN6_WRITE_HEADER; \
 	hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
-	if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) { \
-		if (dev_priv->uncore.forcewake_count == 0) \
-			dev_priv->uncore.funcs.force_wake_get(dev_priv,	\
-							      FORCEWAKE_ALL); \
-		__raw_i915_write##x(dev_priv, reg, val); \
-		if (dev_priv->uncore.forcewake_count == 0) \
-			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
-							      FORCEWAKE_ALL); \
-	} else { \
-		__raw_i915_write##x(dev_priv, reg, val); \
-	} \
+	if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) \
+		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
+	__raw_i915_write##x(dev_priv, reg, val); \
 	hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
 	hsw_unclaimed_reg_detect(dev_priv); \
 	GEN6_WRITE_FOOTER; \
@@ -1005,28 +896,17 @@ gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
 #define __chv_write(x) \
 static void \
 chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
-	unsigned fwengine = 0; \
 	bool shadowed = is_gen8_shadowed(dev_priv, reg); \
 	GEN6_WRITE_HEADER; \
 	if (!shadowed) { \
-		if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
-			if (dev_priv->uncore.fw_rendercount == 0) \
-				fwengine = FORCEWAKE_RENDER; \
-		} else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
-			if (dev_priv->uncore.fw_mediacount == 0) \
-				fwengine = FORCEWAKE_MEDIA; \
-		} else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
-			if (dev_priv->uncore.fw_rendercount == 0) \
-				fwengine |= FORCEWAKE_RENDER; \
-			if (dev_priv->uncore.fw_mediacount == 0) \
-				fwengine |= FORCEWAKE_MEDIA; \
-		} \
+		if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) \
+			__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
+		else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) \
+			__force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
+		else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) \
+			__force_wake_get(dev_priv, FORCEWAKE_RENDER | FORCEWAKE_MEDIA); \
 	} \
-	if (fwengine) \
-		dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
 	__raw_i915_write##x(dev_priv, reg, val); \
-	if (fwengine) \
-		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
 	GEN6_WRITE_FOOTER; \
 }
 
@@ -1057,35 +937,22 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
 static void \
 gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
 		bool trace) { \
+	unsigned fw_engine; \
 	GEN6_WRITE_HEADER; \
-	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
-			is_gen9_shadowed(dev_priv, reg)) { \
-		__raw_i915_write##x(dev_priv, reg, val); \
-	} else { \
-		unsigned fwengine = 0; \
-		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
-			if (dev_priv->uncore.fw_rendercount == 0) \
-				fwengine = FORCEWAKE_RENDER; \
-		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
-			if (dev_priv->uncore.fw_mediacount == 0) \
-				fwengine = FORCEWAKE_MEDIA; \
-		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
-			if (dev_priv->uncore.fw_rendercount == 0) \
-				fwengine |= FORCEWAKE_RENDER; \
-			if (dev_priv->uncore.fw_mediacount == 0) \
-				fwengine |= FORCEWAKE_MEDIA; \
-		} else { \
-			if (dev_priv->uncore.fw_blittercount == 0) \
-				fwengine = FORCEWAKE_BLITTER; \
-		} \
-		if (fwengine) \
-			dev_priv->uncore.funcs.force_wake_get(dev_priv, \
-					fwengine); \
-		__raw_i915_write##x(dev_priv, reg, val); \
-		if (fwengine) \
-			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
-					fwengine); \
-	} \
+	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) ||	\
+	    is_gen9_shadowed(dev_priv, reg)) \
+		fw_engine = 0; \
+	else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) \
+		fw_engine = FORCEWAKE_RENDER; \
+	else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \
+		fw_engine = FORCEWAKE_MEDIA; \
+	else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) \
+		fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
+	else \
+		fw_engine = FORCEWAKE_BLITTER; \
+	if (fw_engine) \
+		__force_wake_get(dev_priv, fw_engine); \
+	__raw_i915_write##x(dev_priv, reg, val); \
 	GEN6_WRITE_FOOTER; \
 }
 
@@ -1137,21 +1004,24 @@ do { \
 void intel_uncore_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	setup_timer(&dev_priv->uncore.force_wake_timer,
-		    gen6_force_wake_timer, (unsigned long)dev_priv);
+	struct intel_uncore_forcewake_domain *domain;
+	int i;
 
 	__intel_uncore_early_sanitize(dev, false);
 
 	if (IS_GEN9(dev)) {
 		dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
 		dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
+		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER |
+			FORCEWAKE_BLITTER | FORCEWAKE_MEDIA;
 	} else if (IS_VALLEYVIEW(dev)) {
 		dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
 		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
+		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER | FORCEWAKE_MEDIA;
 	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
 		dev_priv->uncore.funcs.force_wake_get = __gen7_gt_force_wake_mt_get;
 		dev_priv->uncore.funcs.force_wake_put = __gen7_gt_force_wake_mt_put;
+		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
 	} else if (IS_IVYBRIDGE(dev)) {
 		u32 ecobus;
 
@@ -1183,11 +1053,21 @@ void intel_uncore_init(struct drm_device *dev)
 			dev_priv->uncore.funcs.force_wake_put =
 				__gen6_gt_force_wake_put;
 		}
+		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
 	} else if (IS_GEN6(dev)) {
 		dev_priv->uncore.funcs.force_wake_get =
 			__gen6_gt_force_wake_get;
 		dev_priv->uncore.funcs.force_wake_put =
 			__gen6_gt_force_wake_put;
+		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
+	}
+
+	for_each_fw_domain(domain, dev_priv, i) {
+		domain->i915 = dev_priv;
+		domain->id = i;
+
+		setup_timer(&domain->timer, gen6_force_wake_timer,
+			    (unsigned long)domain);
 	}
 
 	switch (INTEL_INFO(dev)->gen) {
-- 
1.9.1

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

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

* [PATCH 5/8] drm/i915: Consolidate forcewake code
  2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
                   ` (2 preceding siblings ...)
  2014-12-08 18:27 ` [PATCH 4/8] drm/i915: Reduce duplicated forcewake logic Mika Kuoppala
@ 2014-12-08 18:27 ` Mika Kuoppala
  2014-12-12 13:13   ` Deepak S
  2014-12-08 18:27 ` [PATCH 6/8] drm/i915: Make vlv and chv forcewake put generic Mika Kuoppala
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-08 18:27 UTC (permalink / raw
  To: intel-gfx; +Cc: miku

As we now have forcewake domains, take advantage of it
by putting the differences in gen fw handling in data rather
than in code.

In past we have opencoded this quite extensively as the fw handling
is in the fast path. There has also been a lot of cargo-culted
copy'n'pasting from older gens to newer ones.

Now when the releasing of the forcewake is done by deferred timer,
it gives chance to consolidate more. Due to the frequency of actual hw
access being significantly less.

Take advantage of this and generalize the fw handling code
as much as possible. But we still aim to keep the forcewake sequence
particularities for each gen intact. So the access pattern
to fw engines should remain the same.

v2: - s/old_ack/clear_ack (Chris)
    - s/post_read/posting_read (Chris)
    - less polite commit msg (Chris)

Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c |   7 +-
 drivers/gpu/drm/i915/i915_drv.h     |   7 +
 drivers/gpu/drm/i915/intel_uncore.c | 469 ++++++++++++++++--------------------
 3 files changed, 212 insertions(+), 271 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 5cc838b..93390c9 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1241,17 +1241,12 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
 	struct drm_device *dev = node->minor->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_uncore_forcewake_domain *fw_domain;
-	const char *domain_names[] = {
-		"render",
-		"blitter",
-		"media",
-	};
 	int i;
 
 	spin_lock_irq(&dev_priv->uncore.lock);
 	for_each_fw_domain(fw_domain, dev_priv, i) {
 		seq_printf(m, "%s.wake_count = %u\n",
-			   domain_names[i],
+			   intel_uncore_forcewake_domain_to_str(i),
 			   fw_domain->wake_count);
 	}
 	spin_unlock_irq(&dev_priv->uncore.lock);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 410558a..4263084 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -575,6 +575,12 @@ struct intel_uncore {
 		int id;
 		unsigned wake_count;
 		struct timer_list timer;
+		u32 reg_set;
+		u32 val_set;
+		u32 val_clear;
+		u32 reg_ack;
+		u32 reg_post;
+		u32 val_reset;
 	} fw_domain[FW_DOMAIN_ID_COUNT];
 #define FORCEWAKE_RENDER	(1 << FW_DOMAIN_ID_RENDER)
 #define FORCEWAKE_BLITTER	(1 << FW_DOMAIN_ID_BLITTER)
@@ -2443,6 +2449,7 @@ extern void intel_uncore_init(struct drm_device *dev);
 extern void intel_uncore_check_errors(struct drm_device *dev);
 extern void intel_uncore_fini(struct drm_device *dev);
 extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
+const char *intel_uncore_forcewake_domain_to_str(const int domain_id);
 
 void
 i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 85e46b0..e883790 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -42,6 +42,26 @@
 
 #define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__)
 
+static const char * const forcewake_domain_names[] = {
+	"render",
+	"blitter",
+	"media",
+};
+
+const char *
+intel_uncore_forcewake_domain_to_str(const int id)
+{
+	BUILD_BUG_ON((sizeof(forcewake_domain_names)/sizeof(const char *)) !=
+		     FW_DOMAIN_ID_COUNT);
+
+	if (id >= 0 && id < FW_DOMAIN_ID_COUNT)
+		return forcewake_domain_names[id];
+
+	WARN_ON(id);
+
+	return "unknown";
+}
+
 static void
 assert_device_not_suspended(struct drm_i915_private *dev_priv)
 {
@@ -49,73 +69,123 @@ assert_device_not_suspended(struct drm_i915_private *dev_priv)
 		  "Device suspended\n");
 }
 
-static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
+static inline void
+fw_domain_reset(const struct intel_uncore_forcewake_domain *d)
 {
-	/* w/a for a sporadic read returning 0 by waiting for the GT
-	 * thread to wake up.
-	 */
-	if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) &
-				GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 500))
-		DRM_ERROR("GT thread status wait timed out\n");
+	__raw_i915_write32(d->i915, d->reg_set, d->val_reset);
 }
 
-static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv)
+static inline void
+fw_domain_arm_timer(struct intel_uncore_forcewake_domain *d)
 {
-	__raw_i915_write32(dev_priv, FORCEWAKE, 0);
-	/* something from same cacheline, but !FORCEWAKE */
-	__raw_posting_read(dev_priv, ECOBUS);
+	mod_timer_pinned(&d->timer, jiffies + 1);
 }
 
-static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
-				     int fw_engine)
+static inline void
+fw_domain_wait_ack_clear(const struct intel_uncore_forcewake_domain *d)
 {
-	if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0,
+	if (wait_for_atomic((__raw_i915_read32(d->i915, d->reg_ack) &
+			     FORCEWAKE_KERNEL) == 0,
 			    FORCEWAKE_ACK_TIMEOUT_MS))
-		DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
+		DRM_ERROR("%s: timed out waiting for forcewake ack to clear.\n",
+			  intel_uncore_forcewake_domain_to_str(d->id));
+}
 
-	__raw_i915_write32(dev_priv, FORCEWAKE, 1);
-	/* something from same cacheline, but !FORCEWAKE */
-	__raw_posting_read(dev_priv, ECOBUS);
+static inline void
+fw_domain_get(const struct intel_uncore_forcewake_domain *d)
+{
+	__raw_i915_write32(d->i915, d->reg_set, d->val_set);
+}
 
-	if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1),
+static inline void
+fw_domain_wait_ack(const struct intel_uncore_forcewake_domain *d)
+{
+	if (wait_for_atomic((__raw_i915_read32(d->i915, d->reg_ack) &
+			     FORCEWAKE_KERNEL),
 			    FORCEWAKE_ACK_TIMEOUT_MS))
-		DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
+		DRM_ERROR("%s: timed out waiting for forcewake ack request.\n",
+			  intel_uncore_forcewake_domain_to_str(d->id));
+}
 
-	/* WaRsForcewakeWaitTC0:snb */
-	__gen6_gt_wait_for_thread_c0(dev_priv);
+static inline void
+fw_domain_put(const struct intel_uncore_forcewake_domain *d)
+{
+	__raw_i915_write32(d->i915, d->reg_set, d->val_clear);
 }
 
-static void __gen7_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
+static inline void
+fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
 {
-	__raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff));
-	/* something from same cacheline, but !FORCEWAKE_MT */
-	__raw_posting_read(dev_priv, ECOBUS);
+	/* something from same cacheline, but not from the set register */
+	if (d->reg_post)
+		__raw_posting_read(d->i915, d->reg_post);
 }
 
-static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv,
-					int fw_engine)
+static void
+fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
 {
-	u32 forcewake_ack;
+	struct intel_uncore_forcewake_domain *d;
+	int id;
 
-	if (IS_HASWELL(dev_priv->dev) || IS_BROADWELL(dev_priv->dev))
-		forcewake_ack = FORCEWAKE_ACK_HSW;
-	else
-		forcewake_ack = FORCEWAKE_MT_ACK;
+	for_each_fw_domain_mask(d, fw_domains, dev_priv, id) {
+		fw_domain_wait_ack_clear(d);
+		fw_domain_get(d);
+		fw_domain_posting_read(d);
+		fw_domain_wait_ack(d);
+	}
+}
 
-	if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL) == 0,
-			    FORCEWAKE_ACK_TIMEOUT_MS))
-		DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
+static void
+fw_domains_put(struct drm_i915_private *dev_priv, int fw_domains)
+{
+	struct intel_uncore_forcewake_domain *d;
+	int id;
 
-	__raw_i915_write32(dev_priv, FORCEWAKE_MT,
-			   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-	/* something from same cacheline, but !FORCEWAKE_MT */
-	__raw_posting_read(dev_priv, ECOBUS);
+	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
+		fw_domain_put(d);
+}
 
-	if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL),
-			    FORCEWAKE_ACK_TIMEOUT_MS))
-		DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
+static void
+fw_domains_posting_read(struct drm_i915_private *dev_priv)
+{
+	struct intel_uncore_forcewake_domain *d;
+	int id;
+
+	/* No need to do for all, just do for first found */
+	for_each_fw_domain(d, dev_priv, id) {
+		fw_domain_posting_read(d);
+		break;
+	}
+}
+
+static void
+fw_domains_reset(struct drm_i915_private *dev_priv, const unsigned fw_domains)
+{
+	struct intel_uncore_forcewake_domain *d;
+	int id;
+
+	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
+		fw_domain_reset(d);
+
+	fw_domains_posting_read(dev_priv);
+}
+
+static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
+{
+	/* w/a for a sporadic read returning 0 by waiting for the GT
+	 * thread to wake up.
+	 */
+	if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) &
+				GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 500))
+		DRM_ERROR("GT thread status wait timed out\n");
+}
 
-	/* WaRsForcewakeWaitTC0:ivb,hsw */
+static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
+					      int fw_domains)
+{
+	fw_domains_get(dev_priv, fw_domains);
+
+	/* WaRsForcewakeWaitTC0:snb,ivb,hsw,bdw,vlv */
 	__gen6_gt_wait_for_thread_c0(dev_priv);
 }
 
@@ -128,27 +198,13 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
 		__raw_i915_write32(dev_priv, GTFIFODBG, gtfifodbg);
 }
 
-static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
-				     int fw_engine)
+static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
+				     int fw_domains)
 {
-	__raw_i915_write32(dev_priv, FORCEWAKE, 0);
-	/* something from same cacheline, but !FORCEWAKE */
-	__raw_posting_read(dev_priv, ECOBUS);
+	fw_domains_put(dev_priv, fw_domains);
 	gen6_gt_check_fifodbg(dev_priv);
 }
 
-static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv,
-					int fw_engine)
-{
-	__raw_i915_write32(dev_priv, FORCEWAKE_MT,
-			   _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-	/* something from same cacheline, but !FORCEWAKE_MT */
-	__raw_posting_read(dev_priv, ECOBUS);
-
-	if (IS_GEN7(dev_priv->dev))
-		gen6_gt_check_fifodbg(dev_priv);
-}
-
 static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 {
 	int ret = 0;
@@ -176,165 +232,16 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 	return ret;
 }
 
-static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
-{
-	__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
-			   _MASKED_BIT_DISABLE(0xffff));
-	__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
-			   _MASKED_BIT_DISABLE(0xffff));
-	/* something from same cacheline, but !FORCEWAKE_VLV */
-	__raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
-}
-
-static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
-				 int fw_engine)
-{
-	/* Check for Render Engine */
-	if (FORCEWAKE_RENDER & fw_engine) {
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_VLV) &
-						FORCEWAKE_KERNEL) == 0,
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
-
-		__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
-				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_VLV) &
-						FORCEWAKE_KERNEL),
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: waiting for Render to ack.\n");
-	}
-
-	/* Check for Media Engine */
-	if (FORCEWAKE_MEDIA & fw_engine) {
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_MEDIA_VLV) &
-						FORCEWAKE_KERNEL) == 0,
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
-
-		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
-				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_MEDIA_VLV) &
-						FORCEWAKE_KERNEL),
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: waiting for media to ack.\n");
-	}
-}
-
 static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
 				 int fw_engine)
 {
-	/* Check for Render Engine */
-	if (FORCEWAKE_RENDER & fw_engine)
-		__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
-					_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
+	fw_domains_put(dev_priv, fw_engine);
+	fw_domains_posting_read(dev_priv);
 
-
-	/* Check for Media Engine */
-	if (FORCEWAKE_MEDIA & fw_engine)
-		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
-				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-
-	/* something from same cacheline, but !FORCEWAKE_VLV */
-	__raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
 	if (!IS_CHERRYVIEW(dev_priv->dev))
 		gen6_gt_check_fifodbg(dev_priv);
 }
 
-static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
-{
-	__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
-			_MASKED_BIT_DISABLE(0xffff));
-
-	__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
-			_MASKED_BIT_DISABLE(0xffff));
-
-	__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
-			_MASKED_BIT_DISABLE(0xffff));
-}
-
-static void
-__gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
-{
-	/* Check for Render Engine */
-	if (FORCEWAKE_RENDER & fw_engine) {
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_RENDER_GEN9) &
-						FORCEWAKE_KERNEL) == 0,
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
-
-		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
-				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_RENDER_GEN9) &
-						FORCEWAKE_KERNEL),
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: waiting for Render to ack.\n");
-	}
-
-	/* Check for Media Engine */
-	if (FORCEWAKE_MEDIA & fw_engine) {
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_MEDIA_GEN9) &
-						FORCEWAKE_KERNEL) == 0,
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
-
-		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
-				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_MEDIA_GEN9) &
-						FORCEWAKE_KERNEL),
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: waiting for Media to ack.\n");
-	}
-
-	/* Check for Blitter Engine */
-	if (FORCEWAKE_BLITTER & fw_engine) {
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_BLITTER_GEN9) &
-						FORCEWAKE_KERNEL) == 0,
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: Blitter forcewake old ack to clear.\n");
-
-		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
-				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
-
-		if (wait_for_atomic((__raw_i915_read32(dev_priv,
-						FORCEWAKE_ACK_BLITTER_GEN9) &
-						FORCEWAKE_KERNEL),
-					FORCEWAKE_ACK_TIMEOUT_MS))
-			DRM_ERROR("Timed out: waiting for Blitter to ack.\n");
-	}
-}
-
-static void
-__gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
-{
-	/* Check for Render Engine */
-	if (FORCEWAKE_RENDER & fw_engine)
-		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
-				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-
-	/* Check for Media Engine */
-	if (FORCEWAKE_MEDIA & fw_engine)
-		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
-				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-
-	/* Check for Blitter Engine */
-	if (FORCEWAKE_BLITTER & fw_engine)
-		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
-				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
-}
-
 static void gen6_force_wake_timer(unsigned long arg)
 {
 	struct intel_uncore_forcewake_domain *domain = (void *)arg;
@@ -358,28 +265,20 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 	struct intel_uncore_forcewake_domain *domain;
 	int id;
 
-	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 	/* Hold uncore.lock across reset to prevent any register access
 	 * with forcewake not set correctly
 	 */
+	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
 	for_each_fw_domain(domain, dev_priv, id)
 		if (domain->wake_count)
 			fw |= 1 << id;
 
+	/* Don't stop the timer, just turn domains off for reset */
 	if (fw)
 		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw);
 
-	if (IS_VALLEYVIEW(dev))
-		vlv_force_wake_reset(dev_priv);
-	else if (IS_GEN6(dev) || IS_GEN7(dev))
-		__gen6_gt_force_wake_reset(dev_priv);
-
-	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
-		__gen7_gt_force_wake_mt_reset(dev_priv);
-
-	if (IS_GEN9(dev))
-		__gen9_gt_force_wake_mt_reset(dev_priv);
+	fw_domains_reset(dev_priv, FORCEWAKE_ALL);
 
 	if (restore) { /* If reset with a user forcewake, try to restore */
 		if (fw)
@@ -488,7 +387,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
 			continue;
 
 		domain->wake_count++;
-		mod_timer_pinned(&domain->timer, jiffies + 1);
+		fw_domain_arm_timer(domain);
 	}
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
@@ -497,12 +396,12 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
 void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
 {
 	struct intel_uncore_forcewake_domain *domain;
-	int i;
+	int id;
 
 	if (!dev_priv->uncore.funcs.force_wake_get)
 		return;
 
-	for_each_fw_domain(domain, dev_priv, i)
+	for_each_fw_domain(domain, dev_priv, id)
 		WARN_ON(domain->wake_count);
 }
 
@@ -673,19 +572,19 @@ static inline void __force_wake_get(struct drm_i915_private *dev_priv,
 				    unsigned fw_domains)
 {
 	struct intel_uncore_forcewake_domain *domain;
-	int i;
+	int id;
 
 	if (WARN_ON(!fw_domains))
 		return;
 
 	/* Ideally GCC would be constant-fold and eliminate this loop */
-	for_each_fw_domain_mask(domain, fw_domains, dev_priv, i) {
+	for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
 		if (domain->wake_count)
-			fw_domains &= ~(1 << i);
+			fw_domains &= ~(1 << id);
 		else
 			domain->wake_count++;
 
-		mod_timer_pinned(&domain->timer, jiffies + 1);
+		fw_domain_arm_timer(domain);
 	}
 
 	if (fw_domains)
@@ -1001,27 +900,75 @@ do { \
 	dev_priv->uncore.funcs.mmio_readq = x##_read64; \
 } while (0)
 
+
+static void fw_domain_init(struct drm_i915_private *dev_priv,
+			   u32 domain_id, u32 reg_set, u32 reg_ack)
+{
+	struct intel_uncore_forcewake_domain *d;
+
+	if (WARN_ON(domain_id >= FW_DOMAIN_ID_COUNT))
+		return;
+
+	d = &dev_priv->uncore.fw_domain[domain_id];
+
+	d->reg_set = reg_set;
+	d->reg_ack = reg_ack;
+
+	if (IS_GEN6(dev_priv)) {
+		d->val_reset = 0;
+		d->val_set = FORCEWAKE_KERNEL;
+		d->val_clear = 0;
+	} else {
+		d->val_reset = _MASKED_BIT_DISABLE(0xffff);
+		d->val_set = _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL);
+		d->val_clear = _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL);
+	}
+
+	if (IS_VALLEYVIEW(dev_priv))
+		d->reg_post = FORCEWAKE_ACK_VLV;
+	else if (IS_GEN6(dev_priv) || IS_GEN7(dev_priv))
+		d->reg_post = ECOBUS;
+	else
+		d->reg_post = 0;
+
+	d->i915 = dev_priv;
+	d->id = domain_id;
+
+	setup_timer(&d->timer, gen6_force_wake_timer, (unsigned long)d);
+
+	dev_priv->uncore.fw_domains |= (1 << domain_id);
+}
+
 void intel_uncore_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_uncore_forcewake_domain *domain;
-	int i;
 
 	__intel_uncore_early_sanitize(dev, false);
 
 	if (IS_GEN9(dev)) {
-		dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
-		dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
-		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER |
-			FORCEWAKE_BLITTER | FORCEWAKE_MEDIA;
+		dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
+		dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE_RENDER_GEN9,
+			       FORCEWAKE_ACK_RENDER_GEN9);
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_BLITTER,
+			       FORCEWAKE_BLITTER_GEN9,
+			       FORCEWAKE_ACK_BLITTER_GEN9);
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
+			       FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
 	} else if (IS_VALLEYVIEW(dev)) {
-		dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
+		dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
 		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
-		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER | FORCEWAKE_MEDIA;
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
+			       FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV);
 	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
-		dev_priv->uncore.funcs.force_wake_get = __gen7_gt_force_wake_mt_get;
-		dev_priv->uncore.funcs.force_wake_put = __gen7_gt_force_wake_mt_put;
-		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
+		dev_priv->uncore.funcs.force_wake_get =
+			fw_domains_get_with_thread_status;
+		dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
 	} else if (IS_IVYBRIDGE(dev)) {
 		u32 ecobus;
 
@@ -1034,40 +981,32 @@ void intel_uncore_init(struct drm_device *dev)
 		 * (correctly) interpreted by the test below as MT
 		 * forcewake being disabled.
 		 */
+		dev_priv->uncore.funcs.force_wake_get =
+			fw_domains_get_with_thread_status;
+		dev_priv->uncore.funcs.force_wake_put =
+			fw_domains_put_with_fifo;
+
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE_MT, FORCEWAKE_MT_ACK);
 		mutex_lock(&dev->struct_mutex);
-		__gen7_gt_force_wake_mt_get(dev_priv, FORCEWAKE_ALL);
+		fw_domains_get_with_thread_status(dev_priv, FORCEWAKE_ALL);
 		ecobus = __raw_i915_read32(dev_priv, ECOBUS);
-		__gen7_gt_force_wake_mt_put(dev_priv, FORCEWAKE_ALL);
+		fw_domains_put_with_fifo(dev_priv, FORCEWAKE_ALL);
 		mutex_unlock(&dev->struct_mutex);
 
-		if (ecobus & FORCEWAKE_MT_ENABLE) {
-			dev_priv->uncore.funcs.force_wake_get =
-				__gen7_gt_force_wake_mt_get;
-			dev_priv->uncore.funcs.force_wake_put =
-				__gen7_gt_force_wake_mt_put;
-		} else {
+		if (!(ecobus & FORCEWAKE_MT_ENABLE)) {
 			DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n");
 			DRM_INFO("when using vblank-synced partial screen updates.\n");
-			dev_priv->uncore.funcs.force_wake_get =
-				__gen6_gt_force_wake_get;
-			dev_priv->uncore.funcs.force_wake_put =
-				__gen6_gt_force_wake_put;
+			fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+				       FORCEWAKE, FORCEWAKE_ACK);
 		}
-		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
 	} else if (IS_GEN6(dev)) {
 		dev_priv->uncore.funcs.force_wake_get =
-			__gen6_gt_force_wake_get;
+			fw_domains_get_with_thread_status;
 		dev_priv->uncore.funcs.force_wake_put =
-			__gen6_gt_force_wake_put;
-		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
-	}
-
-	for_each_fw_domain(domain, dev_priv, i) {
-		domain->i915 = dev_priv;
-		domain->id = i;
-
-		setup_timer(&domain->timer, gen6_force_wake_timer,
-			    (unsigned long)domain);
+			fw_domains_put_with_fifo;
+		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
+			       FORCEWAKE, FORCEWAKE_ACK);
 	}
 
 	switch (INTEL_INFO(dev)->gen) {
-- 
1.9.1

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

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

* [PATCH 6/8] drm/i915: Make vlv and chv forcewake put generic.
  2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
                   ` (3 preceding siblings ...)
  2014-12-08 18:27 ` [PATCH 5/8] drm/i915: Consolidate forcewake code Mika Kuoppala
@ 2014-12-08 18:27 ` Mika Kuoppala
  2014-12-12 13:16   ` Deepak S
  2014-12-08 18:27 ` [PATCH 7/8] drm/i915: Rename the forcewake get/put functions Mika Kuoppala
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-08 18:27 UTC (permalink / raw
  To: intel-gfx; +Cc: miku

These two were using a fw dance logic where posting read was done
after both domain bit were set. When in other gens, the posting
read is done immediately after setting the forcewake bit for each
domain.

Now bring these in line with other gens.

Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index e883790..8021bec 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -232,16 +232,6 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 	return ret;
 }
 
-static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
-				 int fw_engine)
-{
-	fw_domains_put(dev_priv, fw_engine);
-	fw_domains_posting_read(dev_priv);
-
-	if (!IS_CHERRYVIEW(dev_priv->dev))
-		gen6_gt_check_fifodbg(dev_priv);
-}
-
 static void gen6_force_wake_timer(unsigned long arg)
 {
 	struct intel_uncore_forcewake_domain *domain = (void *)arg;
@@ -958,7 +948,11 @@ void intel_uncore_init(struct drm_device *dev)
 			       FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
 	} else if (IS_VALLEYVIEW(dev)) {
 		dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
-		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
+		if (!IS_CHERRYVIEW(dev))
+			dev_priv->uncore.funcs.force_wake_put =
+				fw_domains_put_with_fifo;
+		else
+			dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
 		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
 			       FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
 		fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
-- 
1.9.1

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

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

* [PATCH 7/8] drm/i915: Rename the forcewake get/put functions
  2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
                   ` (4 preceding siblings ...)
  2014-12-08 18:27 ` [PATCH 6/8] drm/i915: Make vlv and chv forcewake put generic Mika Kuoppala
@ 2014-12-08 18:27 ` Mika Kuoppala
  2014-12-12 13:19   ` Deepak S
  2014-12-08 18:27 ` [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors Mika Kuoppala
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-08 18:27 UTC (permalink / raw
  To: intel-gfx; +Cc: miku

We have multiple forcewake domains now on recent gens. Change the
function naming to reflect this.

v2: More verbose names (Chris)

Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c     |  8 ++++----
 drivers/gpu/drm/i915/i915_drv.c         |  2 +-
 drivers/gpu/drm/i915/i915_drv.h         | 15 +++++----------
 drivers/gpu/drm/i915/intel_display.c    |  4 ++--
 drivers/gpu/drm/i915/intel_lrc.c        |  4 ++--
 drivers/gpu/drm/i915/intel_pm.c         | 28 ++++++++++++++--------------
 drivers/gpu/drm/i915/intel_ringbuffer.c |  4 ++--
 drivers/gpu/drm/i915/intel_uncore.c     | 18 +++++++++---------
 8 files changed, 39 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 93390c9..ecc4b42 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1052,7 +1052,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 		if (ret)
 			goto out;
 
-		gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+		intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 		reqf = I915_READ(GEN6_RPNSWREQ);
 		reqf &= ~GEN6_TURBO_DISABLE;
@@ -1079,7 +1079,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
 			cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
 		cagf *= GT_FREQUENCY_MULTIPLIER;
 
-		gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+		intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 		mutex_unlock(&dev->struct_mutex);
 
 		if (IS_GEN6(dev) || IS_GEN7(dev)) {
@@ -4233,7 +4233,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
 		return 0;
 
 	intel_runtime_pm_get(dev_priv);
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	return 0;
 }
@@ -4246,7 +4246,7 @@ static int i915_forcewake_release(struct inode *inode, struct file *file)
 	if (INTEL_INFO(dev)->gen < 6)
 		return 0;
 
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 	intel_runtime_pm_put(dev_priv);
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 706b122..011caa2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1362,7 +1362,7 @@ static int intel_runtime_suspend(struct device *device)
 	if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev)))
 		return -ENODEV;
 
-	assert_force_wake_inactive(dev_priv);
+	assert_forcewakes_inactive(dev_priv);
 
 	DRM_DEBUG_KMS("Suspending device\n");
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4263084..a2a8536 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2450,6 +2450,11 @@ extern void intel_uncore_check_errors(struct drm_device *dev);
 extern void intel_uncore_fini(struct drm_device *dev);
 extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
 const char *intel_uncore_forcewake_domain_to_str(const int domain_id);
+void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
+				unsigned fw_domains);
+void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
+				unsigned fw_domains);
+void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
 
 void
 i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
@@ -3026,16 +3031,6 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
 					    struct drm_device *dev,
 					    struct intel_display_error_state *error);
 
-/* On SNB platform, before reading ring registers forcewake bit
- * must be set to prevent GT core from power down and stale values being
- * returned.
- */
-void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
-			    unsigned fw_domains);
-void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
-			    unsigned fw_domains);
-void assert_force_wake_inactive(struct drm_i915_private *dev_priv);
-
 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);
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 86c2885..d2d60f0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7863,7 +7863,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
 	 * Make sure we're not on PC8 state before disabling PC8, otherwise
 	 * we'll hang the machine. To prevent PC8 state, just enable force_wake.
 	 */
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	if (val & LCPLL_POWER_DOWN_ALLOW) {
 		val &= ~LCPLL_POWER_DOWN_ALLOW;
@@ -7893,7 +7893,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
 			DRM_ERROR("Switching back to LCPLL failed\n");
 	}
 
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index fcb5140..be9d00b 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -297,7 +297,7 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
 	desc[3] = (u32)(temp >> 32);
 	desc[2] = (u32)temp;
 
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 	I915_WRITE(RING_ELSP(ring), desc[1]);
 	I915_WRITE(RING_ELSP(ring), desc[0]);
 	I915_WRITE(RING_ELSP(ring), desc[3]);
@@ -307,7 +307,7 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
 
 	/* ELSP is a wo register, so use another nearby reg for posting instead */
 	POSTING_READ(RING_EXECLIST_STATUS(ring));
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 static int execlists_update_context(struct drm_i915_gem_object *ctx_obj,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 78911e2..64e06a3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -228,7 +228,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)
 
 	/* Blitter is part of Media powerwell on VLV. No impact of
 	 * his param in other platforms for now */
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_MEDIA);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_MEDIA);
 
 	blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
 	blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
@@ -241,7 +241,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)
 	I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
 	POSTING_READ(GEN6_BLITTER_ECOSKPD);
 
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_MEDIA);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_MEDIA);
 }
 
 static void ironlake_enable_fbc(struct drm_crtc *crtc)
@@ -4541,11 +4541,11 @@ static void valleyview_disable_rps(struct drm_device *dev)
 
 	/* we're doing forcewake before Disabling RC6,
 	 * This what the BIOS expects when going into suspend */
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	I915_WRITE(GEN6_RC_CONTROL, 0);
 
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
@@ -4663,7 +4663,7 @@ static void gen9_enable_rps(struct drm_device *dev)
 
 	/* 1b: Get forcewake during program sequence. Although the driver
 	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	/* 2a: Disable RC states. */
 	I915_WRITE(GEN6_RC_CONTROL, 0);
@@ -4686,7 +4686,7 @@ static void gen9_enable_rps(struct drm_device *dev)
 				   GEN6_RC_CTL_EI_MODE(1) |
 				   rc6_mask);
 
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 
 }
 
@@ -4702,7 +4702,7 @@ static void gen8_enable_rps(struct drm_device *dev)
 
 	/* 1c & 1d: Get forcewake during program sequence. Although the driver
 	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	/* 2a: Disable RC states. */
 	I915_WRITE(GEN6_RC_CONTROL, 0);
@@ -4769,7 +4769,7 @@ static void gen8_enable_rps(struct drm_device *dev)
 	dev_priv->rps.power = HIGH_POWER; /* force a reset */
 	gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
 
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 static void gen6_enable_rps(struct drm_device *dev)
@@ -4797,7 +4797,7 @@ static void gen6_enable_rps(struct drm_device *dev)
 		I915_WRITE(GTFIFODBG, gtfifodbg);
 	}
 
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	/* Initialize rps frequencies */
 	gen6_init_rps_frequencies(dev);
@@ -4877,7 +4877,7 @@ static void gen6_enable_rps(struct drm_device *dev)
 			DRM_ERROR("Couldn't fix incorrect rc6 voltage\n");
 	}
 
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 static void __gen6_update_ring_freq(struct drm_device *dev)
@@ -5296,7 +5296,7 @@ static void cherryview_enable_rps(struct drm_device *dev)
 
 	/* 1a & 1b: Get forcewake during program sequence. Although the driver
 	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	/* 2a: Program RC6 thresholds.*/
 	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
@@ -5364,7 +5364,7 @@ static void cherryview_enable_rps(struct drm_device *dev)
 
 	valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
 
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 static void valleyview_enable_rps(struct drm_device *dev)
@@ -5385,7 +5385,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
 	}
 
 	/* If VLV, Forcewake all wells, else re-direct to regular path */
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
 	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
@@ -5445,7 +5445,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
 
 	valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
 
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 void ironlake_teardown_rc6(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 3887f1a..210728f 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -536,7 +536,7 @@ static int init_ring_common(struct intel_engine_cs *ring)
 	struct drm_i915_gem_object *obj = ringbuf->obj;
 	int ret = 0;
 
-	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
 	if (!stop_ring(ring)) {
 		/* G45 ring initialization often fails to reset head to zero */
@@ -608,7 +608,7 @@ static int init_ring_common(struct intel_engine_cs *ring)
 	memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
 
 out:
-	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
+	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 8021bec..509b9c9 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -232,7 +232,7 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 	return ret;
 }
 
-static void gen6_force_wake_timer(unsigned long arg)
+static void intel_uncore_fw_release_timer(unsigned long arg)
 {
 	struct intel_uncore_forcewake_domain *domain = (void *)arg;
 	unsigned long irqflags;
@@ -326,10 +326,10 @@ void intel_uncore_sanitize(struct drm_device *dev)
  * Generally this is called implicitly by the register read function. However,
  * if some sequence requires the GT to not power down then this function should
  * be called at the beginning of the sequence followed by a call to
- * gen6_gt_force_wake_put() at the end of the sequence.
+ * intel_uncore_forcewake_put() at the end of the sequence.
  */
-void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
-			    unsigned fw_domains)
+void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
+				unsigned fw_domains)
 {
 	unsigned long irqflags;
 	struct intel_uncore_forcewake_domain *domain;
@@ -355,10 +355,10 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
 }
 
 /*
- * see gen6_gt_force_wake_get()
+ * see intel_uncore_forcewake_get()
  */
-void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
-			    unsigned fw_domains)
+void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
+				unsigned fw_domains)
 {
 	unsigned long irqflags;
 	struct intel_uncore_forcewake_domain *domain;
@@ -383,7 +383,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
-void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
+void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
 {
 	struct intel_uncore_forcewake_domain *domain;
 	int id;
@@ -924,7 +924,7 @@ static void fw_domain_init(struct drm_i915_private *dev_priv,
 	d->i915 = dev_priv;
 	d->id = domain_id;
 
-	setup_timer(&d->timer, gen6_force_wake_timer, (unsigned long)d);
+	setup_timer(&d->timer, intel_uncore_fw_release_timer, (unsigned long)d);
 
 	dev_priv->uncore.fw_domains |= (1 << domain_id);
 }
-- 
1.9.1

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

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

* [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors
  2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
                   ` (5 preceding siblings ...)
  2014-12-08 18:27 ` [PATCH 7/8] drm/i915: Rename the forcewake get/put functions Mika Kuoppala
@ 2014-12-08 18:27 ` Mika Kuoppala
  2014-12-09 11:46   ` [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers Mika Kuoppala
                     ` (2 more replies)
  2014-12-12 10:00 ` [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Deepak S
  2014-12-12 16:22 ` Paulo Zanoni
  8 siblings, 3 replies; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-08 18:27 UTC (permalink / raw
  To: intel-gfx; +Cc: miku

Forcewake domain code uses unsigned int as a type for 'domains mask'.
Bring the hw accessors inline with this.

Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h     | 4 ++--
 drivers/gpu/drm/i915/intel_uncore.c | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a2a8536..917614e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -535,9 +535,9 @@ struct drm_i915_display_funcs {
 
 struct intel_uncore_funcs {
 	void (*force_wake_get)(struct drm_i915_private *dev_priv,
-							int fw_engine);
+							unsigned fw_domains);
 	void (*force_wake_put)(struct drm_i915_private *dev_priv,
-							int fw_engine);
+							unsigned fw_domains);
 
 	uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
 	uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 509b9c9..be02aab 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -122,7 +122,7 @@ fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
 }
 
 static void
-fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
+fw_domains_get(struct drm_i915_private *dev_priv, unsigned fw_domains)
 {
 	struct intel_uncore_forcewake_domain *d;
 	int id;
@@ -136,7 +136,7 @@ fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
 }
 
 static void
-fw_domains_put(struct drm_i915_private *dev_priv, int fw_domains)
+fw_domains_put(struct drm_i915_private *dev_priv, unsigned fw_domains)
 {
 	struct intel_uncore_forcewake_domain *d;
 	int id;
@@ -181,7 +181,7 @@ static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
 }
 
 static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
-					      int fw_domains)
+					      unsigned fw_domains)
 {
 	fw_domains_get(dev_priv, fw_domains);
 
@@ -199,7 +199,7 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
 }
 
 static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
-				     int fw_domains)
+				     unsigned fw_domains)
 {
 	fw_domains_put(dev_priv, fw_domains);
 	gen6_gt_check_fifodbg(dev_priv);
-- 
1.9.1

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

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

* [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers
  2014-12-08 18:27 ` [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors Mika Kuoppala
@ 2014-12-09 11:46   ` Mika Kuoppala
  2014-12-09 13:32     ` Jani Nikula
  2014-12-12 13:21     ` [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers Deepak S
  2014-12-09 23:29   ` [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors shuang.he
  2014-12-12 13:20   ` Deepak S
  2 siblings, 2 replies; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-09 11:46 UTC (permalink / raw
  To: intel-gfx; +Cc: daniel.vetter

Make the domains and domain identifiers enums. To emphasize
the difference in order to avoid mistakes.

Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h     | 41 +++++++++++++++++----------------
 drivers/gpu/drm/i915/intel_uncore.c | 45 +++++++++++++++++++------------------
 2 files changed, 45 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0d47397..5c6c372 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -533,11 +533,28 @@ struct drm_i915_display_funcs {
 	void (*enable_backlight)(struct intel_connector *connector);
 };
 
+enum fw_domain_id {
+	FW_DOMAIN_ID_RENDER = 0,
+	FW_DOMAIN_ID_BLITTER,
+	FW_DOMAIN_ID_MEDIA,
+
+	FW_DOMAIN_ID_COUNT
+};
+
+enum fw_domains {
+	FORCEWAKE_RENDER = (1 << FW_DOMAIN_ID_RENDER),
+	FORCEWAKE_BLITTER = (1 << FW_DOMAIN_ID_BLITTER),
+	FORCEWAKE_MEDIA	= (1 << FW_DOMAIN_ID_MEDIA),
+	FORCEWAKE_ALL = (FORCEWAKE_RENDER |
+			 FORCEWAKE_BLITTER |
+			 FORCEWAKE_MEDIA)
+};
+
 struct intel_uncore_funcs {
 	void (*force_wake_get)(struct drm_i915_private *dev_priv,
-							int fw_engine);
+							enum fw_domains domains);
 	void (*force_wake_put)(struct drm_i915_private *dev_priv,
-							int fw_engine);
+							enum fw_domains domains);
 
 	uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
 	uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
@@ -554,25 +571,17 @@ struct intel_uncore_funcs {
 				uint64_t val, bool trace);
 };
 
-enum {
-	FW_DOMAIN_ID_RENDER = 0,
-	FW_DOMAIN_ID_BLITTER,
-	FW_DOMAIN_ID_MEDIA,
-
-	FW_DOMAIN_ID_COUNT
-};
-
 struct intel_uncore {
 	spinlock_t lock; /** lock is also taken in irq contexts. */
 
 	struct intel_uncore_funcs funcs;
 
 	unsigned fifo_count;
-	unsigned fw_domains;
+	enum fw_domains fw_domains;
 
 	struct intel_uncore_forcewake_domain {
 		struct drm_i915_private *i915;
-		int id;
+		enum fw_domain_id id;
 		unsigned wake_count;
 		struct timer_list timer;
 		u32 reg_set;
@@ -582,12 +591,6 @@ struct intel_uncore {
 		u32 reg_post;
 		u32 val_reset;
 	} fw_domain[FW_DOMAIN_ID_COUNT];
-#define FORCEWAKE_RENDER	(1 << FW_DOMAIN_ID_RENDER)
-#define FORCEWAKE_BLITTER	(1 << FW_DOMAIN_ID_BLITTER)
-#define FORCEWAKE_MEDIA		(1 << FW_DOMAIN_ID_MEDIA)
-#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | \
-				 FORCEWAKE_BLITTER | \
-				 FORCEWAKE_MEDIA)
 };
 
 /* Iterate over initialised fw domains */
@@ -2449,7 +2452,7 @@ extern void intel_uncore_init(struct drm_device *dev);
 extern void intel_uncore_check_errors(struct drm_device *dev);
 extern void intel_uncore_fini(struct drm_device *dev);
 extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
-const char *intel_uncore_forcewake_domain_to_str(const int domain_id);
+const char *intel_uncore_forcewake_domain_to_str(const enum fw_domain_id id);
 void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
 				unsigned fw_domains);
 void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 509b9c9..e802486 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -49,7 +49,7 @@ static const char * const forcewake_domain_names[] = {
 };
 
 const char *
-intel_uncore_forcewake_domain_to_str(const int id)
+intel_uncore_forcewake_domain_to_str(const enum fw_domain_id id)
 {
 	BUILD_BUG_ON((sizeof(forcewake_domain_names)/sizeof(const char *)) !=
 		     FW_DOMAIN_ID_COUNT);
@@ -122,10 +122,10 @@ fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
 }
 
 static void
-fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
+fw_domains_get(struct drm_i915_private *dev_priv, enum fw_domains fw_domains)
 {
 	struct intel_uncore_forcewake_domain *d;
-	int id;
+	enum fw_domain_id id;
 
 	for_each_fw_domain_mask(d, fw_domains, dev_priv, id) {
 		fw_domain_wait_ack_clear(d);
@@ -136,10 +136,10 @@ fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
 }
 
 static void
-fw_domains_put(struct drm_i915_private *dev_priv, int fw_domains)
+fw_domains_put(struct drm_i915_private *dev_priv, enum fw_domains fw_domains)
 {
 	struct intel_uncore_forcewake_domain *d;
-	int id;
+	enum fw_domain_id id;
 
 	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
 		fw_domain_put(d);
@@ -149,7 +149,7 @@ static void
 fw_domains_posting_read(struct drm_i915_private *dev_priv)
 {
 	struct intel_uncore_forcewake_domain *d;
-	int id;
+	enum fw_domain_id id;
 
 	/* No need to do for all, just do for first found */
 	for_each_fw_domain(d, dev_priv, id) {
@@ -159,10 +159,10 @@ fw_domains_posting_read(struct drm_i915_private *dev_priv)
 }
 
 static void
-fw_domains_reset(struct drm_i915_private *dev_priv, const unsigned fw_domains)
+fw_domains_reset(struct drm_i915_private *dev_priv, enum fw_domains fw_domains)
 {
 	struct intel_uncore_forcewake_domain *d;
-	int id;
+	enum fw_domain_id id;
 
 	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
 		fw_domain_reset(d);
@@ -181,7 +181,7 @@ static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
 }
 
 static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
-					      int fw_domains)
+					      enum fw_domains fw_domains)
 {
 	fw_domains_get(dev_priv, fw_domains);
 
@@ -199,7 +199,7 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
 }
 
 static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
-				     int fw_domains)
+				     enum fw_domains fw_domains)
 {
 	fw_domains_put(dev_priv, fw_domains);
 	gen6_gt_check_fifodbg(dev_priv);
@@ -251,9 +251,10 @@ static void intel_uncore_fw_release_timer(unsigned long arg)
 void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	unsigned long irqflags, fw = 0;
+	unsigned long irqflags;
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum fw_domain_id id;
+	enum fw_domains fw = 0;
 
 	/* Hold uncore.lock across reset to prevent any register access
 	 * with forcewake not set correctly
@@ -329,11 +330,11 @@ void intel_uncore_sanitize(struct drm_device *dev)
  * intel_uncore_forcewake_put() at the end of the sequence.
  */
 void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
-				unsigned fw_domains)
+				enum fw_domains fw_domains)
 {
 	unsigned long irqflags;
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum fw_domain_id id;
 
 	if (!dev_priv->uncore.funcs.force_wake_get)
 		return;
@@ -358,11 +359,11 @@ void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
  * see intel_uncore_forcewake_get()
  */
 void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
-				unsigned fw_domains)
+				enum fw_domains fw_domains)
 {
 	unsigned long irqflags;
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum fw_domain_id id;
 
 	if (!dev_priv->uncore.funcs.force_wake_put)
 		return;
@@ -386,7 +387,7 @@ void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
 void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
 {
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum fw_domain_id id;
 
 	if (!dev_priv->uncore.funcs.force_wake_get)
 		return;
@@ -559,10 +560,10 @@ __gen2_read(64)
 	return val
 
 static inline void __force_wake_get(struct drm_i915_private *dev_priv,
-				    unsigned fw_domains)
+				    enum fw_domains fw_domains)
 {
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum fw_domain_id id;
 
 	if (WARN_ON(!fw_domains))
 		return;
@@ -626,7 +627,7 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 #define __gen9_read(x) \
 static u##x \
 gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
-	unsigned fw_engine; \
+	enum fw_domains fw_engine; \
 	GEN6_READ_HEADER(x); \
 	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)))	\
 		fw_engine = 0; \
@@ -826,7 +827,7 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
 static void \
 gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
 		bool trace) { \
-	unsigned fw_engine; \
+	enum fw_domains fw_engine; \
 	GEN6_WRITE_HEADER; \
 	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) ||	\
 	    is_gen9_shadowed(dev_priv, reg)) \
@@ -892,7 +893,7 @@ do { \
 
 
 static void fw_domain_init(struct drm_i915_private *dev_priv,
-			   u32 domain_id, u32 reg_set, u32 reg_ack)
+			   enum fw_domain_id domain_id, u32 reg_set, u32 reg_ack)
 {
 	struct intel_uncore_forcewake_domain *d;
 
-- 
1.9.1

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

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

* [PATCH 00/10] Prep work patches for GPU scheduler
@ 2014-12-09 12:59 John.C.Harrison
  2014-12-09 12:59 ` [PATCH 01/10] drm/i915: Rename 'flags' to 'dispatch_flags' for better code reading John.C.Harrison
                   ` (9 more replies)
  0 siblings, 10 replies; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Assorted patches to make the tree more friendly to the GPU scheduler.

The biggest change is to re-organise the execbuff code path. Basically, the
scheduler needs to split the submission path into two sections which are
essentially software only (data structure creation, manipulation, etc.) and
hardware only (actually writing the commands to the write / execlist). As this
is not a small change, any other changes to the execution code path tend to
cause merge conflicts and other such headaches for the scheduler. Thus it would
be extremely useful to get this preparation work committed to the tree while the
scheduler is still being re-worked for upstream acceptability.

The other patches in the series are various minor fixes that were spotted along
the way to getting the scheduler working.

[Patches against drm-intel-nightly tree fetched 08/12/2014]

Dave Gordon (3):
  drm/i915: Updating assorted register and status page definitions
  drm/i915: FIFO space query code refactor
  drm/i915: Disable 'get seqno' workaround for VLV

John Harrison (7):
  drm/i915: Rename 'flags' to 'dispatch_flags' for better code reading
  drm/i915: Add missing trace point to LRC execbuff code path
  drm/i915: Add extra add_request calls
  drm/i915: Early alloc request
  drm/i915: Prelude to splitting i915_gem_do_execbuffer in two
  drm/i915: Split i915_dem_do_execbuffer() in half
  drm/i915: Cache ringbuf pointer in request structure

 drivers/gpu/drm/i915/i915_drv.h              |   53 ++++--
 drivers/gpu/drm/i915/i915_gem.c              |   63 +++----
 drivers/gpu/drm/i915/i915_gem_context.c      |    9 +
 drivers/gpu/drm/i915/i915_gem_execbuffer.c   |  237 +++++++++++++++++---------
 drivers/gpu/drm/i915/i915_gem_gtt.c          |    9 +
 drivers/gpu/drm/i915/i915_gem_render_state.c |    2 +-
 drivers/gpu/drm/i915/i915_reg.h              |   30 +++-
 drivers/gpu/drm/i915/intel_display.c         |   23 ++-
 drivers/gpu/drm/i915/intel_lrc.c             |  102 +++++++----
 drivers/gpu/drm/i915/intel_lrc.h             |   12 +-
 drivers/gpu/drm/i915/intel_ringbuffer.c      |   12 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h      |   44 ++++-
 drivers/gpu/drm/i915/intel_uncore.c          |   19 ++-
 13 files changed, 426 insertions(+), 189 deletions(-)

-- 
1.7.9.5

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

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

* [PATCH 01/10] drm/i915: Rename 'flags' to 'dispatch_flags' for better code reading
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  2014-12-09 12:59 ` [PATCH 02/10] drm/i915: Add missing trace point to LRC execbuff code path John.C.Harrison
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

There is a flags word that is passed through the execbuffer code path all the
way from initial decoding of the user parameters down to the very final dispatch
buffer call. It is simply called 'flags'. Unfortuantely, there are many other
flags words floating around in the same blocks of code. Even more once the GPU
scheduler arrives.

This patch makes it more obvious exactly which flags word is which by renaming
'flags' to 'dispatch_flags'. Note that the bit definitions for this flags word
already have an 'I915_DISPATCH_' prefix on them and so are not quite so
ambiguous.

Change-Id: Ibc858930c4a606763f84750c5008af07cf245a90
For: VIZ-1587
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |   23 ++++++++++++-----------
 drivers/gpu/drm/i915/intel_lrc.c           |    6 +++---
 drivers/gpu/drm/i915/intel_lrc.h           |    2 +-
 drivers/gpu/drm/i915/intel_ringbuffer.h    |    2 +-
 4 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 0c25f62..aa4566e 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1071,7 +1071,7 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 			       struct drm_i915_gem_execbuffer2 *args,
 			       struct list_head *vmas,
 			       struct drm_i915_gem_object *batch_obj,
-			       u64 exec_start, u32 flags)
+			       u64 exec_start, u32 dispatch_flags)
 {
 	struct drm_clip_rect *cliprects = NULL;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1199,19 +1199,19 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 
 			ret = ring->dispatch_execbuffer(ring,
 							exec_start, exec_len,
-							flags);
+							dispatch_flags);
 			if (ret)
 				goto error;
 		}
 	} else {
 		ret = ring->dispatch_execbuffer(ring,
 						exec_start, exec_len,
-						flags);
+						dispatch_flags);
 		if (ret)
 			return ret;
 	}
 
-	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), flags);
+	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), dispatch_flags);
 
 	i915_gem_execbuffer_move_to_active(vmas, ring);
 	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
@@ -1285,7 +1285,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	struct i915_address_space *vm;
 	const u32 ctx_id = i915_execbuffer2_get_context_id(*args);
 	u64 exec_start = args->batch_start_offset;
-	u32 flags;
+	u32 dispatch_flags;
 	int ret;
 	bool need_relocs;
 
@@ -1296,15 +1296,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	if (ret)
 		return ret;
 
-	flags = 0;
+	dispatch_flags = 0;
 	if (args->flags & I915_EXEC_SECURE) {
 		if (!file->is_master || !capable(CAP_SYS_ADMIN))
 		    return -EPERM;
 
-		flags |= I915_DISPATCH_SECURE;
+		dispatch_flags |= I915_DISPATCH_SECURE;
 	}
 	if (args->flags & I915_EXEC_IS_PINNED)
-		flags |= I915_DISPATCH_PINNED;
+		dispatch_flags |= I915_DISPATCH_PINNED;
 
 	if ((args->flags & I915_EXEC_RING_MASK) > LAST_USER_RING) {
 		DRM_DEBUG("execbuf with unknown ring: %d\n",
@@ -1421,7 +1421,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	/* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure
 	 * batch" bit. Hence we need to pin secure batches into the global gtt.
 	 * hsw should have this fixed, but bdw mucks it up again. */
-	if (flags & I915_DISPATCH_SECURE) {
+	if (dispatch_flags & I915_DISPATCH_SECURE) {
 		/*
 		 * So on first glance it looks freaky that we pin the batch here
 		 * outside of the reservation loop. But:
@@ -1441,7 +1441,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		exec_start += i915_gem_obj_offset(batch_obj, vm);
 
 	ret = dev_priv->gt.do_execbuf(dev, file, ring, ctx, args,
-				      &eb->vmas, batch_obj, exec_start, flags);
+				      &eb->vmas, batch_obj, exec_start,
+				      dispatch_flags);
 
 	/*
 	 * FIXME: We crucially rely upon the active tracking for the (ppgtt)
@@ -1449,7 +1450,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	 * needs to be adjusted to also track the ggtt batch vma properly as
 	 * active.
 	 */
-	if (flags & I915_DISPATCH_SECURE)
+	if (dispatch_flags & I915_DISPATCH_SECURE)
 		i915_gem_object_ggtt_unpin(batch_obj);
 err:
 	/* the request owns the ref now */
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index a82020e..b8baf11 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -646,7 +646,7 @@ static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf,
  * @vmas: list of vmas.
  * @batch_obj: the batchbuffer to submit.
  * @exec_start: batchbuffer start virtual address pointer.
- * @flags: translated execbuffer call flags.
+ * @dispatch_flags: translated execbuffer call flags.
  *
  * This is the evil twin version of i915_gem_ringbuffer_submission. It abstracts
  * away the submission details of the execbuffer ioctl call.
@@ -659,7 +659,7 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
 			       struct drm_i915_gem_execbuffer2 *args,
 			       struct list_head *vmas,
 			       struct drm_i915_gem_object *batch_obj,
-			       u64 exec_start, u32 flags)
+			       u64 exec_start, u32 dispatch_flags)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf;
@@ -732,7 +732,7 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
 		dev_priv->relative_constants_mode = instp_mode;
 	}
 
-	ret = ring->emit_bb_start(ringbuf, exec_start, flags);
+	ret = ring->emit_bb_start(ringbuf, exec_start, dispatch_flags);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 14b216b..b8d5364 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -80,7 +80,7 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
 			       struct drm_i915_gem_execbuffer2 *args,
 			       struct list_head *vmas,
 			       struct drm_i915_gem_object *batch_obj,
-			       u64 exec_start, u32 flags);
+			       u64 exec_start, u32 dispatch_flags);
 u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj);
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 6dbb6f4..2e0fa7b 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -169,7 +169,7 @@ struct  intel_engine_cs {
 				     u32 seqno);
 	int		(*dispatch_execbuffer)(struct intel_engine_cs *ring,
 					       u64 offset, u32 length,
-					       unsigned flags);
+					       unsigned dispatch_flags);
 #define I915_DISPATCH_SECURE 0x1
 #define I915_DISPATCH_PINNED 0x2
 	void		(*cleanup)(struct intel_engine_cs *ring);
-- 
1.7.9.5

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

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

* [PATCH 02/10] drm/i915: Add missing trace point to LRC execbuff code path
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
  2014-12-09 12:59 ` [PATCH 01/10] drm/i915: Rename 'flags' to 'dispatch_flags' for better code reading John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  2014-12-09 12:59 ` [PATCH 03/10] drm/i915: Updating assorted register and status page definitions John.C.Harrison
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

There is a trace point in the legacy execbuffer execution path that is missing
from the execlist path. Trace points are extremely useful for debugging and are
used by various automated validation tests. Hence, this patch adds the missing
trace point back in.

Change-Id: I8bc80a892e5f7effbe3a0883a58a828d59c10c07
For: VIZ-1587
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/intel_lrc.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index b8baf11..82a47e3 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -736,6 +736,8 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
 	if (ret)
 		return ret;
 
+	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), dispatch_flags);
+
 	i915_gem_execbuffer_move_to_active(vmas, ring);
 	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
 
-- 
1.7.9.5

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

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

* [PATCH 03/10] drm/i915: Updating assorted register and status page definitions
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
  2014-12-09 12:59 ` [PATCH 01/10] drm/i915: Rename 'flags' to 'dispatch_flags' for better code reading John.C.Harrison
  2014-12-09 12:59 ` [PATCH 02/10] drm/i915: Add missing trace point to LRC execbuff code path John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  2014-12-10 10:40   ` Daniel Vetter
  2014-12-09 12:59 ` [PATCH 04/10] drm/i915: FIFO space query code refactor John.C.Harrison
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: Dave Gordon <david.s.gordon@intel.com>

Added various definitions that will be useful for the scheduler in general and
pre-emptive context switching in particular.

Change-Id: Ica805b94160426def51f5d520f5ce51c60864a98
For: VIZ-1587
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h         |   30 ++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_ringbuffer.h |   40 +++++++++++++++++++++++++++++--
 2 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 869e5ae..6169720 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -216,6 +216,10 @@
 #define  MI_GLOBAL_GTT    (1<<22)
 
 #define MI_NOOP			MI_INSTR(0, 0)
+#define   MI_NOOP_WRITE_ID		(1<<22)
+#define   MI_NOOP_ID_MASK		((1<<22) - 1)
+#define   MI_NOOP_MID(id)		((id) & MI_NOOP_ID_MASK)
+#define MI_NOOP_WITH_ID(id)	MI_INSTR(0, MI_NOOP_WRITE_ID|MI_NOOP_MID(id))
 #define MI_USER_INTERRUPT	MI_INSTR(0x02, 0)
 #define MI_WAIT_FOR_EVENT       MI_INSTR(0x03, 0)
 #define   MI_WAIT_FOR_OVERLAY_FLIP	(1<<16)
@@ -233,6 +237,7 @@
 #define MI_ARB_ON_OFF		MI_INSTR(0x08, 0)
 #define   MI_ARB_ENABLE			(1<<0)
 #define   MI_ARB_DISABLE		(0<<0)
+#define MI_ARB_CHECK		MI_INSTR(0x05, 0)
 #define MI_BATCH_BUFFER_END	MI_INSTR(0x0a, 0)
 #define MI_SUSPEND_FLUSH	MI_INSTR(0x0b, 0)
 #define   MI_SUSPEND_FLUSH_EN	(1<<0)
@@ -281,6 +286,8 @@
 #define   MI_SEMAPHORE_SYNC_INVALID (3<<16)
 #define   MI_SEMAPHORE_SYNC_MASK    (3<<16)
 #define MI_SET_CONTEXT		MI_INSTR(0x18, 0)
+#define   MI_CONTEXT_ADDR_MASK		((~0)<<12)
+#define   MI_SET_CONTEXT_FLAG_MASK	((1<<12)-1)
 #define   MI_MM_SPACE_GTT		(1<<8)
 #define   MI_MM_SPACE_PHYSICAL		(0<<8)
 #define   MI_SAVE_EXT_STATE_EN		(1<<3)
@@ -298,6 +305,10 @@
 #define   MI_USE_GGTT		(1 << 22) /* g4x+ */
 #define MI_STORE_DWORD_INDEX	MI_INSTR(0x21, 1)
 #define   MI_STORE_DWORD_INDEX_SHIFT 2
+#define MI_STORE_REG_MEM	MI_INSTR(0x24, 1)
+#define   MI_STORE_REG_MEM_GTT		(1 << 22)
+#define   MI_STORE_REG_MEM_PREDICATE	(1 << 21)
+
 /* Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM:
  * - Always issue a MI_NOOP _before_ the MI_LOAD_REGISTER_IMM - otherwise hw
  *   simply ignores the register load under certain conditions.
@@ -312,7 +323,10 @@
 #define MI_FLUSH_DW		MI_INSTR(0x26, 1) /* for GEN6 */
 #define   MI_FLUSH_DW_STORE_INDEX	(1<<21)
 #define   MI_INVALIDATE_TLB		(1<<18)
+#define   MI_FLUSH_DW_OP_NONE		(0<<14)
 #define   MI_FLUSH_DW_OP_STOREDW	(1<<14)
+#define   MI_FLUSH_DW_OP_RSVD		(2<<14)
+#define   MI_FLUSH_DW_OP_STAMP		(3<<14)
 #define   MI_FLUSH_DW_OP_MASK		(3<<14)
 #define   MI_FLUSH_DW_NOTIFY		(1<<8)
 #define   MI_INVALIDATE_BSD		(1<<7)
@@ -1119,6 +1133,19 @@ enum punit_power_well {
 #define GEN6_VERSYNC	(RING_SYNC_1(VEBOX_RING_BASE))
 #define GEN6_VEVSYNC	(RING_SYNC_2(VEBOX_RING_BASE))
 #define GEN6_NOSYNC 0
+
+/*
+ * Premption-related registers
+ */
+#define RING_UHPTR(base)	((base)+0x134)
+#define   UHPTR_GFX_ADDR_ALIGN		(0x7)
+#define   UHPTR_VALID			(0x1)
+#define RING_PREEMPT_ADDR	0x0214c
+#define   PREEMPT_BATCH_LEVEL_MASK	(0x3)
+#define BB_PREEMPT_ADDR		0x02148
+#define SBB_PREEMPT_ADDR	0x0213c
+#define RS_PREEMPT_STATUS	0x0215c
+
 #define RING_MAX_IDLE(base)	((base)+0x54)
 #define RING_HWS_PGA(base)	((base)+0x80)
 #define RING_HWS_PGA_GEN6(base)	((base)+0x2080)
@@ -5917,7 +5944,8 @@ enum punit_power_well {
 #define  VLV_SPAREG2H				0xA194
 
 #define  GTFIFODBG				0x120000
-#define    GT_FIFO_SBDROPERR			(1<<6)
+#define    GT_FIFO_CPU_ERROR_MASK		0xf
+#define    GT_FIFO_SDDROPERR			(1<<6)
 #define    GT_FIFO_BLOBDROPERR			(1<<5)
 #define    GT_FIFO_SB_READ_ABORTERR		(1<<4)
 #define    GT_FIFO_DROPERR			(1<<3)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 2e0fa7b..f15fc46 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -47,6 +47,12 @@ struct  intel_hw_status_page {
 #define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base))
 #define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val)
 
+#define I915_READ_UHPTR(ring) \
+		I915_READ(RING_UHPTR((ring)->mmio_base))
+#define I915_WRITE_UHPTR(ring, val) \
+		I915_WRITE(RING_UHPTR((ring)->mmio_base), val)
+#define I915_READ_NOPID(ring) I915_READ(RING_NOPID((ring)->mmio_base))
+
 /* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to
  * do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
  */
@@ -377,10 +383,40 @@ intel_write_status_page(struct intel_engine_cs *ring,
  * 0x1f: Last written status offset. (GM45)
  *
  * The area from dword 0x20 to 0x3ff is available for driver usage.
+ *
+ * Note: in general the allocation of these indices is arbitrary, as long
+ * as they are all unique. But a few of them are used with instructions that
+ * have specific alignment requirements, those particular indices must be
+ * chosen carefully to meet those requirements. The list below shows the
+ * currently-known alignment requirements:
+ *
+ *	I915_GEM_SCRATCH_INDEX	    must be EVEN
  */
 #define I915_GEM_HWS_INDEX		0x20
-#define I915_GEM_HWS_SCRATCH_INDEX	0x30
-#define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
+
+#define I915_GEM_HWS_SCRATCH_INDEX	0x24  /* QWord */
+#define I915_GEM_HWS_SCRATCH_ADDR	(I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
+
+/*
+ * Tracking; these are updated by the GPU at the beginning and/or end of every
+ * batch. One pair for regular buffers, the other for preemptive ones.
+ */
+#define I915_BATCH_DONE_SEQNO		0x30  /* Completed batch seqno        */
+#define I915_BATCH_ACTIVE_SEQNO		0x31  /* In progress batch seqno      */
+#define I915_PREEMPTIVE_DONE_SEQNO	0x32  /* Completed preemptive batch   */
+#define I915_PREEMPTIVE_ACTIVE_SEQNO	0x33  /* In progress preemptive batch */
+
+/*
+ * Preemption; these are used by the GPU to save important registers
+ */
+#define I915_SAVE_PREEMPTED_RING_PTR	0x34  /* HEAD before preemption     */
+#define I915_SAVE_PREEMPTED_BB_PTR	0x35  /* BB ptr before preemption   */
+#define I915_SAVE_PREEMPTED_SBB_PTR	0x36  /* SBB before preemption      */
+#define I915_SAVE_PREEMPTED_UHPTR	0x37  /* UHPTR after preemption     */
+#define I915_SAVE_PREEMPTED_HEAD	0x38  /* HEAD after preemption      */
+#define I915_SAVE_PREEMPTED_TAIL	0x39  /* TAIL after preemption      */
+#define I915_SAVE_PREEMPTED_STATUS	0x3A  /* RS preemption status       */
+#define I915_SAVE_PREEMPTED_NOPID	0x3B  /* Dummy                      */
 
 void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf);
 int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
-- 
1.7.9.5

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

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

* [PATCH 04/10] drm/i915: FIFO space query code refactor
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
                   ` (2 preceding siblings ...)
  2014-12-09 12:59 ` [PATCH 03/10] drm/i915: Updating assorted register and status page definitions John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  2014-12-10 10:41   ` Daniel Vetter
  2014-12-09 12:59 ` [PATCH 05/10] drm/i915: Disable 'get seqno' workaround for VLV John.C.Harrison
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: Dave Gordon <david.s.gordon@intel.com>

When querying the GTFIFOCTL register to check the FIFO space, the read value
must be masked. The operation is repeated explicitly in several places. This
change refactors the read-and-mask code into a function call.

Change-Id: Id1a9f3785cb20b82d4caa330c37b31e4e384a3ef
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 46de8d7..4021831 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -47,6 +47,13 @@ assert_device_not_suspended(struct drm_i915_private *dev_priv)
 		  "Device suspended\n");
 }
 
+static inline u32 fifo_free_entries(struct drm_i915_private *dev_priv)
+{
+	u32 count = __raw_i915_read32(dev_priv, GTFIFOCTL);
+
+	return count & GT_FIFO_FREE_ENTRIES_MASK;
+}
+
 static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
 {
 	/* w/a for a sporadic read returning 0 by waiting for the GT
@@ -154,16 +161,15 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 	/* On VLV, FIFO will be shared by both SW and HW.
 	 * So, we need to read the FREE_ENTRIES everytime */
 	if (IS_VALLEYVIEW(dev_priv->dev))
-		dev_priv->uncore.fifo_count =
-			__raw_i915_read32(dev_priv, GTFIFOCTL) &
-						GT_FIFO_FREE_ENTRIES_MASK;
+		dev_priv->uncore.fifo_count = fifo_free_entries(dev_priv);
 
 	if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
 		int loop = 500;
-		u32 fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
+		u32 fifo = fifo_free_entries(dev_priv);
+
 		while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
 			udelay(10);
-			fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
+			fifo = fifo_free_entries(dev_priv);
 		}
 		if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
 			++ret;
@@ -505,8 +511,7 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 
 		if (IS_GEN6(dev) || IS_GEN7(dev))
 			dev_priv->uncore.fifo_count =
-				__raw_i915_read32(dev_priv, GTFIFOCTL) &
-				GT_FIFO_FREE_ENTRIES_MASK;
+				fifo_free_entries(dev_priv);
 	}
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-- 
1.7.9.5

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

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

* [PATCH 05/10] drm/i915: Disable 'get seqno' workaround for VLV
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
                   ` (3 preceding siblings ...)
  2014-12-09 12:59 ` [PATCH 04/10] drm/i915: FIFO space query code refactor John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  2014-12-10 10:42   ` Daniel Vetter
  2014-12-09 12:59 ` [PATCH 06/10] drm/i915: Add extra add_request calls John.C.Harrison
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: Dave Gordon <david.s.gordon@intel.com>

There is a workaround for a hardware bug when reading the seqno from the status
page. The bug does not exist on VLV however, the workaround was still being
applied.

Change-Id: Ic781fdb31e1f794ce1fa8a6d0d5ee379756c5db6
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
---
 drivers/gpu/drm/i915/intel_ringbuffer.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 3887f1a..f990ce4 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2367,7 +2367,10 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
 		ring->irq_get = gen6_ring_get_irq;
 		ring->irq_put = gen6_ring_put_irq;
 		ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
-		ring->get_seqno = gen6_ring_get_seqno;
+		if (IS_VALLEYVIEW(dev))
+			ring->get_seqno = ring_get_seqno;
+		else
+			ring->get_seqno = gen6_ring_get_seqno;
 		ring->set_seqno = ring_set_seqno;
 		if (i915_semaphore_is_enabled(dev)) {
 			ring->semaphore.sync_to = gen6_ring_sync;
-- 
1.7.9.5

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

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

* [PATCH 06/10] drm/i915: Add extra add_request calls
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
                   ` (4 preceding siblings ...)
  2014-12-09 12:59 ` [PATCH 05/10] drm/i915: Disable 'get seqno' workaround for VLV John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  2014-12-10 10:55   ` Daniel Vetter
  2014-12-09 12:59 ` [PATCH 07/10] drm/i915: Early alloc request John.C.Harrison
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The scheduler needs to track batch buffers by request without extra, non-batch
buffer work being attached to the same request. This means that anywhere which
adds work to the ring should explicitly call i915_add_request() when it has
finished writing to the ring.

The add_request() function does extra work, such as flushing caches, that does
not necessarily want to be done everywhere. Instead, a new
i915_add_request_wo_flush() function has been added which skips the cache flush
and just tidies up the request structure.

Note, much of this patch was implemented by Naresh Kumar Kachhi for pending
power management improvements. However, it is also directly applicable to the
scheduler work as noted above.

Change-Id: I66a6861118ee8e7ad7ca6c80c71a3b256db92e18
For: VIZ-1587
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h              |    9 ++++--
 drivers/gpu/drm/i915/i915_gem.c              |   45 ++++++++++++++++----------
 drivers/gpu/drm/i915/i915_gem_context.c      |    9 ++++++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c   |    4 +--
 drivers/gpu/drm/i915/i915_gem_gtt.c          |    9 ++++++
 drivers/gpu/drm/i915/i915_gem_render_state.c |    2 +-
 drivers/gpu/drm/i915/intel_display.c         |   23 +++++++++----
 drivers/gpu/drm/i915/intel_lrc.c             |    4 +--
 8 files changed, 73 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 11e85cb..0e280c4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2553,7 +2553,7 @@ static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
 
 int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
 int i915_gem_object_sync(struct drm_i915_gem_object *obj,
-			 struct intel_engine_cs *to);
+			 struct intel_engine_cs *to, bool add_request);
 void i915_vma_move_to_active(struct i915_vma *vma,
 			     struct intel_engine_cs *ring);
 int i915_gem_dumb_create(struct drm_file *file_priv,
@@ -2641,9 +2641,12 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
 int __must_check i915_gem_suspend(struct drm_device *dev);
 int __i915_add_request(struct intel_engine_cs *ring,
 		       struct drm_file *file,
-		       struct drm_i915_gem_object *batch_obj);
+		       struct drm_i915_gem_object *batch_obj,
+		       bool flush_caches);
 #define i915_add_request(ring) \
-	__i915_add_request(ring, NULL, NULL)
+	__i915_add_request(ring, NULL, NULL, true)
+#define i915_add_request_no_flush(ring) \
+	__i915_add_request(ring, NULL, NULL, false)
 int __i915_wait_request(struct drm_i915_gem_request *req,
 			unsigned reset_counter,
 			bool interruptible,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index de241eb..b022a2d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2419,7 +2419,8 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
 
 int __i915_add_request(struct intel_engine_cs *ring,
 		       struct drm_file *file,
-		       struct drm_i915_gem_object *obj)
+		       struct drm_i915_gem_object *obj,
+		       bool flush_caches)
 {
 	struct drm_i915_private *dev_priv = ring->dev->dev_private;
 	struct drm_i915_gem_request *request;
@@ -2445,12 +2446,11 @@ int __i915_add_request(struct intel_engine_cs *ring,
 	 * is that the flush _must_ happen before the next request, no matter
 	 * what.
 	 */
-	if (i915.enable_execlists) {
-		ret = logical_ring_flush_all_caches(ringbuf);
-		if (ret)
-			return ret;
-	} else {
-		ret = intel_ring_flush_all_caches(ring);
+	if (flush_caches) {
+		if (i915.enable_execlists)
+			ret = logical_ring_flush_all_caches(ringbuf);
+		else
+			ret = intel_ring_flush_all_caches(ring);
 		if (ret)
 			return ret;
 	}
@@ -2462,15 +2462,12 @@ int __i915_add_request(struct intel_engine_cs *ring,
 	 */
 	request_ring_position = intel_ring_get_tail(ringbuf);
 
-	if (i915.enable_execlists) {
+	if (i915.enable_execlists)
 		ret = ring->emit_request(ringbuf);
-		if (ret)
-			return ret;
-	} else {
+	else
 		ret = ring->add_request(ring);
-		if (ret)
-			return ret;
-	}
+	if (ret)
+		return ret;
 
 	request->head = request_start;
 	request->tail = request_ring_position;
@@ -2974,6 +2971,8 @@ out:
  *
  * @obj: object which may be in use on another ring.
  * @to: ring we wish to use the object on. May be NULL.
+ * @add_request: do we need to add a request to track operations
+ *    submitted on ring with sync_to function
  *
  * This code is meant to abstract object synchronization with the GPU.
  * Calling with NULL implies synchronizing the object with the CPU
@@ -2983,7 +2982,7 @@ out:
  */
 int
 i915_gem_object_sync(struct drm_i915_gem_object *obj,
-		     struct intel_engine_cs *to)
+		     struct intel_engine_cs *to, bool add_request)
 {
 	struct intel_engine_cs *from;
 	u32 seqno;
@@ -3011,13 +3010,16 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
 
 	trace_i915_gem_ring_sync_to(from, to, obj->last_read_req);
 	ret = to->semaphore.sync_to(to, from, seqno);
-	if (!ret)
+	if (!ret) {
 		/* We use last_read_req because sync_to()
 		 * might have just caused seqno wrap under
 		 * the radar.
 		 */
 		from->semaphore.sync_seqno[idx] =
 				i915_gem_request_get_seqno(obj->last_read_req);
+		if (add_request)
+			i915_add_request_no_flush(to);
+	}
 
 	return ret;
 }
@@ -3126,6 +3128,15 @@ int i915_gpu_idle(struct drm_device *dev)
 				return ret;
 		}
 
+		/* Make sure the context switch (if one actually happened)
+		 * gets wrapped up and finished rather than hanging around
+		 * and confusing things later. */
+		if (ring->outstanding_lazy_request) {
+			ret = i915_add_request(ring);
+			if (ret)
+				return ret;
+		}
+
 		ret = intel_ring_idle(ring);
 		if (ret)
 			return ret;
@@ -3946,7 +3957,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
 	int ret;
 
 	if (pipelined != i915_gem_request_get_ring(obj->last_read_req)) {
-		ret = i915_gem_object_sync(obj, pipelined);
+		ret = i915_gem_object_sync(obj, pipelined, true);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 5cd2b97..b2f1296 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -426,6 +426,15 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
 			ret = i915_switch_context(ring, ring->default_context);
 			if (ret)
 				return ret;
+
+			/* Make sure the context switch (if one actually happened)
+			 * gets wrapped up and finished rather than hanging around
+			 * and confusing things later. */
+			if (ring->outstanding_lazy_request) {
+				ret = i915_add_request_no_flush(ring);
+				if (ret)
+					return ret;
+			}
 		}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index aa4566e..1268e89 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -832,7 +832,7 @@ i915_gem_execbuffer_move_to_gpu(struct intel_engine_cs *ring,
 
 	list_for_each_entry(vma, vmas, exec_list) {
 		struct drm_i915_gem_object *obj = vma->obj;
-		ret = i915_gem_object_sync(obj, ring);
+		ret = i915_gem_object_sync(obj, ring, false);
 		if (ret)
 			return ret;
 
@@ -993,7 +993,7 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev,
 	ring->gpu_caches_dirty = true;
 
 	/* Add a breadcrumb for the completion of the batch buffer */
-	(void)__i915_add_request(ring, file, obj);
+	(void)__i915_add_request(ring, file, obj, true);
 }
 
 static int
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index ac03a38..7eead93 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1153,6 +1153,15 @@ int i915_ppgtt_init_hw(struct drm_device *dev)
 			ret = ppgtt->switch_mm(ppgtt, ring);
 			if (ret != 0)
 				return ret;
+
+			/* Make sure the context switch (if one actually happened)
+			 * gets wrapped up and finished rather than hanging around
+			 * and confusing things later. */
+			if (ring->outstanding_lazy_request) {
+				ret = i915_add_request_no_flush(ring);
+				if (ret)
+					return ret;
+			}
 		}
 	}
 
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 521548a..aba39c3 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -173,7 +173,7 @@ int i915_gem_render_state_init(struct intel_engine_cs *ring)
 
 	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
 
-	ret = __i915_add_request(ring, NULL, so.obj);
+	ret = __i915_add_request(ring, NULL, so.obj, true);
 	/* __i915_add_request moves object to inactive if it fails */
 out:
 	i915_gem_render_state_fini(&so);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a9bdc12..5b8d4f9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9116,7 +9116,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
 	intel_ring_emit(ring, 0); /* aux display base address, unused */
 
 	intel_mark_page_flip_active(intel_crtc);
-	__intel_ring_advance(ring);
+	i915_add_request_no_flush(ring);
 	return 0;
 }
 
@@ -9148,7 +9148,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
 	intel_ring_emit(ring, MI_NOOP);
 
 	intel_mark_page_flip_active(intel_crtc);
-	__intel_ring_advance(ring);
+	i915_add_request_no_flush(ring);
 	return 0;
 }
 
@@ -9187,7 +9187,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
 	intel_ring_emit(ring, pf | pipesrc);
 
 	intel_mark_page_flip_active(intel_crtc);
-	__intel_ring_advance(ring);
+	i915_add_request_no_flush(ring);
 	return 0;
 }
 
@@ -9223,7 +9223,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
 	intel_ring_emit(ring, pf | pipesrc);
 
 	intel_mark_page_flip_active(intel_crtc);
-	__intel_ring_advance(ring);
+	i915_add_request_no_flush(ring);
 	return 0;
 }
 
@@ -9318,7 +9318,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
 	intel_ring_emit(ring, (MI_NOOP));
 
 	intel_mark_page_flip_active(intel_crtc);
-	__intel_ring_advance(ring);
+	i915_add_request_no_flush(ring);
 	return 0;
 }
 
@@ -9528,7 +9528,7 @@ static int intel_gen9_queue_flip(struct drm_device *dev,
 	intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
 
 	intel_mark_page_flip_active(intel_crtc);
-	__intel_ring_advance(ring);
+	i915_add_request_no_flush(ring);
 
 	return 0;
 }
@@ -9734,8 +9734,17 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 		if (ret)
 			goto cleanup_unpin;
 
+		/* Borked: need to get the seqno for the request submitted in
+		 * 'queue_flip()' above. However, either the request has been
+		 * posted already and the seqno is gone (q_f calls add_request),
+		 * or the request never gets posted and is merged into whatever
+		 * render comes along next (q_f calls ring_advance).
+		 *
+		 * On the other hand, seqnos are going away soon anyway! So
+		 * hopefully the problem will disappear...
+		 */
 		i915_gem_request_assign(&work->flip_queued_req,
-					intel_ring_get_request(ring));
+					ring->outstanding_lazy_request ? intel_ring_get_request(ring) : NULL);
 	}
 
 	work->flip_queued_vblank = drm_vblank_count(dev, intel_crtc->pipe);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 82a47e3..643a56a 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -617,7 +617,7 @@ static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf,
 	list_for_each_entry(vma, vmas, exec_list) {
 		struct drm_i915_gem_object *obj = vma->obj;
 
-		ret = i915_gem_object_sync(obj, ring);
+		ret = i915_gem_object_sync(obj, ring, true);
 		if (ret)
 			return ret;
 
@@ -1630,7 +1630,7 @@ int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
 
 	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
 
-	ret = __i915_add_request(ring, file, so.obj);
+	ret = __i915_add_request(ring, file, so.obj, true);
 	/* intel_logical_ring_add_request moves object to inactive if it
 	 * fails */
 out:
-- 
1.7.9.5

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

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

* [PATCH 07/10] drm/i915: Early alloc request
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
                   ` (5 preceding siblings ...)
  2014-12-09 12:59 ` [PATCH 06/10] drm/i915: Add extra add_request calls John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  2014-12-09 12:59 ` [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two John.C.Harrison
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The scheduler needs to explicitly allocate a request to track each submitted
batch buffer. This must happen a long time before any commands are actually
written to the ring.

Change-Id: Id01fbda123bcfaa84531896c38292435270025b1
For: VIZ-1587
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h            |    2 ++
 drivers/gpu/drm/i915/i915_gem.c            |    2 ++
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |   13 ++++++++++---
 drivers/gpu/drm/i915/intel_lrc.c           |    6 +++---
 drivers/gpu/drm/i915/intel_lrc.h           |    2 ++
 drivers/gpu/drm/i915/intel_ringbuffer.c    |    6 +++---
 drivers/gpu/drm/i915/intel_ringbuffer.h    |    2 ++
 7 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0e280c4..8628a83 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1775,6 +1775,8 @@ struct drm_i915_private {
 
 	/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
 	struct {
+		int (*alloc_request)(struct intel_engine_cs *ring,
+				     struct intel_context *ctx);
 		int (*do_execbuf)(struct drm_device *dev, struct drm_file *file,
 				  struct intel_engine_cs *ring,
 				  struct intel_context *ctx,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b022a2d..09332ff 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4870,11 +4870,13 @@ int i915_gem_init(struct drm_device *dev)
 	}
 
 	if (!i915.enable_execlists) {
+		dev_priv->gt.alloc_request = intel_ring_alloc_request;
 		dev_priv->gt.do_execbuf = i915_gem_ringbuffer_submission;
 		dev_priv->gt.init_rings = i915_gem_init_rings;
 		dev_priv->gt.cleanup_ring = intel_cleanup_ring_buffer;
 		dev_priv->gt.stop_ring = intel_stop_ring_buffer;
 	} else {
+		dev_priv->gt.alloc_request = intel_logical_ring_alloc_request;
 		dev_priv->gt.do_execbuf = intel_execlists_submission;
 		dev_priv->gt.init_rings = intel_logical_rings_init;
 		dev_priv->gt.cleanup_ring = intel_logical_ring_cleanup;
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 1268e89..f09501c 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1287,7 +1287,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	u64 exec_start = args->batch_start_offset;
 	u32 dispatch_flags;
 	int ret;
-	bool need_relocs;
+	bool need_relocs, batch_pinned = false;
 
 	if (!i915_gem_check_execbuffer(args))
 		return -EINVAL;
@@ -1436,23 +1436,30 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		if (ret)
 			goto err;
 
+		batch_pinned = true;
 		exec_start += i915_gem_obj_ggtt_offset(batch_obj);
 	} else
 		exec_start += i915_gem_obj_offset(batch_obj, vm);
 
+	/* Allocate a request for this batch buffer nice and early. */
+	ret = dev_priv->gt.alloc_request(ring, ctx);
+	if (ret)
+		goto err;
+
 	ret = dev_priv->gt.do_execbuf(dev, file, ring, ctx, args,
 				      &eb->vmas, batch_obj, exec_start,
 				      dispatch_flags);
 
+err:
 	/*
 	 * FIXME: We crucially rely upon the active tracking for the (ppgtt)
 	 * batch vma for correctness. For less ugly and less fragility this
 	 * needs to be adjusted to also track the ggtt batch vma properly as
 	 * active.
 	 */
-	if (dispatch_flags & I915_DISPATCH_SECURE)
+	if (batch_pinned)
 		i915_gem_object_ggtt_unpin(batch_obj);
-err:
+
 	/* the request owns the ref now */
 	i915_gem_context_unreference(ctx);
 	eb_destroy(eb);
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 643a56a..037cbd5 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -878,8 +878,8 @@ void intel_lr_context_unpin(struct intel_engine_cs *ring,
 	}
 }
 
-static int logical_ring_alloc_request(struct intel_engine_cs *ring,
-				      struct intel_context *ctx)
+int intel_logical_ring_alloc_request(struct intel_engine_cs *ring,
+				     struct intel_context *ctx)
 {
 	struct drm_i915_gem_request *request;
 	struct drm_i915_private *dev_private = ring->dev->dev_private;
@@ -1082,7 +1082,7 @@ int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords)
 		return ret;
 
 	/* Preallocate the olr before touching the ring */
-	ret = logical_ring_alloc_request(ring, ringbuf->FIXME_lrc_ctx);
+	ret = intel_logical_ring_alloc_request(ring, ringbuf->FIXME_lrc_ctx);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index b8d5364..2bf868a 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -34,6 +34,8 @@
 #define RING_CONTEXT_STATUS_PTR(ring)	((ring)->mmio_base+0x3a0)
 
 /* Logical Rings */
+int __must_check intel_logical_ring_alloc_request(struct intel_engine_cs *ring,
+						  struct intel_context *ctx);
 void intel_logical_ring_stop(struct intel_engine_cs *ring);
 void intel_logical_ring_cleanup(struct intel_engine_cs *ring);
 int intel_logical_rings_init(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index f990ce4..65ffdd1 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2023,8 +2023,8 @@ int intel_ring_idle(struct intel_engine_cs *ring)
 	return i915_wait_request(req);
 }
 
-static int
-intel_ring_alloc_request(struct intel_engine_cs *ring)
+int
+intel_ring_alloc_request(struct intel_engine_cs *ring, struct intel_context *ctx)
 {
 	int ret;
 	struct drm_i915_gem_request *request;
@@ -2088,7 +2088,7 @@ int intel_ring_begin(struct intel_engine_cs *ring,
 		return ret;
 
 	/* Preallocate the olr before touching the ring */
-	ret = intel_ring_alloc_request(ring);
+	ret = intel_ring_alloc_request(ring, NULL);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index f15fc46..b313144 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -430,6 +430,8 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring);
 
 int __must_check intel_ring_begin(struct intel_engine_cs *ring, int n);
 int __must_check intel_ring_cacheline_align(struct intel_engine_cs *ring);
+int __must_check intel_ring_alloc_request(struct intel_engine_cs *ring,
+					  struct intel_context *ctx);
 static inline void intel_ring_emit(struct intel_engine_cs *ring,
 				   u32 data)
 {
-- 
1.7.9.5

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

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

* [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
                   ` (6 preceding siblings ...)
  2014-12-09 12:59 ` [PATCH 07/10] drm/i915: Early alloc request John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  2014-12-10 10:58   ` Daniel Vetter
  2014-12-09 12:59 ` [PATCH 09/10] drm/i915: Split i915_dem_do_execbuffer() in half John.C.Harrison
  2014-12-09 12:59 ` [PATCH 10/10] drm/i915: Cache ringbuf pointer in request structure John.C.Harrison
  9 siblings, 1 reply; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The scheduler decouples the submission of batch buffers to the driver with their
submission to the hardware. This basically means splitting the execbuffer()
function in half. This change rearranges some code ready for the split to occur.

Change-Id: Icc9c8afaac18821f3eb8a151a49f918f90c068a3
For: VIZ-1587
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |   47 +++++++++++++++++-----------
 drivers/gpu/drm/i915/intel_lrc.c           |   17 +++++++---
 2 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index f09501c..a339556 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -848,10 +848,7 @@ i915_gem_execbuffer_move_to_gpu(struct intel_engine_cs *ring,
 	if (flush_domains & I915_GEM_DOMAIN_GTT)
 		wmb();
 
-	/* Unconditionally invalidate gpu caches and ensure that we do flush
-	 * any residual writes from the previous batch.
-	 */
-	return intel_ring_invalidate_all_caches(ring);
+	return 0;
 }
 
 static bool
@@ -1123,14 +1120,6 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 		}
 	}
 
-	ret = i915_gem_execbuffer_move_to_gpu(ring, vmas);
-	if (ret)
-		goto error;
-
-	ret = i915_switch_context(ring, ctx);
-	if (ret)
-		goto error;
-
 	instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
 	instp_mask = I915_EXEC_CONSTANTS_MASK;
 	switch (instp_mode) {
@@ -1168,6 +1157,28 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 		goto error;
 	}
 
+	ret = i915_gem_execbuffer_move_to_gpu(ring, vmas);
+	if (ret)
+		goto error;
+
+	i915_gem_execbuffer_move_to_active(vmas, ring);
+
+	/* To be split into two functions here... */
+
+	intel_runtime_pm_get(dev_priv);
+
+	/* Unconditionally invalidate gpu caches and ensure that we do flush
+	 * any residual writes from the previous batch.
+	 */
+	ret = intel_ring_invalidate_all_caches(ring);
+	if (ret)
+		goto error;
+
+	/* Switch to the correct context for the batch */
+	ret = i915_switch_context(ring, ctx);
+	if (ret)
+		goto error;
+
 	if (ring == &dev_priv->ring[RCS] &&
 			instp_mode != dev_priv->relative_constants_mode) {
 		ret = intel_ring_begin(ring, 4);
@@ -1208,15 +1219,18 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 						exec_start, exec_len,
 						dispatch_flags);
 		if (ret)
-			return ret;
+			goto error;
 	}
 
 	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), dispatch_flags);
 
-	i915_gem_execbuffer_move_to_active(vmas, ring);
 	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
 
 error:
+	/* intel_gpu_busy should also get a ref, so it will free when the device
+	 * is really idle. */
+	intel_runtime_pm_put(dev_priv);
+
 	kfree(cliprects);
 	return ret;
 }
@@ -1335,8 +1349,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		return -EINVAL;
 	}
 
-	intel_runtime_pm_get(dev_priv);
-
 	ret = i915_mutex_lock_interruptible(dev);
 	if (ret)
 		goto pre_mutex_err;
@@ -1467,9 +1479,6 @@ err:
 	mutex_unlock(&dev->struct_mutex);
 
 pre_mutex_err:
-	/* intel_gpu_busy should also get a ref, so it will free when the device
-	 * is really idle. */
-	intel_runtime_pm_put(dev_priv);
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 037cbd5..f16b15d 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -630,10 +630,7 @@ static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf,
 	if (flush_domains & I915_GEM_DOMAIN_GTT)
 		wmb();
 
-	/* Unconditionally invalidate gpu caches and ensure that we do flush
-	 * any residual writes from the previous batch.
-	 */
-	return logical_ring_invalidate_all_caches(ringbuf);
+	return 0;
 }
 
 /**
@@ -717,6 +714,17 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
 	if (ret)
 		return ret;
 
+	i915_gem_execbuffer_move_to_active(vmas, ring);
+
+	/* To be split into two functions here... */
+
+	/* Unconditionally invalidate gpu caches and ensure that we do flush
+	 * any residual writes from the previous batch.
+	 */
+	ret = logical_ring_invalidate_all_caches(ringbuf);
+	if (ret)
+		return ret;
+
 	if (ring == &dev_priv->ring[RCS] &&
 	    instp_mode != dev_priv->relative_constants_mode) {
 		ret = intel_logical_ring_begin(ringbuf, 4);
@@ -738,7 +746,6 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
 
 	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), dispatch_flags);
 
-	i915_gem_execbuffer_move_to_active(vmas, ring);
 	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
 
 	return 0;
-- 
1.7.9.5

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

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

* [PATCH 09/10] drm/i915: Split i915_dem_do_execbuffer() in half
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
                   ` (7 preceding siblings ...)
  2014-12-09 12:59 ` [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  2014-12-09 12:59 ` [PATCH 10/10] drm/i915: Cache ringbuf pointer in request structure John.C.Harrison
  9 siblings, 0 replies; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Split the execbuffer() function in half. The first half collects and validates
all the information requried to process the batch buffer. It also does all the
object pinning, relocations, active list management, etc - basically anything
that must be done upfront before the IOCTL returns and allows the user land side
to start changing/freeing things. The second half does the actual ring
submission.

This change implements the split but leaves the back half being called directly
from the end of the front half.

Change-Id: I5e1c77639ce526ab2401b0323186c518bf13da0a
For: VIZ-1587
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h            |   39 ++++---
 drivers/gpu/drm/i915/i915_gem.c            |    2 +
 drivers/gpu/drm/i915/i915_gem_execbuffer.c |  172 +++++++++++++++++++---------
 drivers/gpu/drm/i915/intel_lrc.c           |   72 ++++++++----
 drivers/gpu/drm/i915/intel_lrc.h           |   10 +-
 5 files changed, 197 insertions(+), 98 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8628a83..f885a90 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1525,6 +1525,25 @@ struct i915_workarounds {
 	u32 count;
 };
 
+struct i915_execbuffer_params {
+	struct drm_device               *dev;
+	struct drm_file                 *file;
+	uint32_t                        dispatch_flags;
+	uint32_t                        args_flags;
+	uint32_t                        args_batch_start_offset;
+	uint32_t                        args_batch_len;
+	uint32_t                        args_num_cliprects;
+	uint32_t                        args_DR1;
+	uint32_t                        args_DR4;
+	uint32_t                        batch_obj_vm_offset;
+	struct intel_engine_cs          *ring;
+	struct drm_i915_gem_object      *batch_obj;
+	struct drm_clip_rect            *cliprects;
+	uint32_t                        instp_mask;
+	int                             instp_mode;
+	struct intel_context            *ctx;
+};
+
 struct drm_i915_private {
 	struct drm_device *dev;
 	struct kmem_cache *slab;
@@ -1777,13 +1796,10 @@ struct drm_i915_private {
 	struct {
 		int (*alloc_request)(struct intel_engine_cs *ring,
 				     struct intel_context *ctx);
-		int (*do_execbuf)(struct drm_device *dev, struct drm_file *file,
-				  struct intel_engine_cs *ring,
-				  struct intel_context *ctx,
+		int (*do_execbuf)(struct i915_execbuffer_params *params,
 				  struct drm_i915_gem_execbuffer2 *args,
-				  struct list_head *vmas,
-				  struct drm_i915_gem_object *batch_obj,
-				  u64 exec_start, u32 flags);
+				  struct list_head *vmas);
+		int (*do_execfinal)(struct i915_execbuffer_params *params);
 		int (*init_rings)(struct drm_device *dev);
 		void (*cleanup_ring)(struct intel_engine_cs *ring);
 		void (*stop_ring)(struct intel_engine_cs *ring);
@@ -2464,14 +2480,11 @@ void i915_gem_execbuffer_retire_commands(struct drm_device *dev,
 					 struct drm_file *file,
 					 struct intel_engine_cs *ring,
 					 struct drm_i915_gem_object *obj);
-int i915_gem_ringbuffer_submission(struct drm_device *dev,
-				   struct drm_file *file,
-				   struct intel_engine_cs *ring,
-				   struct intel_context *ctx,
+void i915_gem_execbuff_release_batch_obj(struct drm_i915_gem_object *batch_obj);
+int i915_gem_ringbuffer_submission(struct i915_execbuffer_params *qe,
 				   struct drm_i915_gem_execbuffer2 *args,
-				   struct list_head *vmas,
-				   struct drm_i915_gem_object *batch_obj,
-				   u64 exec_start, u32 flags);
+				   struct list_head *vmas);
+int i915_gem_ringbuffer_submission_final(struct i915_execbuffer_params *params);
 int i915_gem_execbuffer(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
 int i915_gem_execbuffer2(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 09332ff..031af9d 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4872,12 +4872,14 @@ int i915_gem_init(struct drm_device *dev)
 	if (!i915.enable_execlists) {
 		dev_priv->gt.alloc_request = intel_ring_alloc_request;
 		dev_priv->gt.do_execbuf = i915_gem_ringbuffer_submission;
+		dev_priv->gt.do_execfinal = i915_gem_ringbuffer_submission_final;
 		dev_priv->gt.init_rings = i915_gem_init_rings;
 		dev_priv->gt.cleanup_ring = intel_cleanup_ring_buffer;
 		dev_priv->gt.stop_ring = intel_stop_ring_buffer;
 	} else {
 		dev_priv->gt.alloc_request = intel_logical_ring_alloc_request;
 		dev_priv->gt.do_execbuf = intel_execlists_submission;
+		dev_priv->gt.do_execfinal = intel_execlists_submission_final;
 		dev_priv->gt.init_rings = intel_logical_rings_init;
 		dev_priv->gt.cleanup_ring = intel_logical_ring_cleanup;
 		dev_priv->gt.stop_ring = intel_logical_ring_stop;
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index a339556..3e56494 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1062,20 +1062,14 @@ i915_emit_box(struct intel_engine_cs *ring,
 
 
 int
-i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
-			       struct intel_engine_cs *ring,
-			       struct intel_context *ctx,
+i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params,
 			       struct drm_i915_gem_execbuffer2 *args,
-			       struct list_head *vmas,
-			       struct drm_i915_gem_object *batch_obj,
-			       u64 exec_start, u32 dispatch_flags)
+			       struct list_head *vmas)
 {
-	struct drm_clip_rect *cliprects = NULL;
+	struct drm_device *dev = params->dev;
+	struct intel_engine_cs *ring = params->ring;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	u64 exec_len;
-	int instp_mode;
-	u32 instp_mask;
-	int i, ret = 0;
+	int ret = 0;
 
 	if (args->num_cliprects != 0) {
 		if (ring != &dev_priv->ring[RCS]) {
@@ -1088,23 +1082,23 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 			return -EINVAL;
 		}
 
-		if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) {
+		if (args->num_cliprects > UINT_MAX / sizeof(*params->cliprects)) {
 			DRM_DEBUG("execbuf with %u cliprects\n",
 				  args->num_cliprects);
 			return -EINVAL;
 		}
 
-		cliprects = kcalloc(args->num_cliprects,
-				    sizeof(*cliprects),
+		params->cliprects = kcalloc(args->num_cliprects,
+				    sizeof(*params->cliprects),
 				    GFP_KERNEL);
-		if (cliprects == NULL) {
+		if (params->cliprects == NULL) {
 			ret = -ENOMEM;
 			goto error;
 		}
 
-		if (copy_from_user(cliprects,
+		if (copy_from_user(params->cliprects,
 				   to_user_ptr(args->cliprects_ptr),
-				   sizeof(*cliprects)*args->num_cliprects)) {
+				   sizeof(*params->cliprects)*args->num_cliprects)) {
 			ret = -EFAULT;
 			goto error;
 		}
@@ -1120,19 +1114,19 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 		}
 	}
 
-	instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
-	instp_mask = I915_EXEC_CONSTANTS_MASK;
-	switch (instp_mode) {
+	params->instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
+	params->instp_mask = I915_EXEC_CONSTANTS_MASK;
+	switch (params->instp_mode) {
 	case I915_EXEC_CONSTANTS_REL_GENERAL:
 	case I915_EXEC_CONSTANTS_ABSOLUTE:
 	case I915_EXEC_CONSTANTS_REL_SURFACE:
-		if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) {
+		if (params->instp_mode != 0 && ring != &dev_priv->ring[RCS]) {
 			DRM_DEBUG("non-0 rel constants mode on non-RCS\n");
 			ret = -EINVAL;
 			goto error;
 		}
 
-		if (instp_mode != dev_priv->relative_constants_mode) {
+		if (params->instp_mode != dev_priv->relative_constants_mode) {
 			if (INTEL_INFO(dev)->gen < 4) {
 				DRM_DEBUG("no rel constants on pre-gen4\n");
 				ret = -EINVAL;
@@ -1140,7 +1134,7 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 			}
 
 			if (INTEL_INFO(dev)->gen > 5 &&
-			    instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
+			    params->instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
 				DRM_DEBUG("rel surface constants mode invalid on gen5+\n");
 				ret = -EINVAL;
 				goto error;
@@ -1148,11 +1142,11 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 
 			/* The HW changed the meaning on this bit on gen6 */
 			if (INTEL_INFO(dev)->gen >= 6)
-				instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
+				params->instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
 		}
 		break;
 	default:
-		DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode);
+		DRM_DEBUG("execbuf with unknown constants: %d\n", params->instp_mode);
 		ret = -EINVAL;
 		goto error;
 	}
@@ -1163,7 +1157,36 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 
 	i915_gem_execbuffer_move_to_active(vmas, ring);
 
-	/* To be split into two functions here... */
+	ret = dev_priv->gt.do_execfinal(params);
+	if (ret)
+		goto error;
+
+	/* Free everything that was stored in the QE structure (until the
+	 * scheduler arrives and does it instead): */
+	kfree(params->cliprects);
+	if (params->dispatch_flags & I915_DISPATCH_SECURE)
+		i915_gem_execbuff_release_batch_obj(params->batch_obj);
+
+	return 0;
+
+error:
+	kfree(params->cliprects);
+	return ret;
+}
+
+/*
+ * This is the main function for adding a batch to the ring.
+ * It is called from the scheduler, with the struct_mutex already held.
+ */
+int i915_gem_ringbuffer_submission_final(struct i915_execbuffer_params *params)
+{
+	struct drm_i915_private *dev_priv = params->dev->dev_private;
+	struct intel_engine_cs  *ring = params->ring;
+	u64 exec_start, exec_len;
+	int ret, i;
+
+	/* The mutex must be acquired before calling this function */
+	BUG_ON(!mutex_is_locked(&params->dev->struct_mutex));
 
 	intel_runtime_pm_get(dev_priv);
 
@@ -1175,12 +1198,12 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 		goto error;
 
 	/* Switch to the correct context for the batch */
-	ret = i915_switch_context(ring, ctx);
+	ret = i915_switch_context(ring, params->ctx);
 	if (ret)
 		goto error;
 
 	if (ring == &dev_priv->ring[RCS] &&
-			instp_mode != dev_priv->relative_constants_mode) {
+			params->instp_mode != dev_priv->relative_constants_mode) {
 		ret = intel_ring_begin(ring, 4);
 		if (ret)
 			goto error;
@@ -1188,50 +1211,53 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
 		intel_ring_emit(ring, MI_NOOP);
 		intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
 		intel_ring_emit(ring, INSTPM);
-		intel_ring_emit(ring, instp_mask << 16 | instp_mode);
+		intel_ring_emit(ring, params->instp_mask << 16 | params->instp_mode);
 		intel_ring_advance(ring);
 
-		dev_priv->relative_constants_mode = instp_mode;
+		dev_priv->relative_constants_mode = params->instp_mode;
 	}
 
-	if (args->flags & I915_EXEC_GEN7_SOL_RESET) {
-		ret = i915_reset_gen7_sol_offsets(dev, ring);
+	if (params->args_flags & I915_EXEC_GEN7_SOL_RESET) {
+		ret = i915_reset_gen7_sol_offsets(params->dev, ring);
 		if (ret)
 			goto error;
 	}
 
-	exec_len = args->batch_len;
-	if (cliprects) {
-		for (i = 0; i < args->num_cliprects; i++) {
-			ret = i915_emit_box(ring, &cliprects[i],
-					    args->DR1, args->DR4);
+	exec_len   = params->args_batch_len;
+	exec_start = params->batch_obj_vm_offset +
+		     params->args_batch_start_offset;
+
+	if (params->cliprects) {
+		for (i = 0; i < params->args_num_cliprects; i++) {
+			ret = i915_emit_box(ring, &params->cliprects[i],
+					    params->args_DR1, params->args_DR4);
 			if (ret)
 				goto error;
 
 			ret = ring->dispatch_execbuffer(ring,
 							exec_start, exec_len,
-							dispatch_flags);
+							params->dispatch_flags);
 			if (ret)
 				goto error;
 		}
 	} else {
 		ret = ring->dispatch_execbuffer(ring,
 						exec_start, exec_len,
-						dispatch_flags);
+						params->dispatch_flags);
 		if (ret)
 			goto error;
 	}
 
-	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), dispatch_flags);
+	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), params->dispatch_flags);
 
-	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
+	i915_gem_execbuffer_retire_commands(params->dev, params->file, ring,
+					    params->batch_obj);
 
 error:
 	/* intel_gpu_busy should also get a ref, so it will free when the device
 	 * is really idle. */
 	intel_runtime_pm_put(dev_priv);
 
-	kfree(cliprects);
 	return ret;
 }
 
@@ -1297,8 +1323,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	struct intel_engine_cs *ring;
 	struct intel_context *ctx;
 	struct i915_address_space *vm;
+	struct i915_execbuffer_params params_master; /* XXX: will be removed later */
+	struct i915_execbuffer_params *params = &params_master;
 	const u32 ctx_id = i915_execbuffer2_get_context_id(*args);
-	u64 exec_start = args->batch_start_offset;
 	u32 dispatch_flags;
 	int ret;
 	bool need_relocs, batch_pinned = false;
@@ -1367,6 +1394,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	else
 		vm = &dev_priv->gtt.base;
 
+	memset(&params_master, 0x00, sizeof(params_master));
+
 	eb = eb_create(args);
 	if (eb == NULL) {
 		i915_gem_context_unreference(ctx);
@@ -1449,30 +1478,52 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 			goto err;
 
 		batch_pinned = true;
-		exec_start += i915_gem_obj_ggtt_offset(batch_obj);
+		params->batch_obj_vm_offset = i915_gem_obj_ggtt_offset(batch_obj);
 	} else
-		exec_start += i915_gem_obj_offset(batch_obj, vm);
+		params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm);
 
 	/* Allocate a request for this batch buffer nice and early. */
 	ret = dev_priv->gt.alloc_request(ring, ctx);
 	if (ret)
 		goto err;
 
-	ret = dev_priv->gt.do_execbuf(dev, file, ring, ctx, args,
-				      &eb->vmas, batch_obj, exec_start,
-				      dispatch_flags);
+	/* Save assorted stuff away to pass through to *_submission_final() */
+	params->dev                     = dev;
+	params->file                    = file;
+	params->ring                    = ring;
+	params->dispatch_flags          = dispatch_flags;
+	params->args_flags              = args->flags;
+	params->args_batch_start_offset = args->batch_start_offset;
+	params->args_batch_len          = args->batch_len;
+	params->args_num_cliprects      = args->num_cliprects;
+	params->args_DR1                = args->DR1;
+	params->args_DR4                = args->DR4;
+	params->batch_obj               = batch_obj;
+	params->ctx                     = ctx;
+
+	ret = dev_priv->gt.do_execbuf(params, args, &eb->vmas);
+	if (ret)
+		goto err;
+
+	/* the request owns the ref now */
+	i915_gem_context_unreference(ctx);
+
+	/* The eb list is no longer required. The scheduler has extracted all
+	 * the information than needs to persist. */
+	eb_destroy(eb);
 
-err:
 	/*
-	 * FIXME: We crucially rely upon the active tracking for the (ppgtt)
-	 * batch vma for correctness. For less ugly and less fragility this
-	 * needs to be adjusted to also track the ggtt batch vma properly as
-	 * active.
+	 * Don't clean up everything that is now saved away in the queue.
+	 * Just unlock and return immediately.
 	 */
+	mutex_unlock(&dev->struct_mutex);
+
+	return ret;
+
+err:
 	if (batch_pinned)
-		i915_gem_object_ggtt_unpin(batch_obj);
+		i915_gem_execbuff_release_batch_obj(batch_obj);
 
-	/* the request owns the ref now */
 	i915_gem_context_unreference(ctx);
 	eb_destroy(eb);
 
@@ -1482,6 +1533,17 @@ pre_mutex_err:
 	return ret;
 }
 
+void i915_gem_execbuff_release_batch_obj(struct drm_i915_gem_object *batch_obj)
+{
+	/*
+	 * FIXME: We crucially rely upon the active tracking for the (ppgtt)
+	 * batch vma for correctness. For less ugly and less fragility this
+	 * needs to be adjusted to also track the ggtt batch vma properly as
+	 * active.
+	 */
+	i915_gem_object_ggtt_unpin(batch_obj);
+}
+
 /*
  * Legacy execbuffer just creates an exec2 list from the original exec object
  * list array and passes it to the real function.
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index f16b15d..971ba0c 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -650,43 +650,39 @@ static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf,
  *
  * Return: non-zero if the submission fails.
  */
-int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
-			       struct intel_engine_cs *ring,
-			       struct intel_context *ctx,
+int intel_execlists_submission(struct i915_execbuffer_params *params,
 			       struct drm_i915_gem_execbuffer2 *args,
-			       struct list_head *vmas,
-			       struct drm_i915_gem_object *batch_obj,
-			       u64 exec_start, u32 dispatch_flags)
+			       struct list_head *vmas)
 {
+	struct drm_device       *dev = params->dev;
+	struct intel_engine_cs  *ring = params->ring;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf;
-	int instp_mode;
-	u32 instp_mask;
+	struct intel_ringbuffer *ringbuf = params->ctx->engine[ring->id].ringbuf;
 	int ret;
 
-	instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
-	instp_mask = I915_EXEC_CONSTANTS_MASK;
-	switch (instp_mode) {
+	params->instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
+	params->instp_mask = I915_EXEC_CONSTANTS_MASK;
+	switch (params->instp_mode) {
 	case I915_EXEC_CONSTANTS_REL_GENERAL:
 	case I915_EXEC_CONSTANTS_ABSOLUTE:
 	case I915_EXEC_CONSTANTS_REL_SURFACE:
-		if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) {
+		if (params->instp_mode != 0 && ring != &dev_priv->ring[RCS]) {
 			DRM_DEBUG("non-0 rel constants mode on non-RCS\n");
 			return -EINVAL;
 		}
 
-		if (instp_mode != dev_priv->relative_constants_mode) {
-			if (instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
+		if (params->instp_mode != dev_priv->relative_constants_mode) {
+			if (params->instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) {
 				DRM_DEBUG("rel surface constants mode invalid on gen5+\n");
 				return -EINVAL;
 			}
 
 			/* The HW changed the meaning on this bit on gen6 */
-			instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
+			params->instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
 		}
 		break;
 	default:
-		DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode);
+		DRM_DEBUG("execbuf with unknown constants: %d\n", params->instp_mode);
 		return -EINVAL;
 	}
 
@@ -716,7 +712,32 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
 
 	i915_gem_execbuffer_move_to_active(vmas, ring);
 
-	/* To be split into two functions here... */
+	ret = dev_priv->gt.do_execfinal(params);
+	if (ret)
+		return ret;
+
+	/* Free everything that was stored in the QE structure (until the
+	 * scheduler arrives and does it instead): */
+	if (params->dispatch_flags & I915_DISPATCH_SECURE)
+		i915_gem_execbuff_release_batch_obj(params->batch_obj);
+
+	return 0;
+}
+
+/*
+ * This is the main function for adding a batch to the ring.
+ * It is called from the scheduler, with the struct_mutex already held.
+ */
+int intel_execlists_submission_final(struct i915_execbuffer_params *params)
+{
+	struct drm_i915_private *dev_priv = params->dev->dev_private;
+	struct intel_engine_cs  *ring = params->ring;
+	struct intel_ringbuffer *ringbuf = params->ctx->engine[ring->id].ringbuf;
+	u64 exec_start;
+	int ret;
+
+	/* The mutex must be acquired before calling this function */
+	BUG_ON(!mutex_is_locked(&params->dev->struct_mutex));
 
 	/* Unconditionally invalidate gpu caches and ensure that we do flush
 	 * any residual writes from the previous batch.
@@ -726,7 +747,7 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
 		return ret;
 
 	if (ring == &dev_priv->ring[RCS] &&
-	    instp_mode != dev_priv->relative_constants_mode) {
+	    params->instp_mode != dev_priv->relative_constants_mode) {
 		ret = intel_logical_ring_begin(ringbuf, 4);
 		if (ret)
 			return ret;
@@ -734,19 +755,22 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
 		intel_logical_ring_emit(ringbuf, MI_NOOP);
 		intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(1));
 		intel_logical_ring_emit(ringbuf, INSTPM);
-		intel_logical_ring_emit(ringbuf, instp_mask << 16 | instp_mode);
+		intel_logical_ring_emit(ringbuf, params->instp_mask << 16 | params->instp_mode);
 		intel_logical_ring_advance(ringbuf);
 
-		dev_priv->relative_constants_mode = instp_mode;
+		dev_priv->relative_constants_mode = params->instp_mode;
 	}
 
-	ret = ring->emit_bb_start(ringbuf, exec_start, dispatch_flags);
+	exec_start = params->batch_obj_vm_offset +
+		     params->args_batch_start_offset;
+
+	ret = ring->emit_bb_start(ringbuf, exec_start, params->dispatch_flags);
 	if (ret)
 		return ret;
 
-	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), dispatch_flags);
+	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), params->dispatch_flags);
 
-	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
+	i915_gem_execbuffer_retire_commands(params->dev, params->file, ring, params->batch_obj);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h
index 2bf868a..ea083d9 100644
--- a/drivers/gpu/drm/i915/intel_lrc.h
+++ b/drivers/gpu/drm/i915/intel_lrc.h
@@ -76,13 +76,11 @@ void intel_lr_context_unpin(struct intel_engine_cs *ring,
 
 /* Execlists */
 int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists);
-int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
-			       struct intel_engine_cs *ring,
-			       struct intel_context *ctx,
+struct i915_execbuffer_params;
+int intel_execlists_submission(struct i915_execbuffer_params *params,
 			       struct drm_i915_gem_execbuffer2 *args,
-			       struct list_head *vmas,
-			       struct drm_i915_gem_object *batch_obj,
-			       u64 exec_start, u32 dispatch_flags);
+			       struct list_head *vmas);
+int intel_execlists_submission_final(struct i915_execbuffer_params *params);
 u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj);
 
 /**
-- 
1.7.9.5

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

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

* [PATCH 10/10] drm/i915: Cache ringbuf pointer in request structure
  2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
                   ` (8 preceding siblings ...)
  2014-12-09 12:59 ` [PATCH 09/10] drm/i915: Split i915_dem_do_execbuffer() in half John.C.Harrison
@ 2014-12-09 12:59 ` John.C.Harrison
  9 siblings, 0 replies; 57+ messages in thread
From: John.C.Harrison @ 2014-12-09 12:59 UTC (permalink / raw
  To: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Cache a pointer to the ringbuf so that retire requests does not need to do messy
'are we in execlist mode' decisions.

Change-Id: I75bf6b73dc8a675a5be7bbff1927aa30f393788c
For: VIZ-1587
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h         |    3 ++-
 drivers/gpu/drm/i915/i915_gem.c         |   14 +-------------
 drivers/gpu/drm/i915/intel_lrc.c        |    3 ++-
 drivers/gpu/drm/i915/intel_ringbuffer.c |    1 +
 4 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f885a90..b340455 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2024,8 +2024,9 @@ struct drm_i915_gem_request {
 	/** Position in the ringbuffer of the end of the request */
 	u32 tail;
 
-	/** Context related to this request */
+	/** Context and ring buffer related to this request */
 	struct intel_context *ctx;
+	struct intel_ringbuffer *ringbuf;
 
 	/** Batch buffer related to this request if any */
 	struct drm_i915_gem_object *batch_obj;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 031af9d..b8ee384 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2762,7 +2762,6 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 
 	while (!list_empty(&ring->request_list)) {
 		struct drm_i915_gem_request *request;
-		struct intel_ringbuffer *ringbuf;
 
 		request = list_first_entry(&ring->request_list,
 					   struct drm_i915_gem_request,
@@ -2773,23 +2772,12 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
 
 		trace_i915_gem_request_retire(request);
 
-		/* This is one of the few common intersection points
-		 * between legacy ringbuffer submission and execlists:
-		 * we need to tell them apart in order to find the correct
-		 * ringbuffer to which the request belongs to.
-		 */
-		if (i915.enable_execlists) {
-			struct intel_context *ctx = request->ctx;
-			ringbuf = ctx->engine[ring->id].ringbuf;
-		} else
-			ringbuf = ring->buffer;
-
 		/* We know the GPU must have read the request to have
 		 * sent us the seqno + interrupt, so use the position
 		 * of tail of the request to update the last known position
 		 * of the GPU head.
 		 */
-		ringbuf->last_retired_head = request->tail;
+		request->ringbuf->last_retired_head = request->tail;
 
 		i915_gem_free_request(request);
 	}
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 971ba0c..684eb1e 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -944,10 +944,11 @@ int intel_logical_ring_alloc_request(struct intel_engine_cs *ring,
 
 	/* Hold a reference to the context this request belongs to
 	 * (we will need it when the time comes to emit/retire the
-	 * request).
+	 * request). Likewise, the ringbuff is useful to keep track of.
 	 */
 	request->ctx = ctx;
 	i915_gem_context_reference(request->ctx);
+	request->ringbuf = ctx->engine[ring->id].ringbuf;
 
 	ring->outstanding_lazy_request = request;
 	return 0;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 65ffdd1..f0242cf 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2039,6 +2039,7 @@ intel_ring_alloc_request(struct intel_engine_cs *ring, struct intel_context *ctx
 
 	kref_init(&request->ref);
 	request->ring = ring;
+	request->ringbuf = ring->buffer;
 	request->uniq = dev_private->request_uniq++;
 
 	ret = i915_gem_get_seqno(ring->dev, &request->seqno);
-- 
1.7.9.5

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

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

* Re: [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers
  2014-12-09 11:46   ` [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers Mika Kuoppala
@ 2014-12-09 13:32     ` Jani Nikula
  2014-12-09 13:36       ` Daniel Vetter
                         ` (2 more replies)
  2014-12-12 13:21     ` [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers Deepak S
  1 sibling, 3 replies; 57+ messages in thread
From: Jani Nikula @ 2014-12-09 13:32 UTC (permalink / raw
  To: Mika Kuoppala, intel-gfx; +Cc: daniel.vetter

On Tue, 09 Dec 2014, Mika Kuoppala <mika.kuoppala@linux.intel.com> wrote:
> Make the domains and domain identifiers enums. To emphasize
> the difference in order to avoid mistakes.
>
> Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h     | 41 +++++++++++++++++----------------
>  drivers/gpu/drm/i915/intel_uncore.c | 45 +++++++++++++++++++------------------
>  2 files changed, 45 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 0d47397..5c6c372 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -533,11 +533,28 @@ struct drm_i915_display_funcs {
>  	void (*enable_backlight)(struct intel_connector *connector);
>  };
>  
> +enum fw_domain_id {

Does anyone else think of "firmware" first when seeing "fw", and
"forcewake" only after a moment?

Jani.


> +	FW_DOMAIN_ID_RENDER = 0,
> +	FW_DOMAIN_ID_BLITTER,
> +	FW_DOMAIN_ID_MEDIA,
> +
> +	FW_DOMAIN_ID_COUNT
> +};
> +
> +enum fw_domains {
> +	FORCEWAKE_RENDER = (1 << FW_DOMAIN_ID_RENDER),
> +	FORCEWAKE_BLITTER = (1 << FW_DOMAIN_ID_BLITTER),
> +	FORCEWAKE_MEDIA	= (1 << FW_DOMAIN_ID_MEDIA),
> +	FORCEWAKE_ALL = (FORCEWAKE_RENDER |
> +			 FORCEWAKE_BLITTER |
> +			 FORCEWAKE_MEDIA)
> +};
> +
>  struct intel_uncore_funcs {
>  	void (*force_wake_get)(struct drm_i915_private *dev_priv,
> -							int fw_engine);
> +							enum fw_domains domains);
>  	void (*force_wake_put)(struct drm_i915_private *dev_priv,
> -							int fw_engine);
> +							enum fw_domains domains);
>  
>  	uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
>  	uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
> @@ -554,25 +571,17 @@ struct intel_uncore_funcs {
>  				uint64_t val, bool trace);
>  };
>  
> -enum {
> -	FW_DOMAIN_ID_RENDER = 0,
> -	FW_DOMAIN_ID_BLITTER,
> -	FW_DOMAIN_ID_MEDIA,
> -
> -	FW_DOMAIN_ID_COUNT
> -};
> -
>  struct intel_uncore {
>  	spinlock_t lock; /** lock is also taken in irq contexts. */
>  
>  	struct intel_uncore_funcs funcs;
>  
>  	unsigned fifo_count;
> -	unsigned fw_domains;
> +	enum fw_domains fw_domains;
>  
>  	struct intel_uncore_forcewake_domain {
>  		struct drm_i915_private *i915;
> -		int id;
> +		enum fw_domain_id id;
>  		unsigned wake_count;
>  		struct timer_list timer;
>  		u32 reg_set;
> @@ -582,12 +591,6 @@ struct intel_uncore {
>  		u32 reg_post;
>  		u32 val_reset;
>  	} fw_domain[FW_DOMAIN_ID_COUNT];
> -#define FORCEWAKE_RENDER	(1 << FW_DOMAIN_ID_RENDER)
> -#define FORCEWAKE_BLITTER	(1 << FW_DOMAIN_ID_BLITTER)
> -#define FORCEWAKE_MEDIA		(1 << FW_DOMAIN_ID_MEDIA)
> -#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | \
> -				 FORCEWAKE_BLITTER | \
> -				 FORCEWAKE_MEDIA)
>  };
>  
>  /* Iterate over initialised fw domains */
> @@ -2449,7 +2452,7 @@ extern void intel_uncore_init(struct drm_device *dev);
>  extern void intel_uncore_check_errors(struct drm_device *dev);
>  extern void intel_uncore_fini(struct drm_device *dev);
>  extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
> -const char *intel_uncore_forcewake_domain_to_str(const int domain_id);
> +const char *intel_uncore_forcewake_domain_to_str(const enum fw_domain_id id);
>  void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
>  				unsigned fw_domains);
>  void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 509b9c9..e802486 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -49,7 +49,7 @@ static const char * const forcewake_domain_names[] = {
>  };
>  
>  const char *
> -intel_uncore_forcewake_domain_to_str(const int id)
> +intel_uncore_forcewake_domain_to_str(const enum fw_domain_id id)
>  {
>  	BUILD_BUG_ON((sizeof(forcewake_domain_names)/sizeof(const char *)) !=
>  		     FW_DOMAIN_ID_COUNT);
> @@ -122,10 +122,10 @@ fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
>  }
>  
>  static void
> -fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
> +fw_domains_get(struct drm_i915_private *dev_priv, enum fw_domains fw_domains)
>  {
>  	struct intel_uncore_forcewake_domain *d;
> -	int id;
> +	enum fw_domain_id id;
>  
>  	for_each_fw_domain_mask(d, fw_domains, dev_priv, id) {
>  		fw_domain_wait_ack_clear(d);
> @@ -136,10 +136,10 @@ fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
>  }
>  
>  static void
> -fw_domains_put(struct drm_i915_private *dev_priv, int fw_domains)
> +fw_domains_put(struct drm_i915_private *dev_priv, enum fw_domains fw_domains)
>  {
>  	struct intel_uncore_forcewake_domain *d;
> -	int id;
> +	enum fw_domain_id id;
>  
>  	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
>  		fw_domain_put(d);
> @@ -149,7 +149,7 @@ static void
>  fw_domains_posting_read(struct drm_i915_private *dev_priv)
>  {
>  	struct intel_uncore_forcewake_domain *d;
> -	int id;
> +	enum fw_domain_id id;
>  
>  	/* No need to do for all, just do for first found */
>  	for_each_fw_domain(d, dev_priv, id) {
> @@ -159,10 +159,10 @@ fw_domains_posting_read(struct drm_i915_private *dev_priv)
>  }
>  
>  static void
> -fw_domains_reset(struct drm_i915_private *dev_priv, const unsigned fw_domains)
> +fw_domains_reset(struct drm_i915_private *dev_priv, enum fw_domains fw_domains)
>  {
>  	struct intel_uncore_forcewake_domain *d;
> -	int id;
> +	enum fw_domain_id id;
>  
>  	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
>  		fw_domain_reset(d);
> @@ -181,7 +181,7 @@ static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
>  }
>  
>  static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
> -					      int fw_domains)
> +					      enum fw_domains fw_domains)
>  {
>  	fw_domains_get(dev_priv, fw_domains);
>  
> @@ -199,7 +199,7 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
>  }
>  
>  static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
> -				     int fw_domains)
> +				     enum fw_domains fw_domains)
>  {
>  	fw_domains_put(dev_priv, fw_domains);
>  	gen6_gt_check_fifodbg(dev_priv);
> @@ -251,9 +251,10 @@ static void intel_uncore_fw_release_timer(unsigned long arg)
>  void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> -	unsigned long irqflags, fw = 0;
> +	unsigned long irqflags;
>  	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
> +	enum fw_domains fw = 0;
>  
>  	/* Hold uncore.lock across reset to prevent any register access
>  	 * with forcewake not set correctly
> @@ -329,11 +330,11 @@ void intel_uncore_sanitize(struct drm_device *dev)
>   * intel_uncore_forcewake_put() at the end of the sequence.
>   */
>  void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
> -				unsigned fw_domains)
> +				enum fw_domains fw_domains)
>  {
>  	unsigned long irqflags;
>  	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
>  
>  	if (!dev_priv->uncore.funcs.force_wake_get)
>  		return;
> @@ -358,11 +359,11 @@ void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
>   * see intel_uncore_forcewake_get()
>   */
>  void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
> -				unsigned fw_domains)
> +				enum fw_domains fw_domains)
>  {
>  	unsigned long irqflags;
>  	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
>  
>  	if (!dev_priv->uncore.funcs.force_wake_put)
>  		return;
> @@ -386,7 +387,7 @@ void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
>  void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
>  {
>  	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
>  
>  	if (!dev_priv->uncore.funcs.force_wake_get)
>  		return;
> @@ -559,10 +560,10 @@ __gen2_read(64)
>  	return val
>  
>  static inline void __force_wake_get(struct drm_i915_private *dev_priv,
> -				    unsigned fw_domains)
> +				    enum fw_domains fw_domains)
>  {
>  	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
>  
>  	if (WARN_ON(!fw_domains))
>  		return;
> @@ -626,7 +627,7 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>  #define __gen9_read(x) \
>  static u##x \
>  gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> -	unsigned fw_engine; \
> +	enum fw_domains fw_engine; \
>  	GEN6_READ_HEADER(x); \
>  	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)))	\
>  		fw_engine = 0; \
> @@ -826,7 +827,7 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
>  static void \
>  gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>  		bool trace) { \
> -	unsigned fw_engine; \
> +	enum fw_domains fw_engine; \
>  	GEN6_WRITE_HEADER; \
>  	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) ||	\
>  	    is_gen9_shadowed(dev_priv, reg)) \
> @@ -892,7 +893,7 @@ do { \
>  
>  
>  static void fw_domain_init(struct drm_i915_private *dev_priv,
> -			   u32 domain_id, u32 reg_set, u32 reg_ack)
> +			   enum fw_domain_id domain_id, u32 reg_set, u32 reg_ack)
>  {
>  	struct intel_uncore_forcewake_domain *d;
>  
> -- 
> 1.9.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers
  2014-12-09 13:32     ` Jani Nikula
@ 2014-12-09 13:36       ` Daniel Vetter
  2014-12-09 15:37       ` Mika Kuoppala
  2014-12-10 18:12       ` [PATCH v2] drm/i915: FIFO space query code refactor Dave Gordon
  2 siblings, 0 replies; 57+ messages in thread
From: Daniel Vetter @ 2014-12-09 13:36 UTC (permalink / raw
  To: Jani Nikula; +Cc: intel-gfx, daniel.vetter

On Tue, Dec 09, 2014 at 03:32:05PM +0200, Jani Nikula wrote:
> On Tue, 09 Dec 2014, Mika Kuoppala <mika.kuoppala@linux.intel.com> wrote:
> > Make the domains and domain identifiers enums. To emphasize
> > the difference in order to avoid mistakes.
> >
> > Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h     | 41 +++++++++++++++++----------------
> >  drivers/gpu/drm/i915/intel_uncore.c | 45 +++++++++++++++++++------------------
> >  2 files changed, 45 insertions(+), 41 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index 0d47397..5c6c372 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -533,11 +533,28 @@ struct drm_i915_display_funcs {
> >  	void (*enable_backlight)(struct intel_connector *connector);
> >  };
> >  
> > +enum fw_domain_id {
> 
> Does anyone else think of "firmware" first when seeing "fw", and
> "forcewake" only after a moment?

Hm yeah.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers
  2014-12-09 13:32     ` Jani Nikula
  2014-12-09 13:36       ` Daniel Vetter
@ 2014-12-09 15:37       ` Mika Kuoppala
  2014-12-10 18:12       ` [PATCH v2] drm/i915: FIFO space query code refactor Dave Gordon
  2 siblings, 0 replies; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-09 15:37 UTC (permalink / raw
  To: intel-gfx

Make the domains and domain identifiers enums. To emphasize
the difference in order to avoid mistakes.

v2: s/fw_domain/forcewake_domain (Jani)

Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h     | 45 +++++++++++++++++++-----------------
 drivers/gpu/drm/i915/intel_uncore.c | 46 +++++++++++++++++++------------------
 2 files changed, 48 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0d47397..8591a5c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -533,11 +533,28 @@ struct drm_i915_display_funcs {
 	void (*enable_backlight)(struct intel_connector *connector);
 };
 
+enum forcewake_domain_id {
+	FW_DOMAIN_ID_RENDER = 0,
+	FW_DOMAIN_ID_BLITTER,
+	FW_DOMAIN_ID_MEDIA,
+
+	FW_DOMAIN_ID_COUNT
+};
+
+enum forcewake_domains {
+	FORCEWAKE_RENDER = (1 << FW_DOMAIN_ID_RENDER),
+	FORCEWAKE_BLITTER = (1 << FW_DOMAIN_ID_BLITTER),
+	FORCEWAKE_MEDIA	= (1 << FW_DOMAIN_ID_MEDIA),
+	FORCEWAKE_ALL = (FORCEWAKE_RENDER |
+			 FORCEWAKE_BLITTER |
+			 FORCEWAKE_MEDIA)
+};
+
 struct intel_uncore_funcs {
 	void (*force_wake_get)(struct drm_i915_private *dev_priv,
-							int fw_engine);
+							enum forcewake_domains domains);
 	void (*force_wake_put)(struct drm_i915_private *dev_priv,
-							int fw_engine);
+							enum forcewake_domains domains);
 
 	uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
 	uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
@@ -554,25 +571,17 @@ struct intel_uncore_funcs {
 				uint64_t val, bool trace);
 };
 
-enum {
-	FW_DOMAIN_ID_RENDER = 0,
-	FW_DOMAIN_ID_BLITTER,
-	FW_DOMAIN_ID_MEDIA,
-
-	FW_DOMAIN_ID_COUNT
-};
-
 struct intel_uncore {
 	spinlock_t lock; /** lock is also taken in irq contexts. */
 
 	struct intel_uncore_funcs funcs;
 
 	unsigned fifo_count;
-	unsigned fw_domains;
+	enum forcewake_domains fw_domains;
 
 	struct intel_uncore_forcewake_domain {
 		struct drm_i915_private *i915;
-		int id;
+		enum forcewake_domain_id id;
 		unsigned wake_count;
 		struct timer_list timer;
 		u32 reg_set;
@@ -582,12 +591,6 @@ struct intel_uncore {
 		u32 reg_post;
 		u32 val_reset;
 	} fw_domain[FW_DOMAIN_ID_COUNT];
-#define FORCEWAKE_RENDER	(1 << FW_DOMAIN_ID_RENDER)
-#define FORCEWAKE_BLITTER	(1 << FW_DOMAIN_ID_BLITTER)
-#define FORCEWAKE_MEDIA		(1 << FW_DOMAIN_ID_MEDIA)
-#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | \
-				 FORCEWAKE_BLITTER | \
-				 FORCEWAKE_MEDIA)
 };
 
 /* Iterate over initialised fw domains */
@@ -2449,11 +2452,11 @@ extern void intel_uncore_init(struct drm_device *dev);
 extern void intel_uncore_check_errors(struct drm_device *dev);
 extern void intel_uncore_fini(struct drm_device *dev);
 extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
-const char *intel_uncore_forcewake_domain_to_str(const int domain_id);
+const char *intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id);
 void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
-				unsigned fw_domains);
+				enum forcewake_domains domains);
 void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
-				unsigned fw_domains);
+				enum forcewake_domains domains);
 void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
 
 void
diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 509b9c9..66365e7 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -49,7 +49,7 @@ static const char * const forcewake_domain_names[] = {
 };
 
 const char *
-intel_uncore_forcewake_domain_to_str(const int id)
+intel_uncore_forcewake_domain_to_str(const enum forcewake_domain_id id)
 {
 	BUILD_BUG_ON((sizeof(forcewake_domain_names)/sizeof(const char *)) !=
 		     FW_DOMAIN_ID_COUNT);
@@ -122,10 +122,10 @@ fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
 }
 
 static void
-fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
+fw_domains_get(struct drm_i915_private *dev_priv, enum forcewake_domains fw_domains)
 {
 	struct intel_uncore_forcewake_domain *d;
-	int id;
+	enum forcewake_domain_id id;
 
 	for_each_fw_domain_mask(d, fw_domains, dev_priv, id) {
 		fw_domain_wait_ack_clear(d);
@@ -136,10 +136,10 @@ fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
 }
 
 static void
-fw_domains_put(struct drm_i915_private *dev_priv, int fw_domains)
+fw_domains_put(struct drm_i915_private *dev_priv, enum forcewake_domains fw_domains)
 {
 	struct intel_uncore_forcewake_domain *d;
-	int id;
+	enum forcewake_domain_id id;
 
 	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
 		fw_domain_put(d);
@@ -149,7 +149,7 @@ static void
 fw_domains_posting_read(struct drm_i915_private *dev_priv)
 {
 	struct intel_uncore_forcewake_domain *d;
-	int id;
+	enum forcewake_domain_id id;
 
 	/* No need to do for all, just do for first found */
 	for_each_fw_domain(d, dev_priv, id) {
@@ -159,10 +159,10 @@ fw_domains_posting_read(struct drm_i915_private *dev_priv)
 }
 
 static void
-fw_domains_reset(struct drm_i915_private *dev_priv, const unsigned fw_domains)
+fw_domains_reset(struct drm_i915_private *dev_priv, enum forcewake_domains fw_domains)
 {
 	struct intel_uncore_forcewake_domain *d;
-	int id;
+	enum forcewake_domain_id id;
 
 	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
 		fw_domain_reset(d);
@@ -181,7 +181,7 @@ static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
 }
 
 static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
-					      int fw_domains)
+					      enum forcewake_domains fw_domains)
 {
 	fw_domains_get(dev_priv, fw_domains);
 
@@ -199,7 +199,7 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
 }
 
 static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
-				     int fw_domains)
+				     enum forcewake_domains fw_domains)
 {
 	fw_domains_put(dev_priv, fw_domains);
 	gen6_gt_check_fifodbg(dev_priv);
@@ -251,9 +251,10 @@ static void intel_uncore_fw_release_timer(unsigned long arg)
 void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	unsigned long irqflags, fw = 0;
+	unsigned long irqflags;
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum forcewake_domain_id id;
+	enum forcewake_domains fw = 0;
 
 	/* Hold uncore.lock across reset to prevent any register access
 	 * with forcewake not set correctly
@@ -329,11 +330,11 @@ void intel_uncore_sanitize(struct drm_device *dev)
  * intel_uncore_forcewake_put() at the end of the sequence.
  */
 void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
-				unsigned fw_domains)
+				enum forcewake_domains fw_domains)
 {
 	unsigned long irqflags;
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum forcewake_domain_id id;
 
 	if (!dev_priv->uncore.funcs.force_wake_get)
 		return;
@@ -358,11 +359,11 @@ void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
  * see intel_uncore_forcewake_get()
  */
 void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
-				unsigned fw_domains)
+				enum forcewake_domains fw_domains)
 {
 	unsigned long irqflags;
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum forcewake_domain_id id;
 
 	if (!dev_priv->uncore.funcs.force_wake_put)
 		return;
@@ -386,7 +387,7 @@ void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
 void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
 {
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum forcewake_domain_id id;
 
 	if (!dev_priv->uncore.funcs.force_wake_get)
 		return;
@@ -559,10 +560,10 @@ __gen2_read(64)
 	return val
 
 static inline void __force_wake_get(struct drm_i915_private *dev_priv,
-				    unsigned fw_domains)
+				    enum forcewake_domains fw_domains)
 {
 	struct intel_uncore_forcewake_domain *domain;
-	int id;
+	enum forcewake_domain_id id;
 
 	if (WARN_ON(!fw_domains))
 		return;
@@ -626,7 +627,7 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
 #define __gen9_read(x) \
 static u##x \
 gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
-	unsigned fw_engine; \
+	enum forcewake_domains fw_engine; \
 	GEN6_READ_HEADER(x); \
 	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)))	\
 		fw_engine = 0; \
@@ -826,7 +827,7 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
 static void \
 gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
 		bool trace) { \
-	unsigned fw_engine; \
+	enum forcewake_domains fw_engine; \
 	GEN6_WRITE_HEADER; \
 	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) ||	\
 	    is_gen9_shadowed(dev_priv, reg)) \
@@ -892,7 +893,8 @@ do { \
 
 
 static void fw_domain_init(struct drm_i915_private *dev_priv,
-			   u32 domain_id, u32 reg_set, u32 reg_ack)
+			   enum forcewake_domain_id domain_id,
+			   u32 reg_set, u32 reg_ack)
 {
 	struct intel_uncore_forcewake_domain *d;
 
-- 
1.9.1

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

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

* Re: [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors
  2014-12-08 18:27 ` [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors Mika Kuoppala
  2014-12-09 11:46   ` [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers Mika Kuoppala
@ 2014-12-09 23:29   ` shuang.he
  2014-12-12 13:20   ` Deepak S
  2 siblings, 0 replies; 57+ messages in thread
From: shuang.he @ 2014-12-09 23:29 UTC (permalink / raw
  To: shuang.he, intel-gfx, mika.kuoppala

Tested-By: PRC QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com)
-------------------------------------Summary-------------------------------------
Platform          Delta          drm-intel-nightly          Series Applied
PNV                                  364/364              364/364
ILK              +1-3              364/366              362/366
SNB                 -19              448/450              429/450
IVB                                  497/498              497/498
BYT                                  289/289              289/289
HSW                 -83              563/564              480/564
BDW                 -4              417/417              413/417
-------------------------------------Detailed-------------------------------------
Platform  Test                                drm-intel-nightly          Series Applied
 ILK  igt_kms_flip_blocking-absolute-wf_vblank-interruptible      DMESG_WARN(1, M26)PASS(3, M26)      DMESG_WARN(1, M26)
*ILK  igt_kms_flip_busy-flip-interruptible      PASS(4, M26)      DMESG_WARN(1, M26)
*ILK  igt_kms_flip_flip-vs-panning      PASS(3, M26)      DMESG_WARN(1, M26)
 ILK  igt_kms_flip_wf_vblank-ts-check      DMESG_WARN(1, M26)PASS(10, M26M37)      PASS(1, M26)
*SNB  igt_pm_rpm_cursor      PASS(2, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_cursor-dpms      PASS(2, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_debugfs-forcewake-user      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_dpms-mode-unset-non-lpsp      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_dpms-non-lpsp      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_drm-resources-equal      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_fences      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_fences-dpms      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_gem-execbuf      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_gem-idle      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_gem-mmap-cpu      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_gem-mmap-gtt      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_gem-pread      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_i2c      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_modeset-non-lpsp      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_modeset-non-lpsp-stress-no-wait      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_pci-d3-state      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_reg-read-ioctl      PASS(1, M35)      DMESG_WARN(1, M22)
*SNB  igt_pm_rpm_rte      PASS(1, M35)      DMESG_WARN(1, M22)
*HSW  igt_gem_concurrent_blit_cpu-bcs-overwrite-source-forked      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_vblank-vs-dpms-rpm      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_pipe_crc_basic_read-crc-pipe-A      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_pipe_crc_basic_read-crc-pipe-A-frame-sequence      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_pipe_crc_basic_read-crc-pipe-B      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_pipe_crc_basic_read-crc-pipe-B-frame-sequence      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_pipe_crc_basic_read-crc-pipe-C      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_pipe_crc_basic_read-crc-pipe-C-frame-sequence      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-bottom-right-pipe-A-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-bottom-right-pipe-A-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-bottom-right-pipe-B-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-bottom-right-pipe-B-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-bottom-right-pipe-C-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-bottom-right-pipe-C-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-top-left-pipe-A-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-top-left-pipe-A-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-top-left-pipe-B-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-top-left-pipe-B-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-top-left-pipe-C-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-panning-top-left-pipe-C-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-covered-pipe-A-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-covered-pipe-A-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-covered-pipe-B-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-covered-pipe-C-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-covered-pipe-C-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-hole-pipe-A-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-hole-pipe-A-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-hole-pipe-B-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-hole-pipe-B-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-hole-pipe-C-plane-1      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_plane_plane-position-hole-pipe-C-plane-2      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_lpsp_non-edp      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_lpsp_screens-disabled      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_cursor      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_cursor-dpms      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_debugfs-forcewake-user      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_debugfs-read      PASS(3, M40M20)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_dpms-mode-unset-non-lpsp      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_dpms-non-lpsp      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_drm-resources-equal      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_fences      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_fences-dpms      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_gem-execbuf      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_gem-idle      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_gem-mmap-cpu      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_gem-mmap-gtt      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_gem-pread      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_i2c      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_modeset-non-lpsp      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_modeset-non-lpsp-stress-no-wait      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_pci-d3-state      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_reg-read-ioctl      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_rte      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_pm_rpm_sysfs-read      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_gem_partial_pwrite_pread_reads-snoop      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_absolute-wf_vblank      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_absolute-wf_vblank-interruptible      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_blocking-absolute-wf_vblank      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_blocking-absolute-wf_vblank-interruptible      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_blocking-wf_vblank      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_busy-flip      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_busy-flip-interruptible      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_dpms-off-confusion      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_dpms-off-confusion-interruptible      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_flip-vs-absolute-wf_vblank      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_flip-vs-absolute-wf_vblank-interruptible      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_flip-vs-blocking-wf-vblank      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_flip-vs-panning      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_flip-vs-panning-interruptible      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_flip-vs-rmfb      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_flip-vs-rmfb-interruptible      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_flip-vs-wf_vblank      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_flip-vs-wf_vblank-interruptible      PASS(2, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_plain-flip      PASS(1, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_plain-flip-fb-recreate      PASS(1, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_plain-flip-fb-recreate-interruptible      PASS(1, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_plain-flip-interruptible      PASS(1, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_plain-flip-ts-check      PASS(1, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_plain-flip-ts-check-interruptible      PASS(1, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_wf_vblank      PASS(1, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_wf_vblank-interruptible      PASS(1, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_wf_vblank-ts-check      PASS(1, M40)      DMESG_WARN(1, M40)
*HSW  igt_kms_flip_wf_vblank-ts-check-interruptible      PASS(1, M40)      DMESG_WARN(1, M40)
*BDW  igt_gem_persistent_relocs_forked-interruptible      PASS(2, M30)      DMESG_WARN(1, M30)
*BDW  igt_gem_persistent_relocs_forked-interruptible-faulting-reloc-thrash-inactive      PASS(2, M30)      DMESG_WARN(1, M30)
 BDW  igt_gem_render_linear_blits      TIMEOUT(1, M30)PASS(2, M30M28)      TIMEOUT(1, M30)
 BDW  igt_gem_render_tiled_blits      TIMEOUT(1, M30)PASS(2, M30M28)      TIMEOUT(1, M30)
Note: You need to pay more attention to line start with '*'
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 03/10] drm/i915: Updating assorted register and status page definitions
  2014-12-09 12:59 ` [PATCH 03/10] drm/i915: Updating assorted register and status page definitions John.C.Harrison
@ 2014-12-10 10:40   ` Daniel Vetter
  2014-12-10 16:37     ` Dave Gordon
  0 siblings, 1 reply; 57+ messages in thread
From: Daniel Vetter @ 2014-12-10 10:40 UTC (permalink / raw
  To: John.C.Harrison; +Cc: Intel-GFX

On Tue, Dec 09, 2014 at 12:59:06PM +0000, John.C.Harrison@Intel.com wrote:
> From: Dave Gordon <david.s.gordon@intel.com>
> 
> Added various definitions that will be useful for the scheduler in general and
> pre-emptive context switching in particular.
> 
> Change-Id: Ica805b94160426def51f5d520f5ce51c60864a98
> For: VIZ-1587
> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reg.h         |   30 ++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_ringbuffer.h |   40 +++++++++++++++++++++++++++++--
>  2 files changed, 67 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 869e5ae..6169720 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -216,6 +216,10 @@
>  #define  MI_GLOBAL_GTT    (1<<22)
>  
>  #define MI_NOOP			MI_INSTR(0, 0)
> +#define   MI_NOOP_WRITE_ID		(1<<22)
> +#define   MI_NOOP_ID_MASK		((1<<22) - 1)
> +#define   MI_NOOP_MID(id)		((id) & MI_NOOP_ID_MASK)
> +#define MI_NOOP_WITH_ID(id)	MI_INSTR(0, MI_NOOP_WRITE_ID|MI_NOOP_MID(id))
>  #define MI_USER_INTERRUPT	MI_INSTR(0x02, 0)
>  #define MI_WAIT_FOR_EVENT       MI_INSTR(0x03, 0)
>  #define   MI_WAIT_FOR_OVERLAY_FLIP	(1<<16)
> @@ -233,6 +237,7 @@
>  #define MI_ARB_ON_OFF		MI_INSTR(0x08, 0)
>  #define   MI_ARB_ENABLE			(1<<0)
>  #define   MI_ARB_DISABLE		(0<<0)
> +#define MI_ARB_CHECK		MI_INSTR(0x05, 0)
>  #define MI_BATCH_BUFFER_END	MI_INSTR(0x0a, 0)
>  #define MI_SUSPEND_FLUSH	MI_INSTR(0x0b, 0)
>  #define   MI_SUSPEND_FLUSH_EN	(1<<0)
> @@ -281,6 +286,8 @@
>  #define   MI_SEMAPHORE_SYNC_INVALID (3<<16)
>  #define   MI_SEMAPHORE_SYNC_MASK    (3<<16)
>  #define MI_SET_CONTEXT		MI_INSTR(0x18, 0)
> +#define   MI_CONTEXT_ADDR_MASK		((~0)<<12)
> +#define   MI_SET_CONTEXT_FLAG_MASK	((1<<12)-1)
>  #define   MI_MM_SPACE_GTT		(1<<8)
>  #define   MI_MM_SPACE_PHYSICAL		(0<<8)
>  #define   MI_SAVE_EXT_STATE_EN		(1<<3)
> @@ -298,6 +305,10 @@
>  #define   MI_USE_GGTT		(1 << 22) /* g4x+ */
>  #define MI_STORE_DWORD_INDEX	MI_INSTR(0x21, 1)
>  #define   MI_STORE_DWORD_INDEX_SHIFT 2
> +#define MI_STORE_REG_MEM	MI_INSTR(0x24, 1)
> +#define   MI_STORE_REG_MEM_GTT		(1 << 22)
> +#define   MI_STORE_REG_MEM_PREDICATE	(1 << 21)
> +
>  /* Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM:
>   * - Always issue a MI_NOOP _before_ the MI_LOAD_REGISTER_IMM - otherwise hw
>   *   simply ignores the register load under certain conditions.
> @@ -312,7 +323,10 @@
>  #define MI_FLUSH_DW		MI_INSTR(0x26, 1) /* for GEN6 */
>  #define   MI_FLUSH_DW_STORE_INDEX	(1<<21)
>  #define   MI_INVALIDATE_TLB		(1<<18)
> +#define   MI_FLUSH_DW_OP_NONE		(0<<14)
>  #define   MI_FLUSH_DW_OP_STOREDW	(1<<14)
> +#define   MI_FLUSH_DW_OP_RSVD		(2<<14)
> +#define   MI_FLUSH_DW_OP_STAMP		(3<<14)
>  #define   MI_FLUSH_DW_OP_MASK		(3<<14)
>  #define   MI_FLUSH_DW_NOTIFY		(1<<8)
>  #define   MI_INVALIDATE_BSD		(1<<7)
> @@ -1119,6 +1133,19 @@ enum punit_power_well {
>  #define GEN6_VERSYNC	(RING_SYNC_1(VEBOX_RING_BASE))
>  #define GEN6_VEVSYNC	(RING_SYNC_2(VEBOX_RING_BASE))
>  #define GEN6_NOSYNC 0
> +
> +/*
> + * Premption-related registers
> + */
> +#define RING_UHPTR(base)	((base)+0x134)
> +#define   UHPTR_GFX_ADDR_ALIGN		(0x7)
> +#define   UHPTR_VALID			(0x1)
> +#define RING_PREEMPT_ADDR	0x0214c
> +#define   PREEMPT_BATCH_LEVEL_MASK	(0x3)
> +#define BB_PREEMPT_ADDR		0x02148
> +#define SBB_PREEMPT_ADDR	0x0213c
> +#define RS_PREEMPT_STATUS	0x0215c
> +
>  #define RING_MAX_IDLE(base)	((base)+0x54)
>  #define RING_HWS_PGA(base)	((base)+0x80)
>  #define RING_HWS_PGA_GEN6(base)	((base)+0x2080)
> @@ -5917,7 +5944,8 @@ enum punit_power_well {
>  #define  VLV_SPAREG2H				0xA194
>  
>  #define  GTFIFODBG				0x120000
> -#define    GT_FIFO_SBDROPERR			(1<<6)
> +#define    GT_FIFO_CPU_ERROR_MASK		0xf
> +#define    GT_FIFO_SDDROPERR			(1<<6)
>  #define    GT_FIFO_BLOBDROPERR			(1<<5)
>  #define    GT_FIFO_SB_READ_ABORTERR		(1<<4)
>  #define    GT_FIFO_DROPERR			(1<<3)
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 2e0fa7b..f15fc46 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -47,6 +47,12 @@ struct  intel_hw_status_page {
>  #define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base))
>  #define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val)
>  
> +#define I915_READ_UHPTR(ring) \
> +		I915_READ(RING_UHPTR((ring)->mmio_base))
> +#define I915_WRITE_UHPTR(ring, val) \
> +		I915_WRITE(RING_UHPTR((ring)->mmio_base), val)
> +#define I915_READ_NOPID(ring) I915_READ(RING_NOPID((ring)->mmio_base))
> +
>  /* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to
>   * do the writes, and that must have qw aligned offsets, simply pretend it's 8b.
>   */
> @@ -377,10 +383,40 @@ intel_write_status_page(struct intel_engine_cs *ring,
>   * 0x1f: Last written status offset. (GM45)
>   *
>   * The area from dword 0x20 to 0x3ff is available for driver usage.
> + *
> + * Note: in general the allocation of these indices is arbitrary, as long
> + * as they are all unique. But a few of them are used with instructions that
> + * have specific alignment requirements, those particular indices must be
> + * chosen carefully to meet those requirements. The list below shows the
> + * currently-known alignment requirements:
> + *
> + *	I915_GEM_SCRATCH_INDEX	    must be EVEN
>   */
>  #define I915_GEM_HWS_INDEX		0x20
> -#define I915_GEM_HWS_SCRATCH_INDEX	0x30
> -#define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
> +
> +#define I915_GEM_HWS_SCRATCH_INDEX	0x24  /* QWord */
> +#define I915_GEM_HWS_SCRATCH_ADDR	(I915_GEM_HWS_SCRATCH_INDEX << MI_STORE_DWORD_INDEX_SHIFT)
> +
> +/*
> + * Tracking; these are updated by the GPU at the beginning and/or end of every
> + * batch. One pair for regular buffers, the other for preemptive ones.
> + */
> +#define I915_BATCH_DONE_SEQNO		0x30  /* Completed batch seqno        */
> +#define I915_BATCH_ACTIVE_SEQNO		0x31  /* In progress batch seqno      */
> +#define I915_PREEMPTIVE_DONE_SEQNO	0x32  /* Completed preemptive batch   */
> +#define I915_PREEMPTIVE_ACTIVE_SEQNO	0x33  /* In progress preemptive batch */

This are software define and currently not yet used I think. Imo better to
add them together with the scheduler code that uses them. Splitting out
#define patches only makes sense if they can be reviewed separately (e.g.
registers with Bspec). Just adding software stuff (structs, enums, offsets
not enforced by hw) should be added with the actual code using it.


> +
> +/*
> + * Preemption; these are used by the GPU to save important registers
> + */
> +#define I915_SAVE_PREEMPTED_RING_PTR	0x34  /* HEAD before preemption     */
> +#define I915_SAVE_PREEMPTED_BB_PTR	0x35  /* BB ptr before preemption   */
> +#define I915_SAVE_PREEMPTED_SBB_PTR	0x36  /* SBB before preemption      */
> +#define I915_SAVE_PREEMPTED_UHPTR	0x37  /* UHPTR after preemption     */
> +#define I915_SAVE_PREEMPTED_HEAD	0x38  /* HEAD after preemption      */
> +#define I915_SAVE_PREEMPTED_TAIL	0x39  /* TAIL after preemption      */
> +#define I915_SAVE_PREEMPTED_STATUS	0x3A  /* RS preemption status       */
> +#define I915_SAVE_PREEMPTED_NOPID	0x3B  /* Dummy                      */

I guess this is hardcoded in hw? In that case a HWS instead of I915 prefix
sounds better to me to make it clear this is not something i915/gem code
invented. Also comment should state whether this is execlist or gen8+ or
something like that.
-Daniel

>  
>  void intel_unpin_ringbuffer_obj(struct intel_ringbuffer *ringbuf);
>  int intel_pin_and_map_ringbuffer_obj(struct drm_device *dev,
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 04/10] drm/i915: FIFO space query code refactor
  2014-12-09 12:59 ` [PATCH 04/10] drm/i915: FIFO space query code refactor John.C.Harrison
@ 2014-12-10 10:41   ` Daniel Vetter
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel Vetter @ 2014-12-10 10:41 UTC (permalink / raw
  To: John.C.Harrison; +Cc: Intel-GFX

On Tue, Dec 09, 2014 at 12:59:07PM +0000, John.C.Harrison@Intel.com wrote:
> From: Dave Gordon <david.s.gordon@intel.com>
> 
> When querying the GTFIFOCTL register to check the FIFO space, the read value
> must be masked. The operation is repeated explicitly in several places. This
> change refactors the read-and-mask code into a function call.
> 
> Change-Id: Id1a9f3785cb20b82d4caa330c37b31e4e384a3ef
> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>

Looks like an unrelated patch and probably collides with Mika's forcewake
refactoring. Please rebase on top of that series if still needed.
-Daniel

> ---
>  drivers/gpu/drm/i915/intel_uncore.c |   19 ++++++++++++-------
>  1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 46de8d7..4021831 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -47,6 +47,13 @@ assert_device_not_suspended(struct drm_i915_private *dev_priv)
>  		  "Device suspended\n");
>  }
>  
> +static inline u32 fifo_free_entries(struct drm_i915_private *dev_priv)
> +{
> +	u32 count = __raw_i915_read32(dev_priv, GTFIFOCTL);
> +
> +	return count & GT_FIFO_FREE_ENTRIES_MASK;
> +}
> +
>  static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
>  {
>  	/* w/a for a sporadic read returning 0 by waiting for the GT
> @@ -154,16 +161,15 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
>  	/* On VLV, FIFO will be shared by both SW and HW.
>  	 * So, we need to read the FREE_ENTRIES everytime */
>  	if (IS_VALLEYVIEW(dev_priv->dev))
> -		dev_priv->uncore.fifo_count =
> -			__raw_i915_read32(dev_priv, GTFIFOCTL) &
> -						GT_FIFO_FREE_ENTRIES_MASK;
> +		dev_priv->uncore.fifo_count = fifo_free_entries(dev_priv);
>  
>  	if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
>  		int loop = 500;
> -		u32 fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
> +		u32 fifo = fifo_free_entries(dev_priv);
> +
>  		while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
>  			udelay(10);
> -			fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
> +			fifo = fifo_free_entries(dev_priv);
>  		}
>  		if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
>  			++ret;
> @@ -505,8 +511,7 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>  
>  		if (IS_GEN6(dev) || IS_GEN7(dev))
>  			dev_priv->uncore.fifo_count =
> -				__raw_i915_read32(dev_priv, GTFIFOCTL) &
> -				GT_FIFO_FREE_ENTRIES_MASK;
> +				fifo_free_entries(dev_priv);
>  	}
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/10] drm/i915: Disable 'get seqno' workaround for VLV
  2014-12-09 12:59 ` [PATCH 05/10] drm/i915: Disable 'get seqno' workaround for VLV John.C.Harrison
@ 2014-12-10 10:42   ` Daniel Vetter
  2014-12-10 17:11     ` Dave Gordon
  0 siblings, 1 reply; 57+ messages in thread
From: Daniel Vetter @ 2014-12-10 10:42 UTC (permalink / raw
  To: John.C.Harrison; +Cc: Intel-GFX

On Tue, Dec 09, 2014 at 12:59:08PM +0000, John.C.Harrison@Intel.com wrote:
> From: Dave Gordon <david.s.gordon@intel.com>
> 
> There is a workaround for a hardware bug when reading the seqno from the status
> page. The bug does not exist on VLV however, the workaround was still being
> applied.

Given how much trouble the missed seqno fun cause us I'd like more
justification. What kind of (stress)-testing has been done here? And
you're sure you've never seen the little dmesg notice that the kernel
switched to polling?
-Daniel

> 
> Change-Id: Ic781fdb31e1f794ce1fa8a6d0d5ee379756c5db6
> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ringbuffer.c |    5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 3887f1a..f990ce4 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -2367,7 +2367,10 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
>  		ring->irq_get = gen6_ring_get_irq;
>  		ring->irq_put = gen6_ring_put_irq;
>  		ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
> -		ring->get_seqno = gen6_ring_get_seqno;
> +		if (IS_VALLEYVIEW(dev))
> +			ring->get_seqno = ring_get_seqno;
> +		else
> +			ring->get_seqno = gen6_ring_get_seqno;
>  		ring->set_seqno = ring_set_seqno;
>  		if (i915_semaphore_is_enabled(dev)) {
>  			ring->semaphore.sync_to = gen6_ring_sync;
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 06/10] drm/i915: Add extra add_request calls
  2014-12-09 12:59 ` [PATCH 06/10] drm/i915: Add extra add_request calls John.C.Harrison
@ 2014-12-10 10:55   ` Daniel Vetter
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel Vetter @ 2014-12-10 10:55 UTC (permalink / raw
  To: John.C.Harrison; +Cc: Intel-GFX

On Tue, Dec 09, 2014 at 12:59:09PM +0000, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The scheduler needs to track batch buffers by request without extra, non-batch
> buffer work being attached to the same request. This means that anywhere which
> adds work to the ring should explicitly call i915_add_request() when it has
> finished writing to the ring.
> 
> The add_request() function does extra work, such as flushing caches, that does
> not necessarily want to be done everywhere. Instead, a new
> i915_add_request_wo_flush() function has been added which skips the cache flush
> and just tidies up the request structure.
> 
> Note, much of this patch was implemented by Naresh Kumar Kachhi for pending
> power management improvements. However, it is also directly applicable to the
> scheduler work as noted above.
> 
> Change-Id: I66a6861118ee8e7ad7ca6c80c71a3b256db92e18
> For: VIZ-1587
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

For easier review I think it'd be better to split this into the prep patch
to rework add_request and then patches to roll it out. Some of the places
you're adding an add_requst too look questionable to me. More comments
below.

After reading through the patch (see below for comments) I think there's
only two places where we need to add requests:
- at the end of pageflips, unconditionally (to catch any semaphores
  already emitted if something fails)
- after ring init in init_hw (but perhaps with some of the restructuring
  in-flight applied to make it less messy).

Then a WARN_ON in gpu_idle to make sure no request ever escaped. Should
all be separate patches I think (so that we have a nice empty space in the
commit message for explanation why this works).

This patch here just sprinkles lots of add_requests all over which ime
tends to blow up sooner or later since it's much harder to understand and
leaves no room for selfchecks in the code to catch bugs.

Cheers, Daniel

> ---
>  drivers/gpu/drm/i915/i915_drv.h              |    9 ++++--
>  drivers/gpu/drm/i915/i915_gem.c              |   45 ++++++++++++++++----------
>  drivers/gpu/drm/i915/i915_gem_context.c      |    9 ++++++
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c   |    4 +--
>  drivers/gpu/drm/i915/i915_gem_gtt.c          |    9 ++++++
>  drivers/gpu/drm/i915/i915_gem_render_state.c |    2 +-
>  drivers/gpu/drm/i915/intel_display.c         |   23 +++++++++----
>  drivers/gpu/drm/i915/intel_lrc.c             |    4 +--
>  8 files changed, 73 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 11e85cb..0e280c4 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2553,7 +2553,7 @@ static inline void i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj)
>  
>  int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
>  int i915_gem_object_sync(struct drm_i915_gem_object *obj,
> -			 struct intel_engine_cs *to);
> +			 struct intel_engine_cs *to, bool add_request);
>  void i915_vma_move_to_active(struct i915_vma *vma,
>  			     struct intel_engine_cs *ring);
>  int i915_gem_dumb_create(struct drm_file *file_priv,
> @@ -2641,9 +2641,12 @@ int __must_check i915_gpu_idle(struct drm_device *dev);
>  int __must_check i915_gem_suspend(struct drm_device *dev);
>  int __i915_add_request(struct intel_engine_cs *ring,
>  		       struct drm_file *file,
> -		       struct drm_i915_gem_object *batch_obj);
> +		       struct drm_i915_gem_object *batch_obj,
> +		       bool flush_caches);
>  #define i915_add_request(ring) \
> -	__i915_add_request(ring, NULL, NULL)
> +	__i915_add_request(ring, NULL, NULL, true)
> +#define i915_add_request_no_flush(ring) \
> +	__i915_add_request(ring, NULL, NULL, false)
>  int __i915_wait_request(struct drm_i915_gem_request *req,
>  			unsigned reset_counter,
>  			bool interruptible,
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index de241eb..b022a2d 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2419,7 +2419,8 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
>  
>  int __i915_add_request(struct intel_engine_cs *ring,
>  		       struct drm_file *file,
> -		       struct drm_i915_gem_object *obj)
> +		       struct drm_i915_gem_object *obj,
> +		       bool flush_caches)
>  {
>  	struct drm_i915_private *dev_priv = ring->dev->dev_private;
>  	struct drm_i915_gem_request *request;
> @@ -2445,12 +2446,11 @@ int __i915_add_request(struct intel_engine_cs *ring,
>  	 * is that the flush _must_ happen before the next request, no matter
>  	 * what.
>  	 */
> -	if (i915.enable_execlists) {
> -		ret = logical_ring_flush_all_caches(ringbuf);
> -		if (ret)
> -			return ret;
> -	} else {
> -		ret = intel_ring_flush_all_caches(ring);
> +	if (flush_caches) {
> +		if (i915.enable_execlists)
> +			ret = logical_ring_flush_all_caches(ringbuf);
> +		else
> +			ret = intel_ring_flush_all_caches(ring);
>  		if (ret)
>  			return ret;
>  	}
> @@ -2462,15 +2462,12 @@ int __i915_add_request(struct intel_engine_cs *ring,
>  	 */
>  	request_ring_position = intel_ring_get_tail(ringbuf);
>  
> -	if (i915.enable_execlists) {
> +	if (i915.enable_execlists)
>  		ret = ring->emit_request(ringbuf);
> -		if (ret)
> -			return ret;
> -	} else {
> +	else
>  		ret = ring->add_request(ring);
> -		if (ret)
> -			return ret;
> -	}
> +	if (ret)
> +		return ret;
>  
>  	request->head = request_start;
>  	request->tail = request_ring_position;
> @@ -2974,6 +2971,8 @@ out:
>   *
>   * @obj: object which may be in use on another ring.
>   * @to: ring we wish to use the object on. May be NULL.
> + * @add_request: do we need to add a request to track operations
> + *    submitted on ring with sync_to function
>   *
>   * This code is meant to abstract object synchronization with the GPU.
>   * Calling with NULL implies synchronizing the object with the CPU
> @@ -2983,7 +2982,7 @@ out:
>   */
>  int
>  i915_gem_object_sync(struct drm_i915_gem_object *obj,
> -		     struct intel_engine_cs *to)
> +		     struct intel_engine_cs *to, bool add_request)
>  {
>  	struct intel_engine_cs *from;
>  	u32 seqno;
> @@ -3011,13 +3010,16 @@ i915_gem_object_sync(struct drm_i915_gem_object *obj,
>  
>  	trace_i915_gem_ring_sync_to(from, to, obj->last_read_req);
>  	ret = to->semaphore.sync_to(to, from, seqno);
> -	if (!ret)
> +	if (!ret) {
>  		/* We use last_read_req because sync_to()
>  		 * might have just caused seqno wrap under
>  		 * the radar.
>  		 */
>  		from->semaphore.sync_seqno[idx] =
>  				i915_gem_request_get_seqno(obj->last_read_req);
> +		if (add_request)
> +			i915_add_request_no_flush(to);
> +	}

Is the scheduler really still using hw semaphores for inter-ring sync?
I've thought all the depency tracking gets pushed into software? And even
then I expect that we'll insert semaphores really late and should treat
them as part of the subsequent batch of pageflip.

>  
>  	return ret;
>  }
> @@ -3126,6 +3128,15 @@ int i915_gpu_idle(struct drm_device *dev)
>  				return ret;
>  		}
>  
> +		/* Make sure the context switch (if one actually happened)
> +		 * gets wrapped up and finished rather than hanging around
> +		 * and confusing things later. */
> +		if (ring->outstanding_lazy_request) {
> +			ret = i915_add_request(ring);
> +			if (ret)
> +				return ret;
> +		}

I expect bad interactions with the ilk iommu w/a (see do_idling in
i915_gem_gtt.c) due to the recursion this will cause in the execbuf code.

Except for this case we shouldn't ever leak a request with your code
anywhere any more, so I think instead this should be a WARN_ON (ofc only
when do_idle_maps is false).

> +
>  		ret = intel_ring_idle(ring);
>  		if (ret)
>  			return ret;
> @@ -3946,7 +3957,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
>  	int ret;
>  
>  	if (pipelined != i915_gem_request_get_ring(obj->last_read_req)) {
> -		ret = i915_gem_object_sync(obj, pipelined);
> +		ret = i915_gem_object_sync(obj, pipelined, true);

Async flips should be caught by the flip requests added below. Essentially
same comment as above with object_sync.

>  		if (ret)
>  			return ret;
>  	}
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index 5cd2b97..b2f1296 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -426,6 +426,15 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
>  			ret = i915_switch_context(ring, ring->default_context);
>  			if (ret)
>  				return ret;
> +
> +			/* Make sure the context switch (if one actually happened)
> +			 * gets wrapped up and finished rather than hanging around
> +			 * and confusing things later. */
> +			if (ring->outstanding_lazy_request) {
> +				ret = i915_add_request_no_flush(ring);

We have a lot more randome stuff all over when intializing rings (pde
loads, l3c remapping, context, golden context, w/a). Imo we should have
one central add request for all of them. We've the recently reworked ring
init plus some of the patches from Chris (to preload the ring before
enabling/submitting the ring) that should be fairly straighforward to
implement.

> +				if (ret)
> +					return ret;
> +			}
>  		}
>  
>  	return 0;
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index aa4566e..1268e89 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -832,7 +832,7 @@ i915_gem_execbuffer_move_to_gpu(struct intel_engine_cs *ring,
>  
>  	list_for_each_entry(vma, vmas, exec_list) {
>  		struct drm_i915_gem_object *obj = vma->obj;
> -		ret = i915_gem_object_sync(obj, ring);
> +		ret = i915_gem_object_sync(obj, ring, false);
>  		if (ret)
>  			return ret;
>  
> @@ -993,7 +993,7 @@ i915_gem_execbuffer_retire_commands(struct drm_device *dev,
>  	ring->gpu_caches_dirty = true;
>  
>  	/* Add a breadcrumb for the completion of the batch buffer */
> -	(void)__i915_add_request(ring, file, obj);
> +	(void)__i915_add_request(ring, file, obj, true);
>  }
>  
>  static int
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index ac03a38..7eead93 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -1153,6 +1153,15 @@ int i915_ppgtt_init_hw(struct drm_device *dev)
>  			ret = ppgtt->switch_mm(ppgtt, ring);
>  			if (ret != 0)
>  				return ret;
> +
> +			/* Make sure the context switch (if one actually happened)
> +			 * gets wrapped up and finished rather than hanging around
> +			 * and confusing things later. */
> +			if (ring->outstanding_lazy_request) {
> +				ret = i915_add_request_no_flush(ring);
> +				if (ret)
> +					return ret;
> +			}
>  		}
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c
> index 521548a..aba39c3 100644
> --- a/drivers/gpu/drm/i915/i915_gem_render_state.c
> +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
> @@ -173,7 +173,7 @@ int i915_gem_render_state_init(struct intel_engine_cs *ring)
>  
>  	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
>  
> -	ret = __i915_add_request(ring, NULL, so.obj);
> +	ret = __i915_add_request(ring, NULL, so.obj, true);
>  	/* __i915_add_request moves object to inactive if it fails */
>  out:
>  	i915_gem_render_state_fini(&so);
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index a9bdc12..5b8d4f9 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -9116,7 +9116,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
>  	intel_ring_emit(ring, 0); /* aux display base address, unused */
>  
>  	intel_mark_page_flip_active(intel_crtc);
> -	__intel_ring_advance(ring);
> +	i915_add_request_no_flush(ring);
>  	return 0;
>  }
>  
> @@ -9148,7 +9148,7 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
>  	intel_ring_emit(ring, MI_NOOP);
>  
>  	intel_mark_page_flip_active(intel_crtc);
> -	__intel_ring_advance(ring);
> +	i915_add_request_no_flush(ring);
>  	return 0;
>  }
>  
> @@ -9187,7 +9187,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
>  	intel_ring_emit(ring, pf | pipesrc);
>  
>  	intel_mark_page_flip_active(intel_crtc);
> -	__intel_ring_advance(ring);
> +	i915_add_request_no_flush(ring);
>  	return 0;
>  }
>  
> @@ -9223,7 +9223,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
>  	intel_ring_emit(ring, pf | pipesrc);
>  
>  	intel_mark_page_flip_active(intel_crtc);
> -	__intel_ring_advance(ring);
> +	i915_add_request_no_flush(ring);
>  	return 0;
>  }
>  
> @@ -9318,7 +9318,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
>  	intel_ring_emit(ring, (MI_NOOP));
>  
>  	intel_mark_page_flip_active(intel_crtc);
> -	__intel_ring_advance(ring);
> +	i915_add_request_no_flush(ring);
>  	return 0;
>  }
>  
> @@ -9528,7 +9528,7 @@ static int intel_gen9_queue_flip(struct drm_device *dev,
>  	intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset);
>  
>  	intel_mark_page_flip_active(intel_crtc);
> -	__intel_ring_advance(ring);
> +	i915_add_request_no_flush(ring);
>  
>  	return 0;
>  }
> @@ -9734,8 +9734,17 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
>  		if (ret)
>  			goto cleanup_unpin;
>  
> +		/* Borked: need to get the seqno for the request submitted in
> +		 * 'queue_flip()' above. However, either the request has been
> +		 * posted already and the seqno is gone (q_f calls add_request),
> +		 * or the request never gets posted and is merged into whatever
> +		 * render comes along next (q_f calls ring_advance).
> +		 *
> +		 * On the other hand, seqnos are going away soon anyway! So
> +		 * hopefully the problem will disappear...
> +		 */
>  		i915_gem_request_assign(&work->flip_queued_req,
> -					intel_ring_get_request(ring));
> +					ring->outstanding_lazy_request ? intel_ring_get_request(ring) : NULL);
>  	}
>  
>  	work->flip_queued_vblank = drm_vblank_count(dev, intel_crtc->pipe);
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 82a47e3..643a56a 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -617,7 +617,7 @@ static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf,
>  	list_for_each_entry(vma, vmas, exec_list) {
>  		struct drm_i915_gem_object *obj = vma->obj;
>  
> -		ret = i915_gem_object_sync(obj, ring);
> +		ret = i915_gem_object_sync(obj, ring, true);
>  		if (ret)
>  			return ret;
>  
> @@ -1630,7 +1630,7 @@ int intel_lr_context_render_state_init(struct intel_engine_cs *ring,
>  
>  	i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
>  
> -	ret = __i915_add_request(ring, file, so.obj);
> +	ret = __i915_add_request(ring, file, so.obj, true);
>  	/* intel_logical_ring_add_request moves object to inactive if it
>  	 * fails */
>  out:
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two
  2014-12-09 12:59 ` [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two John.C.Harrison
@ 2014-12-10 10:58   ` Daniel Vetter
  2014-12-10 16:33     ` Dave Gordon
  0 siblings, 1 reply; 57+ messages in thread
From: Daniel Vetter @ 2014-12-10 10:58 UTC (permalink / raw
  To: John.C.Harrison; +Cc: Intel-GFX

On Tue, Dec 09, 2014 at 12:59:11PM +0000, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The scheduler decouples the submission of batch buffers to the driver with their
> submission to the hardware. This basically means splitting the execbuffer()
> function in half. This change rearranges some code ready for the split to occur.

Now there's the curios question: Where will the split in top/bottom halves
be? Without that I have no idea whether it makes sense and so can't review
this patch. At least if the goal is to really prep for the scheduler and
not just move a few lines around ;-)
-Daniel

> 
> Change-Id: Icc9c8afaac18821f3eb8a151a49f918f90c068a3
> For: VIZ-1587
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c |   47 +++++++++++++++++-----------
>  drivers/gpu/drm/i915/intel_lrc.c           |   17 +++++++---
>  2 files changed, 40 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index f09501c..a339556 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -848,10 +848,7 @@ i915_gem_execbuffer_move_to_gpu(struct intel_engine_cs *ring,
>  	if (flush_domains & I915_GEM_DOMAIN_GTT)
>  		wmb();
>  
> -	/* Unconditionally invalidate gpu caches and ensure that we do flush
> -	 * any residual writes from the previous batch.
> -	 */
> -	return intel_ring_invalidate_all_caches(ring);
> +	return 0;
>  }
>  
>  static bool
> @@ -1123,14 +1120,6 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
>  		}
>  	}
>  
> -	ret = i915_gem_execbuffer_move_to_gpu(ring, vmas);
> -	if (ret)
> -		goto error;
> -
> -	ret = i915_switch_context(ring, ctx);
> -	if (ret)
> -		goto error;
> -
>  	instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK;
>  	instp_mask = I915_EXEC_CONSTANTS_MASK;
>  	switch (instp_mode) {
> @@ -1168,6 +1157,28 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
>  		goto error;
>  	}
>  
> +	ret = i915_gem_execbuffer_move_to_gpu(ring, vmas);
> +	if (ret)
> +		goto error;
> +
> +	i915_gem_execbuffer_move_to_active(vmas, ring);
> +
> +	/* To be split into two functions here... */
> +
> +	intel_runtime_pm_get(dev_priv);
> +
> +	/* Unconditionally invalidate gpu caches and ensure that we do flush
> +	 * any residual writes from the previous batch.
> +	 */
> +	ret = intel_ring_invalidate_all_caches(ring);
> +	if (ret)
> +		goto error;
> +
> +	/* Switch to the correct context for the batch */
> +	ret = i915_switch_context(ring, ctx);
> +	if (ret)
> +		goto error;
> +
>  	if (ring == &dev_priv->ring[RCS] &&
>  			instp_mode != dev_priv->relative_constants_mode) {
>  		ret = intel_ring_begin(ring, 4);
> @@ -1208,15 +1219,18 @@ i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file,
>  						exec_start, exec_len,
>  						dispatch_flags);
>  		if (ret)
> -			return ret;
> +			goto error;
>  	}
>  
>  	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), dispatch_flags);
>  
> -	i915_gem_execbuffer_move_to_active(vmas, ring);
>  	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
>  
>  error:
> +	/* intel_gpu_busy should also get a ref, so it will free when the device
> +	 * is really idle. */
> +	intel_runtime_pm_put(dev_priv);
> +
>  	kfree(cliprects);
>  	return ret;
>  }
> @@ -1335,8 +1349,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
>  		return -EINVAL;
>  	}
>  
> -	intel_runtime_pm_get(dev_priv);
> -
>  	ret = i915_mutex_lock_interruptible(dev);
>  	if (ret)
>  		goto pre_mutex_err;
> @@ -1467,9 +1479,6 @@ err:
>  	mutex_unlock(&dev->struct_mutex);
>  
>  pre_mutex_err:
> -	/* intel_gpu_busy should also get a ref, so it will free when the device
> -	 * is really idle. */
> -	intel_runtime_pm_put(dev_priv);
>  	return ret;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 037cbd5..f16b15d 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -630,10 +630,7 @@ static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf,
>  	if (flush_domains & I915_GEM_DOMAIN_GTT)
>  		wmb();
>  
> -	/* Unconditionally invalidate gpu caches and ensure that we do flush
> -	 * any residual writes from the previous batch.
> -	 */
> -	return logical_ring_invalidate_all_caches(ringbuf);
> +	return 0;
>  }
>  
>  /**
> @@ -717,6 +714,17 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
>  	if (ret)
>  		return ret;
>  
> +	i915_gem_execbuffer_move_to_active(vmas, ring);
> +
> +	/* To be split into two functions here... */
> +
> +	/* Unconditionally invalidate gpu caches and ensure that we do flush
> +	 * any residual writes from the previous batch.
> +	 */
> +	ret = logical_ring_invalidate_all_caches(ringbuf);
> +	if (ret)
> +		return ret;
> +
>  	if (ring == &dev_priv->ring[RCS] &&
>  	    instp_mode != dev_priv->relative_constants_mode) {
>  		ret = intel_logical_ring_begin(ringbuf, 4);
> @@ -738,7 +746,6 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file,
>  
>  	trace_i915_gem_ring_dispatch(intel_ring_get_request(ring), dispatch_flags);
>  
> -	i915_gem_execbuffer_move_to_active(vmas, ring);
>  	i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj);
>  
>  	return 0;
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two
  2014-12-10 10:58   ` Daniel Vetter
@ 2014-12-10 16:33     ` Dave Gordon
  2014-12-10 17:15       ` Daniel Vetter
  0 siblings, 1 reply; 57+ messages in thread
From: Dave Gordon @ 2014-12-10 16:33 UTC (permalink / raw
  To: Daniel Vetter, John.C.Harrison; +Cc: Intel-GFX

On 10/12/14 10:58, Daniel Vetter wrote:
> On Tue, Dec 09, 2014 at 12:59:11PM +0000, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> The scheduler decouples the submission of batch buffers to the driver with their
>> submission to the hardware. This basically means splitting the execbuffer()
>> function in half. This change rearranges some code ready for the split to occur.
> 
> Now there's the curios question: Where will the split in top/bottom halves
> be? Without that I have no idea whether it makes sense and so can't review
> this patch. At least if the goal is to really prep for the scheduler and
> not just move a few lines around ;-)
> -Daniel
> 
[snip]
>>  
>> +	i915_gem_execbuffer_move_to_active(vmas, ring);
>> +
>> +	/* To be split into two functions here... */
>> +
>> +	/* Unconditionally invalidate gpu caches and ensure that we do flush
>> +	 * any residual writes from the previous batch.
>> +	 */
>> +	ret = logical_ring_invalidate_all_caches(ringbuf);

It'll be where the marker comment is above. Ahead of that point is stuff
to do with setting up software state; after that we're talking to h/w.
When the scheduler code goes it, it decouples the two by interposing at
this point. Then batches go into it with s/w state set up, but don't get
to talk to the h/w until they're selected for execution, possibly in a
different order.

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

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

* Re: [PATCH 03/10] drm/i915: Updating assorted register and status page definitions
  2014-12-10 10:40   ` Daniel Vetter
@ 2014-12-10 16:37     ` Dave Gordon
  0 siblings, 0 replies; 57+ messages in thread
From: Dave Gordon @ 2014-12-10 16:37 UTC (permalink / raw
  To: Daniel Vetter, John.C.Harrison; +Cc: Intel-GFX

On 10/12/14 10:40, Daniel Vetter wrote:
> On Tue, Dec 09, 2014 at 12:59:06PM +0000, John.C.Harrison@Intel.com wrote:
>> From: Dave Gordon <david.s.gordon@intel.com>
>>
>> Added various definitions that will be useful for the scheduler in general and
>> pre-emptive context switching in particular.
>>
>> Change-Id: Ica805b94160426def51f5d520f5ce51c60864a98
>> For: VIZ-1587
>> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_reg.h         |   30 ++++++++++++++++++++++-
>>  drivers/gpu/drm/i915/intel_ringbuffer.h |   40 +++++++++++++++++++++++++++++--
>>  2 files changed, 67 insertions(+), 3 deletions(-)

[snip]

>> +/*
>> + * Tracking; these are updated by the GPU at the beginning and/or end of every
>> + * batch. One pair for regular buffers, the other for preemptive ones.
>> + */
>> +#define I915_BATCH_DONE_SEQNO		0x30  /* Completed batch seqno        */
>> +#define I915_BATCH_ACTIVE_SEQNO		0x31  /* In progress batch seqno      */
>> +#define I915_PREEMPTIVE_DONE_SEQNO	0x32  /* Completed preemptive batch   */
>> +#define I915_PREEMPTIVE_ACTIVE_SEQNO	0x33  /* In progress preemptive batch */
> 
> This are software define and currently not yet used I think. Imo better to
> add them together with the scheduler code that uses them. Splitting out
> #define patches only makes sense if they can be reviewed separately (e.g.
> registers with Bspec). Just adding software stuff (structs, enums, offsets
> not enforced by hw) should be added with the actual code using it.

OK

>> +
>> +/*
>> + * Preemption; these are used by the GPU to save important registers
>> + */
>> +#define I915_SAVE_PREEMPTED_RING_PTR	0x34  /* HEAD before preemption     */
>> +#define I915_SAVE_PREEMPTED_BB_PTR	0x35  /* BB ptr before preemption   */
>> +#define I915_SAVE_PREEMPTED_SBB_PTR	0x36  /* SBB before preemption      */
>> +#define I915_SAVE_PREEMPTED_UHPTR	0x37  /* UHPTR after preemption     */
>> +#define I915_SAVE_PREEMPTED_HEAD	0x38  /* HEAD after preemption      */
>> +#define I915_SAVE_PREEMPTED_TAIL	0x39  /* TAIL after preemption      */
>> +#define I915_SAVE_PREEMPTED_STATUS	0x3A  /* RS preemption status       */
>> +#define I915_SAVE_PREEMPTED_NOPID	0x3B  /* Dummy                      */
> 
> I guess this is hardcoded in hw? In that case a HWS instead of I915 prefix
> sounds better to me to make it clear this is not something i915/gem code
> invented. Also comment should state whether this is execlist or gen8+ or
> something like that.
> -Daniel

No, these are s/w too, so they can be added later if that's preferred.

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

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

* Re: [PATCH 05/10] drm/i915: Disable 'get seqno' workaround for VLV
  2014-12-10 10:42   ` Daniel Vetter
@ 2014-12-10 17:11     ` Dave Gordon
  2014-12-15  9:02       ` Daniel Vetter
  0 siblings, 1 reply; 57+ messages in thread
From: Dave Gordon @ 2014-12-10 17:11 UTC (permalink / raw
  To: Daniel Vetter, John.C.Harrison; +Cc: Intel-GFX

On 10/12/14 10:42, Daniel Vetter wrote:
> On Tue, Dec 09, 2014 at 12:59:08PM +0000, John.C.Harrison@Intel.com wrote:
>> From: Dave Gordon <david.s.gordon@intel.com>
>>
>> There is a workaround for a hardware bug when reading the seqno from the status
>> page. The bug does not exist on VLV however, the workaround was still being
>> applied.
> 
> Given how much trouble the missed seqno fun cause us I'd like more
> justification. What kind of (stress)-testing has been done here? And
> you're sure you've never seen the little dmesg notice that the kernel
> switched to polling?
> -Daniel

This was necessary during VLV scheduler/preemption work, where we
stressed the command streamer and IRQ path probably more than any of the
usual tests, since we were looking for out-of-sequence anomalies.

The comments in gen6_ring_get_seqno() say it's to fix a bug on ivb/snb,
and nothing in the BSpec suggests it's needed on later chips.

I think the problem was really in the fact that the workaround
implemented in gen6_ring_get_seqno() was reading a nonshadowed register,
therefore triggering forcewake activity, which was pretty buggy; so we
took out the gen6-specific code before finding that there were still
other problems with forcewake.

[Aside]
The original intention appears to have been to generate a single I/O
READ cycle, forcing all pending inbound DMA so be flushed to memory, so
that the subsequent memory read would see the latest value. But now, it
doesn't just generate a single cycle but a whole flurry of writes and
polling reads, because reading ACTHD requires forcewake (unless that was
wrong, and has now been fixed). So should gen6_ring_get_seqno() instead
read a register that doesn't require forcewake? I wouldn't object to
using it in perpetuity if it really only read one register!
[/aside]

.Dave.

>> Change-Id: Ic781fdb31e1f794ce1fa8a6d0d5ee379756c5db6
>> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_ringbuffer.c |    5 ++++-
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
>> index 3887f1a..f990ce4 100644
>> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
>> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
>> @@ -2367,7 +2367,10 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
>>  		ring->irq_get = gen6_ring_get_irq;
>>  		ring->irq_put = gen6_ring_put_irq;
>>  		ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
>> -		ring->get_seqno = gen6_ring_get_seqno;
>> +		if (IS_VALLEYVIEW(dev))
>> +			ring->get_seqno = ring_get_seqno;
>> +		else
>> +			ring->get_seqno = gen6_ring_get_seqno;
>>  		ring->set_seqno = ring_set_seqno;
>>  		if (i915_semaphore_is_enabled(dev)) {
>>  			ring->semaphore.sync_to = gen6_ring_sync;
>> -- 
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 

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

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

* Re: [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two
  2014-12-10 16:33     ` Dave Gordon
@ 2014-12-10 17:15       ` Daniel Vetter
  2014-12-16 14:26         ` Dave Gordon
  0 siblings, 1 reply; 57+ messages in thread
From: Daniel Vetter @ 2014-12-10 17:15 UTC (permalink / raw
  To: Dave Gordon; +Cc: Intel-GFX

On Wed, Dec 10, 2014 at 04:33:14PM +0000, Dave Gordon wrote:
> On 10/12/14 10:58, Daniel Vetter wrote:
> > On Tue, Dec 09, 2014 at 12:59:11PM +0000, John.C.Harrison@Intel.com wrote:
> >> From: John Harrison <John.C.Harrison@Intel.com>
> >>
> >> The scheduler decouples the submission of batch buffers to the driver with their
> >> submission to the hardware. This basically means splitting the execbuffer()
> >> function in half. This change rearranges some code ready for the split to occur.
> > 
> > Now there's the curios question: Where will the split in top/bottom halves
> > be? Without that I have no idea whether it makes sense and so can't review
> > this patch. At least if the goal is to really prep for the scheduler and
> > not just move a few lines around ;-)
> > -Daniel
> > 
> [snip]
> >>  
> >> +	i915_gem_execbuffer_move_to_active(vmas, ring);
> >> +
> >> +	/* To be split into two functions here... */
> >> +
> >> +	/* Unconditionally invalidate gpu caches and ensure that we do flush
> >> +	 * any residual writes from the previous batch.
> >> +	 */
> >> +	ret = logical_ring_invalidate_all_caches(ringbuf);
> 
> It'll be where the marker comment is above. Ahead of that point is stuff
> to do with setting up software state; after that we're talking to h/w.
> When the scheduler code goes it, it decouples the two by interposing at
> this point. Then batches go into it with s/w state set up, but don't get
> to talk to the h/w until they're selected for execution, possibly in a
> different order.

Oops, I guess I need see a doctor to check my eyesight ;-)

Two comments about code that's still in the bottom half:
- There's lots of input validation code still below that cutoff point
  which needs to be moved above to still be able to return -EINVAL. Test
  coverage is the critical part here, but I think we've closed most of our
  gaps. I guess a future patch will address this?

- retire_commands and so add_request are also in the cutoff. For shrinker
  interactions to work seamlessly we need to have both the objects on the
  active list and the request in the lists. So I expect more untangling
  there to separate the request emission to rings from the bookkeeping
  parts in add_request.

Also move_to_active will fall apart once we start to reorder requests I
think. Need to think about this case more, but we definitely need some
testcases with depencies and reordering by the scheduler.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [PATCH v2] drm/i915: FIFO space query code refactor
  2014-12-09 13:32     ` Jani Nikula
  2014-12-09 13:36       ` Daniel Vetter
  2014-12-09 15:37       ` Mika Kuoppala
@ 2014-12-10 18:12       ` Dave Gordon
  2015-02-20  9:34         ` Mika Kuoppala
  2 siblings, 1 reply; 57+ messages in thread
From: Dave Gordon @ 2014-12-10 18:12 UTC (permalink / raw
  To: intel-gfx

When querying the GTFIFOCTL register to check the FIFO space, the read value
must be masked. The operation is repeated explicitly in several places. This
change refactors the read-and-mask code into a function call.

v2: rebased on top of Mika's forcewake patch set, specifically:
	[PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers

Change-Id: Id1a9f3785cb20b82d4caa330c37b31e4e384a3ef
Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 66365e7..a0331a7 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -205,6 +205,13 @@ static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
 	gen6_gt_check_fifodbg(dev_priv);
 }
 
+static inline u32 fifo_free_entries(struct drm_i915_private *dev_priv)
+{
+	u32 count = __raw_i915_read32(dev_priv, GTFIFOCTL);
+
+	return count & GT_FIFO_FREE_ENTRIES_MASK;
+}
+
 static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 {
 	int ret = 0;
@@ -212,16 +219,15 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 	/* On VLV, FIFO will be shared by both SW and HW.
 	 * So, we need to read the FREE_ENTRIES everytime */
 	if (IS_VALLEYVIEW(dev_priv->dev))
-		dev_priv->uncore.fifo_count =
-			__raw_i915_read32(dev_priv, GTFIFOCTL) &
-						GT_FIFO_FREE_ENTRIES_MASK;
+		dev_priv->uncore.fifo_count = fifo_free_entries(dev_priv);
 
 	if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
 		int loop = 500;
-		u32 fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
+		u32 fifo = fifo_free_entries(dev_priv);
+
 		while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
 			udelay(10);
-			fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
+			fifo = fifo_free_entries(dev_priv);
 		}
 		if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
 			++ret;
@@ -277,8 +283,7 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
 
 		if (IS_GEN6(dev) || IS_GEN7(dev))
 			dev_priv->uncore.fifo_count =
-				__raw_i915_read32(dev_priv, GTFIFOCTL) &
-				GT_FIFO_FREE_ENTRIES_MASK;
+				fifo_free_entries(dev_priv);
 	}
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
-- 
1.7.9.5

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

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

* Re: [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake
  2014-12-12 10:00 ` [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Deepak S
@ 2014-12-11 10:15   ` Chris Wilson
  2014-12-12 11:24     ` Deepak S
  2014-12-15  8:46     ` Daniel Vetter
  0 siblings, 2 replies; 57+ messages in thread
From: Chris Wilson @ 2014-12-11 10:15 UTC (permalink / raw
  To: Deepak S; +Cc: intel-gfx

On Fri, Dec 12, 2014 at 03:30:14PM +0530, Deepak S wrote:
> 
> On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> >From: Chris Wilson <chris@chris-wilson.co.uk>
> >
> >Calling intel_runtime_pm_put() is illegal from a soft-irq context, so
> >revert the crude hack
> >
> >commit aa0b3b5bb8768c1a6a6788869d9c7015eae7e80c
> >Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >Date:   Tue Apr 1 14:55:07 2014 -0300
> >
> >     drm/i915: don't schedule force_wake_timer at gen6_read
> >
> >and apply the single line corrective instead.
> >
> >References: https://bugs.freedesktop.org/show_bug.cgi?id=80913
> >Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> >Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> >---
> >@@ -777,12 +772,11 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> >  	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> >  		dev_priv->uncore.funcs.force_wake_get(dev_priv, \
> >  						      FORCEWAKE_ALL); \
> >-		val = __raw_i915_read##x(dev_priv, reg); \
> >-		dev_priv->uncore.funcs.force_wake_put(dev_priv, \
> >-						      FORCEWAKE_ALL); \
> >-	} else { \
> >-		val = __raw_i915_read##x(dev_priv, reg); \
> >+		dev_priv->uncore.forcewake_count++; \
> >+		mod_timer_pinned(&dev_priv->uncore. , \
> >+				 jiffies + 1); \
> 
> why timer, we can do a put after register read right?

The presumption is that we will do another mmio access requiring the
forcewake very shortly, and we want to avoid the forcewake clear/ack
cycle. So we defer dropping the forcewake until the end of the kernel
context on this cpu (the goal being that as the scheduler switches back
to the userspace context, we release the wakelock, it would be great if
there was an explicit callback for that...).
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 2/8] drm/i915: Assert that runtime pm is active on user fw access
  2014-12-12 11:39   ` Deepak S
@ 2014-12-11 11:53     ` Chris Wilson
  2014-12-12 11:59       ` Deepak S
  0 siblings, 1 reply; 57+ messages in thread
From: Chris Wilson @ 2014-12-11 11:53 UTC (permalink / raw
  To: Deepak S; +Cc: intel-gfx

On Fri, Dec 12, 2014 at 05:09:26PM +0530, Deepak S wrote:
> >@@ -564,17 +542,20 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
> >  	intel_runtime_pm_get(dev_priv);
> 
> I think we need to remove "intel_runtime_pm_get" here?
> I see runtime_put is removed from "gen6_gt_force_wake_put"
> 
> >-	/* Redirect to Gen9 specific routine */
> >-	if (IS_GEN9(dev_priv->dev))
> >-		return gen9_force_wake_get(dev_priv, fw_engine);
> >-
> >-	/* Redirect to VLV specific routine */
> >-	if (IS_VALLEYVIEW(dev_priv->dev))
> >-		return vlv_force_wake_get(dev_priv, fw_engine);
> >+	WARN_ON(!pm_runtime_active(&dev_priv->dev->pdev->dev));

Indeed, the purpose of this patch was to remove the rpm_get() and
replace it with this WARN_ON (and so make sure that all call paths here
already held the rpm reference). Something went wrong in the rebase I
hope.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake
  2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
                   ` (6 preceding siblings ...)
  2014-12-08 18:27 ` [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors Mika Kuoppala
@ 2014-12-12 10:00 ` Deepak S
  2014-12-11 10:15   ` Chris Wilson
  2014-12-12 16:22 ` Paulo Zanoni
  8 siblings, 1 reply; 57+ messages in thread
From: Deepak S @ 2014-12-12 10:00 UTC (permalink / raw
  To: intel-gfx


On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> From: Chris Wilson <chris@chris-wilson.co.uk>
>
> Calling intel_runtime_pm_put() is illegal from a soft-irq context, so
> revert the crude hack
>
> commit aa0b3b5bb8768c1a6a6788869d9c7015eae7e80c
> Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Date:   Tue Apr 1 14:55:07 2014 -0300
>
>      drm/i915: don't schedule force_wake_timer at gen6_read
>
> and apply the single line corrective instead.
>
> References: https://bugs.freedesktop.org/show_bug.cgi?id=80913
> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/i915_drv.c     |  1 +
>   drivers/gpu/drm/i915/intel_uncore.c | 18 ++++++------------
>   2 files changed, 7 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 71be3c9..706b122 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1402,6 +1402,7 @@ static int intel_runtime_suspend(struct device *device)
>   	}
>   
>   	del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
> +	intel_uncore_forcewake_reset(dev, false);
>   	dev_priv->pm.suspended = true;
>   
>   	/*
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 46de8d7..38ac389 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -449,8 +449,6 @@ static void gen6_force_wake_timer(unsigned long arg)
>   	if (--dev_priv->uncore.forcewake_count == 0)
>   		dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -
> -	intel_runtime_pm_put(dev_priv);
>   }
>   
>   void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
> @@ -586,7 +584,6 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>   void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   {
>   	unsigned long irqflags;
> -	bool delayed = false;
>   
>   	if (!dev_priv->uncore.funcs.force_wake_put)
>   		return;
> @@ -603,21 +600,19 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   		goto out;
>   	}
>   
> -
>   	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>   	WARN_ON(!dev_priv->uncore.forcewake_count);
>   
>   	if (--dev_priv->uncore.forcewake_count == 0) {
>   		dev_priv->uncore.forcewake_count++;
> -		delayed = true;
>   		mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
>   				 jiffies + 1);
>   	}
> +
>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>   
>   out:
> -	if (!delayed)
> -		intel_runtime_pm_put(dev_priv);
> +	intel_runtime_pm_put(dev_priv);
>   }
>   
>   void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
> @@ -777,12 +772,11 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>   		dev_priv->uncore.funcs.force_wake_get(dev_priv, \
>   						      FORCEWAKE_ALL); \
> -		val = __raw_i915_read##x(dev_priv, reg); \
> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, \
> -						      FORCEWAKE_ALL); \
> -	} else { \
> -		val = __raw_i915_read##x(dev_priv, reg); \
> +		dev_priv->uncore.forcewake_count++; \
> +		mod_timer_pinned(&dev_priv->uncore. , \
> +				 jiffies + 1); \

why timer, we can do a put after register read right?

Other changes looks fine to me
Reviewed-by: Deepak S <deepak.s@linux.intel.com>

>   	} \
> +	val = __raw_i915_read##x(dev_priv, reg); \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
>   	REG_READ_FOOTER; \
>   }

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

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

* Re: [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake
  2014-12-11 10:15   ` Chris Wilson
@ 2014-12-12 11:24     ` Deepak S
  2014-12-15  8:46     ` Daniel Vetter
  1 sibling, 0 replies; 57+ messages in thread
From: Deepak S @ 2014-12-12 11:24 UTC (permalink / raw
  To: Chris Wilson, intel-gfx


On Thursday 11 December 2014 03:45 PM, Chris Wilson wrote:
> On Fri, Dec 12, 2014 at 03:30:14PM +0530, Deepak S wrote:
>> On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
>>> From: Chris Wilson <chris@chris-wilson.co.uk>
>>>
>>> Calling intel_runtime_pm_put() is illegal from a soft-irq context, so
>>> revert the crude hack
>>>
>>> commit aa0b3b5bb8768c1a6a6788869d9c7015eae7e80c
>>> Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
>>> Date:   Tue Apr 1 14:55:07 2014 -0300
>>>
>>>      drm/i915: don't schedule force_wake_timer at gen6_read
>>>
>>> and apply the single line corrective instead.
>>>
>>> References: https://bugs.freedesktop.org/show_bug.cgi?id=80913
>>> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
>>> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
>>> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
>>> ---
>>> @@ -777,12 +772,11 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>>>   	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>>>   		dev_priv->uncore.funcs.force_wake_get(dev_priv, \
>>>   						      FORCEWAKE_ALL); \
>>> -		val = __raw_i915_read##x(dev_priv, reg); \
>>> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, \
>>> -						      FORCEWAKE_ALL); \
>>> -	} else { \
>>> -		val = __raw_i915_read##x(dev_priv, reg); \
>>> +		dev_priv->uncore.forcewake_count++; \
>>> +		mod_timer_pinned(&dev_priv->uncore. , \
>>> +				 jiffies + 1); \
>> why timer, we can do a put after register read right?
> The presumption is that we will do another mmio access requiring the
> forcewake very shortly, and we want to avoid the forcewake clear/ack
> cycle. So we defer dropping the forcewake until the end of the kernel
> context on this cpu (the goal being that as the scheduler switches back
> to the userspace context, we release the wakelock, it would be great if
> there was an explicit callback for that...).
> -Chris

Thanks Chris. got it :)


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

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

* Re: [PATCH 2/8] drm/i915: Assert that runtime pm is active on user fw access
  2014-12-08 18:27 ` [PATCH 2/8] drm/i915: Assert that runtime pm is active on user fw access Mika Kuoppala
@ 2014-12-12 11:39   ` Deepak S
  2014-12-11 11:53     ` Chris Wilson
  0 siblings, 1 reply; 57+ messages in thread
From: Deepak S @ 2014-12-12 11:39 UTC (permalink / raw
  To: intel-gfx


On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> From: Chris Wilson <chris@chris-wilson.co.uk>
>
> On user forcewake access, assert that runtime pm reference is held.
> Fix and cleanup the callsites accordingly.
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c  |  2 +
>   drivers/gpu/drm/i915/intel_display.c | 19 +--------
>   drivers/gpu/drm/i915/intel_lrc.c     | 53 ++-----------------------
>   drivers/gpu/drm/i915/intel_uncore.c  | 76 ++++++++++++------------------------
>   4 files changed, 31 insertions(+), 119 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index d0e445e..e142629 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -4250,6 +4250,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
>   	if (INTEL_INFO(dev)->gen < 6)
>   		return 0;
>   
> +	intel_runtime_pm_get(dev_priv);
>   	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	return 0;
> @@ -4264,6 +4265,7 @@ static int i915_forcewake_release(struct inode *inode, struct file *file)
>   		return 0;
>   
>   	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_runtime_pm_put(dev_priv);
>   
>   	return 0;
>   }
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index d5153a4..86c2885 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -7862,19 +7862,8 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
>   	/*
>   	 * Make sure we're not on PC8 state before disabling PC8, otherwise
>   	 * we'll hang the machine. To prevent PC8 state, just enable force_wake.
> -	 *
> -	 * The other problem is that hsw_restore_lcpll() is called as part of
> -	 * the runtime PM resume sequence, so we can't just call
> -	 * gen6_gt_force_wake_get() because that function calls
> -	 * intel_runtime_pm_get(), and we can't change the runtime PM refcount
> -	 * while we are on the resume sequence. So to solve this problem we have
> -	 * to call special forcewake code that doesn't touch runtime PM and
> -	 * doesn't enable the forcewake delayed work.
>   	 */
> -	spin_lock_irq(&dev_priv->uncore.lock);
> -	if (dev_priv->uncore.forcewake_count++ == 0)
> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL);
> -	spin_unlock_irq(&dev_priv->uncore.lock);
> +	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	if (val & LCPLL_POWER_DOWN_ALLOW) {
>   		val &= ~LCPLL_POWER_DOWN_ALLOW;
> @@ -7904,11 +7893,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
>   			DRM_ERROR("Switching back to LCPLL failed\n");
>   	}
>   
> -	/* See the big comment above. */
> -	spin_lock_irq(&dev_priv->uncore.lock);
> -	if (--dev_priv->uncore.forcewake_count == 0)
> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
> -	spin_unlock_irq(&dev_priv->uncore.lock);
> +	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
>   }
>   
>   /*
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index a82020e..fcb5140 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -284,7 +284,6 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
>   	struct drm_i915_private *dev_priv = dev->dev_private;
>   	uint64_t temp = 0;
>   	uint32_t desc[4];
> -	unsigned long flags;
>   
>   	/* XXX: You must always write both descriptors in the order below. */
>   	if (ctx_obj1)
> @@ -298,63 +297,17 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
>   	desc[3] = (u32)(temp >> 32);
>   	desc[2] = (u32)temp;
>   
> -	/* Set Force Wakeup bit to prevent GT from entering C6 while ELSP writes
> -	 * are in progress.
> -	 *
> -	 * The other problem is that we can't just call gen6_gt_force_wake_get()
> -	 * because that function calls intel_runtime_pm_get(), which might sleep.
> -	 * Instead, we do the runtime_pm_get/put when creating/destroying requests.
> -	 */
> -	spin_lock_irqsave(&dev_priv->uncore.lock, flags);
> -	if (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen >= 9) {
> -		if (dev_priv->uncore.fw_rendercount++ == 0)
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> -							      FORCEWAKE_RENDER);
> -		if (dev_priv->uncore.fw_mediacount++ == 0)
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> -							      FORCEWAKE_MEDIA);
> -		if (INTEL_INFO(dev)->gen >= 9) {
> -			if (dev_priv->uncore.fw_blittercount++ == 0)
> -				dev_priv->uncore.funcs.force_wake_get(dev_priv,
> -							FORCEWAKE_BLITTER);
> -		}
> -	} else {
> -		if (dev_priv->uncore.forcewake_count++ == 0)
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> -							      FORCEWAKE_ALL);
> -	}
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
> -
> +	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
>   	I915_WRITE(RING_ELSP(ring), desc[1]);
>   	I915_WRITE(RING_ELSP(ring), desc[0]);
>   	I915_WRITE(RING_ELSP(ring), desc[3]);
> +
>   	/* The context is automatically loaded after the following */
>   	I915_WRITE(RING_ELSP(ring), desc[2]);
>   
>   	/* ELSP is a wo register, so use another nearby reg for posting instead */
>   	POSTING_READ(RING_EXECLIST_STATUS(ring));
> -
> -	/* Release Force Wakeup (see the big comment above). */
> -	spin_lock_irqsave(&dev_priv->uncore.lock, flags);
> -	if (IS_CHERRYVIEW(dev) || INTEL_INFO(dev)->gen >= 9) {
> -		if (--dev_priv->uncore.fw_rendercount == 0)
> -			dev_priv->uncore.funcs.force_wake_put(dev_priv,
> -							      FORCEWAKE_RENDER);
> -		if (--dev_priv->uncore.fw_mediacount == 0)
> -			dev_priv->uncore.funcs.force_wake_put(dev_priv,
> -							      FORCEWAKE_MEDIA);
> -		if (INTEL_INFO(dev)->gen >= 9) {
> -			if (--dev_priv->uncore.fw_blittercount == 0)
> -				dev_priv->uncore.funcs.force_wake_put(dev_priv,
> -							FORCEWAKE_BLITTER);
> -		}
> -	} else {
> -		if (--dev_priv->uncore.forcewake_count == 0)
> -			dev_priv->uncore.funcs.force_wake_put(dev_priv,
> -							      FORCEWAKE_ALL);
> -	}
> -
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, flags);
> +	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
>   }
>   
>   static int execlists_update_context(struct drm_i915_gem_object *ctx_obj,
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 38ac389..a1ceb92 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -24,6 +24,8 @@
>   #include "i915_drv.h"
>   #include "intel_drv.h"
>   
> +#include <linux/pm_runtime.h>
> +
>   #define FORCEWAKE_ACK_TIMEOUT_MS 2
>   
>   #define __raw_i915_read8(dev_priv__, reg__) readb((dev_priv__)->regs + (reg__))
> @@ -247,10 +249,6 @@ static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
>   
>   static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>   {
> -	unsigned long irqflags;
> -
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -
>   	if (fw_engine & FORCEWAKE_RENDER &&
>   	    dev_priv->uncore.fw_rendercount++ != 0)
>   		fw_engine &= ~FORCEWAKE_RENDER;
> @@ -260,16 +258,10 @@ static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>   
>   	if (fw_engine)
>   		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine);
> -
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>   }
>   
>   static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   {
> -	unsigned long irqflags;
> -
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -
>   	if (fw_engine & FORCEWAKE_RENDER) {
>   		WARN_ON(!dev_priv->uncore.fw_rendercount);
>   		if (--dev_priv->uncore.fw_rendercount != 0)
> @@ -284,8 +276,6 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   
>   	if (fw_engine)
>   		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw_engine);
> -
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>   }
>   
>   static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
> @@ -380,10 +370,6 @@ __gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   static void
>   gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>   {
> -	unsigned long irqflags;
> -
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -
>   	if (FORCEWAKE_RENDER & fw_engine) {
>   		if (dev_priv->uncore.fw_rendercount++ == 0)
>   			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> @@ -401,17 +387,11 @@ gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>   			dev_priv->uncore.funcs.force_wake_get(dev_priv,
>   							FORCEWAKE_BLITTER);
>   	}
> -
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>   }
>   
>   static void
>   gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   {
> -	unsigned long irqflags;
> -
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -
>   	if (FORCEWAKE_RENDER & fw_engine) {
>   		WARN_ON(dev_priv->uncore.fw_rendercount == 0);
>   		if (--dev_priv->uncore.fw_rendercount == 0)
> @@ -432,8 +412,6 @@ gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   			dev_priv->uncore.funcs.force_wake_put(dev_priv,
>   							FORCEWAKE_BLITTER);
>   	}
> -
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>   }
>   
>   static void gen6_force_wake_timer(unsigned long arg)
> @@ -564,17 +542,20 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>   
>   	intel_runtime_pm_get(dev_priv);
>   

I think we need to remove "intel_runtime_pm_get" here?
I see runtime_put is removed from "gen6_gt_force_wake_put"

> -	/* Redirect to Gen9 specific routine */
> -	if (IS_GEN9(dev_priv->dev))
> -		return gen9_force_wake_get(dev_priv, fw_engine);
> -
> -	/* Redirect to VLV specific routine */
> -	if (IS_VALLEYVIEW(dev_priv->dev))
> -		return vlv_force_wake_get(dev_priv, fw_engine);
> +	WARN_ON(!pm_runtime_active(&dev_priv->dev->pdev->dev));
>   
>   	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -	if (dev_priv->uncore.forcewake_count++ == 0)
> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL);
> +
> +	if (IS_GEN9(dev_priv->dev)) {
> +		gen9_force_wake_get(dev_priv, fw_engine);
> +	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
> +		vlv_force_wake_get(dev_priv, fw_engine);
> +	} else {
> +		if (dev_priv->uncore.forcewake_count++ == 0)
> +			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> +							      FORCEWAKE_ALL);
> +	}
> +
>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>   }
>   
> @@ -588,31 +569,22 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   	if (!dev_priv->uncore.funcs.force_wake_put)
>   		return;
>   
> -	/* Redirect to Gen9 specific routine */
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> +
>   	if (IS_GEN9(dev_priv->dev)) {
>   		gen9_force_wake_put(dev_priv, fw_engine);
> -		goto out;
> -	}
> -
> -	/* Redirect to VLV specific routine */
> -	if (IS_VALLEYVIEW(dev_priv->dev)) {
> +	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
>   		vlv_force_wake_put(dev_priv, fw_engine);
> -		goto out;
> -	}
> -
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -	WARN_ON(!dev_priv->uncore.forcewake_count);
> -
> -	if (--dev_priv->uncore.forcewake_count == 0) {
> -		dev_priv->uncore.forcewake_count++;
> -		mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
> -				 jiffies + 1);
> +	} else {
> +		WARN_ON(!dev_priv->uncore.forcewake_count);
> +		if (--dev_priv->uncore.forcewake_count == 0) {
> +			dev_priv->uncore.forcewake_count++;
> +			mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
> +					 jiffies + 1);
> +		}
>   	}
>   
>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -
> -out:
> -	intel_runtime_pm_put(dev_priv);
>   }
>   
>   void assert_force_wake_inactive(struct drm_i915_private *dev_priv)

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

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

* Re: [PATCH 3/8] drm/i915: Skip uncore lock on earlier gens
  2014-12-08 18:27 ` [PATCH 3/8] drm/i915: Skip uncore lock on earlier gens Mika Kuoppala
@ 2014-12-12 11:57   ` Deepak S
  0 siblings, 0 replies; 57+ messages in thread
From: Deepak S @ 2014-12-12 11:57 UTC (permalink / raw
  To: intel-gfx


On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> From: Chris Wilson <chris@chris-wilson.co.uk>
>
> With gen < 6 we don't need to take uncore lock as we
> don't have anything to protect from concurrent access.
>
> v2: rebase and account for gen9 changes
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_uncore.c | 158 +++++++++++++++++++++---------------
>   1 file changed, 91 insertions(+), 67 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index a1ceb92..069fe7a 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -707,38 +707,61 @@ hsw_unclaimed_reg_detect(struct drm_i915_private *dev_priv)
>   	}
>   }
>   
> -#define REG_READ_HEADER(x) \
> -	unsigned long irqflags; \
> +#define GEN2_READ_HEADER(x) \
>   	u##x val = 0; \
> -	assert_device_not_suspended(dev_priv); \
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
> +	assert_device_not_suspended(dev_priv);
>   
> -#define REG_READ_FOOTER \
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
> +#define GEN2_READ_FOOTER \
>   	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
>   	return val
>   
> -#define __gen4_read(x) \
> +#define __gen2_read(x) \
>   static u##x \
> -gen4_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> -	REG_READ_HEADER(x); \
> +gen2_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> +	GEN2_READ_HEADER(x); \
>   	val = __raw_i915_read##x(dev_priv, reg); \
> -	REG_READ_FOOTER; \
> +	GEN2_READ_FOOTER; \
>   }
>   
>   #define __gen5_read(x) \
>   static u##x \
>   gen5_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> -	REG_READ_HEADER(x); \
> +	GEN2_READ_HEADER(x); \
>   	ilk_dummy_write(dev_priv); \
>   	val = __raw_i915_read##x(dev_priv, reg); \
> -	REG_READ_FOOTER; \
> +	GEN2_READ_FOOTER; \
>   }
>   
> +__gen5_read(8)
> +__gen5_read(16)
> +__gen5_read(32)
> +__gen5_read(64)
> +__gen2_read(8)
> +__gen2_read(16)
> +__gen2_read(32)
> +__gen2_read(64)
> +
> +#undef __gen5_read
> +#undef __gen2_read
> +
> +#undef GEN2_READ_FOOTER
> +#undef GEN2_READ_HEADER
> +
> +#define GEN6_READ_HEADER(x) \
> +	unsigned long irqflags; \
> +	u##x val = 0; \
> +	assert_device_not_suspended(dev_priv); \
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
> +
> +#define GEN6_READ_FOOTER \
> +	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); \
> +	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
> +	return val
> +
>   #define __gen6_read(x) \
>   static u##x \
>   gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> -	REG_READ_HEADER(x); \
> +	GEN6_READ_HEADER(x); \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \
>   	if (dev_priv->uncore.forcewake_count == 0 && \
>   	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> @@ -750,14 +773,14 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   	} \
>   	val = __raw_i915_read##x(dev_priv, reg); \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
> -	REG_READ_FOOTER; \
> +	GEN6_READ_FOOTER; \
>   }
>   
>   #define __vlv_read(x) \
>   static u##x \
>   vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   	unsigned fwengine = 0; \
> -	REG_READ_HEADER(x); \
> +	GEN6_READ_HEADER(x); \
>   	if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \
>   		if (dev_priv->uncore.fw_rendercount == 0) \
>   			fwengine = FORCEWAKE_RENDER; \
> @@ -770,14 +793,14 @@ vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   	val = __raw_i915_read##x(dev_priv, reg); \
>   	if (fwengine) \
>   		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
> -	REG_READ_FOOTER; \
> +	GEN6_READ_FOOTER; \
>   }
>   
>   #define __chv_read(x) \
>   static u##x \
>   chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   	unsigned fwengine = 0; \
> -	REG_READ_HEADER(x); \
> +	GEN6_READ_HEADER(x); \
>   	if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
>   		if (dev_priv->uncore.fw_rendercount == 0) \
>   			fwengine = FORCEWAKE_RENDER; \
> @@ -795,7 +818,7 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   	val = __raw_i915_read##x(dev_priv, reg); \
>   	if (fwengine) \
>   		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
> -	REG_READ_FOOTER; \
> +	GEN6_READ_FOOTER; \
>   }
>   
>   #define SKL_NEEDS_FORCE_WAKE(dev_priv, reg)	\
> @@ -804,7 +827,7 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   #define __gen9_read(x) \
>   static u##x \
>   gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> -	REG_READ_HEADER(x); \
> +	GEN6_READ_HEADER(x); \
>   	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>   		val = __raw_i915_read##x(dev_priv, reg); \
>   	} else { \
> @@ -830,7 +853,7 @@ gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   		if (fwengine) \
>   			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>   	} \
> -	REG_READ_FOOTER; \
> +	GEN6_READ_FOOTER; \
>   }
>   
>   __gen9_read(8)
> @@ -849,55 +872,66 @@ __gen6_read(8)
>   __gen6_read(16)
>   __gen6_read(32)
>   __gen6_read(64)
> -__gen5_read(8)
> -__gen5_read(16)
> -__gen5_read(32)
> -__gen5_read(64)
> -__gen4_read(8)
> -__gen4_read(16)
> -__gen4_read(32)
> -__gen4_read(64)
>   
>   #undef __gen9_read
>   #undef __chv_read
>   #undef __vlv_read
>   #undef __gen6_read
> -#undef __gen5_read
> -#undef __gen4_read
> -#undef REG_READ_FOOTER
> -#undef REG_READ_HEADER
> +#undef GEN6_READ_FOOTER
> +#undef GEN6_READ_HEADER
>   
> -#define REG_WRITE_HEADER \
> -	unsigned long irqflags; \
> +#define GEN2_WRITE_HEADER \
>   	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
>   	assert_device_not_suspended(dev_priv); \
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
>   
> -#define REG_WRITE_FOOTER \
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags)
> +#define GEN2_WRITE_FOOTER
>   
> -#define __gen4_write(x) \
> +#define __gen2_write(x) \
>   static void \
> -gen4_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
> -	REG_WRITE_HEADER; \
> +gen2_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
> +	GEN2_WRITE_HEADER; \
>   	__raw_i915_write##x(dev_priv, reg, val); \
> -	REG_WRITE_FOOTER; \
> +	GEN2_WRITE_FOOTER; \
>   }
>   
>   #define __gen5_write(x) \
>   static void \
>   gen5_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
> -	REG_WRITE_HEADER; \
> +	GEN2_WRITE_HEADER; \
>   	ilk_dummy_write(dev_priv); \
>   	__raw_i915_write##x(dev_priv, reg, val); \
> -	REG_WRITE_FOOTER; \
> +	GEN2_WRITE_FOOTER; \
>   }
>   
> +__gen5_write(8)
> +__gen5_write(16)
> +__gen5_write(32)
> +__gen5_write(64)
> +__gen2_write(8)
> +__gen2_write(16)
> +__gen2_write(32)
> +__gen2_write(64)
> +
> +#undef __gen5_write
> +#undef __gen2_write
> +
> +#undef GEN2_WRITE_FOOTER
> +#undef GEN2_WRITE_HEADER
> +
> +#define GEN6_WRITE_HEADER \
> +	unsigned long irqflags; \
> +	trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \
> +	assert_device_not_suspended(dev_priv); \
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags)
> +
> +#define GEN6_WRITE_FOOTER \
> +	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags)
> +
>   #define __gen6_write(x) \
>   static void \
>   gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
>   	u32 __fifo_ret = 0; \
> -	REG_WRITE_HEADER; \
> +	GEN6_WRITE_HEADER; \
>   	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>   		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
>   	} \
> @@ -905,14 +939,14 @@ gen6_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
>   	if (unlikely(__fifo_ret)) { \
>   		gen6_gt_check_fifodbg(dev_priv); \
>   	} \
> -	REG_WRITE_FOOTER; \
> +	GEN6_WRITE_FOOTER; \
>   }
>   
>   #define __hsw_write(x) \
>   static void \
>   hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
>   	u32 __fifo_ret = 0; \
> -	REG_WRITE_HEADER; \
> +	GEN6_WRITE_HEADER; \
>   	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>   		__fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
>   	} \
> @@ -923,7 +957,7 @@ hsw_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>   	} \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
>   	hsw_unclaimed_reg_detect(dev_priv); \
> -	REG_WRITE_FOOTER; \
> +	GEN6_WRITE_FOOTER; \
>   }
>   
>   static const u32 gen8_shadowed_regs[] = {
> @@ -950,7 +984,7 @@ static bool is_gen8_shadowed(struct drm_i915_private *dev_priv, u32 reg)
>   #define __gen8_write(x) \
>   static void \
>   gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
> -	REG_WRITE_HEADER; \
> +	GEN6_WRITE_HEADER; \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
>   	if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) { \
>   		if (dev_priv->uncore.forcewake_count == 0) \
> @@ -965,7 +999,7 @@ gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
>   	} \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
>   	hsw_unclaimed_reg_detect(dev_priv); \
> -	REG_WRITE_FOOTER; \
> +	GEN6_WRITE_FOOTER; \
>   }
>   
>   #define __chv_write(x) \
> @@ -973,7 +1007,7 @@ static void \
>   chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
>   	unsigned fwengine = 0; \
>   	bool shadowed = is_gen8_shadowed(dev_priv, reg); \
> -	REG_WRITE_HEADER; \
> +	GEN6_WRITE_HEADER; \
>   	if (!shadowed) { \
>   		if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
>   			if (dev_priv->uncore.fw_rendercount == 0) \
> @@ -993,7 +1027,7 @@ chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace)
>   	__raw_i915_write##x(dev_priv, reg, val); \
>   	if (fwengine) \
>   		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
> -	REG_WRITE_FOOTER; \
> +	GEN6_WRITE_FOOTER; \
>   }
>   
>   static const u32 gen9_shadowed_regs[] = {
> @@ -1023,7 +1057,7 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
>   static void \
>   gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>   		bool trace) { \
> -	REG_WRITE_HEADER; \
> +	GEN6_WRITE_HEADER; \
>   	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
>   			is_gen9_shadowed(dev_priv, reg)) { \
>   		__raw_i915_write##x(dev_priv, reg, val); \
> @@ -1052,7 +1086,7 @@ gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>   			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
>   					fwengine); \
>   	} \
> -	REG_WRITE_FOOTER; \
> +	GEN6_WRITE_FOOTER; \
>   }
>   
>   __gen9_write(8)
> @@ -1075,24 +1109,14 @@ __gen6_write(8)
>   __gen6_write(16)
>   __gen6_write(32)
>   __gen6_write(64)
> -__gen5_write(8)
> -__gen5_write(16)
> -__gen5_write(32)
> -__gen5_write(64)
> -__gen4_write(8)
> -__gen4_write(16)
> -__gen4_write(32)
> -__gen4_write(64)
>   
>   #undef __gen9_write
>   #undef __chv_write
>   #undef __gen8_write
>   #undef __hsw_write
>   #undef __gen6_write
> -#undef __gen5_write
> -#undef __gen4_write
> -#undef REG_WRITE_FOOTER
> -#undef REG_WRITE_HEADER
> +#undef GEN6_WRITE_FOOTER
> +#undef GEN6_WRITE_HEADER
>   
>   #define ASSIGN_WRITE_MMIO_VFUNCS(x) \
>   do { \
> @@ -1205,8 +1229,8 @@ void intel_uncore_init(struct drm_device *dev)
>   	case 4:
>   	case 3:
>   	case 2:
> -		ASSIGN_WRITE_MMIO_VFUNCS(gen4);
> -		ASSIGN_READ_MMIO_VFUNCS(gen4);
> +		ASSIGN_WRITE_MMIO_VFUNCS(gen2);
> +		ASSIGN_READ_MMIO_VFUNCS(gen2);
>   		break;
>   	}
>   

changes looks fine to me
Reviewed-by: Deepak S<deepak.s@linux.intel.com>


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

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

* Re: [PATCH 2/8] drm/i915: Assert that runtime pm is active on user fw access
  2014-12-11 11:53     ` Chris Wilson
@ 2014-12-12 11:59       ` Deepak S
  0 siblings, 0 replies; 57+ messages in thread
From: Deepak S @ 2014-12-12 11:59 UTC (permalink / raw
  To: Chris Wilson, intel-gfx


On Thursday 11 December 2014 05:23 PM, Chris Wilson wrote:
> On Fri, Dec 12, 2014 at 05:09:26PM +0530, Deepak S wrote:
>>> @@ -564,17 +542,20 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>>>   	intel_runtime_pm_get(dev_priv);
>> I think we need to remove "intel_runtime_pm_get" here?
>> I see runtime_put is removed from "gen6_gt_force_wake_put"
>>
>>> -	/* Redirect to Gen9 specific routine */
>>> -	if (IS_GEN9(dev_priv->dev))
>>> -		return gen9_force_wake_get(dev_priv, fw_engine);
>>> -
>>> -	/* Redirect to VLV specific routine */
>>> -	if (IS_VALLEYVIEW(dev_priv->dev))
>>> -		return vlv_force_wake_get(dev_priv, fw_engine);
>>> +	WARN_ON(!pm_runtime_active(&dev_priv->dev->pdev->dev));
> Indeed, the purpose of this patch was to remove the rpm_get() and
> replace it with this WARN_ON (and so make sure that all call paths here
> already held the rpm reference). Something went wrong in the rebase I
> hope.
> -Chris

Yeah, Looks like it got missed.

Hi Mika,
once we fix the issue, you can add my r-b, Other changes looks fine


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

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

* Re: [PATCH 4/8] drm/i915: Reduce duplicated forcewake logic
  2014-12-08 18:27 ` [PATCH 4/8] drm/i915: Reduce duplicated forcewake logic Mika Kuoppala
@ 2014-12-12 12:48   ` Deepak S
  2014-12-16 15:26     ` Mika Kuoppala
  0 siblings, 1 reply; 57+ messages in thread
From: Deepak S @ 2014-12-12 12:48 UTC (permalink / raw
  To: intel-gfx


On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> From: Chris Wilson <chris@chris-wilson.co.uk>
>
> Introduce a structure to track the individual forcewake domains and use
> that to eliminate duplicate logic.
>
> v2: - Rebase on latest dinq (Mika)
>      - for_each_fw_domain macro (Mika)
>      - Handle reset atomically, keeping the timer running (Mika)
>      - for_each_fw_domain parameter ordering (Chris)
>      - defer timer on new register access (Mika)
>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c |  65 +++---
>   drivers/gpu/drm/i915/i915_drv.h     |  54 +++--
>   drivers/gpu/drm/i915/intel_uncore.c | 410 +++++++++++++-----------------------
>   3 files changed, 208 insertions(+), 321 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index e142629..5cc838b 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1235,14 +1235,36 @@ static int ironlake_drpc_info(struct seq_file *m)
>   	return 0;
>   }
>   
> -static int vlv_drpc_info(struct seq_file *m)
> +static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
>   {
> +	struct drm_info_node *node = m->private;
> +	struct drm_device *dev = node->minor->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_uncore_forcewake_domain *fw_domain;
> +	const char *domain_names[] = {
> +		"render",
> +		"blitter",
> +		"media",
> +	};
> +	int i;
> +
> +	spin_lock_irq(&dev_priv->uncore.lock);
> +	for_each_fw_domain(fw_domain, dev_priv, i) {
> +		seq_printf(m, "%s.wake_count = %u\n",
> +			   domain_names[i],
> +			   fw_domain->wake_count);
> +	}
> +	spin_unlock_irq(&dev_priv->uncore.lock);
>   
> +	return 0;
> +}
> +
> +static int vlv_drpc_info(struct seq_file *m)
> +{
>   	struct drm_info_node *node = m->private;
>   	struct drm_device *dev = node->minor->dev;
>   	struct drm_i915_private *dev_priv = dev->dev_private;
>   	u32 rpmodectl1, rcctl1, pw_status;
> -	unsigned fw_rendercount = 0, fw_mediacount = 0;
>   
>   	intel_runtime_pm_get(dev_priv);
>   
> @@ -1274,22 +1296,11 @@ static int vlv_drpc_info(struct seq_file *m)
>   	seq_printf(m, "Media RC6 residency since boot: %u\n",
>   		   I915_READ(VLV_GT_MEDIA_RC6));
>   
> -	spin_lock_irq(&dev_priv->uncore.lock);
> -	fw_rendercount = dev_priv->uncore.fw_rendercount;
> -	fw_mediacount = dev_priv->uncore.fw_mediacount;
> -	spin_unlock_irq(&dev_priv->uncore.lock);
> -
> -	seq_printf(m, "Forcewake Render Count = %u\n", fw_rendercount);
> -	seq_printf(m, "Forcewake Media Count = %u\n", fw_mediacount);
> -
> -
> -	return 0;
> +	return i915_gen6_forcewake_count_info(m, NULL);
>   }
>   
> -
>   static int gen6_drpc_info(struct seq_file *m)
>   {
> -
>   	struct drm_info_node *node = m->private;
>   	struct drm_device *dev = node->minor->dev;
>   	struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -1303,7 +1314,7 @@ static int gen6_drpc_info(struct seq_file *m)
>   	intel_runtime_pm_get(dev_priv);
>   
>   	spin_lock_irq(&dev_priv->uncore.lock);
> -	forcewake_count = dev_priv->uncore.forcewake_count;
> +	forcewake_count = dev_priv->uncore.fw_domain[FW_DOMAIN_ID_RENDER].wake_count;
>   	spin_unlock_irq(&dev_priv->uncore.lock);
>   
>   	if (forcewake_count) {
> @@ -1931,30 +1942,6 @@ static int i915_execlists(struct seq_file *m, void *data)
>   	return 0;
>   }
>   
> -static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
> -{
> -	struct drm_info_node *node = m->private;
> -	struct drm_device *dev = node->minor->dev;
> -	struct drm_i915_private *dev_priv = dev->dev_private;
> -	unsigned forcewake_count = 0, fw_rendercount = 0, fw_mediacount = 0;
> -
> -	spin_lock_irq(&dev_priv->uncore.lock);
> -	if (IS_VALLEYVIEW(dev)) {
> -		fw_rendercount = dev_priv->uncore.fw_rendercount;
> -		fw_mediacount = dev_priv->uncore.fw_mediacount;
> -	} else
> -		forcewake_count = dev_priv->uncore.forcewake_count;
> -	spin_unlock_irq(&dev_priv->uncore.lock);
> -
> -	if (IS_VALLEYVIEW(dev)) {
> -		seq_printf(m, "fw_rendercount = %u\n", fw_rendercount);
> -		seq_printf(m, "fw_mediacount = %u\n", fw_mediacount);
> -	} else
> -		seq_printf(m, "forcewake count = %u\n", forcewake_count);
> -
> -	return 0;
> -}
> -
>   static const char *swizzle_string(unsigned swizzle)
>   {
>   	switch (swizzle) {
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 95dfa2d..410558a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -554,20 +554,45 @@ struct intel_uncore_funcs {
>   				uint64_t val, bool trace);
>   };
>   
> +enum {
> +	FW_DOMAIN_ID_RENDER = 0,
> +	FW_DOMAIN_ID_BLITTER,
> +	FW_DOMAIN_ID_MEDIA,
> +
> +	FW_DOMAIN_ID_COUNT
> +};
> +
>   struct intel_uncore {
>   	spinlock_t lock; /** lock is also taken in irq contexts. */
>   
>   	struct intel_uncore_funcs funcs;
>   
>   	unsigned fifo_count;
> -	unsigned forcewake_count;
> -
> -	unsigned fw_rendercount;
> -	unsigned fw_mediacount;
> -	unsigned fw_blittercount;
> -
> -	struct timer_list force_wake_timer;
> -};
> +	unsigned fw_domains;
> +
> +	struct intel_uncore_forcewake_domain {
> +		struct drm_i915_private *i915;
> +		int id;
> +		unsigned wake_count;
> +		struct timer_list timer;
> +	} fw_domain[FW_DOMAIN_ID_COUNT];
> +#define FORCEWAKE_RENDER	(1 << FW_DOMAIN_ID_RENDER)
> +#define FORCEWAKE_BLITTER	(1 << FW_DOMAIN_ID_BLITTER)
> +#define FORCEWAKE_MEDIA		(1 << FW_DOMAIN_ID_MEDIA)
> +#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | \
> +				 FORCEWAKE_BLITTER | \
> +				 FORCEWAKE_MEDIA)
> +};
> +
> +/* Iterate over initialised fw domains */
> +#define for_each_fw_domain_mask(domain__, mask__, dev_priv__, i__) \
> +	for ((i__) = 0, (domain__) = &(dev_priv__)->uncore.fw_domain[0]; \
> +	     (i__) < FW_DOMAIN_ID_COUNT; \
> +	     (i__)++, (domain__) = &(dev_priv__)->uncore.fw_domain[i__]) \
> +		if (((mask__) & (dev_priv__)->uncore.fw_domains) & (1 << (i__)))
> +
> +#define for_each_fw_domain(domain__, dev_priv__, i__) \
> +	for_each_fw_domain_mask(domain__, FORCEWAKE_ALL, dev_priv__, i__)
>   
>   #define DEV_INFO_FOR_EACH_FLAG(func, sep) \
>   	func(is_mobile) sep \
> @@ -2998,8 +3023,10 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
>    * must be set to prevent GT core from power down and stale values being
>    * returned.
>    */
> -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine);
> -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine);
> +void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
> +			    unsigned fw_domains);
> +void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
> +			    unsigned fw_domains);
>   void assert_force_wake_inactive(struct drm_i915_private *dev_priv);
>   
>   int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
> @@ -3031,13 +3058,6 @@ void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
>   int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val);
>   int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
>   
> -#define FORCEWAKE_RENDER	(1 << 0)
> -#define FORCEWAKE_MEDIA		(1 << 1)
> -#define FORCEWAKE_BLITTER	(1 << 2)
> -#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
> -					FORCEWAKE_BLITTER)
> -
> -
>   #define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
>   #define I915_WRITE8(reg, val)	dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
>   
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 069fe7a..85e46b0 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -67,7 +67,7 @@ static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv)
>   }
>   
>   static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
> -							int fw_engine)
> +				     int fw_engine)
>   {
>   	if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0,
>   			    FORCEWAKE_ACK_TIMEOUT_MS))
> @@ -93,7 +93,7 @@ static void __gen7_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
>   }
>   
>   static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv,
> -							int fw_engine)
> +					int fw_engine)
>   {
>   	u32 forcewake_ack;
>   
> @@ -129,7 +129,7 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
>   }
>   
>   static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
> -							int fw_engine)
> +				     int fw_engine)
>   {
>   	__raw_i915_write32(dev_priv, FORCEWAKE, 0);
>   	/* something from same cacheline, but !FORCEWAKE */
> @@ -138,7 +138,7 @@ static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
>   }
>   
>   static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv,
> -							int fw_engine)
> +					int fw_engine)
>   {
>   	__raw_i915_write32(dev_priv, FORCEWAKE_MT,
>   			   _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> @@ -187,7 +187,7 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
>   }
>   
>   static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
> -						int fw_engine)
> +				 int fw_engine)
>   {
>   	/* Check for Render Engine */
>   	if (FORCEWAKE_RENDER & fw_engine) {
> @@ -227,9 +227,8 @@ static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
>   }
>   
>   static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
> -					int fw_engine)
> +				 int fw_engine)
>   {
> -
>   	/* Check for Render Engine */
>   	if (FORCEWAKE_RENDER & fw_engine)
>   		__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
> @@ -247,37 +246,6 @@ static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
>   		gen6_gt_check_fifodbg(dev_priv);
>   }
>   
> -static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
> -{
> -	if (fw_engine & FORCEWAKE_RENDER &&
> -	    dev_priv->uncore.fw_rendercount++ != 0)
> -		fw_engine &= ~FORCEWAKE_RENDER;
> -	if (fw_engine & FORCEWAKE_MEDIA &&
> -	    dev_priv->uncore.fw_mediacount++ != 0)
> -		fw_engine &= ~FORCEWAKE_MEDIA;
> -
> -	if (fw_engine)
> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine);
> -}
> -
> -static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
> -{
> -	if (fw_engine & FORCEWAKE_RENDER) {
> -		WARN_ON(!dev_priv->uncore.fw_rendercount);
> -		if (--dev_priv->uncore.fw_rendercount != 0)
> -			fw_engine &= ~FORCEWAKE_RENDER;
> -	}
> -
> -	if (fw_engine & FORCEWAKE_MEDIA) {
> -		WARN_ON(!dev_priv->uncore.fw_mediacount);
> -		if (--dev_priv->uncore.fw_mediacount != 0)
> -			fw_engine &= ~FORCEWAKE_MEDIA;
> -	}
> -
> -	if (fw_engine)
> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw_engine);
> -}
> -
>   static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
>   {
>   	__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
> @@ -367,80 +335,40 @@ __gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
>   }
>   
> -static void
> -gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
> -{
> -	if (FORCEWAKE_RENDER & fw_engine) {
> -		if (dev_priv->uncore.fw_rendercount++ == 0)
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> -							FORCEWAKE_RENDER);
> -	}
> -
> -	if (FORCEWAKE_MEDIA & fw_engine) {
> -		if (dev_priv->uncore.fw_mediacount++ == 0)
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> -							FORCEWAKE_MEDIA);
> -	}
> -
> -	if (FORCEWAKE_BLITTER & fw_engine) {
> -		if (dev_priv->uncore.fw_blittercount++ == 0)
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> -							FORCEWAKE_BLITTER);
> -	}
> -}
> -
> -static void
> -gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
> -{
> -	if (FORCEWAKE_RENDER & fw_engine) {
> -		WARN_ON(dev_priv->uncore.fw_rendercount == 0);
> -		if (--dev_priv->uncore.fw_rendercount == 0)
> -			dev_priv->uncore.funcs.force_wake_put(dev_priv,
> -							FORCEWAKE_RENDER);
> -	}
> -
> -	if (FORCEWAKE_MEDIA & fw_engine) {
> -		WARN_ON(dev_priv->uncore.fw_mediacount == 0);
> -		if (--dev_priv->uncore.fw_mediacount == 0)
> -			dev_priv->uncore.funcs.force_wake_put(dev_priv,
> -							FORCEWAKE_MEDIA);
> -	}
> -
> -	if (FORCEWAKE_BLITTER & fw_engine) {
> -		WARN_ON(dev_priv->uncore.fw_blittercount == 0);
> -		if (--dev_priv->uncore.fw_blittercount == 0)
> -			dev_priv->uncore.funcs.force_wake_put(dev_priv,
> -							FORCEWAKE_BLITTER);
> -	}
> -}
> -
>   static void gen6_force_wake_timer(unsigned long arg)
>   {
> -	struct drm_i915_private *dev_priv = (void *)arg;
> +	struct intel_uncore_forcewake_domain *domain = (void *)arg;
>   	unsigned long irqflags;
>   
> -	assert_device_not_suspended(dev_priv);
> +	assert_device_not_suspended(domain->i915);
>   
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -	WARN_ON(!dev_priv->uncore.forcewake_count);
> +	spin_lock_irqsave(&domain->i915->uncore.lock, irqflags);
> +	WARN_ON(!domain->wake_count);
>   
> -	if (--dev_priv->uncore.forcewake_count == 0)
> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> +	if (--domain->wake_count == 0)
> +		domain->i915->uncore.funcs.force_wake_put(domain->i915,
> +							  1 << domain->id);
> +	spin_unlock_irqrestore(&domain->i915->uncore.lock, irqflags);
>   }
>   
>   void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>   {
>   	struct drm_i915_private *dev_priv = dev->dev_private;
> -	unsigned long irqflags;
> -
> -	if (del_timer_sync(&dev_priv->uncore.force_wake_timer))
> -		gen6_force_wake_timer((unsigned long)dev_priv);
> +	unsigned long irqflags, fw = 0;
> +	struct intel_uncore_forcewake_domain *domain;
> +	int id;
>   
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>   	/* Hold uncore.lock across reset to prevent any register access
>   	 * with forcewake not set correctly
>   	 */
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> +
> +	for_each_fw_domain(domain, dev_priv, id)
> +		if (domain->wake_count)
> +			fw |= 1 << id;
> +
> +	if (fw)
> +		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw);
>   

Hi Mika,

Why do put?

Is there a possibility of getting get & put count mismatch? for example,
1. We Read the register
    -> forcewake_get & start domain_timer. (count = 1)
2. Now we call "intel_uncore_forcewake_reset" which does a put. (count = 0)
3. now the domain_timer from step #1 comes (count -1)? right?
    or i am missing something here?


Others Looks fine to me.
Acked-by: Deepak S <deepak.s@linux.intel.com>

>   	if (IS_VALLEYVIEW(dev))
>   		vlv_force_wake_reset(dev_priv);
> @@ -454,28 +382,6 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>   		__gen9_gt_force_wake_mt_reset(dev_priv);
>   
>   	if (restore) { /* If reset with a user forcewake, try to restore */
> -		unsigned fw = 0;
> -
> -		if (IS_VALLEYVIEW(dev)) {
> -			if (dev_priv->uncore.fw_rendercount)
> -				fw |= FORCEWAKE_RENDER;
> -
> -			if (dev_priv->uncore.fw_mediacount)
> -				fw |= FORCEWAKE_MEDIA;
> -		} else if (IS_GEN9(dev)) {
> -			if (dev_priv->uncore.fw_rendercount)
> -				fw |= FORCEWAKE_RENDER;
> -
> -			if (dev_priv->uncore.fw_mediacount)
> -				fw |= FORCEWAKE_MEDIA;
> -
> -			if (dev_priv->uncore.fw_blittercount)
> -				fw |= FORCEWAKE_BLITTER;
> -		} else {
> -			if (dev_priv->uncore.forcewake_count)
> -				fw = FORCEWAKE_ALL;
> -		}
> -
>   		if (fw)
>   			dev_priv->uncore.funcs.force_wake_get(dev_priv, fw);
>   
> @@ -533,28 +439,28 @@ void intel_uncore_sanitize(struct drm_device *dev)
>    * be called at the beginning of the sequence followed by a call to
>    * gen6_gt_force_wake_put() at the end of the sequence.
>    */
> -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
> +void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
> +			    unsigned fw_domains)
>   {
>   	unsigned long irqflags;
> +	struct intel_uncore_forcewake_domain *domain;
> +	int id;
>   
>   	if (!dev_priv->uncore.funcs.force_wake_get)
>   		return;
>   
> -	intel_runtime_pm_get(dev_priv);
> -

you need to change this in Patch #2

>   	WARN_ON(!pm_runtime_active(&dev_priv->dev->pdev->dev));
>   
> +	fw_domains &= dev_priv->uncore.fw_domains;
> +
>   	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>   
> -	if (IS_GEN9(dev_priv->dev)) {
> -		gen9_force_wake_get(dev_priv, fw_engine);
> -	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
> -		vlv_force_wake_get(dev_priv, fw_engine);
> -	} else {
> -		if (dev_priv->uncore.forcewake_count++ == 0)
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
> -							      FORCEWAKE_ALL);
> -	}
> +	for_each_fw_domain_mask(domain, fw_domains, dev_priv, id)
> +		if (domain->wake_count++)
> +			fw_domains &= ~(1 << id);
> +
> +	if (fw_domains)
> +		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
>   
>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>   }
> @@ -562,26 +468,27 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>   /*
>    * see gen6_gt_force_wake_get()
>    */
> -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
> +void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
> +			    unsigned fw_domains)
>   {
>   	unsigned long irqflags;
> +	struct intel_uncore_forcewake_domain *domain;
> +	int id;
>   
>   	if (!dev_priv->uncore.funcs.force_wake_put)
>   		return;
>   
> +	fw_domains &= dev_priv->uncore.fw_domains;
> +
>   	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>   
> -	if (IS_GEN9(dev_priv->dev)) {
> -		gen9_force_wake_put(dev_priv, fw_engine);
> -	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
> -		vlv_force_wake_put(dev_priv, fw_engine);
> -	} else {
> -		WARN_ON(!dev_priv->uncore.forcewake_count);
> -		if (--dev_priv->uncore.forcewake_count == 0) {
> -			dev_priv->uncore.forcewake_count++;
> -			mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
> -					 jiffies + 1);
> -		}
> +	for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
> +		WARN_ON(!domain->wake_count);
> +		if (--domain->wake_count)
> +			continue;
> +
> +		domain->wake_count++;
> +		mod_timer_pinned(&domain->timer, jiffies + 1);
>   	}
>   
>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> @@ -589,10 +496,14 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>   
>   void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
>   {
> +	struct intel_uncore_forcewake_domain *domain;
> +	int i;
> +
>   	if (!dev_priv->uncore.funcs.force_wake_get)
>   		return;
>   
> -	WARN_ON(dev_priv->uncore.forcewake_count > 0);
> +	for_each_fw_domain(domain, dev_priv, i)
> +		WARN_ON(domain->wake_count);
>   }
>   
>   /* We give fast paths for the really cool registers */
> @@ -758,19 +669,36 @@ __gen2_read(64)
>   	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
>   	return val
>   
> +static inline void __force_wake_get(struct drm_i915_private *dev_priv,
> +				    unsigned fw_domains)
> +{
> +	struct intel_uncore_forcewake_domain *domain;
> +	int i;
> +
> +	if (WARN_ON(!fw_domains))
> +		return;
> +
> +	/* Ideally GCC would be constant-fold and eliminate this loop */
> +	for_each_fw_domain_mask(domain, fw_domains, dev_priv, i) {
> +		if (domain->wake_count)
> +			fw_domains &= ~(1 << i);
> +		else
> +			domain->wake_count++;
> +
> +		mod_timer_pinned(&domain->timer, jiffies + 1);
> +	}
> +
> +	if (fw_domains)
> +		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
> +}
> +
>   #define __gen6_read(x) \
>   static u##x \
>   gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   	GEN6_READ_HEADER(x); \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \
> -	if (dev_priv->uncore.forcewake_count == 0 && \
> -	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, \
> -						      FORCEWAKE_ALL); \
> -		dev_priv->uncore.forcewake_count++; \
> -		mod_timer_pinned(&dev_priv->uncore.force_wake_timer, \
> -				 jiffies + 1); \
> -	} \
> +	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) \
> +		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
>   	val = __raw_i915_read##x(dev_priv, reg); \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
>   	GEN6_READ_FOOTER; \
> @@ -779,45 +707,27 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   #define __vlv_read(x) \
>   static u##x \
>   vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> -	unsigned fwengine = 0; \
>   	GEN6_READ_HEADER(x); \
> -	if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \
> -		if (dev_priv->uncore.fw_rendercount == 0) \
> -			fwengine = FORCEWAKE_RENDER; \
> -	} else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) { \
> -		if (dev_priv->uncore.fw_mediacount == 0) \
> -			fwengine = FORCEWAKE_MEDIA; \
> -	}  \
> -	if (fwengine) \
> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
> +	if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) \
> +		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
> +	else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) \
> +		__force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
>   	val = __raw_i915_read##x(dev_priv, reg); \
> -	if (fwengine) \
> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>   	GEN6_READ_FOOTER; \
>   }
>   
>   #define __chv_read(x) \
>   static u##x \
>   chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> -	unsigned fwengine = 0; \
>   	GEN6_READ_HEADER(x); \
> -	if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
> -		if (dev_priv->uncore.fw_rendercount == 0) \
> -			fwengine = FORCEWAKE_RENDER; \
> -	} else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
> -		if (dev_priv->uncore.fw_mediacount == 0) \
> -			fwengine = FORCEWAKE_MEDIA; \
> -	} else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
> -		if (dev_priv->uncore.fw_rendercount == 0) \
> -			fwengine |= FORCEWAKE_RENDER; \
> -		if (dev_priv->uncore.fw_mediacount == 0) \
> -			fwengine |= FORCEWAKE_MEDIA; \
> -	} \
> -	if (fwengine) \
> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
> +	if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) \
> +		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
> +	else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) \
> +		__force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
> +	else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) \
> +		__force_wake_get(dev_priv, \
> +				 FORCEWAKE_RENDER | FORCEWAKE_MEDIA); \
>   	val = __raw_i915_read##x(dev_priv, reg); \
> -	if (fwengine) \
> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>   	GEN6_READ_FOOTER; \
>   }
>   
> @@ -827,32 +737,21 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   #define __gen9_read(x) \
>   static u##x \
>   gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> +	unsigned fw_engine; \
>   	GEN6_READ_HEADER(x); \
> -	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> -		val = __raw_i915_read##x(dev_priv, reg); \
> -	} else { \
> -		unsigned fwengine = 0; \
> -		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
> -			if (dev_priv->uncore.fw_rendercount == 0) \
> -				fwengine = FORCEWAKE_RENDER; \
> -		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
> -			if (dev_priv->uncore.fw_mediacount == 0) \
> -				fwengine = FORCEWAKE_MEDIA; \
> -		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
> -			if (dev_priv->uncore.fw_rendercount == 0) \
> -				fwengine |= FORCEWAKE_RENDER; \
> -			if (dev_priv->uncore.fw_mediacount == 0) \
> -				fwengine |= FORCEWAKE_MEDIA; \
> -		} else { \
> -			if (dev_priv->uncore.fw_blittercount == 0) \
> -				fwengine = FORCEWAKE_BLITTER; \
> -		} \
> -		if (fwengine) \
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
> -		val = __raw_i915_read##x(dev_priv, reg); \
> -		if (fwengine) \
> -			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
> -	} \
> +	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)))	\
> +		fw_engine = 0; \
> +	else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg))	\
> +		fw_engine = FORCEWAKE_RENDER; \
> +	else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \
> +		fw_engine = FORCEWAKE_MEDIA; \
> +	else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) \
> +		fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
> +	else \
> +		fw_engine = FORCEWAKE_BLITTER; \
> +	if (fw_engine) \
> +		__force_wake_get(dev_priv, fw_engine); \
> +	val = __raw_i915_read##x(dev_priv, reg); \
>   	GEN6_READ_FOOTER; \
>   }
>   
> @@ -986,17 +885,9 @@ static void \
>   gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
>   	GEN6_WRITE_HEADER; \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
> -	if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) { \
> -		if (dev_priv->uncore.forcewake_count == 0) \
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,	\
> -							      FORCEWAKE_ALL); \
> -		__raw_i915_write##x(dev_priv, reg, val); \
> -		if (dev_priv->uncore.forcewake_count == 0) \
> -			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
> -							      FORCEWAKE_ALL); \
> -	} else { \
> -		__raw_i915_write##x(dev_priv, reg, val); \
> -	} \
> +	if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) \
> +		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
> +	__raw_i915_write##x(dev_priv, reg, val); \
>   	hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
>   	hsw_unclaimed_reg_detect(dev_priv); \
>   	GEN6_WRITE_FOOTER; \
> @@ -1005,28 +896,17 @@ gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
>   #define __chv_write(x) \
>   static void \
>   chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
> -	unsigned fwengine = 0; \
>   	bool shadowed = is_gen8_shadowed(dev_priv, reg); \
>   	GEN6_WRITE_HEADER; \
>   	if (!shadowed) { \
> -		if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
> -			if (dev_priv->uncore.fw_rendercount == 0) \
> -				fwengine = FORCEWAKE_RENDER; \
> -		} else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
> -			if (dev_priv->uncore.fw_mediacount == 0) \
> -				fwengine = FORCEWAKE_MEDIA; \
> -		} else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
> -			if (dev_priv->uncore.fw_rendercount == 0) \
> -				fwengine |= FORCEWAKE_RENDER; \
> -			if (dev_priv->uncore.fw_mediacount == 0) \
> -				fwengine |= FORCEWAKE_MEDIA; \
> -		} \
> +		if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) \
> +			__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
> +		else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) \
> +			__force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
> +		else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) \
> +			__force_wake_get(dev_priv, FORCEWAKE_RENDER | FORCEWAKE_MEDIA); \
>   	} \
> -	if (fwengine) \
> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
>   	__raw_i915_write##x(dev_priv, reg, val); \
> -	if (fwengine) \
> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>   	GEN6_WRITE_FOOTER; \
>   }
>   
> @@ -1057,35 +937,22 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
>   static void \
>   gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>   		bool trace) { \
> +	unsigned fw_engine; \
>   	GEN6_WRITE_HEADER; \
> -	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
> -			is_gen9_shadowed(dev_priv, reg)) { \
> -		__raw_i915_write##x(dev_priv, reg, val); \
> -	} else { \
> -		unsigned fwengine = 0; \
> -		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
> -			if (dev_priv->uncore.fw_rendercount == 0) \
> -				fwengine = FORCEWAKE_RENDER; \
> -		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
> -			if (dev_priv->uncore.fw_mediacount == 0) \
> -				fwengine = FORCEWAKE_MEDIA; \
> -		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
> -			if (dev_priv->uncore.fw_rendercount == 0) \
> -				fwengine |= FORCEWAKE_RENDER; \
> -			if (dev_priv->uncore.fw_mediacount == 0) \
> -				fwengine |= FORCEWAKE_MEDIA; \
> -		} else { \
> -			if (dev_priv->uncore.fw_blittercount == 0) \
> -				fwengine = FORCEWAKE_BLITTER; \
> -		} \
> -		if (fwengine) \
> -			dev_priv->uncore.funcs.force_wake_get(dev_priv, \
> -					fwengine); \
> -		__raw_i915_write##x(dev_priv, reg, val); \
> -		if (fwengine) \
> -			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
> -					fwengine); \
> -	} \
> +	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) ||	\
> +	    is_gen9_shadowed(dev_priv, reg)) \
> +		fw_engine = 0; \
> +	else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) \
> +		fw_engine = FORCEWAKE_RENDER; \
> +	else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \
> +		fw_engine = FORCEWAKE_MEDIA; \
> +	else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) \
> +		fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
> +	else \
> +		fw_engine = FORCEWAKE_BLITTER; \
> +	if (fw_engine) \
> +		__force_wake_get(dev_priv, fw_engine); \
> +	__raw_i915_write##x(dev_priv, reg, val); \
>   	GEN6_WRITE_FOOTER; \
>   }
>   
> @@ -1137,21 +1004,24 @@ do { \
>   void intel_uncore_init(struct drm_device *dev)
>   {
>   	struct drm_i915_private *dev_priv = dev->dev_private;
> -
> -	setup_timer(&dev_priv->uncore.force_wake_timer,
> -		    gen6_force_wake_timer, (unsigned long)dev_priv);
> +	struct intel_uncore_forcewake_domain *domain;
> +	int i;
>   
>   	__intel_uncore_early_sanitize(dev, false);
>   
>   	if (IS_GEN9(dev)) {
>   		dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
>   		dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER |
> +			FORCEWAKE_BLITTER | FORCEWAKE_MEDIA;
>   	} else if (IS_VALLEYVIEW(dev)) {
>   		dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
>   		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER | FORCEWAKE_MEDIA;
>   	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
>   		dev_priv->uncore.funcs.force_wake_get = __gen7_gt_force_wake_mt_get;
>   		dev_priv->uncore.funcs.force_wake_put = __gen7_gt_force_wake_mt_put;
> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
>   	} else if (IS_IVYBRIDGE(dev)) {
>   		u32 ecobus;
>   
> @@ -1183,11 +1053,21 @@ void intel_uncore_init(struct drm_device *dev)
>   			dev_priv->uncore.funcs.force_wake_put =
>   				__gen6_gt_force_wake_put;
>   		}
> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
>   	} else if (IS_GEN6(dev)) {
>   		dev_priv->uncore.funcs.force_wake_get =
>   			__gen6_gt_force_wake_get;
>   		dev_priv->uncore.funcs.force_wake_put =
>   			__gen6_gt_force_wake_put;
> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
> +	}
> +
> +	for_each_fw_domain(domain, dev_priv, i) {
> +		domain->i915 = dev_priv;
> +		domain->id = i;
> +
> +		setup_timer(&domain->timer, gen6_force_wake_timer,
> +			    (unsigned long)domain);
>   	}
>   
>   	switch (INTEL_INFO(dev)->gen) {


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

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

* Re: [PATCH 5/8] drm/i915: Consolidate forcewake code
  2014-12-08 18:27 ` [PATCH 5/8] drm/i915: Consolidate forcewake code Mika Kuoppala
@ 2014-12-12 13:13   ` Deepak S
  0 siblings, 0 replies; 57+ messages in thread
From: Deepak S @ 2014-12-12 13:13 UTC (permalink / raw
  To: intel-gfx


On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> As we now have forcewake domains, take advantage of it
> by putting the differences in gen fw handling in data rather
> than in code.
>
> In past we have opencoded this quite extensively as the fw handling
> is in the fast path. There has also been a lot of cargo-culted
> copy'n'pasting from older gens to newer ones.
>
> Now when the releasing of the forcewake is done by deferred timer,
> it gives chance to consolidate more. Due to the frequency of actual hw
> access being significantly less.
>
> Take advantage of this and generalize the fw handling code
> as much as possible. But we still aim to keep the forcewake sequence
> particularities for each gen intact. So the access pattern
> to fw engines should remain the same.
>
> v2: - s/old_ack/clear_ack (Chris)
>      - s/post_read/posting_read (Chris)
>      - less polite commit msg (Chris)
>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c |   7 +-
>   drivers/gpu/drm/i915/i915_drv.h     |   7 +
>   drivers/gpu/drm/i915/intel_uncore.c | 469 ++++++++++++++++--------------------
>   3 files changed, 212 insertions(+), 271 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 5cc838b..93390c9 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1241,17 +1241,12 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
>   	struct drm_device *dev = node->minor->dev;
>   	struct drm_i915_private *dev_priv = dev->dev_private;
>   	struct intel_uncore_forcewake_domain *fw_domain;
> -	const char *domain_names[] = {
> -		"render",
> -		"blitter",
> -		"media",
> -	};
>   	int i;
>   
>   	spin_lock_irq(&dev_priv->uncore.lock);
>   	for_each_fw_domain(fw_domain, dev_priv, i) {
>   		seq_printf(m, "%s.wake_count = %u\n",
> -			   domain_names[i],
> +			   intel_uncore_forcewake_domain_to_str(i),
>   			   fw_domain->wake_count);
>   	}
>   	spin_unlock_irq(&dev_priv->uncore.lock);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 410558a..4263084 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -575,6 +575,12 @@ struct intel_uncore {
>   		int id;
>   		unsigned wake_count;
>   		struct timer_list timer;
> +		u32 reg_set;
> +		u32 val_set;
> +		u32 val_clear;
> +		u32 reg_ack;
> +		u32 reg_post;
> +		u32 val_reset;
>   	} fw_domain[FW_DOMAIN_ID_COUNT];
>   #define FORCEWAKE_RENDER	(1 << FW_DOMAIN_ID_RENDER)
>   #define FORCEWAKE_BLITTER	(1 << FW_DOMAIN_ID_BLITTER)
> @@ -2443,6 +2449,7 @@ extern void intel_uncore_init(struct drm_device *dev);
>   extern void intel_uncore_check_errors(struct drm_device *dev);
>   extern void intel_uncore_fini(struct drm_device *dev);
>   extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
> +const char *intel_uncore_forcewake_domain_to_str(const int domain_id);
>   
>   void
>   i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 85e46b0..e883790 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -42,6 +42,26 @@
>   
>   #define __raw_posting_read(dev_priv__, reg__) (void)__raw_i915_read32(dev_priv__, reg__)
>   
> +static const char * const forcewake_domain_names[] = {
> +	"render",
> +	"blitter",
> +	"media",
> +};
> +
> +const char *
> +intel_uncore_forcewake_domain_to_str(const int id)
> +{
> +	BUILD_BUG_ON((sizeof(forcewake_domain_names)/sizeof(const char *)) !=
> +		     FW_DOMAIN_ID_COUNT);
> +
> +	if (id >= 0 && id < FW_DOMAIN_ID_COUNT)
> +		return forcewake_domain_names[id];
> +
> +	WARN_ON(id);
> +
> +	return "unknown";
> +}
> +
>   static void
>   assert_device_not_suspended(struct drm_i915_private *dev_priv)
>   {
> @@ -49,73 +69,123 @@ assert_device_not_suspended(struct drm_i915_private *dev_priv)
>   		  "Device suspended\n");
>   }
>   
> -static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
> +static inline void
> +fw_domain_reset(const struct intel_uncore_forcewake_domain *d)
>   {
> -	/* w/a for a sporadic read returning 0 by waiting for the GT
> -	 * thread to wake up.
> -	 */
> -	if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) &
> -				GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 500))
> -		DRM_ERROR("GT thread status wait timed out\n");
> +	__raw_i915_write32(d->i915, d->reg_set, d->val_reset);
>   }
>   
> -static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv)
> +static inline void
> +fw_domain_arm_timer(struct intel_uncore_forcewake_domain *d)
>   {
> -	__raw_i915_write32(dev_priv, FORCEWAKE, 0);
> -	/* something from same cacheline, but !FORCEWAKE */
> -	__raw_posting_read(dev_priv, ECOBUS);
> +	mod_timer_pinned(&d->timer, jiffies + 1);
>   }
>   
> -static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
> -				     int fw_engine)
> +static inline void
> +fw_domain_wait_ack_clear(const struct intel_uncore_forcewake_domain *d)
>   {
> -	if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0,
> +	if (wait_for_atomic((__raw_i915_read32(d->i915, d->reg_ack) &
> +			     FORCEWAKE_KERNEL) == 0,
>   			    FORCEWAKE_ACK_TIMEOUT_MS))
> -		DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
> +		DRM_ERROR("%s: timed out waiting for forcewake ack to clear.\n",
> +			  intel_uncore_forcewake_domain_to_str(d->id));
> +}
>   
> -	__raw_i915_write32(dev_priv, FORCEWAKE, 1);
> -	/* something from same cacheline, but !FORCEWAKE */
> -	__raw_posting_read(dev_priv, ECOBUS);
> +static inline void
> +fw_domain_get(const struct intel_uncore_forcewake_domain *d)
> +{
> +	__raw_i915_write32(d->i915, d->reg_set, d->val_set);
> +}
>   
> -	if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1),
> +static inline void
> +fw_domain_wait_ack(const struct intel_uncore_forcewake_domain *d)
> +{
> +	if (wait_for_atomic((__raw_i915_read32(d->i915, d->reg_ack) &
> +			     FORCEWAKE_KERNEL),
>   			    FORCEWAKE_ACK_TIMEOUT_MS))
> -		DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
> +		DRM_ERROR("%s: timed out waiting for forcewake ack request.\n",
> +			  intel_uncore_forcewake_domain_to_str(d->id));
> +}
>   
> -	/* WaRsForcewakeWaitTC0:snb */
> -	__gen6_gt_wait_for_thread_c0(dev_priv);
> +static inline void
> +fw_domain_put(const struct intel_uncore_forcewake_domain *d)
> +{
> +	__raw_i915_write32(d->i915, d->reg_set, d->val_clear);
>   }
>   
> -static void __gen7_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
> +static inline void
> +fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
>   {
> -	__raw_i915_write32(dev_priv, FORCEWAKE_MT, _MASKED_BIT_DISABLE(0xffff));
> -	/* something from same cacheline, but !FORCEWAKE_MT */
> -	__raw_posting_read(dev_priv, ECOBUS);
> +	/* something from same cacheline, but not from the set register */
> +	if (d->reg_post)
> +		__raw_posting_read(d->i915, d->reg_post);
>   }
>   
> -static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv,
> -					int fw_engine)
> +static void
> +fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
>   {
> -	u32 forcewake_ack;
> +	struct intel_uncore_forcewake_domain *d;
> +	int id;
>   
> -	if (IS_HASWELL(dev_priv->dev) || IS_BROADWELL(dev_priv->dev))
> -		forcewake_ack = FORCEWAKE_ACK_HSW;
> -	else
> -		forcewake_ack = FORCEWAKE_MT_ACK;
> +	for_each_fw_domain_mask(d, fw_domains, dev_priv, id) {
> +		fw_domain_wait_ack_clear(d);
> +		fw_domain_get(d);
> +		fw_domain_posting_read(d);
> +		fw_domain_wait_ack(d);
> +	}
> +}
>   
> -	if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL) == 0,
> -			    FORCEWAKE_ACK_TIMEOUT_MS))
> -		DRM_ERROR("Timed out waiting for forcewake old ack to clear.\n");
> +static void
> +fw_domains_put(struct drm_i915_private *dev_priv, int fw_domains)
> +{
> +	struct intel_uncore_forcewake_domain *d;
> +	int id;
>   
> -	__raw_i915_write32(dev_priv, FORCEWAKE_MT,
> -			   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
> -	/* something from same cacheline, but !FORCEWAKE_MT */
> -	__raw_posting_read(dev_priv, ECOBUS);
> +	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
> +		fw_domain_put(d);
> +}
>   
> -	if (wait_for_atomic((__raw_i915_read32(dev_priv, forcewake_ack) & FORCEWAKE_KERNEL),
> -			    FORCEWAKE_ACK_TIMEOUT_MS))
> -		DRM_ERROR("Timed out waiting for forcewake to ack request.\n");
> +static void
> +fw_domains_posting_read(struct drm_i915_private *dev_priv)
> +{
> +	struct intel_uncore_forcewake_domain *d;
> +	int id;
> +
> +	/* No need to do for all, just do for first found */
> +	for_each_fw_domain(d, dev_priv, id) {
> +		fw_domain_posting_read(d);
> +		break;
> +	}
> +}
> +
> +static void
> +fw_domains_reset(struct drm_i915_private *dev_priv, const unsigned fw_domains)
> +{
> +	struct intel_uncore_forcewake_domain *d;
> +	int id;
> +
> +	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
> +		fw_domain_reset(d);
> +
> +	fw_domains_posting_read(dev_priv);
> +}
> +
> +static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
> +{
> +	/* w/a for a sporadic read returning 0 by waiting for the GT
> +	 * thread to wake up.
> +	 */
> +	if (wait_for_atomic_us((__raw_i915_read32(dev_priv, GEN6_GT_THREAD_STATUS_REG) &
> +				GEN6_GT_THREAD_STATUS_CORE_MASK) == 0, 500))
> +		DRM_ERROR("GT thread status wait timed out\n");
> +}
>   
> -	/* WaRsForcewakeWaitTC0:ivb,hsw */
> +static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
> +					      int fw_domains)
> +{
> +	fw_domains_get(dev_priv, fw_domains);
> +
> +	/* WaRsForcewakeWaitTC0:snb,ivb,hsw,bdw,vlv */
>   	__gen6_gt_wait_for_thread_c0(dev_priv);
>   }
>   
> @@ -128,27 +198,13 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
>   		__raw_i915_write32(dev_priv, GTFIFODBG, gtfifodbg);
>   }
>   
> -static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
> -				     int fw_engine)
> +static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
> +				     int fw_domains)
>   {
> -	__raw_i915_write32(dev_priv, FORCEWAKE, 0);
> -	/* something from same cacheline, but !FORCEWAKE */
> -	__raw_posting_read(dev_priv, ECOBUS);
> +	fw_domains_put(dev_priv, fw_domains);
>   	gen6_gt_check_fifodbg(dev_priv);
>   }
>   
> -static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv,
> -					int fw_engine)
> -{
> -	__raw_i915_write32(dev_priv, FORCEWAKE_MT,
> -			   _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> -	/* something from same cacheline, but !FORCEWAKE_MT */
> -	__raw_posting_read(dev_priv, ECOBUS);
> -
> -	if (IS_GEN7(dev_priv->dev))
> -		gen6_gt_check_fifodbg(dev_priv);
> -}
> -
>   static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
>   {
>   	int ret = 0;
> @@ -176,165 +232,16 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
>   	return ret;
>   }
>   
> -static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
> -{
> -	__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
> -			   _MASKED_BIT_DISABLE(0xffff));
> -	__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
> -			   _MASKED_BIT_DISABLE(0xffff));
> -	/* something from same cacheline, but !FORCEWAKE_VLV */
> -	__raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
> -}
> -
> -static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
> -				 int fw_engine)
> -{
> -	/* Check for Render Engine */
> -	if (FORCEWAKE_RENDER & fw_engine) {
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_VLV) &
> -						FORCEWAKE_KERNEL) == 0,
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
> -
> -		__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
> -				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
> -
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_VLV) &
> -						FORCEWAKE_KERNEL),
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: waiting for Render to ack.\n");
> -	}
> -
> -	/* Check for Media Engine */
> -	if (FORCEWAKE_MEDIA & fw_engine) {
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_MEDIA_VLV) &
> -						FORCEWAKE_KERNEL) == 0,
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
> -
> -		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
> -				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
> -
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_MEDIA_VLV) &
> -						FORCEWAKE_KERNEL),
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: waiting for media to ack.\n");
> -	}
> -}
> -
>   static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
>   				 int fw_engine)
>   {
> -	/* Check for Render Engine */
> -	if (FORCEWAKE_RENDER & fw_engine)
> -		__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
> -					_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> +	fw_domains_put(dev_priv, fw_engine);
> +	fw_domains_posting_read(dev_priv);
>   
> -
> -	/* Check for Media Engine */
> -	if (FORCEWAKE_MEDIA & fw_engine)
> -		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_VLV,
> -				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> -
> -	/* something from same cacheline, but !FORCEWAKE_VLV */
> -	__raw_posting_read(dev_priv, FORCEWAKE_ACK_VLV);
>   	if (!IS_CHERRYVIEW(dev_priv->dev))
>   		gen6_gt_check_fifodbg(dev_priv);
>   }
>   
> -static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
> -{
> -	__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
> -			_MASKED_BIT_DISABLE(0xffff));
> -
> -	__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
> -			_MASKED_BIT_DISABLE(0xffff));
> -
> -	__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
> -			_MASKED_BIT_DISABLE(0xffff));
> -}
> -
> -static void
> -__gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
> -{
> -	/* Check for Render Engine */
> -	if (FORCEWAKE_RENDER & fw_engine) {
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_RENDER_GEN9) &
> -						FORCEWAKE_KERNEL) == 0,
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: Render forcewake old ack to clear.\n");
> -
> -		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
> -				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
> -
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_RENDER_GEN9) &
> -						FORCEWAKE_KERNEL),
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: waiting for Render to ack.\n");
> -	}
> -
> -	/* Check for Media Engine */
> -	if (FORCEWAKE_MEDIA & fw_engine) {
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_MEDIA_GEN9) &
> -						FORCEWAKE_KERNEL) == 0,
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: Media forcewake old ack to clear.\n");
> -
> -		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
> -				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
> -
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_MEDIA_GEN9) &
> -						FORCEWAKE_KERNEL),
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: waiting for Media to ack.\n");
> -	}
> -
> -	/* Check for Blitter Engine */
> -	if (FORCEWAKE_BLITTER & fw_engine) {
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_BLITTER_GEN9) &
> -						FORCEWAKE_KERNEL) == 0,
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: Blitter forcewake old ack to clear.\n");
> -
> -		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
> -				   _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL));
> -
> -		if (wait_for_atomic((__raw_i915_read32(dev_priv,
> -						FORCEWAKE_ACK_BLITTER_GEN9) &
> -						FORCEWAKE_KERNEL),
> -					FORCEWAKE_ACK_TIMEOUT_MS))
> -			DRM_ERROR("Timed out: waiting for Blitter to ack.\n");
> -	}
> -}
> -
> -static void
> -__gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
> -{
> -	/* Check for Render Engine */
> -	if (FORCEWAKE_RENDER & fw_engine)
> -		__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
> -				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> -
> -	/* Check for Media Engine */
> -	if (FORCEWAKE_MEDIA & fw_engine)
> -		__raw_i915_write32(dev_priv, FORCEWAKE_MEDIA_GEN9,
> -				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> -
> -	/* Check for Blitter Engine */
> -	if (FORCEWAKE_BLITTER & fw_engine)
> -		__raw_i915_write32(dev_priv, FORCEWAKE_BLITTER_GEN9,
> -				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
> -}
> -
>   static void gen6_force_wake_timer(unsigned long arg)
>   {
>   	struct intel_uncore_forcewake_domain *domain = (void *)arg;
> @@ -358,28 +265,20 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>   	struct intel_uncore_forcewake_domain *domain;
>   	int id;
>   
> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>   	/* Hold uncore.lock across reset to prevent any register access
>   	 * with forcewake not set correctly
>   	 */
> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>   
>   	for_each_fw_domain(domain, dev_priv, id)
>   		if (domain->wake_count)
>   			fw |= 1 << id;
>   
> +	/* Don't stop the timer, just turn domains off for reset */
>   	if (fw)
>   		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw);
>   
> -	if (IS_VALLEYVIEW(dev))
> -		vlv_force_wake_reset(dev_priv);
> -	else if (IS_GEN6(dev) || IS_GEN7(dev))
> -		__gen6_gt_force_wake_reset(dev_priv);
> -
> -	if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev))
> -		__gen7_gt_force_wake_mt_reset(dev_priv);
> -
> -	if (IS_GEN9(dev))
> -		__gen9_gt_force_wake_mt_reset(dev_priv);
> +	fw_domains_reset(dev_priv, FORCEWAKE_ALL);
>   
>   	if (restore) { /* If reset with a user forcewake, try to restore */
>   		if (fw)
> @@ -488,7 +387,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
>   			continue;
>   
>   		domain->wake_count++;
> -		mod_timer_pinned(&domain->timer, jiffies + 1);
> +		fw_domain_arm_timer(domain);
>   	}
>   
>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> @@ -497,12 +396,12 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
>   void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_uncore_forcewake_domain *domain;
> -	int i;
> +	int id;
>   
>   	if (!dev_priv->uncore.funcs.force_wake_get)
>   		return;
>   
> -	for_each_fw_domain(domain, dev_priv, i)
> +	for_each_fw_domain(domain, dev_priv, id)
>   		WARN_ON(domain->wake_count);
>   }
>   
> @@ -673,19 +572,19 @@ static inline void __force_wake_get(struct drm_i915_private *dev_priv,
>   				    unsigned fw_domains)
>   {
>   	struct intel_uncore_forcewake_domain *domain;
> -	int i;
> +	int id;
>   
>   	if (WARN_ON(!fw_domains))
>   		return;
>   
>   	/* Ideally GCC would be constant-fold and eliminate this loop */
> -	for_each_fw_domain_mask(domain, fw_domains, dev_priv, i) {
> +	for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
>   		if (domain->wake_count)
> -			fw_domains &= ~(1 << i);
> +			fw_domains &= ~(1 << id);
>   		else
>   			domain->wake_count++;
>   
> -		mod_timer_pinned(&domain->timer, jiffies + 1);
> +		fw_domain_arm_timer(domain);
>   	}
>   
>   	if (fw_domains)
> @@ -1001,27 +900,75 @@ do { \
>   	dev_priv->uncore.funcs.mmio_readq = x##_read64; \
>   } while (0)
>   
> +
> +static void fw_domain_init(struct drm_i915_private *dev_priv,
> +			   u32 domain_id, u32 reg_set, u32 reg_ack)
> +{
> +	struct intel_uncore_forcewake_domain *d;
> +
> +	if (WARN_ON(domain_id >= FW_DOMAIN_ID_COUNT))
> +		return;
> +
> +	d = &dev_priv->uncore.fw_domain[domain_id];
> +
> +	d->reg_set = reg_set;
> +	d->reg_ack = reg_ack;
> +
> +	if (IS_GEN6(dev_priv)) {
> +		d->val_reset = 0;
> +		d->val_set = FORCEWAKE_KERNEL;
> +		d->val_clear = 0;
> +	} else {
> +		d->val_reset = _MASKED_BIT_DISABLE(0xffff);
> +		d->val_set = _MASKED_BIT_ENABLE(FORCEWAKE_KERNEL);
> +		d->val_clear = _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL);
> +	}
> +
> +	if (IS_VALLEYVIEW(dev_priv))
> +		d->reg_post = FORCEWAKE_ACK_VLV;
> +	else if (IS_GEN6(dev_priv) || IS_GEN7(dev_priv))
> +		d->reg_post = ECOBUS;
> +	else
> +		d->reg_post = 0;
> +
> +	d->i915 = dev_priv;
> +	d->id = domain_id;
> +
> +	setup_timer(&d->timer, gen6_force_wake_timer, (unsigned long)d);
> +
> +	dev_priv->uncore.fw_domains |= (1 << domain_id);
> +}
> +
>   void intel_uncore_init(struct drm_device *dev)
>   {
>   	struct drm_i915_private *dev_priv = dev->dev_private;
> -	struct intel_uncore_forcewake_domain *domain;
> -	int i;
>   
>   	__intel_uncore_early_sanitize(dev, false);
>   
>   	if (IS_GEN9(dev)) {
> -		dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
> -		dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
> -		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER |
> -			FORCEWAKE_BLITTER | FORCEWAKE_MEDIA;
> +		dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
> +		dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
> +		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
> +			       FORCEWAKE_RENDER_GEN9,
> +			       FORCEWAKE_ACK_RENDER_GEN9);
> +		fw_domain_init(dev_priv, FW_DOMAIN_ID_BLITTER,
> +			       FORCEWAKE_BLITTER_GEN9,
> +			       FORCEWAKE_ACK_BLITTER_GEN9);
> +		fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
> +			       FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
>   	} else if (IS_VALLEYVIEW(dev)) {
> -		dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
> +		dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
>   		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
> -		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER | FORCEWAKE_MEDIA;
> +		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
> +			       FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
> +		fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
> +			       FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV);
>   	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
> -		dev_priv->uncore.funcs.force_wake_get = __gen7_gt_force_wake_mt_get;
> -		dev_priv->uncore.funcs.force_wake_put = __gen7_gt_force_wake_mt_put;
> -		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
> +		dev_priv->uncore.funcs.force_wake_get =
> +			fw_domains_get_with_thread_status;
> +		dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
> +		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
> +			       FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
>   	} else if (IS_IVYBRIDGE(dev)) {
>   		u32 ecobus;
>   
> @@ -1034,40 +981,32 @@ void intel_uncore_init(struct drm_device *dev)
>   		 * (correctly) interpreted by the test below as MT
>   		 * forcewake being disabled.
>   		 */
> +		dev_priv->uncore.funcs.force_wake_get =
> +			fw_domains_get_with_thread_status;
> +		dev_priv->uncore.funcs.force_wake_put =
> +			fw_domains_put_with_fifo;
> +
> +		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
> +			       FORCEWAKE_MT, FORCEWAKE_MT_ACK);
>   		mutex_lock(&dev->struct_mutex);
> -		__gen7_gt_force_wake_mt_get(dev_priv, FORCEWAKE_ALL);
> +		fw_domains_get_with_thread_status(dev_priv, FORCEWAKE_ALL);
>   		ecobus = __raw_i915_read32(dev_priv, ECOBUS);
> -		__gen7_gt_force_wake_mt_put(dev_priv, FORCEWAKE_ALL);
> +		fw_domains_put_with_fifo(dev_priv, FORCEWAKE_ALL);
>   		mutex_unlock(&dev->struct_mutex);
>   
> -		if (ecobus & FORCEWAKE_MT_ENABLE) {
> -			dev_priv->uncore.funcs.force_wake_get =
> -				__gen7_gt_force_wake_mt_get;
> -			dev_priv->uncore.funcs.force_wake_put =
> -				__gen7_gt_force_wake_mt_put;
> -		} else {
> +		if (!(ecobus & FORCEWAKE_MT_ENABLE)) {
>   			DRM_INFO("No MT forcewake available on Ivybridge, this can result in issues\n");
>   			DRM_INFO("when using vblank-synced partial screen updates.\n");
> -			dev_priv->uncore.funcs.force_wake_get =
> -				__gen6_gt_force_wake_get;
> -			dev_priv->uncore.funcs.force_wake_put =
> -				__gen6_gt_force_wake_put;
> +			fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
> +				       FORCEWAKE, FORCEWAKE_ACK);
>   		}
> -		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
>   	} else if (IS_GEN6(dev)) {
>   		dev_priv->uncore.funcs.force_wake_get =
> -			__gen6_gt_force_wake_get;
> +			fw_domains_get_with_thread_status;
>   		dev_priv->uncore.funcs.force_wake_put =
> -			__gen6_gt_force_wake_put;
> -		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
> -	}
> -
> -	for_each_fw_domain(domain, dev_priv, i) {
> -		domain->i915 = dev_priv;
> -		domain->id = i;
> -
> -		setup_timer(&domain->timer, gen6_force_wake_timer,
> -			    (unsigned long)domain);
> +			fw_domains_put_with_fifo;
> +		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
> +			       FORCEWAKE, FORCEWAKE_ACK);
>   	}
>   
>   	switch (INTEL_INFO(dev)->gen) {
>

Looks fine
Reviewed-by: Deepak S <deepak.s@linux.intel.com>


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

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

* Re: [PATCH 6/8] drm/i915: Make vlv and chv forcewake put generic.
  2014-12-08 18:27 ` [PATCH 6/8] drm/i915: Make vlv and chv forcewake put generic Mika Kuoppala
@ 2014-12-12 13:16   ` Deepak S
  0 siblings, 0 replies; 57+ messages in thread
From: Deepak S @ 2014-12-12 13:16 UTC (permalink / raw
  To: intel-gfx


On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> These two were using a fw dance logic where posting read was done
> after both domain bit were set. When in other gens, the posting
> read is done immediately after setting the forcewake bit for each
> domain.
>
> Now bring these in line with other gens.
>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>   drivers/gpu/drm/i915/intel_uncore.c | 16 +++++-----------
>   1 file changed, 5 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index e883790..8021bec 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -232,16 +232,6 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
>   	return ret;
>   }
>   
> -static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
> -				 int fw_engine)
> -{
> -	fw_domains_put(dev_priv, fw_engine);
> -	fw_domains_posting_read(dev_priv);
> -
> -	if (!IS_CHERRYVIEW(dev_priv->dev))
> -		gen6_gt_check_fifodbg(dev_priv);
> -}
> -
>   static void gen6_force_wake_timer(unsigned long arg)
>   {
>   	struct intel_uncore_forcewake_domain *domain = (void *)arg;
> @@ -958,7 +948,11 @@ void intel_uncore_init(struct drm_device *dev)
>   			       FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
>   	} else if (IS_VALLEYVIEW(dev)) {
>   		dev_priv->uncore.funcs.force_wake_get = fw_domains_get;
> -		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
> +		if (!IS_CHERRYVIEW(dev))
> +			dev_priv->uncore.funcs.force_wake_put =
> +				fw_domains_put_with_fifo;
> +		else
> +			dev_priv->uncore.funcs.force_wake_put = fw_domains_put;
>   		fw_domain_init(dev_priv, FW_DOMAIN_ID_RENDER,
>   			       FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
>   		fw_domain_init(dev_priv, FW_DOMAIN_ID_MEDIA,
>
Looks fine
Reviewed-by: Deepak S<deepak.s@linux.intel.com>

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

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

* Re: [PATCH 7/8] drm/i915: Rename the forcewake get/put functions
  2014-12-08 18:27 ` [PATCH 7/8] drm/i915: Rename the forcewake get/put functions Mika Kuoppala
@ 2014-12-12 13:19   ` Deepak S
  0 siblings, 0 replies; 57+ messages in thread
From: Deepak S @ 2014-12-12 13:19 UTC (permalink / raw
  To: intel-gfx


On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> We have multiple forcewake domains now on recent gens. Change the
> function naming to reflect this.
>
> v2: More verbose names (Chris)
>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_debugfs.c     |  8 ++++----
>   drivers/gpu/drm/i915/i915_drv.c         |  2 +-
>   drivers/gpu/drm/i915/i915_drv.h         | 15 +++++----------
>   drivers/gpu/drm/i915/intel_display.c    |  4 ++--
>   drivers/gpu/drm/i915/intel_lrc.c        |  4 ++--
>   drivers/gpu/drm/i915/intel_pm.c         | 28 ++++++++++++++--------------
>   drivers/gpu/drm/i915/intel_ringbuffer.c |  4 ++--
>   drivers/gpu/drm/i915/intel_uncore.c     | 18 +++++++++---------
>   8 files changed, 39 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 93390c9..ecc4b42 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1052,7 +1052,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
>   		if (ret)
>   			goto out;
>   
> -		gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +		intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   		reqf = I915_READ(GEN6_RPNSWREQ);
>   		reqf &= ~GEN6_TURBO_DISABLE;
> @@ -1079,7 +1079,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
>   			cagf = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT;
>   		cagf *= GT_FREQUENCY_MULTIPLIER;
>   
> -		gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +		intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   		mutex_unlock(&dev->struct_mutex);
>   
>   		if (IS_GEN6(dev) || IS_GEN7(dev)) {
> @@ -4233,7 +4233,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file)
>   		return 0;
>   
>   	intel_runtime_pm_get(dev_priv);
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	return 0;
>   }
> @@ -4246,7 +4246,7 @@ static int i915_forcewake_release(struct inode *inode, struct file *file)
>   	if (INTEL_INFO(dev)->gen < 6)
>   		return 0;
>   
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   	intel_runtime_pm_put(dev_priv);
>   
>   	return 0;
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 706b122..011caa2 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1362,7 +1362,7 @@ static int intel_runtime_suspend(struct device *device)
>   	if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev)))
>   		return -ENODEV;
>   
> -	assert_force_wake_inactive(dev_priv);
> +	assert_forcewakes_inactive(dev_priv);
>   
>   	DRM_DEBUG_KMS("Suspending device\n");
>   
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 4263084..a2a8536 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2450,6 +2450,11 @@ extern void intel_uncore_check_errors(struct drm_device *dev);
>   extern void intel_uncore_fini(struct drm_device *dev);
>   extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
>   const char *intel_uncore_forcewake_domain_to_str(const int domain_id);
> +void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
> +				unsigned fw_domains);
> +void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
> +				unsigned fw_domains);
> +void assert_forcewakes_inactive(struct drm_i915_private *dev_priv);
>   
>   void
>   i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
> @@ -3026,16 +3031,6 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
>   					    struct drm_device *dev,
>   					    struct intel_display_error_state *error);
>   
> -/* On SNB platform, before reading ring registers forcewake bit
> - * must be set to prevent GT core from power down and stale values being
> - * returned.
> - */
> -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
> -			    unsigned fw_domains);
> -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
> -			    unsigned fw_domains);
> -void assert_force_wake_inactive(struct drm_i915_private *dev_priv);
> -
>   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);
>   
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 86c2885..d2d60f0 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -7863,7 +7863,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
>   	 * Make sure we're not on PC8 state before disabling PC8, otherwise
>   	 * we'll hang the machine. To prevent PC8 state, just enable force_wake.
>   	 */
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	if (val & LCPLL_POWER_DOWN_ALLOW) {
>   		val &= ~LCPLL_POWER_DOWN_ALLOW;
> @@ -7893,7 +7893,7 @@ static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
>   			DRM_ERROR("Switching back to LCPLL failed\n");
>   	}
>   
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   }
>   
>   /*
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index fcb5140..be9d00b 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -297,7 +297,7 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
>   	desc[3] = (u32)(temp >> 32);
>   	desc[2] = (u32)temp;
>   
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   	I915_WRITE(RING_ELSP(ring), desc[1]);
>   	I915_WRITE(RING_ELSP(ring), desc[0]);
>   	I915_WRITE(RING_ELSP(ring), desc[3]);
> @@ -307,7 +307,7 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
>   
>   	/* ELSP is a wo register, so use another nearby reg for posting instead */
>   	POSTING_READ(RING_EXECLIST_STATUS(ring));
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   }
>   
>   static int execlists_update_context(struct drm_i915_gem_object *ctx_obj,
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 78911e2..64e06a3 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -228,7 +228,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)
>   
>   	/* Blitter is part of Media powerwell on VLV. No impact of
>   	 * his param in other platforms for now */
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_MEDIA);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_MEDIA);
>   
>   	blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
>   	blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
> @@ -241,7 +241,7 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)
>   	I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
>   	POSTING_READ(GEN6_BLITTER_ECOSKPD);
>   
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_MEDIA);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_MEDIA);
>   }
>   
>   static void ironlake_enable_fbc(struct drm_crtc *crtc)
> @@ -4541,11 +4541,11 @@ static void valleyview_disable_rps(struct drm_device *dev)
>   
>   	/* we're doing forcewake before Disabling RC6,
>   	 * This what the BIOS expects when going into suspend */
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	I915_WRITE(GEN6_RC_CONTROL, 0);
>   
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   }
>   
>   static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
> @@ -4663,7 +4663,7 @@ static void gen9_enable_rps(struct drm_device *dev)
>   
>   	/* 1b: Get forcewake during program sequence. Although the driver
>   	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	/* 2a: Disable RC states. */
>   	I915_WRITE(GEN6_RC_CONTROL, 0);
> @@ -4686,7 +4686,7 @@ static void gen9_enable_rps(struct drm_device *dev)
>   				   GEN6_RC_CTL_EI_MODE(1) |
>   				   rc6_mask);
>   
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   
>   }
>   
> @@ -4702,7 +4702,7 @@ static void gen8_enable_rps(struct drm_device *dev)
>   
>   	/* 1c & 1d: Get forcewake during program sequence. Although the driver
>   	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	/* 2a: Disable RC states. */
>   	I915_WRITE(GEN6_RC_CONTROL, 0);
> @@ -4769,7 +4769,7 @@ static void gen8_enable_rps(struct drm_device *dev)
>   	dev_priv->rps.power = HIGH_POWER; /* force a reset */
>   	gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
>   
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   }
>   
>   static void gen6_enable_rps(struct drm_device *dev)
> @@ -4797,7 +4797,7 @@ static void gen6_enable_rps(struct drm_device *dev)
>   		I915_WRITE(GTFIFODBG, gtfifodbg);
>   	}
>   
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	/* Initialize rps frequencies */
>   	gen6_init_rps_frequencies(dev);
> @@ -4877,7 +4877,7 @@ static void gen6_enable_rps(struct drm_device *dev)
>   			DRM_ERROR("Couldn't fix incorrect rc6 voltage\n");
>   	}
>   
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   }
>   
>   static void __gen6_update_ring_freq(struct drm_device *dev)
> @@ -5296,7 +5296,7 @@ static void cherryview_enable_rps(struct drm_device *dev)
>   
>   	/* 1a & 1b: Get forcewake during program sequence. Although the driver
>   	 * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	/* 2a: Program RC6 thresholds.*/
>   	I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16);
> @@ -5364,7 +5364,7 @@ static void cherryview_enable_rps(struct drm_device *dev)
>   
>   	valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
>   
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   }
>   
>   static void valleyview_enable_rps(struct drm_device *dev)
> @@ -5385,7 +5385,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
>   	}
>   
>   	/* If VLV, Forcewake all wells, else re-direct to regular path */
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
>   	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
> @@ -5445,7 +5445,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
>   
>   	valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
>   
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   }
>   
>   void ironlake_teardown_rc6(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 3887f1a..210728f 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -536,7 +536,7 @@ static int init_ring_common(struct intel_engine_cs *ring)
>   	struct drm_i915_gem_object *obj = ringbuf->obj;
>   	int ret = 0;
>   
> -	gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>   
>   	if (!stop_ring(ring)) {
>   		/* G45 ring initialization often fails to reset head to zero */
> @@ -608,7 +608,7 @@ static int init_ring_common(struct intel_engine_cs *ring)
>   	memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
>   
>   out:
> -	gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
> +	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
>   
>   	return ret;
>   }
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 8021bec..509b9c9 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -232,7 +232,7 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
>   	return ret;
>   }
>   
> -static void gen6_force_wake_timer(unsigned long arg)
> +static void intel_uncore_fw_release_timer(unsigned long arg)
>   {
>   	struct intel_uncore_forcewake_domain *domain = (void *)arg;
>   	unsigned long irqflags;
> @@ -326,10 +326,10 @@ void intel_uncore_sanitize(struct drm_device *dev)
>    * Generally this is called implicitly by the register read function. However,
>    * if some sequence requires the GT to not power down then this function should
>    * be called at the beginning of the sequence followed by a call to
> - * gen6_gt_force_wake_put() at the end of the sequence.
> + * intel_uncore_forcewake_put() at the end of the sequence.
>    */
> -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
> -			    unsigned fw_domains)
> +void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
> +				unsigned fw_domains)
>   {
>   	unsigned long irqflags;
>   	struct intel_uncore_forcewake_domain *domain;
> @@ -355,10 +355,10 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
>   }
>   
>   /*
> - * see gen6_gt_force_wake_get()
> + * see intel_uncore_forcewake_get()
>    */
> -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
> -			    unsigned fw_domains)
> +void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
> +				unsigned fw_domains)
>   {
>   	unsigned long irqflags;
>   	struct intel_uncore_forcewake_domain *domain;
> @@ -383,7 +383,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>   }
>   
> -void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
> +void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_uncore_forcewake_domain *domain;
>   	int id;
> @@ -924,7 +924,7 @@ static void fw_domain_init(struct drm_i915_private *dev_priv,
>   	d->i915 = dev_priv;
>   	d->id = domain_id;
>   
> -	setup_timer(&d->timer, gen6_force_wake_timer, (unsigned long)d);
> +	setup_timer(&d->timer, intel_uncore_fw_release_timer, (unsigned long)d);
>   
>   	dev_priv->uncore.fw_domains |= (1 << domain_id);
>   }

Looks fine
Reviewed-by: Deepak S<deepak.s@linux.intel.com>

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

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

* Re: [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors
  2014-12-08 18:27 ` [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors Mika Kuoppala
  2014-12-09 11:46   ` [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers Mika Kuoppala
  2014-12-09 23:29   ` [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors shuang.he
@ 2014-12-12 13:20   ` Deepak S
  2 siblings, 0 replies; 57+ messages in thread
From: Deepak S @ 2014-12-12 13:20 UTC (permalink / raw
  To: intel-gfx


On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> Forcewake domain code uses unsigned int as a type for 'domains mask'.
> Bring the hw accessors inline with this.
>
> Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_drv.h     | 4 ++--
>   drivers/gpu/drm/i915/intel_uncore.c | 8 ++++----
>   2 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index a2a8536..917614e 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -535,9 +535,9 @@ struct drm_i915_display_funcs {
>   
>   struct intel_uncore_funcs {
>   	void (*force_wake_get)(struct drm_i915_private *dev_priv,
> -							int fw_engine);
> +							unsigned fw_domains);
>   	void (*force_wake_put)(struct drm_i915_private *dev_priv,
> -							int fw_engine);
> +							unsigned fw_domains);
>   
>   	uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
>   	uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 509b9c9..be02aab 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -122,7 +122,7 @@ fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
>   }
>   
>   static void
> -fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
> +fw_domains_get(struct drm_i915_private *dev_priv, unsigned fw_domains)
>   {
>   	struct intel_uncore_forcewake_domain *d;
>   	int id;
> @@ -136,7 +136,7 @@ fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
>   }
>   
>   static void
> -fw_domains_put(struct drm_i915_private *dev_priv, int fw_domains)
> +fw_domains_put(struct drm_i915_private *dev_priv, unsigned fw_domains)
>   {
>   	struct intel_uncore_forcewake_domain *d;
>   	int id;
> @@ -181,7 +181,7 @@ static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
>   }
>   
>   static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
> -					      int fw_domains)
> +					      unsigned fw_domains)
>   {
>   	fw_domains_get(dev_priv, fw_domains);
>   
> @@ -199,7 +199,7 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
>   }
>   
>   static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
> -				     int fw_domains)
> +				     unsigned fw_domains)
>   {
>   	fw_domains_put(dev_priv, fw_domains);
>   	gen6_gt_check_fifodbg(dev_priv);

Looks fine

Reviewed-by: Deepak S<deepak.s@linux.intel.com>

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

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

* Re: [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers
  2014-12-09 11:46   ` [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers Mika Kuoppala
  2014-12-09 13:32     ` Jani Nikula
@ 2014-12-12 13:21     ` Deepak S
  1 sibling, 0 replies; 57+ messages in thread
From: Deepak S @ 2014-12-12 13:21 UTC (permalink / raw
  To: intel-gfx


On Tuesday 09 December 2014 05:16 PM, Mika Kuoppala wrote:
> Make the domains and domain identifiers enums. To emphasize
> the difference in order to avoid mistakes.
>
> Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_drv.h     | 41 +++++++++++++++++----------------
>   drivers/gpu/drm/i915/intel_uncore.c | 45 +++++++++++++++++++------------------
>   2 files changed, 45 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 0d47397..5c6c372 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -533,11 +533,28 @@ struct drm_i915_display_funcs {
>   	void (*enable_backlight)(struct intel_connector *connector);
>   };
>   
> +enum fw_domain_id {
> +	FW_DOMAIN_ID_RENDER = 0,
> +	FW_DOMAIN_ID_BLITTER,
> +	FW_DOMAIN_ID_MEDIA,
> +
> +	FW_DOMAIN_ID_COUNT
> +};
> +
> +enum fw_domains {
> +	FORCEWAKE_RENDER = (1 << FW_DOMAIN_ID_RENDER),
> +	FORCEWAKE_BLITTER = (1 << FW_DOMAIN_ID_BLITTER),
> +	FORCEWAKE_MEDIA	= (1 << FW_DOMAIN_ID_MEDIA),
> +	FORCEWAKE_ALL = (FORCEWAKE_RENDER |
> +			 FORCEWAKE_BLITTER |
> +			 FORCEWAKE_MEDIA)
> +};
> +
>   struct intel_uncore_funcs {
>   	void (*force_wake_get)(struct drm_i915_private *dev_priv,
> -							int fw_engine);
> +							enum fw_domains domains);
>   	void (*force_wake_put)(struct drm_i915_private *dev_priv,
> -							int fw_engine);
> +							enum fw_domains domains);
>   
>   	uint8_t  (*mmio_readb)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
>   	uint16_t (*mmio_readw)(struct drm_i915_private *dev_priv, off_t offset, bool trace);
> @@ -554,25 +571,17 @@ struct intel_uncore_funcs {
>   				uint64_t val, bool trace);
>   };
>   
> -enum {
> -	FW_DOMAIN_ID_RENDER = 0,
> -	FW_DOMAIN_ID_BLITTER,
> -	FW_DOMAIN_ID_MEDIA,
> -
> -	FW_DOMAIN_ID_COUNT
> -};
> -
>   struct intel_uncore {
>   	spinlock_t lock; /** lock is also taken in irq contexts. */
>   
>   	struct intel_uncore_funcs funcs;
>   
>   	unsigned fifo_count;
> -	unsigned fw_domains;
> +	enum fw_domains fw_domains;
>   
>   	struct intel_uncore_forcewake_domain {
>   		struct drm_i915_private *i915;
> -		int id;
> +		enum fw_domain_id id;
>   		unsigned wake_count;
>   		struct timer_list timer;
>   		u32 reg_set;
> @@ -582,12 +591,6 @@ struct intel_uncore {
>   		u32 reg_post;
>   		u32 val_reset;
>   	} fw_domain[FW_DOMAIN_ID_COUNT];
> -#define FORCEWAKE_RENDER	(1 << FW_DOMAIN_ID_RENDER)
> -#define FORCEWAKE_BLITTER	(1 << FW_DOMAIN_ID_BLITTER)
> -#define FORCEWAKE_MEDIA		(1 << FW_DOMAIN_ID_MEDIA)
> -#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | \
> -				 FORCEWAKE_BLITTER | \
> -				 FORCEWAKE_MEDIA)
>   };
>   
>   /* Iterate over initialised fw domains */
> @@ -2449,7 +2452,7 @@ extern void intel_uncore_init(struct drm_device *dev);
>   extern void intel_uncore_check_errors(struct drm_device *dev);
>   extern void intel_uncore_fini(struct drm_device *dev);
>   extern void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore);
> -const char *intel_uncore_forcewake_domain_to_str(const int domain_id);
> +const char *intel_uncore_forcewake_domain_to_str(const enum fw_domain_id id);
>   void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
>   				unsigned fw_domains);
>   void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 509b9c9..e802486 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -49,7 +49,7 @@ static const char * const forcewake_domain_names[] = {
>   };
>   
>   const char *
> -intel_uncore_forcewake_domain_to_str(const int id)
> +intel_uncore_forcewake_domain_to_str(const enum fw_domain_id id)
>   {
>   	BUILD_BUG_ON((sizeof(forcewake_domain_names)/sizeof(const char *)) !=
>   		     FW_DOMAIN_ID_COUNT);
> @@ -122,10 +122,10 @@ fw_domain_posting_read(const struct intel_uncore_forcewake_domain *d)
>   }
>   
>   static void
> -fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
> +fw_domains_get(struct drm_i915_private *dev_priv, enum fw_domains fw_domains)
>   {
>   	struct intel_uncore_forcewake_domain *d;
> -	int id;
> +	enum fw_domain_id id;
>   
>   	for_each_fw_domain_mask(d, fw_domains, dev_priv, id) {
>   		fw_domain_wait_ack_clear(d);
> @@ -136,10 +136,10 @@ fw_domains_get(struct drm_i915_private *dev_priv, int fw_domains)
>   }
>   
>   static void
> -fw_domains_put(struct drm_i915_private *dev_priv, int fw_domains)
> +fw_domains_put(struct drm_i915_private *dev_priv, enum fw_domains fw_domains)
>   {
>   	struct intel_uncore_forcewake_domain *d;
> -	int id;
> +	enum fw_domain_id id;
>   
>   	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
>   		fw_domain_put(d);
> @@ -149,7 +149,7 @@ static void
>   fw_domains_posting_read(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_uncore_forcewake_domain *d;
> -	int id;
> +	enum fw_domain_id id;
>   
>   	/* No need to do for all, just do for first found */
>   	for_each_fw_domain(d, dev_priv, id) {
> @@ -159,10 +159,10 @@ fw_domains_posting_read(struct drm_i915_private *dev_priv)
>   }
>   
>   static void
> -fw_domains_reset(struct drm_i915_private *dev_priv, const unsigned fw_domains)
> +fw_domains_reset(struct drm_i915_private *dev_priv, enum fw_domains fw_domains)
>   {
>   	struct intel_uncore_forcewake_domain *d;
> -	int id;
> +	enum fw_domain_id id;
>   
>   	for_each_fw_domain_mask(d, fw_domains, dev_priv, id)
>   		fw_domain_reset(d);
> @@ -181,7 +181,7 @@ static void __gen6_gt_wait_for_thread_c0(struct drm_i915_private *dev_priv)
>   }
>   
>   static void fw_domains_get_with_thread_status(struct drm_i915_private *dev_priv,
> -					      int fw_domains)
> +					      enum fw_domains fw_domains)
>   {
>   	fw_domains_get(dev_priv, fw_domains);
>   
> @@ -199,7 +199,7 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
>   }
>   
>   static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
> -				     int fw_domains)
> +				     enum fw_domains fw_domains)
>   {
>   	fw_domains_put(dev_priv, fw_domains);
>   	gen6_gt_check_fifodbg(dev_priv);
> @@ -251,9 +251,10 @@ static void intel_uncore_fw_release_timer(unsigned long arg)
>   void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>   {
>   	struct drm_i915_private *dev_priv = dev->dev_private;
> -	unsigned long irqflags, fw = 0;
> +	unsigned long irqflags;
>   	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
> +	enum fw_domains fw = 0;
>   
>   	/* Hold uncore.lock across reset to prevent any register access
>   	 * with forcewake not set correctly
> @@ -329,11 +330,11 @@ void intel_uncore_sanitize(struct drm_device *dev)
>    * intel_uncore_forcewake_put() at the end of the sequence.
>    */
>   void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
> -				unsigned fw_domains)
> +				enum fw_domains fw_domains)
>   {
>   	unsigned long irqflags;
>   	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
>   
>   	if (!dev_priv->uncore.funcs.force_wake_get)
>   		return;
> @@ -358,11 +359,11 @@ void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
>    * see intel_uncore_forcewake_get()
>    */
>   void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
> -				unsigned fw_domains)
> +				enum fw_domains fw_domains)
>   {
>   	unsigned long irqflags;
>   	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
>   
>   	if (!dev_priv->uncore.funcs.force_wake_put)
>   		return;
> @@ -386,7 +387,7 @@ void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
>   void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
>   {
>   	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
>   
>   	if (!dev_priv->uncore.funcs.force_wake_get)
>   		return;
> @@ -559,10 +560,10 @@ __gen2_read(64)
>   	return val
>   
>   static inline void __force_wake_get(struct drm_i915_private *dev_priv,
> -				    unsigned fw_domains)
> +				    enum fw_domains fw_domains)
>   {
>   	struct intel_uncore_forcewake_domain *domain;
> -	int id;
> +	enum fw_domain_id id;
>   
>   	if (WARN_ON(!fw_domains))
>   		return;
> @@ -626,7 +627,7 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>   #define __gen9_read(x) \
>   static u##x \
>   gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> -	unsigned fw_engine; \
> +	enum fw_domains fw_engine; \
>   	GEN6_READ_HEADER(x); \
>   	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)))	\
>   		fw_engine = 0; \
> @@ -826,7 +827,7 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
>   static void \
>   gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>   		bool trace) { \
> -	unsigned fw_engine; \
> +	enum fw_domains fw_engine; \
>   	GEN6_WRITE_HEADER; \
>   	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) ||	\
>   	    is_gen9_shadowed(dev_priv, reg)) \
> @@ -892,7 +893,7 @@ do { \
>   
>   
>   static void fw_domain_init(struct drm_i915_private *dev_priv,
> -			   u32 domain_id, u32 reg_set, u32 reg_ack)
> +			   enum fw_domain_id domain_id, u32 reg_set, u32 reg_ack)
>   {
>   	struct intel_uncore_forcewake_domain *d;
>   

Looks fine
Reviewed-by: Deepak S<deepak.s@linux.intel.com>

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

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

* Re: [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake
  2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
                   ` (7 preceding siblings ...)
  2014-12-12 10:00 ` [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Deepak S
@ 2014-12-12 16:22 ` Paulo Zanoni
  2014-12-12 16:45   ` Chris Wilson
  8 siblings, 1 reply; 57+ messages in thread
From: Paulo Zanoni @ 2014-12-12 16:22 UTC (permalink / raw
  To: Mika Kuoppala
  Cc: Daniel Vetter, Intel Graphics Development, miku, Paulo Zanoni

2014-12-08 16:27 GMT-02:00 Mika Kuoppala <mika.kuoppala@linux.intel.com>:
> From: Chris Wilson <chris@chris-wilson.co.uk>
>
> Calling intel_runtime_pm_put() is illegal from a soft-irq context, so
> revert the crude hack
>
> commit aa0b3b5bb8768c1a6a6788869d9c7015eae7e80c
> Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Date:   Tue Apr 1 14:55:07 2014 -0300
>
>     drm/i915: don't schedule force_wake_timer at gen6_read
>
> and apply the single line corrective instead.
>
> References: https://bugs.freedesktop.org/show_bug.cgi?id=80913
> Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

This patch adds tons and tons of new WARNs when running
igt/tests/pm_rpm on BDW, including:

WARNING: CPU: 1 PID: 228 at drivers/gpu/drm/i915/intel_uncore.c:623
assert_force_wake_inactive+0x36/0x40 [i915]()
WARN_ON(dev_priv->uncore.forcewake_count > 0)


> ---
>  drivers/gpu/drm/i915/i915_drv.c     |  1 +
>  drivers/gpu/drm/i915/intel_uncore.c | 18 ++++++------------
>  2 files changed, 7 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 71be3c9..706b122 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1402,6 +1402,7 @@ static int intel_runtime_suspend(struct device *device)
>         }
>
>         del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
> +       intel_uncore_forcewake_reset(dev, false);
>         dev_priv->pm.suspended = true;
>
>         /*
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 46de8d7..38ac389 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -449,8 +449,6 @@ static void gen6_force_wake_timer(unsigned long arg)
>         if (--dev_priv->uncore.forcewake_count == 0)
>                 dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
>         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -
> -       intel_runtime_pm_put(dev_priv);
>  }
>
>  void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
> @@ -586,7 +584,6 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>  void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>  {
>         unsigned long irqflags;
> -       bool delayed = false;
>
>         if (!dev_priv->uncore.funcs.force_wake_put)
>                 return;
> @@ -603,21 +600,19 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>                 goto out;
>         }
>
> -
>         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>         WARN_ON(!dev_priv->uncore.forcewake_count);
>
>         if (--dev_priv->uncore.forcewake_count == 0) {
>                 dev_priv->uncore.forcewake_count++;
> -               delayed = true;
>                 mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
>                                  jiffies + 1);
>         }
> +
>         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>
>  out:
> -       if (!delayed)
> -               intel_runtime_pm_put(dev_priv);
> +       intel_runtime_pm_put(dev_priv);
>  }
>
>  void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
> @@ -777,12 +772,11 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>             NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>                 dev_priv->uncore.funcs.force_wake_get(dev_priv, \
>                                                       FORCEWAKE_ALL); \
> -               val = __raw_i915_read##x(dev_priv, reg); \
> -               dev_priv->uncore.funcs.force_wake_put(dev_priv, \
> -                                                     FORCEWAKE_ALL); \
> -       } else { \
> -               val = __raw_i915_read##x(dev_priv, reg); \
> +               dev_priv->uncore.forcewake_count++; \
> +               mod_timer_pinned(&dev_priv->uncore.force_wake_timer, \
> +                                jiffies + 1); \
>         } \
> +       val = __raw_i915_read##x(dev_priv, reg); \
>         hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
>         REG_READ_FOOTER; \
>  }
> --
> 1.9.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx



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

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

* Re: [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake
  2014-12-12 16:22 ` Paulo Zanoni
@ 2014-12-12 16:45   ` Chris Wilson
  0 siblings, 0 replies; 57+ messages in thread
From: Chris Wilson @ 2014-12-12 16:45 UTC (permalink / raw
  To: Paulo Zanoni
  Cc: Intel Graphics Development, miku, Paulo Zanoni, Daniel Vetter

On Fri, Dec 12, 2014 at 02:22:31PM -0200, Paulo Zanoni wrote:
> 2014-12-08 16:27 GMT-02:00 Mika Kuoppala <mika.kuoppala@linux.intel.com>:
> > From: Chris Wilson <chris@chris-wilson.co.uk>
> >
> > Calling intel_runtime_pm_put() is illegal from a soft-irq context, so
> > revert the crude hack
> >
> > commit aa0b3b5bb8768c1a6a6788869d9c7015eae7e80c
> > Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > Date:   Tue Apr 1 14:55:07 2014 -0300
> >
> >     drm/i915: don't schedule force_wake_timer at gen6_read
> >
> > and apply the single line corrective instead.
> >
> > References: https://bugs.freedesktop.org/show_bug.cgi?id=80913
> > Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> 
> This patch adds tons and tons of new WARNs when running
> igt/tests/pm_rpm on BDW, including:
> 
> WARNING: CPU: 1 PID: 228 at drivers/gpu/drm/i915/intel_uncore.c:623
> assert_force_wake_inactive+0x36/0x40 [i915]()
> WARN_ON(dev_priv->uncore.forcewake_count > 0)

The assert is in the incorrect place, it should be after the suspend
disables forcewake.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake
  2014-12-11 10:15   ` Chris Wilson
  2014-12-12 11:24     ` Deepak S
@ 2014-12-15  8:46     ` Daniel Vetter
  1 sibling, 0 replies; 57+ messages in thread
From: Daniel Vetter @ 2014-12-15  8:46 UTC (permalink / raw
  To: Chris Wilson, Deepak S, intel-gfx

On Thu, Dec 11, 2014 at 10:15:58AM +0000, Chris Wilson wrote:
> On Fri, Dec 12, 2014 at 03:30:14PM +0530, Deepak S wrote:
> > 
> > On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
> > >From: Chris Wilson <chris@chris-wilson.co.uk>
> > >
> > >Calling intel_runtime_pm_put() is illegal from a soft-irq context, so
> > >revert the crude hack
> > >
> > >commit aa0b3b5bb8768c1a6a6788869d9c7015eae7e80c
> > >Author: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > >Date:   Tue Apr 1 14:55:07 2014 -0300
> > >
> > >     drm/i915: don't schedule force_wake_timer at gen6_read
> > >
> > >and apply the single line corrective instead.
> > >
> > >References: https://bugs.freedesktop.org/show_bug.cgi?id=80913
> > >Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
> > >Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > >Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > >---
> > >@@ -777,12 +772,11 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
> > >  	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
> > >  		dev_priv->uncore.funcs.force_wake_get(dev_priv, \
> > >  						      FORCEWAKE_ALL); \
> > >-		val = __raw_i915_read##x(dev_priv, reg); \
> > >-		dev_priv->uncore.funcs.force_wake_put(dev_priv, \
> > >-						      FORCEWAKE_ALL); \
> > >-	} else { \
> > >-		val = __raw_i915_read##x(dev_priv, reg); \
> > >+		dev_priv->uncore.forcewake_count++; \
> > >+		mod_timer_pinned(&dev_priv->uncore. , \
> > >+				 jiffies + 1); \
> > 
> > why timer, we can do a put after register read right?
> 
> The presumption is that we will do another mmio access requiring the
> forcewake very shortly, and we want to avoid the forcewake clear/ack
> cycle. So we defer dropping the forcewake until the end of the kernel
> context on this cpu (the goal being that as the scheduler switches back
> to the userspace context, we release the wakelock, it would be great if
> there was an explicit callback for that...).

task_work might be what you're looking for. It's a horribly crude
interface though, so we'd need a small wrapper which either picks the task
work or timer. Which complicates the logic further since we then have
either or both lazy cleanup tasks pending.

Probably not worth the trouble.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 05/10] drm/i915: Disable 'get seqno' workaround for VLV
  2014-12-10 17:11     ` Dave Gordon
@ 2014-12-15  9:02       ` Daniel Vetter
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel Vetter @ 2014-12-15  9:02 UTC (permalink / raw
  To: Dave Gordon; +Cc: Intel-GFX

On Wed, Dec 10, 2014 at 05:11:09PM +0000, Dave Gordon wrote:
> On 10/12/14 10:42, Daniel Vetter wrote:
> > On Tue, Dec 09, 2014 at 12:59:08PM +0000, John.C.Harrison@Intel.com wrote:
> >> From: Dave Gordon <david.s.gordon@intel.com>
> >>
> >> There is a workaround for a hardware bug when reading the seqno from the status
> >> page. The bug does not exist on VLV however, the workaround was still being
> >> applied.
> > 
> > Given how much trouble the missed seqno fun cause us I'd like more
> > justification. What kind of (stress)-testing has been done here? And
> > you're sure you've never seen the little dmesg notice that the kernel
> > switched to polling?
> > -Daniel
> 
> This was necessary during VLV scheduler/preemption work, where we
> stressed the command streamer and IRQ path probably more than any of the
> usual tests, since we were looking for out-of-sequence anomalies.
> 
> The comments in gen6_ring_get_seqno() say it's to fix a bug on ivb/snb,
> and nothing in the BSpec suggests it's needed on later chips.
> 
> I think the problem was really in the fact that the workaround
> implemented in gen6_ring_get_seqno() was reading a nonshadowed register,
> therefore triggering forcewake activity, which was pretty buggy; so we
> took out the gen6-specific code before finding that there were still
> other problems with forcewake.
> 
> [Aside]
> The original intention appears to have been to generate a single I/O
> READ cycle, forcing all pending inbound DMA so be flushed to memory, so
> that the subsequent memory read would see the latest value. But now, it
> doesn't just generate a single cycle but a whole flurry of writes and
> polling reads, because reading ACTHD requires forcewake (unless that was
> wrong, and has now been fixed). So should gen6_ring_get_seqno() instead
> read a register that doesn't require forcewake? I wouldn't object to
> using it in perpetuity if it really only read one register!
> [/aside]

The original intention was to work around missed interrupts. We still have
them on pretty much everything gen6+. The workaround we've done for the
performance issues this causes is the lazy_coherency trick where we only
do this when waiting. It's all pretty nicely cargo-culted and not in
Bspec, but it's also fairly real. We've given up on debugging, current
kernels switch all wait_request calls to polling once the first missed
interrupt happened. See the logic around gpu_error.missed_irq_rings.

It might be that it's not real on vlv and only on big core machines, but
then we don't have a lot of people using vlv on upstream and reporting
bugs.

For added insult we don't have any nice way to reproduce this really :(
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two
  2014-12-10 17:15       ` Daniel Vetter
@ 2014-12-16 14:26         ` Dave Gordon
  2014-12-17 20:09           ` Daniel Vetter
  0 siblings, 1 reply; 57+ messages in thread
From: Dave Gordon @ 2014-12-16 14:26 UTC (permalink / raw
  To: Daniel Vetter, John.C.Harrison; +Cc: Intel-GFX

On 10/12/14 17:15, Daniel Vetter wrote:
> On Wed, Dec 10, 2014 at 04:33:14PM +0000, Dave Gordon wrote:
>> On 10/12/14 10:58, Daniel Vetter wrote:
>>> On Tue, Dec 09, 2014 at 12:59:11PM +0000, John.C.Harrison@Intel.com wrote:
>>>> From: John Harrison <John.C.Harrison@Intel.com>
>>>>
>>>> The scheduler decouples the submission of batch buffers to the driver with their
>>>> submission to the hardware. This basically means splitting the execbuffer()
>>>> function in half. This change rearranges some code ready for the split to occur.
>>>
>>> Now there's the curios question: Where will the split in top/bottom halves
>>> be? Without that I have no idea whether it makes sense and so can't review
>>> this patch. At least if the goal is to really prep for the scheduler and
>>> not just move a few lines around ;-)
>>> -Daniel
>>>
>> [snip]
>>>>  
>>>> +	i915_gem_execbuffer_move_to_active(vmas, ring);
>>>> +
>>>> +	/* To be split into two functions here... */
>>>> +
>>>> +	/* Unconditionally invalidate gpu caches and ensure that we do flush
>>>> +	 * any residual writes from the previous batch.
>>>> +	 */
>>>> +	ret = logical_ring_invalidate_all_caches(ringbuf);
>>
>> It'll be where the marker comment is above. Ahead of that point is stuff
>> to do with setting up software state; after that we're talking to h/w.
>> When the scheduler code goes it, it decouples the two by interposing at
>> this point. Then batches go into it with s/w state set up, but don't get
>> to talk to the h/w until they're selected for execution, possibly in a
>> different order.
> 
> Oops, I guess I need see a doctor to check my eyesight ;-)
> 
> Two comments about code that's still in the bottom half:
> - There's lots of input validation code still below that cutoff point
>   which needs to be moved above to still be able to return -EINVAL. Test
>   coverage is the critical part here, but I think we've closed most of our
>   gaps. I guess a future patch will address this?

Yes, all validation will end up before the batch gets pushed into the
scheduler queue. It had already been shuffled there in an earlier
version, but some of it then got relocated into less convenient places
during the legacy-vs-execlist split. So for now, the execbuffer path has
some common code (including early validation), then a split by
submission mechanism (with additional validation that may someday get
reconverged into the common section); and back to common code, and
/then/ the batches get passed to the scheduler, whereafter there won't
be any more EINVAL cases (though there will be other error cases, such
as ENOMEM). Then as and when batches are selected for execution, they're
passed to the specific backend submission mechanism code (which of
course won't contain any further validation code either).

> - retire_commands and so add_request are also in the cutoff. For shrinker
>   interactions to work seamlessly we need to have both the objects on the
>   active list and the request in the lists. So I expect more untangling
>   there to separate the request emission to rings from the bookkeeping
>   parts in add_request.
> 
> Also move_to_active will fall apart once we start to reorder requests I
> think. Need to think about this case more, but we definitely need some
> testcases with depencies and reordering by the scheduler.
> -Daniel

I'll leave the rest to John to comment on, as he's still rebasing this
section of the scheduler on top of all the other changes that have been
going on ...

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

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

* Re: [PATCH 4/8] drm/i915: Reduce duplicated forcewake logic
  2014-12-12 12:48   ` Deepak S
@ 2014-12-16 15:26     ` Mika Kuoppala
  0 siblings, 0 replies; 57+ messages in thread
From: Mika Kuoppala @ 2014-12-16 15:26 UTC (permalink / raw
  To: Deepak S, intel-gfx

Deepak S <deepak.s@linux.intel.com> writes:

> On Monday 08 December 2014 11:57 PM, Mika Kuoppala wrote:
>> From: Chris Wilson <chris@chris-wilson.co.uk>
>>
>> Introduce a structure to track the individual forcewake domains and use
>> that to eliminate duplicate logic.
>>
>> v2: - Rebase on latest dinq (Mika)
>>      - for_each_fw_domain macro (Mika)
>>      - Handle reset atomically, keeping the timer running (Mika)
>>      - for_each_fw_domain parameter ordering (Chris)
>>      - defer timer on new register access (Mika)
>>
>> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
>> Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
>> ---
>>   drivers/gpu/drm/i915/i915_debugfs.c |  65 +++---
>>   drivers/gpu/drm/i915/i915_drv.h     |  54 +++--
>>   drivers/gpu/drm/i915/intel_uncore.c | 410 +++++++++++++-----------------------
>>   3 files changed, 208 insertions(+), 321 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
>> index e142629..5cc838b 100644
>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>> @@ -1235,14 +1235,36 @@ static int ironlake_drpc_info(struct seq_file *m)
>>   	return 0;
>>   }
>>   
>> -static int vlv_drpc_info(struct seq_file *m)
>> +static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
>>   {
>> +	struct drm_info_node *node = m->private;
>> +	struct drm_device *dev = node->minor->dev;
>> +	struct drm_i915_private *dev_priv = dev->dev_private;
>> +	struct intel_uncore_forcewake_domain *fw_domain;
>> +	const char *domain_names[] = {
>> +		"render",
>> +		"blitter",
>> +		"media",
>> +	};
>> +	int i;
>> +
>> +	spin_lock_irq(&dev_priv->uncore.lock);
>> +	for_each_fw_domain(fw_domain, dev_priv, i) {
>> +		seq_printf(m, "%s.wake_count = %u\n",
>> +			   domain_names[i],
>> +			   fw_domain->wake_count);
>> +	}
>> +	spin_unlock_irq(&dev_priv->uncore.lock);
>>   
>> +	return 0;
>> +}
>> +
>> +static int vlv_drpc_info(struct seq_file *m)
>> +{
>>   	struct drm_info_node *node = m->private;
>>   	struct drm_device *dev = node->minor->dev;
>>   	struct drm_i915_private *dev_priv = dev->dev_private;
>>   	u32 rpmodectl1, rcctl1, pw_status;
>> -	unsigned fw_rendercount = 0, fw_mediacount = 0;
>>   
>>   	intel_runtime_pm_get(dev_priv);
>>   
>> @@ -1274,22 +1296,11 @@ static int vlv_drpc_info(struct seq_file *m)
>>   	seq_printf(m, "Media RC6 residency since boot: %u\n",
>>   		   I915_READ(VLV_GT_MEDIA_RC6));
>>   
>> -	spin_lock_irq(&dev_priv->uncore.lock);
>> -	fw_rendercount = dev_priv->uncore.fw_rendercount;
>> -	fw_mediacount = dev_priv->uncore.fw_mediacount;
>> -	spin_unlock_irq(&dev_priv->uncore.lock);
>> -
>> -	seq_printf(m, "Forcewake Render Count = %u\n", fw_rendercount);
>> -	seq_printf(m, "Forcewake Media Count = %u\n", fw_mediacount);
>> -
>> -
>> -	return 0;
>> +	return i915_gen6_forcewake_count_info(m, NULL);
>>   }
>>   
>> -
>>   static int gen6_drpc_info(struct seq_file *m)
>>   {
>> -
>>   	struct drm_info_node *node = m->private;
>>   	struct drm_device *dev = node->minor->dev;
>>   	struct drm_i915_private *dev_priv = dev->dev_private;
>> @@ -1303,7 +1314,7 @@ static int gen6_drpc_info(struct seq_file *m)
>>   	intel_runtime_pm_get(dev_priv);
>>   
>>   	spin_lock_irq(&dev_priv->uncore.lock);
>> -	forcewake_count = dev_priv->uncore.forcewake_count;
>> +	forcewake_count = dev_priv->uncore.fw_domain[FW_DOMAIN_ID_RENDER].wake_count;
>>   	spin_unlock_irq(&dev_priv->uncore.lock);
>>   
>>   	if (forcewake_count) {
>> @@ -1931,30 +1942,6 @@ static int i915_execlists(struct seq_file *m, void *data)
>>   	return 0;
>>   }
>>   
>> -static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
>> -{
>> -	struct drm_info_node *node = m->private;
>> -	struct drm_device *dev = node->minor->dev;
>> -	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	unsigned forcewake_count = 0, fw_rendercount = 0, fw_mediacount = 0;
>> -
>> -	spin_lock_irq(&dev_priv->uncore.lock);
>> -	if (IS_VALLEYVIEW(dev)) {
>> -		fw_rendercount = dev_priv->uncore.fw_rendercount;
>> -		fw_mediacount = dev_priv->uncore.fw_mediacount;
>> -	} else
>> -		forcewake_count = dev_priv->uncore.forcewake_count;
>> -	spin_unlock_irq(&dev_priv->uncore.lock);
>> -
>> -	if (IS_VALLEYVIEW(dev)) {
>> -		seq_printf(m, "fw_rendercount = %u\n", fw_rendercount);
>> -		seq_printf(m, "fw_mediacount = %u\n", fw_mediacount);
>> -	} else
>> -		seq_printf(m, "forcewake count = %u\n", forcewake_count);
>> -
>> -	return 0;
>> -}
>> -
>>   static const char *swizzle_string(unsigned swizzle)
>>   {
>>   	switch (swizzle) {
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index 95dfa2d..410558a 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -554,20 +554,45 @@ struct intel_uncore_funcs {
>>   				uint64_t val, bool trace);
>>   };
>>   
>> +enum {
>> +	FW_DOMAIN_ID_RENDER = 0,
>> +	FW_DOMAIN_ID_BLITTER,
>> +	FW_DOMAIN_ID_MEDIA,
>> +
>> +	FW_DOMAIN_ID_COUNT
>> +};
>> +
>>   struct intel_uncore {
>>   	spinlock_t lock; /** lock is also taken in irq contexts. */
>>   
>>   	struct intel_uncore_funcs funcs;
>>   
>>   	unsigned fifo_count;
>> -	unsigned forcewake_count;
>> -
>> -	unsigned fw_rendercount;
>> -	unsigned fw_mediacount;
>> -	unsigned fw_blittercount;
>> -
>> -	struct timer_list force_wake_timer;
>> -};
>> +	unsigned fw_domains;
>> +
>> +	struct intel_uncore_forcewake_domain {
>> +		struct drm_i915_private *i915;
>> +		int id;
>> +		unsigned wake_count;
>> +		struct timer_list timer;
>> +	} fw_domain[FW_DOMAIN_ID_COUNT];
>> +#define FORCEWAKE_RENDER	(1 << FW_DOMAIN_ID_RENDER)
>> +#define FORCEWAKE_BLITTER	(1 << FW_DOMAIN_ID_BLITTER)
>> +#define FORCEWAKE_MEDIA		(1 << FW_DOMAIN_ID_MEDIA)
>> +#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | \
>> +				 FORCEWAKE_BLITTER | \
>> +				 FORCEWAKE_MEDIA)
>> +};
>> +
>> +/* Iterate over initialised fw domains */
>> +#define for_each_fw_domain_mask(domain__, mask__, dev_priv__, i__) \
>> +	for ((i__) = 0, (domain__) = &(dev_priv__)->uncore.fw_domain[0]; \
>> +	     (i__) < FW_DOMAIN_ID_COUNT; \
>> +	     (i__)++, (domain__) = &(dev_priv__)->uncore.fw_domain[i__]) \
>> +		if (((mask__) & (dev_priv__)->uncore.fw_domains) & (1 << (i__)))
>> +
>> +#define for_each_fw_domain(domain__, dev_priv__, i__) \
>> +	for_each_fw_domain_mask(domain__, FORCEWAKE_ALL, dev_priv__, i__)
>>   
>>   #define DEV_INFO_FOR_EACH_FLAG(func, sep) \
>>   	func(is_mobile) sep \
>> @@ -2998,8 +3023,10 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
>>    * must be set to prevent GT core from power down and stale values being
>>    * returned.
>>    */
>> -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine);
>> -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine);
>> +void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
>> +			    unsigned fw_domains);
>> +void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
>> +			    unsigned fw_domains);
>>   void assert_force_wake_inactive(struct drm_i915_private *dev_priv);
>>   
>>   int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
>> @@ -3031,13 +3058,6 @@ void vlv_flisdsi_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
>>   int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val);
>>   int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val);
>>   
>> -#define FORCEWAKE_RENDER	(1 << 0)
>> -#define FORCEWAKE_MEDIA		(1 << 1)
>> -#define FORCEWAKE_BLITTER	(1 << 2)
>> -#define FORCEWAKE_ALL		(FORCEWAKE_RENDER | FORCEWAKE_MEDIA | \
>> -					FORCEWAKE_BLITTER)
>> -
>> -
>>   #define I915_READ8(reg)		dev_priv->uncore.funcs.mmio_readb(dev_priv, (reg), true)
>>   #define I915_WRITE8(reg, val)	dev_priv->uncore.funcs.mmio_writeb(dev_priv, (reg), (val), true)
>>   
>> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
>> index 069fe7a..85e46b0 100644
>> --- a/drivers/gpu/drm/i915/intel_uncore.c
>> +++ b/drivers/gpu/drm/i915/intel_uncore.c
>> @@ -67,7 +67,7 @@ static void __gen6_gt_force_wake_reset(struct drm_i915_private *dev_priv)
>>   }
>>   
>>   static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
>> -							int fw_engine)
>> +				     int fw_engine)
>>   {
>>   	if (wait_for_atomic((__raw_i915_read32(dev_priv, FORCEWAKE_ACK) & 1) == 0,
>>   			    FORCEWAKE_ACK_TIMEOUT_MS))
>> @@ -93,7 +93,7 @@ static void __gen7_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
>>   }
>>   
>>   static void __gen7_gt_force_wake_mt_get(struct drm_i915_private *dev_priv,
>> -							int fw_engine)
>> +					int fw_engine)
>>   {
>>   	u32 forcewake_ack;
>>   
>> @@ -129,7 +129,7 @@ static void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv)
>>   }
>>   
>>   static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
>> -							int fw_engine)
>> +				     int fw_engine)
>>   {
>>   	__raw_i915_write32(dev_priv, FORCEWAKE, 0);
>>   	/* something from same cacheline, but !FORCEWAKE */
>> @@ -138,7 +138,7 @@ static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
>>   }
>>   
>>   static void __gen7_gt_force_wake_mt_put(struct drm_i915_private *dev_priv,
>> -							int fw_engine)
>> +					int fw_engine)
>>   {
>>   	__raw_i915_write32(dev_priv, FORCEWAKE_MT,
>>   			   _MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
>> @@ -187,7 +187,7 @@ static void vlv_force_wake_reset(struct drm_i915_private *dev_priv)
>>   }
>>   
>>   static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
>> -						int fw_engine)
>> +				 int fw_engine)
>>   {
>>   	/* Check for Render Engine */
>>   	if (FORCEWAKE_RENDER & fw_engine) {
>> @@ -227,9 +227,8 @@ static void __vlv_force_wake_get(struct drm_i915_private *dev_priv,
>>   }
>>   
>>   static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
>> -					int fw_engine)
>> +				 int fw_engine)
>>   {
>> -
>>   	/* Check for Render Engine */
>>   	if (FORCEWAKE_RENDER & fw_engine)
>>   		__raw_i915_write32(dev_priv, FORCEWAKE_VLV,
>> @@ -247,37 +246,6 @@ static void __vlv_force_wake_put(struct drm_i915_private *dev_priv,
>>   		gen6_gt_check_fifodbg(dev_priv);
>>   }
>>   
>> -static void vlv_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>> -{
>> -	if (fw_engine & FORCEWAKE_RENDER &&
>> -	    dev_priv->uncore.fw_rendercount++ != 0)
>> -		fw_engine &= ~FORCEWAKE_RENDER;
>> -	if (fw_engine & FORCEWAKE_MEDIA &&
>> -	    dev_priv->uncore.fw_mediacount++ != 0)
>> -		fw_engine &= ~FORCEWAKE_MEDIA;
>> -
>> -	if (fw_engine)
>> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_engine);
>> -}
>> -
>> -static void vlv_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>> -{
>> -	if (fw_engine & FORCEWAKE_RENDER) {
>> -		WARN_ON(!dev_priv->uncore.fw_rendercount);
>> -		if (--dev_priv->uncore.fw_rendercount != 0)
>> -			fw_engine &= ~FORCEWAKE_RENDER;
>> -	}
>> -
>> -	if (fw_engine & FORCEWAKE_MEDIA) {
>> -		WARN_ON(!dev_priv->uncore.fw_mediacount);
>> -		if (--dev_priv->uncore.fw_mediacount != 0)
>> -			fw_engine &= ~FORCEWAKE_MEDIA;
>> -	}
>> -
>> -	if (fw_engine)
>> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw_engine);
>> -}
>> -
>>   static void __gen9_gt_force_wake_mt_reset(struct drm_i915_private *dev_priv)
>>   {
>>   	__raw_i915_write32(dev_priv, FORCEWAKE_RENDER_GEN9,
>> @@ -367,80 +335,40 @@ __gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>>   				_MASKED_BIT_DISABLE(FORCEWAKE_KERNEL));
>>   }
>>   
>> -static void
>> -gen9_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>> -{
>> -	if (FORCEWAKE_RENDER & fw_engine) {
>> -		if (dev_priv->uncore.fw_rendercount++ == 0)
>> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
>> -							FORCEWAKE_RENDER);
>> -	}
>> -
>> -	if (FORCEWAKE_MEDIA & fw_engine) {
>> -		if (dev_priv->uncore.fw_mediacount++ == 0)
>> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
>> -							FORCEWAKE_MEDIA);
>> -	}
>> -
>> -	if (FORCEWAKE_BLITTER & fw_engine) {
>> -		if (dev_priv->uncore.fw_blittercount++ == 0)
>> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
>> -							FORCEWAKE_BLITTER);
>> -	}
>> -}
>> -
>> -static void
>> -gen9_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>> -{
>> -	if (FORCEWAKE_RENDER & fw_engine) {
>> -		WARN_ON(dev_priv->uncore.fw_rendercount == 0);
>> -		if (--dev_priv->uncore.fw_rendercount == 0)
>> -			dev_priv->uncore.funcs.force_wake_put(dev_priv,
>> -							FORCEWAKE_RENDER);
>> -	}
>> -
>> -	if (FORCEWAKE_MEDIA & fw_engine) {
>> -		WARN_ON(dev_priv->uncore.fw_mediacount == 0);
>> -		if (--dev_priv->uncore.fw_mediacount == 0)
>> -			dev_priv->uncore.funcs.force_wake_put(dev_priv,
>> -							FORCEWAKE_MEDIA);
>> -	}
>> -
>> -	if (FORCEWAKE_BLITTER & fw_engine) {
>> -		WARN_ON(dev_priv->uncore.fw_blittercount == 0);
>> -		if (--dev_priv->uncore.fw_blittercount == 0)
>> -			dev_priv->uncore.funcs.force_wake_put(dev_priv,
>> -							FORCEWAKE_BLITTER);
>> -	}
>> -}
>> -
>>   static void gen6_force_wake_timer(unsigned long arg)
>>   {
>> -	struct drm_i915_private *dev_priv = (void *)arg;
>> +	struct intel_uncore_forcewake_domain *domain = (void *)arg;
>>   	unsigned long irqflags;
>>   
>> -	assert_device_not_suspended(dev_priv);
>> +	assert_device_not_suspended(domain->i915);
>>   
>> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>> -	WARN_ON(!dev_priv->uncore.forcewake_count);
>> +	spin_lock_irqsave(&domain->i915->uncore.lock, irqflags);
>> +	WARN_ON(!domain->wake_count);
>>   
>> -	if (--dev_priv->uncore.forcewake_count == 0)
>> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL);
>> -	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>> +	if (--domain->wake_count == 0)
>> +		domain->i915->uncore.funcs.force_wake_put(domain->i915,
>> +							  1 << domain->id);
>> +	spin_unlock_irqrestore(&domain->i915->uncore.lock, irqflags);
>>   }
>>   
>>   void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>>   {
>>   	struct drm_i915_private *dev_priv = dev->dev_private;
>> -	unsigned long irqflags;
>> -
>> -	if (del_timer_sync(&dev_priv->uncore.force_wake_timer))
>> -		gen6_force_wake_timer((unsigned long)dev_priv);
>> +	unsigned long irqflags, fw = 0;
>> +	struct intel_uncore_forcewake_domain *domain;
>> +	int id;
>>   
>> +	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>>   	/* Hold uncore.lock across reset to prevent any register access
>>   	 * with forcewake not set correctly
>>   	 */
>> -	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>> +
>> +	for_each_fw_domain(domain, dev_priv, id)
>> +		if (domain->wake_count)
>> +			fw |= 1 << id;
>> +
>> +	if (fw)
>> +		dev_priv->uncore.funcs.force_wake_put(dev_priv, fw);
>>   
>
> Hi Mika,
>
> Why do put?
>
> Is there a possibility of getting get & put count mismatch? for example,
> 1. We Read the register
>     -> forcewake_get & start domain_timer. (count = 1)
> 2. Now we call "intel_uncore_forcewake_reset" which does a put. (count = 0)
> 3. now the domain_timer from step #1 comes (count -1)? right?
>     or i am missing something here?

1. We read the register, wake_count = 1 and domain timer is armed.
2. In reset we see which domains are awake and store them in fw
3. We do a put for all domains with the hw callback,
   this doesn't touch the wake_count. I wanted this so that
   we first try with the soft approach by doing the disable and
   all the related fifodbg dance here like this was a normal put.
4. Regardless if the above did the trick, we then we take the gloves
   off and use more blunt approach by resetting the register.
5. We restore all the forcewakes

But while I was reading this through, there is one other
problem which is that if we don't restore, we mess the counts
and the timers will be still running.

I posted a new series with a fix for this.

-Mika

>
>
> Others Looks fine to me.
> Acked-by: Deepak S <deepak.s@linux.intel.com>
>
>>   	if (IS_VALLEYVIEW(dev))
>>   		vlv_force_wake_reset(dev_priv);
>> @@ -454,28 +382,6 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>>   		__gen9_gt_force_wake_mt_reset(dev_priv);
>>   
>>   	if (restore) { /* If reset with a user forcewake, try to restore */
>> -		unsigned fw = 0;
>> -
>> -		if (IS_VALLEYVIEW(dev)) {
>> -			if (dev_priv->uncore.fw_rendercount)
>> -				fw |= FORCEWAKE_RENDER;
>> -
>> -			if (dev_priv->uncore.fw_mediacount)
>> -				fw |= FORCEWAKE_MEDIA;
>> -		} else if (IS_GEN9(dev)) {
>> -			if (dev_priv->uncore.fw_rendercount)
>> -				fw |= FORCEWAKE_RENDER;
>> -
>> -			if (dev_priv->uncore.fw_mediacount)
>> -				fw |= FORCEWAKE_MEDIA;
>> -
>> -			if (dev_priv->uncore.fw_blittercount)
>> -				fw |= FORCEWAKE_BLITTER;
>> -		} else {
>> -			if (dev_priv->uncore.forcewake_count)
>> -				fw = FORCEWAKE_ALL;
>> -		}
>> -
>>   		if (fw)
>>   			dev_priv->uncore.funcs.force_wake_get(dev_priv, fw);
>>   
>> @@ -533,28 +439,28 @@ void intel_uncore_sanitize(struct drm_device *dev)
>>    * be called at the beginning of the sequence followed by a call to
>>    * gen6_gt_force_wake_put() at the end of the sequence.
>>    */
>> -void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>> +void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv,
>> +			    unsigned fw_domains)
>>   {
>>   	unsigned long irqflags;
>> +	struct intel_uncore_forcewake_domain *domain;
>> +	int id;
>>   
>>   	if (!dev_priv->uncore.funcs.force_wake_get)
>>   		return;
>>   
>> -	intel_runtime_pm_get(dev_priv);
>> -
>
> you need to change this in Patch #2
>
>>   	WARN_ON(!pm_runtime_active(&dev_priv->dev->pdev->dev));
>>   
>> +	fw_domains &= dev_priv->uncore.fw_domains;
>> +
>>   	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>>   
>> -	if (IS_GEN9(dev_priv->dev)) {
>> -		gen9_force_wake_get(dev_priv, fw_engine);
>> -	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
>> -		vlv_force_wake_get(dev_priv, fw_engine);
>> -	} else {
>> -		if (dev_priv->uncore.forcewake_count++ == 0)
>> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,
>> -							      FORCEWAKE_ALL);
>> -	}
>> +	for_each_fw_domain_mask(domain, fw_domains, dev_priv, id)
>> +		if (domain->wake_count++)
>> +			fw_domains &= ~(1 << id);
>> +
>> +	if (fw_domains)
>> +		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
>>   
>>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>>   }
>> @@ -562,26 +468,27 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv, int fw_engine)
>>   /*
>>    * see gen6_gt_force_wake_get()
>>    */
>> -void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>> +void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv,
>> +			    unsigned fw_domains)
>>   {
>>   	unsigned long irqflags;
>> +	struct intel_uncore_forcewake_domain *domain;
>> +	int id;
>>   
>>   	if (!dev_priv->uncore.funcs.force_wake_put)
>>   		return;
>>   
>> +	fw_domains &= dev_priv->uncore.fw_domains;
>> +
>>   	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
>>   
>> -	if (IS_GEN9(dev_priv->dev)) {
>> -		gen9_force_wake_put(dev_priv, fw_engine);
>> -	} else if (IS_VALLEYVIEW(dev_priv->dev)) {
>> -		vlv_force_wake_put(dev_priv, fw_engine);
>> -	} else {
>> -		WARN_ON(!dev_priv->uncore.forcewake_count);
>> -		if (--dev_priv->uncore.forcewake_count == 0) {
>> -			dev_priv->uncore.forcewake_count++;
>> -			mod_timer_pinned(&dev_priv->uncore.force_wake_timer,
>> -					 jiffies + 1);
>> -		}
>> +	for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
>> +		WARN_ON(!domain->wake_count);
>> +		if (--domain->wake_count)
>> +			continue;
>> +
>> +		domain->wake_count++;
>> +		mod_timer_pinned(&domain->timer, jiffies + 1);
>>   	}
>>   
>>   	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>> @@ -589,10 +496,14 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv, int fw_engine)
>>   
>>   void assert_force_wake_inactive(struct drm_i915_private *dev_priv)
>>   {
>> +	struct intel_uncore_forcewake_domain *domain;
>> +	int i;
>> +
>>   	if (!dev_priv->uncore.funcs.force_wake_get)
>>   		return;
>>   
>> -	WARN_ON(dev_priv->uncore.forcewake_count > 0);
>> +	for_each_fw_domain(domain, dev_priv, i)
>> +		WARN_ON(domain->wake_count);
>>   }
>>   
>>   /* We give fast paths for the really cool registers */
>> @@ -758,19 +669,36 @@ __gen2_read(64)
>>   	trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \
>>   	return val
>>   
>> +static inline void __force_wake_get(struct drm_i915_private *dev_priv,
>> +				    unsigned fw_domains)
>> +{
>> +	struct intel_uncore_forcewake_domain *domain;
>> +	int i;
>> +
>> +	if (WARN_ON(!fw_domains))
>> +		return;
>> +
>> +	/* Ideally GCC would be constant-fold and eliminate this loop */
>> +	for_each_fw_domain_mask(domain, fw_domains, dev_priv, i) {
>> +		if (domain->wake_count)
>> +			fw_domains &= ~(1 << i);
>> +		else
>> +			domain->wake_count++;
>> +
>> +		mod_timer_pinned(&domain->timer, jiffies + 1);
>> +	}
>> +
>> +	if (fw_domains)
>> +		dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
>> +}
>> +
>>   #define __gen6_read(x) \
>>   static u##x \
>>   gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>>   	GEN6_READ_HEADER(x); \
>>   	hsw_unclaimed_reg_debug(dev_priv, reg, true, true); \
>> -	if (dev_priv->uncore.forcewake_count == 0 && \
>> -	    NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, \
>> -						      FORCEWAKE_ALL); \
>> -		dev_priv->uncore.forcewake_count++; \
>> -		mod_timer_pinned(&dev_priv->uncore.force_wake_timer, \
>> -				 jiffies + 1); \
>> -	} \
>> +	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) \
>> +		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
>>   	val = __raw_i915_read##x(dev_priv, reg); \
>>   	hsw_unclaimed_reg_debug(dev_priv, reg, true, false); \
>>   	GEN6_READ_FOOTER; \
>> @@ -779,45 +707,27 @@ gen6_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>>   #define __vlv_read(x) \
>>   static u##x \
>>   vlv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>> -	unsigned fwengine = 0; \
>>   	GEN6_READ_HEADER(x); \
>> -	if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) { \
>> -		if (dev_priv->uncore.fw_rendercount == 0) \
>> -			fwengine = FORCEWAKE_RENDER; \
>> -	} else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) { \
>> -		if (dev_priv->uncore.fw_mediacount == 0) \
>> -			fwengine = FORCEWAKE_MEDIA; \
>> -	}  \
>> -	if (fwengine) \
>> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
>> +	if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg)) \
>> +		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
>> +	else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(reg)) \
>> +		__force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
>>   	val = __raw_i915_read##x(dev_priv, reg); \
>> -	if (fwengine) \
>> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>>   	GEN6_READ_FOOTER; \
>>   }
>>   
>>   #define __chv_read(x) \
>>   static u##x \
>>   chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>> -	unsigned fwengine = 0; \
>>   	GEN6_READ_HEADER(x); \
>> -	if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
>> -		if (dev_priv->uncore.fw_rendercount == 0) \
>> -			fwengine = FORCEWAKE_RENDER; \
>> -	} else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
>> -		if (dev_priv->uncore.fw_mediacount == 0) \
>> -			fwengine = FORCEWAKE_MEDIA; \
>> -	} else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
>> -		if (dev_priv->uncore.fw_rendercount == 0) \
>> -			fwengine |= FORCEWAKE_RENDER; \
>> -		if (dev_priv->uncore.fw_mediacount == 0) \
>> -			fwengine |= FORCEWAKE_MEDIA; \
>> -	} \
>> -	if (fwengine) \
>> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
>> +	if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) \
>> +		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
>> +	else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) \
>> +		__force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
>> +	else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) \
>> +		__force_wake_get(dev_priv, \
>> +				 FORCEWAKE_RENDER | FORCEWAKE_MEDIA); \
>>   	val = __raw_i915_read##x(dev_priv, reg); \
>> -	if (fwengine) \
>> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>>   	GEN6_READ_FOOTER; \
>>   }
>>   
>> @@ -827,32 +737,21 @@ chv_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>>   #define __gen9_read(x) \
>>   static u##x \
>>   gen9_read##x(struct drm_i915_private *dev_priv, off_t reg, bool trace) { \
>> +	unsigned fw_engine; \
>>   	GEN6_READ_HEADER(x); \
>> -	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
>> -		val = __raw_i915_read##x(dev_priv, reg); \
>> -	} else { \
>> -		unsigned fwengine = 0; \
>> -		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
>> -			if (dev_priv->uncore.fw_rendercount == 0) \
>> -				fwengine = FORCEWAKE_RENDER; \
>> -		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
>> -			if (dev_priv->uncore.fw_mediacount == 0) \
>> -				fwengine = FORCEWAKE_MEDIA; \
>> -		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
>> -			if (dev_priv->uncore.fw_rendercount == 0) \
>> -				fwengine |= FORCEWAKE_RENDER; \
>> -			if (dev_priv->uncore.fw_mediacount == 0) \
>> -				fwengine |= FORCEWAKE_MEDIA; \
>> -		} else { \
>> -			if (dev_priv->uncore.fw_blittercount == 0) \
>> -				fwengine = FORCEWAKE_BLITTER; \
>> -		} \
>> -		if (fwengine) \
>> -			dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
>> -		val = __raw_i915_read##x(dev_priv, reg); \
>> -		if (fwengine) \
>> -			dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>> -	} \
>> +	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)))	\
>> +		fw_engine = 0; \
>> +	else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg))	\
>> +		fw_engine = FORCEWAKE_RENDER; \
>> +	else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \
>> +		fw_engine = FORCEWAKE_MEDIA; \
>> +	else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) \
>> +		fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
>> +	else \
>> +		fw_engine = FORCEWAKE_BLITTER; \
>> +	if (fw_engine) \
>> +		__force_wake_get(dev_priv, fw_engine); \
>> +	val = __raw_i915_read##x(dev_priv, reg); \
>>   	GEN6_READ_FOOTER; \
>>   }
>>   
>> @@ -986,17 +885,9 @@ static void \
>>   gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
>>   	GEN6_WRITE_HEADER; \
>>   	hsw_unclaimed_reg_debug(dev_priv, reg, false, true); \
>> -	if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) { \
>> -		if (dev_priv->uncore.forcewake_count == 0) \
>> -			dev_priv->uncore.funcs.force_wake_get(dev_priv,	\
>> -							      FORCEWAKE_ALL); \
>> -		__raw_i915_write##x(dev_priv, reg, val); \
>> -		if (dev_priv->uncore.forcewake_count == 0) \
>> -			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
>> -							      FORCEWAKE_ALL); \
>> -	} else { \
>> -		__raw_i915_write##x(dev_priv, reg, val); \
>> -	} \
>> +	if (reg < 0x40000 && !is_gen8_shadowed(dev_priv, reg)) \
>> +		__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
>> +	__raw_i915_write##x(dev_priv, reg, val); \
>>   	hsw_unclaimed_reg_debug(dev_priv, reg, false, false); \
>>   	hsw_unclaimed_reg_detect(dev_priv); \
>>   	GEN6_WRITE_FOOTER; \
>> @@ -1005,28 +896,17 @@ gen8_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace
>>   #define __chv_write(x) \
>>   static void \
>>   chv_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, bool trace) { \
>> -	unsigned fwengine = 0; \
>>   	bool shadowed = is_gen8_shadowed(dev_priv, reg); \
>>   	GEN6_WRITE_HEADER; \
>>   	if (!shadowed) { \
>> -		if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) { \
>> -			if (dev_priv->uncore.fw_rendercount == 0) \
>> -				fwengine = FORCEWAKE_RENDER; \
>> -		} else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) { \
>> -			if (dev_priv->uncore.fw_mediacount == 0) \
>> -				fwengine = FORCEWAKE_MEDIA; \
>> -		} else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) { \
>> -			if (dev_priv->uncore.fw_rendercount == 0) \
>> -				fwengine |= FORCEWAKE_RENDER; \
>> -			if (dev_priv->uncore.fw_mediacount == 0) \
>> -				fwengine |= FORCEWAKE_MEDIA; \
>> -		} \
>> +		if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg)) \
>> +			__force_wake_get(dev_priv, FORCEWAKE_RENDER); \
>> +		else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(reg)) \
>> +			__force_wake_get(dev_priv, FORCEWAKE_MEDIA); \
>> +		else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(reg)) \
>> +			__force_wake_get(dev_priv, FORCEWAKE_RENDER | FORCEWAKE_MEDIA); \
>>   	} \
>> -	if (fwengine) \
>> -		dev_priv->uncore.funcs.force_wake_get(dev_priv, fwengine); \
>>   	__raw_i915_write##x(dev_priv, reg, val); \
>> -	if (fwengine) \
>> -		dev_priv->uncore.funcs.force_wake_put(dev_priv, fwengine); \
>>   	GEN6_WRITE_FOOTER; \
>>   }
>>   
>> @@ -1057,35 +937,22 @@ static bool is_gen9_shadowed(struct drm_i915_private *dev_priv, u32 reg)
>>   static void \
>>   gen9_write##x(struct drm_i915_private *dev_priv, off_t reg, u##x val, \
>>   		bool trace) { \
>> +	unsigned fw_engine; \
>>   	GEN6_WRITE_HEADER; \
>> -	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) || \
>> -			is_gen9_shadowed(dev_priv, reg)) { \
>> -		__raw_i915_write##x(dev_priv, reg, val); \
>> -	} else { \
>> -		unsigned fwengine = 0; \
>> -		if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) { \
>> -			if (dev_priv->uncore.fw_rendercount == 0) \
>> -				fwengine = FORCEWAKE_RENDER; \
>> -		} else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) { \
>> -			if (dev_priv->uncore.fw_mediacount == 0) \
>> -				fwengine = FORCEWAKE_MEDIA; \
>> -		} else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) { \
>> -			if (dev_priv->uncore.fw_rendercount == 0) \
>> -				fwengine |= FORCEWAKE_RENDER; \
>> -			if (dev_priv->uncore.fw_mediacount == 0) \
>> -				fwengine |= FORCEWAKE_MEDIA; \
>> -		} else { \
>> -			if (dev_priv->uncore.fw_blittercount == 0) \
>> -				fwengine = FORCEWAKE_BLITTER; \
>> -		} \
>> -		if (fwengine) \
>> -			dev_priv->uncore.funcs.force_wake_get(dev_priv, \
>> -					fwengine); \
>> -		__raw_i915_write##x(dev_priv, reg, val); \
>> -		if (fwengine) \
>> -			dev_priv->uncore.funcs.force_wake_put(dev_priv, \
>> -					fwengine); \
>> -	} \
>> +	if (!SKL_NEEDS_FORCE_WAKE((dev_priv), (reg)) ||	\
>> +	    is_gen9_shadowed(dev_priv, reg)) \
>> +		fw_engine = 0; \
>> +	else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(reg)) \
>> +		fw_engine = FORCEWAKE_RENDER; \
>> +	else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg)) \
>> +		fw_engine = FORCEWAKE_MEDIA; \
>> +	else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) \
>> +		fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
>> +	else \
>> +		fw_engine = FORCEWAKE_BLITTER; \
>> +	if (fw_engine) \
>> +		__force_wake_get(dev_priv, fw_engine); \
>> +	__raw_i915_write##x(dev_priv, reg, val); \
>>   	GEN6_WRITE_FOOTER; \
>>   }
>>   
>> @@ -1137,21 +1004,24 @@ do { \
>>   void intel_uncore_init(struct drm_device *dev)
>>   {
>>   	struct drm_i915_private *dev_priv = dev->dev_private;
>> -
>> -	setup_timer(&dev_priv->uncore.force_wake_timer,
>> -		    gen6_force_wake_timer, (unsigned long)dev_priv);
>> +	struct intel_uncore_forcewake_domain *domain;
>> +	int i;
>>   
>>   	__intel_uncore_early_sanitize(dev, false);
>>   
>>   	if (IS_GEN9(dev)) {
>>   		dev_priv->uncore.funcs.force_wake_get = __gen9_force_wake_get;
>>   		dev_priv->uncore.funcs.force_wake_put = __gen9_force_wake_put;
>> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER |
>> +			FORCEWAKE_BLITTER | FORCEWAKE_MEDIA;
>>   	} else if (IS_VALLEYVIEW(dev)) {
>>   		dev_priv->uncore.funcs.force_wake_get = __vlv_force_wake_get;
>>   		dev_priv->uncore.funcs.force_wake_put = __vlv_force_wake_put;
>> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER | FORCEWAKE_MEDIA;
>>   	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
>>   		dev_priv->uncore.funcs.force_wake_get = __gen7_gt_force_wake_mt_get;
>>   		dev_priv->uncore.funcs.force_wake_put = __gen7_gt_force_wake_mt_put;
>> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
>>   	} else if (IS_IVYBRIDGE(dev)) {
>>   		u32 ecobus;
>>   
>> @@ -1183,11 +1053,21 @@ void intel_uncore_init(struct drm_device *dev)
>>   			dev_priv->uncore.funcs.force_wake_put =
>>   				__gen6_gt_force_wake_put;
>>   		}
>> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
>>   	} else if (IS_GEN6(dev)) {
>>   		dev_priv->uncore.funcs.force_wake_get =
>>   			__gen6_gt_force_wake_get;
>>   		dev_priv->uncore.funcs.force_wake_put =
>>   			__gen6_gt_force_wake_put;
>> +		dev_priv->uncore.fw_domains = FORCEWAKE_RENDER;
>> +	}
>> +
>> +	for_each_fw_domain(domain, dev_priv, i) {
>> +		domain->i915 = dev_priv;
>> +		domain->id = i;
>> +
>> +		setup_timer(&domain->timer, gen6_force_wake_timer,
>> +			    (unsigned long)domain);
>>   	}
>>   
>>   	switch (INTEL_INFO(dev)->gen) {
>
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two
  2014-12-16 14:26         ` Dave Gordon
@ 2014-12-17 20:09           ` Daniel Vetter
  2014-12-18 14:06             ` Dave Gordon
  0 siblings, 1 reply; 57+ messages in thread
From: Daniel Vetter @ 2014-12-17 20:09 UTC (permalink / raw
  To: Dave Gordon; +Cc: Intel-GFX

On Tue, Dec 16, 2014 at 02:26:55PM +0000, Dave Gordon wrote:
> On 10/12/14 17:15, Daniel Vetter wrote:
> > On Wed, Dec 10, 2014 at 04:33:14PM +0000, Dave Gordon wrote:
> >> On 10/12/14 10:58, Daniel Vetter wrote:
> >>> On Tue, Dec 09, 2014 at 12:59:11PM +0000, John.C.Harrison@Intel.com wrote:
> >>>> From: John Harrison <John.C.Harrison@Intel.com>
> >>>>
> >>>> The scheduler decouples the submission of batch buffers to the driver with their
> >>>> submission to the hardware. This basically means splitting the execbuffer()
> >>>> function in half. This change rearranges some code ready for the split to occur.
> >>>
> >>> Now there's the curios question: Where will the split in top/bottom halves
> >>> be? Without that I have no idea whether it makes sense and so can't review
> >>> this patch. At least if the goal is to really prep for the scheduler and
> >>> not just move a few lines around ;-)
> >>> -Daniel
> >>>
> >> [snip]
> >>>>  
> >>>> +	i915_gem_execbuffer_move_to_active(vmas, ring);
> >>>> +
> >>>> +	/* To be split into two functions here... */
> >>>> +
> >>>> +	/* Unconditionally invalidate gpu caches and ensure that we do flush
> >>>> +	 * any residual writes from the previous batch.
> >>>> +	 */
> >>>> +	ret = logical_ring_invalidate_all_caches(ringbuf);
> >>
> >> It'll be where the marker comment is above. Ahead of that point is stuff
> >> to do with setting up software state; after that we're talking to h/w.
> >> When the scheduler code goes it, it decouples the two by interposing at
> >> this point. Then batches go into it with s/w state set up, but don't get
> >> to talk to the h/w until they're selected for execution, possibly in a
> >> different order.
> > 
> > Oops, I guess I need see a doctor to check my eyesight ;-)
> > 
> > Two comments about code that's still in the bottom half:
> > - There's lots of input validation code still below that cutoff point
> >   which needs to be moved above to still be able to return -EINVAL. Test
> >   coverage is the critical part here, but I think we've closed most of our
> >   gaps. I guess a future patch will address this?
> 
> Yes, all validation will end up before the batch gets pushed into the
> scheduler queue. It had already been shuffled there in an earlier
> version, but some of it then got relocated into less convenient places
> during the legacy-vs-execlist split. So for now, the execbuffer path has
> some common code (including early validation), then a split by
> submission mechanism (with additional validation that may someday get
> reconverged into the common section); and back to common code, and
> /then/ the batches get passed to the scheduler, whereafter there won't
> be any more EINVAL cases (though there will be other error cases, such
> as ENOMEM). Then as and when batches are selected for execution, they're
> passed to the specific backend submission mechanism code (which of
> course won't contain any further validation code either).

Hm, what can still go ENOMEM in there? We should pin everything we need,
the struct is preallocated and everything else should be in place too. Or
at least that's how I think it should work out. If the scheduler needs any
allocations for its internal tracking the we need to push them all into
other places, most likely requests.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two
  2014-12-17 20:09           ` Daniel Vetter
@ 2014-12-18 14:06             ` Dave Gordon
  0 siblings, 0 replies; 57+ messages in thread
From: Dave Gordon @ 2014-12-18 14:06 UTC (permalink / raw
  To: Daniel Vetter; +Cc: Intel-GFX@Lists.FreeDesktop.Org

On 17/12/14 20:09, Daniel Vetter wrote:
> On Tue, Dec 16, 2014 at 02:26:55PM +0000, Dave Gordon wrote:
>> On 10/12/14 17:15, Daniel Vetter wrote:
>>> On Wed, Dec 10, 2014 at 04:33:14PM +0000, Dave Gordon wrote:
>>>> On 10/12/14 10:58, Daniel Vetter wrote:
>>>>> On Tue, Dec 09, 2014 at 12:59:11PM +0000, John.C.Harrison@Intel.com wrote:
>>>>>> From: John Harrison <John.C.Harrison@Intel.com>
>>>>>>
>>>>>> The scheduler decouples the submission of batch buffers to the driver with their
>>>>>> submission to the hardware. This basically means splitting the execbuffer()
>>>>>> function in half. This change rearranges some code ready for the split to occur.
>>>>>
>>>>> Now there's the curios question: Where will the split in top/bottom halves
>>>>> be? Without that I have no idea whether it makes sense and so can't review
>>>>> this patch. At least if the goal is to really prep for the scheduler and
>>>>> not just move a few lines around ;-)
>>>>> -Daniel
>>>>>
>>>> [snip]
>>>>>>  
>>>>>> +	i915_gem_execbuffer_move_to_active(vmas, ring);
>>>>>> +
>>>>>> +	/* To be split into two functions here... */
>>>>>> +
>>>>>> +	/* Unconditionally invalidate gpu caches and ensure that we do flush
>>>>>> +	 * any residual writes from the previous batch.
>>>>>> +	 */
>>>>>> +	ret = logical_ring_invalidate_all_caches(ringbuf);
>>>>
>>>> It'll be where the marker comment is above. Ahead of that point is stuff
>>>> to do with setting up software state; after that we're talking to h/w.
>>>> When the scheduler code goes it, it decouples the two by interposing at
>>>> this point. Then batches go into it with s/w state set up, but don't get
>>>> to talk to the h/w until they're selected for execution, possibly in a
>>>> different order.
>>>
>>> Oops, I guess I need see a doctor to check my eyesight ;-)
>>>
>>> Two comments about code that's still in the bottom half:
>>> - There's lots of input validation code still below that cutoff point
>>>   which needs to be moved above to still be able to return -EINVAL. Test
>>>   coverage is the critical part here, but I think we've closed most of our
>>>   gaps. I guess a future patch will address this?
>>
>> Yes, all validation will end up before the batch gets pushed into the
>> scheduler queue. It had already been shuffled there in an earlier
>> version, but some of it then got relocated into less convenient places
>> during the legacy-vs-execlist split. So for now, the execbuffer path has
>> some common code (including early validation), then a split by
>> submission mechanism (with additional validation that may someday get
>> reconverged into the common section); and back to common code, and
>> /then/ the batches get passed to the scheduler, whereafter there won't
>> be any more EINVAL cases (though there will be other error cases, such
>> as ENOMEM). Then as and when batches are selected for execution, they're
>> passed to the specific backend submission mechanism code (which of
>> course won't contain any further validation code either).
> 
> Hm, what can still go ENOMEM in there? We should pin everything we need,
> the struct is preallocated and everything else should be in place too. Or
> at least that's how I think it should work out. If the scheduler needs any
> allocations for its internal tracking the we need to push them all into
> other places, most likely requests.
> -Daniel

It used to be the case that the scheduler had to allocate some tracking
data, but John may well have changed that with the advent of the
seqno-request transformation.

I'd like to eventually move all batch-related allocations into a single
chunk per request, done after input validation and before acquiring any
locks :)

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

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

* Re: [PATCH v2] drm/i915: FIFO space query code refactor
  2014-12-10 18:12       ` [PATCH v2] drm/i915: FIFO space query code refactor Dave Gordon
@ 2015-02-20  9:34         ` Mika Kuoppala
  2015-02-23 15:46           ` Daniel Vetter
  0 siblings, 1 reply; 57+ messages in thread
From: Mika Kuoppala @ 2015-02-20  9:34 UTC (permalink / raw
  To: Dave Gordon, intel-gfx

Dave Gordon <david.s.gordon@intel.com> writes:

> When querying the GTFIFOCTL register to check the FIFO space, the read value
> must be masked. The operation is repeated explicitly in several places. This
> change refactors the read-and-mask code into a function call.
>
> v2: rebased on top of Mika's forcewake patch set, specifically:
> 	[PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers
>
> Change-Id: Id1a9f3785cb20b82d4caa330c37b31e4e384a3ef
> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>

Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

> ---
>  drivers/gpu/drm/i915/intel_uncore.c |   19 ++++++++++++-------
>  1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 66365e7..a0331a7 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -205,6 +205,13 @@ static void fw_domains_put_with_fifo(struct drm_i915_private *dev_priv,
>  	gen6_gt_check_fifodbg(dev_priv);
>  }
>  
> +static inline u32 fifo_free_entries(struct drm_i915_private *dev_priv)
> +{
> +	u32 count = __raw_i915_read32(dev_priv, GTFIFOCTL);
> +
> +	return count & GT_FIFO_FREE_ENTRIES_MASK;
> +}
> +
>  static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
>  {
>  	int ret = 0;
> @@ -212,16 +219,15 @@ static int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
>  	/* On VLV, FIFO will be shared by both SW and HW.
>  	 * So, we need to read the FREE_ENTRIES everytime */
>  	if (IS_VALLEYVIEW(dev_priv->dev))
> -		dev_priv->uncore.fifo_count =
> -			__raw_i915_read32(dev_priv, GTFIFOCTL) &
> -						GT_FIFO_FREE_ENTRIES_MASK;
> +		dev_priv->uncore.fifo_count = fifo_free_entries(dev_priv);
>  
>  	if (dev_priv->uncore.fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
>  		int loop = 500;
> -		u32 fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
> +		u32 fifo = fifo_free_entries(dev_priv);
> +
>  		while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
>  			udelay(10);
> -			fifo = __raw_i915_read32(dev_priv, GTFIFOCTL) & GT_FIFO_FREE_ENTRIES_MASK;
> +			fifo = fifo_free_entries(dev_priv);
>  		}
>  		if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
>  			++ret;
> @@ -277,8 +283,7 @@ void intel_uncore_forcewake_reset(struct drm_device *dev, bool restore)
>  
>  		if (IS_GEN6(dev) || IS_GEN7(dev))
>  			dev_priv->uncore.fifo_count =
> -				__raw_i915_read32(dev_priv, GTFIFOCTL) &
> -				GT_FIFO_FREE_ENTRIES_MASK;
> +				fifo_free_entries(dev_priv);
>  	}
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -- 
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v2] drm/i915: FIFO space query code refactor
  2015-02-20  9:34         ` Mika Kuoppala
@ 2015-02-23 15:46           ` Daniel Vetter
  0 siblings, 0 replies; 57+ messages in thread
From: Daniel Vetter @ 2015-02-23 15:46 UTC (permalink / raw
  To: Mika Kuoppala; +Cc: intel-gfx

On Fri, Feb 20, 2015 at 11:34:29AM +0200, Mika Kuoppala wrote:
> Dave Gordon <david.s.gordon@intel.com> writes:
> 
> > When querying the GTFIFOCTL register to check the FIFO space, the read value
> > must be masked. The operation is repeated explicitly in several places. This
> > change refactors the read-and-mask code into a function call.
> >
> > v2: rebased on top of Mika's forcewake patch set, specifically:
> > 	[PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers
> >
> > Change-Id: Id1a9f3785cb20b82d4caa330c37b31e4e384a3ef
> > Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
> 
> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>

Queued for -next, thanks for the patch.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2015-02-23 15:45 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-09 12:59 [PATCH 00/10] Prep work patches for GPU scheduler John.C.Harrison
2014-12-09 12:59 ` [PATCH 01/10] drm/i915: Rename 'flags' to 'dispatch_flags' for better code reading John.C.Harrison
2014-12-09 12:59 ` [PATCH 02/10] drm/i915: Add missing trace point to LRC execbuff code path John.C.Harrison
2014-12-09 12:59 ` [PATCH 03/10] drm/i915: Updating assorted register and status page definitions John.C.Harrison
2014-12-10 10:40   ` Daniel Vetter
2014-12-10 16:37     ` Dave Gordon
2014-12-09 12:59 ` [PATCH 04/10] drm/i915: FIFO space query code refactor John.C.Harrison
2014-12-10 10:41   ` Daniel Vetter
2014-12-09 12:59 ` [PATCH 05/10] drm/i915: Disable 'get seqno' workaround for VLV John.C.Harrison
2014-12-10 10:42   ` Daniel Vetter
2014-12-10 17:11     ` Dave Gordon
2014-12-15  9:02       ` Daniel Vetter
2014-12-09 12:59 ` [PATCH 06/10] drm/i915: Add extra add_request calls John.C.Harrison
2014-12-10 10:55   ` Daniel Vetter
2014-12-09 12:59 ` [PATCH 07/10] drm/i915: Early alloc request John.C.Harrison
2014-12-09 12:59 ` [PATCH 08/10] drm/i915: Prelude to splitting i915_gem_do_execbuffer in two John.C.Harrison
2014-12-10 10:58   ` Daniel Vetter
2014-12-10 16:33     ` Dave Gordon
2014-12-10 17:15       ` Daniel Vetter
2014-12-16 14:26         ` Dave Gordon
2014-12-17 20:09           ` Daniel Vetter
2014-12-18 14:06             ` Dave Gordon
2014-12-09 12:59 ` [PATCH 09/10] drm/i915: Split i915_dem_do_execbuffer() in half John.C.Harrison
2014-12-09 12:59 ` [PATCH 10/10] drm/i915: Cache ringbuf pointer in request structure John.C.Harrison
  -- strict thread matches above, loose matches on Subject: below --
2014-12-08 18:27 [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Mika Kuoppala
2014-12-08 18:27 ` [PATCH 2/8] drm/i915: Assert that runtime pm is active on user fw access Mika Kuoppala
2014-12-12 11:39   ` Deepak S
2014-12-11 11:53     ` Chris Wilson
2014-12-12 11:59       ` Deepak S
2014-12-08 18:27 ` [PATCH 3/8] drm/i915: Skip uncore lock on earlier gens Mika Kuoppala
2014-12-12 11:57   ` Deepak S
2014-12-08 18:27 ` [PATCH 4/8] drm/i915: Reduce duplicated forcewake logic Mika Kuoppala
2014-12-12 12:48   ` Deepak S
2014-12-16 15:26     ` Mika Kuoppala
2014-12-08 18:27 ` [PATCH 5/8] drm/i915: Consolidate forcewake code Mika Kuoppala
2014-12-12 13:13   ` Deepak S
2014-12-08 18:27 ` [PATCH 6/8] drm/i915: Make vlv and chv forcewake put generic Mika Kuoppala
2014-12-12 13:16   ` Deepak S
2014-12-08 18:27 ` [PATCH 7/8] drm/i915: Rename the forcewake get/put functions Mika Kuoppala
2014-12-12 13:19   ` Deepak S
2014-12-08 18:27 ` [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors Mika Kuoppala
2014-12-09 11:46   ` [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers Mika Kuoppala
2014-12-09 13:32     ` Jani Nikula
2014-12-09 13:36       ` Daniel Vetter
2014-12-09 15:37       ` Mika Kuoppala
2014-12-10 18:12       ` [PATCH v2] drm/i915: FIFO space query code refactor Dave Gordon
2015-02-20  9:34         ` Mika Kuoppala
2015-02-23 15:46           ` Daniel Vetter
2014-12-12 13:21     ` [PATCH 8/8] drm/i915: Enum forcewake domains and domain identifiers Deepak S
2014-12-09 23:29   ` [PATCH 8/8] drm/i915: Follow the forcewake domains type on hw accessors shuang.he
2014-12-12 13:20   ` Deepak S
2014-12-12 10:00 ` [PATCH 1/8] drm/i915: Rebalance runtime pm vs forcewake Deepak S
2014-12-11 10:15   ` Chris Wilson
2014-12-12 11:24     ` Deepak S
2014-12-15  8:46     ` Daniel Vetter
2014-12-12 16:22 ` Paulo Zanoni
2014-12-12 16:45   ` 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.