* [PATCH] drm/i915: add multi-threaded forcewake support
@ 2011-11-18 19:36 Jesse Barnes
2011-11-18 22:01 ` Keith Packard
0 siblings, 1 reply; 11+ messages in thread
From: Jesse Barnes @ 2011-11-18 19:36 UTC (permalink / raw)
To: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 6945 bytes --]
On IVB C0+ with newer BIOSes, the forcewake handshake has changed. There's
now a bitfield for different driver components to keep the GT powered
on. On Linux, we centralize forcewake handling in one place, so we
still just need a single bit, but we need to use the new registers if MT
forcewake is enabled.
This needs testing on affected machines. Please reply with your
tested-by if you had problems after a BIOS upgrade and this patch fixes
them.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
drivers/gpu/drm/i915/i915_drv.c | 35 ++++++++++++++++++++++++++++-----
drivers/gpu/drm/i915/i915_drv.h | 13 ++++++++++-
drivers/gpu/drm/i915/i915_reg.h | 4 +++
drivers/gpu/drm/i915/intel_display.c | 13 ++++++++++++
4 files changed, 57 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 548e04b..629c591 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -327,7 +327,7 @@ void intel_detect_pch(struct drm_device *dev)
}
}
-static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
int count;
@@ -343,6 +343,22 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
udelay(10);
}
+void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
+{
+ int count;
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
+ udelay(10);
+
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<15) | 1);
+ POSTING_READ(FORCEWAKE_MT);
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
+ udelay(10);
+}
+
/*
* 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
@@ -355,15 +371,21 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
/* Forcewake is atomic in case we get in here without the lock */
if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
- __gen6_gt_force_wake_get(dev_priv);
+ dev_priv->display.force_wake_get(dev_priv);
}
-static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE, 0);
POSTING_READ(FORCEWAKE);
}
+void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
+{
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<15) | 0);
+ POSTING_READ(FORCEWAKE_MT);
+}
+
/*
* see gen6_gt_force_wake_get()
*/
@@ -372,7 +394,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
if (atomic_dec_and_test(&dev_priv->forcewake_count))
- __gen6_gt_force_wake_put(dev_priv);
+ dev_priv->display.force_wake_put(dev_priv);
}
void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
@@ -902,8 +924,9 @@ MODULE_LICENSE("GPL and additional rights");
/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
(((dev_priv)->info->gen >= 6) && \
- ((reg) < 0x40000) && \
- ((reg) != FORCEWAKE))
+ ((reg) < 0x40000) && \
+ ((reg) != FORCEWAKE) && \
+ ((reg) != ECOBUS))
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 06a37f4..502ce9b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -107,6 +107,7 @@ struct opregion_header;
struct opregion_acpi;
struct opregion_swsci;
struct opregion_asle;
+struct drm_i915_private;
struct intel_opregion {
struct opregion_header *header;
@@ -218,6 +219,8 @@ struct drm_i915_display_funcs {
struct drm_i915_gem_object *obj);
int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y);
+ void (*force_wake_get)(struct drm_i915_private *dev_priv);
+ void (*force_wake_put)(struct drm_i915_private *dev_priv);
/* clock updates for mode set */
/* cursor updates */
/* render clock increase/decrease */
@@ -1307,6 +1310,11 @@ extern void gen6_set_rps(struct drm_device *dev, u8 val);
extern void intel_detect_pch(struct drm_device *dev);
extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
+extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv);
+
/* overlay */
#ifdef CONFIG_DEBUG_FS
extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
@@ -1351,8 +1359,9 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
(((dev_priv)->info->gen >= 6) && \
- ((reg) < 0x40000) && \
- ((reg) != FORCEWAKE))
+ ((reg) < 0x40000) && \
+ ((reg) != FORCEWAKE) && \
+ ((reg) != ECOBUS))
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index d486bab..1a8b6eb 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3567,7 +3567,11 @@
#define EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B (0x38<<22)
#define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22)
+#define ECOBUS 0xa180
+#define FORCEWAKE_MT_ENABLE (1<<5)
#define FORCEWAKE 0xA18C
+#define FORCEWAKE_MT 0xa188 /* multi-threaded */
+#define FORCEWAKE_MT_ACK 0x130040
#define FORCEWAKE_ACK 0x130090
#define GT_FIFO_FREE_ENTRIES 0x120008
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3f165d3..1ab79ea 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8482,6 +8482,19 @@ static void intel_init_display(struct drm_device *dev)
/* For FIFO watermark updates */
if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->display.force_wake_get = __gen6_gt_force_wake_get;
+ dev_priv->display.force_wake_put = __gen6_gt_force_wake_put;
+
+ /* IVB configs may use multi-threaded forcewake */
+ if (IS_IVYBRIDGE(dev)) {
+ if (I915_READ(ECOBUS) & FORCEWAKE_MT_ENABLE) {
+ dev_priv->display.force_wake_get =
+ __gen6_gt_force_wake_mt_get;
+ dev_priv->display.force_wake_put =
+ __gen6_gt_force_wake_mt_put;
+ }
+ }
+
if (HAS_PCH_IBX(dev))
dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating;
else if (HAS_PCH_CPT(dev))
--
1.7.4.1
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
2011-11-18 19:36 [PATCH] drm/i915: add multi-threaded forcewake support Jesse Barnes
@ 2011-11-18 22:01 ` Keith Packard
2011-11-18 22:12 ` Jesse Barnes
0 siblings, 1 reply; 11+ messages in thread
From: Keith Packard @ 2011-11-18 22:01 UTC (permalink / raw)
To: Jesse Barnes, intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 530 bytes --]
On Fri, 18 Nov 2011 11:36:32 -0800, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
You said this should be << 16
> + I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<15) | 1);
and this should be << 16 too
> + if (I915_READ(ECOBUS) & FORCEWAKE_MT_ENABLE) {
ECOBUS (0xa180) is zero on my machine, but I need the new functions.
Removing the ECOBUS check and switching the shifts to 16 makes this work
on my machine.
--
keith.packard@intel.com
[-- Attachment #1.2: Type: application/pgp-signature, Size: 827 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
2011-11-18 22:01 ` Keith Packard
@ 2011-11-18 22:12 ` Jesse Barnes
2011-11-18 22:35 ` Keith Packard
0 siblings, 1 reply; 11+ messages in thread
From: Jesse Barnes @ 2011-11-18 22:12 UTC (permalink / raw)
To: Keith Packard; +Cc: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 843 bytes --]
On Fri, 18 Nov 2011 14:01:00 -0800
Keith Packard <keithp@keithp.com> wrote:
> On Fri, 18 Nov 2011 11:36:32 -0800, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>
> > + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
>
> You said this should be << 16
No this one should be looking at the bottom bit, so I think it's ok.
>
> > + I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<15) | 1);
>
> and this should be << 16 too
The write needs the mask, and I'm always off by one. :p
> > + if (I915_READ(ECOBUS) & FORCEWAKE_MT_ENABLE) {
>
> ECOBUS (0xa180) is zero on my machine, but I need the new functions.
>
> Removing the ECOBUS check and switching the shifts to 16 makes this work
> on my machine.
Cool, hope it'll help others too.
Thanks,
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
2011-11-18 22:12 ` Jesse Barnes
@ 2011-11-18 22:35 ` Keith Packard
2011-11-18 22:48 ` Jesse Barnes
0 siblings, 1 reply; 11+ messages in thread
From: Keith Packard @ 2011-11-18 22:35 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 1130 bytes --]
On Fri, 18 Nov 2011 14:12:03 -0800, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> No this one should be looking at the bottom bit, so I think it's ok.
Sorry, bad mail edit. There's one << 15 in both force_wake_mt_put and
force_wake_mt_get and they both need to be << 16:
+void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
+{
+ int count;
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
+ udelay(10);
+
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<15) | 1);
<<16
+ POSTING_READ(FORCEWAKE_MT);
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
+ udelay(10);
+}
+
...
+void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
+{
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<15) | 0);
<<16
+ POSTING_READ(FORCEWAKE_MT);
+}
+
> Cool, hope it'll help others too.
Let me know when you hear back from the VPG folks about how we're
supposed to know which method to use.
--
keith.packard@intel.com
[-- Attachment #1.2: Type: application/pgp-signature, Size: 827 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
2011-11-18 22:35 ` Keith Packard
@ 2011-11-18 22:48 ` Jesse Barnes
2011-11-18 23:27 ` Keith Packard
2011-11-19 5:33 ` Keith Packard
0 siblings, 2 replies; 11+ messages in thread
From: Jesse Barnes @ 2011-11-18 22:48 UTC (permalink / raw)
To: Keith Packard; +Cc: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 1513 bytes --]
On Fri, 18 Nov 2011 14:35:22 -0800
Keith Packard <keithp@keithp.com> wrote:
> On Fri, 18 Nov 2011 14:12:03 -0800, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>
> > No this one should be looking at the bottom bit, so I think it's ok.
>
> Sorry, bad mail edit. There's one << 15 in both force_wake_mt_put and
> force_wake_mt_get and they both need to be << 16:
>
>
> +void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
> +{
> + int count;
> +
> + count = 0;
> + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
> + udelay(10);
> +
> + I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<15) | 1);
>
> <<16
>
> + POSTING_READ(FORCEWAKE_MT);
> +
> + count = 0;
> + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
> + udelay(10);
> +}
> +
>
> ...
>
> +void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
> +{
> + I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<15) | 0);
>
> <<16
>
> + POSTING_READ(FORCEWAKE_MT);
> +}
> +
>
> > Cool, hope it'll help others too.
>
> Let me know when you hear back from the VPG folks about how we're
> supposed to know which method to use.
So the ECOBUS reg *is* in the GT power well. Which means in order to
read it we have to disable RC6 altogether, forcibly, using the 0xa090
reg, set up force wake, then re-enable RC6.
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
2011-11-18 22:48 ` Jesse Barnes
@ 2011-11-18 23:27 ` Keith Packard
2011-11-18 23:34 ` Ben Widawsky
2011-11-19 5:33 ` Keith Packard
1 sibling, 1 reply; 11+ messages in thread
From: Keith Packard @ 2011-11-18 23:27 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 620 bytes --]
On Fri, 18 Nov 2011 14:48:39 -0800, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> So the ECOBUS reg *is* in the GT power well. Which means in order to
> read it we have to disable RC6 altogether, forcibly, using the 0xa090
> reg, set up force wake, then re-enable RC6.
Not surprising the ECOBUS is in the well; we really only need to read it
when rc6 is getting set up, so it'll be disabled at that point.
But, unless I'm confused, ECOBUS doesn't have any useful information in
it anyways:
# intel_reg_read 0xa090
0xA090 : 0x0
# intel_reg_read 0xa080
0xA080 : 0x0
--
keith.packard@intel.com
[-- Attachment #1.2: Type: application/pgp-signature, Size: 827 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
2011-11-18 23:27 ` Keith Packard
@ 2011-11-18 23:34 ` Ben Widawsky
0 siblings, 0 replies; 11+ messages in thread
From: Ben Widawsky @ 2011-11-18 23:34 UTC (permalink / raw)
To: Keith Packard; +Cc: intel-gfx
On Fri, 18 Nov 2011 15:27:14 -0800
Keith Packard <keithp@keithp.com> wrote:
> On Fri, 18 Nov 2011 14:48:39 -0800, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>
> > So the ECOBUS reg *is* in the GT power well. Which means in order to
> > read it we have to disable RC6 altogether, forcibly, using the 0xa090
> > reg, set up force wake, then re-enable RC6.
>
> Not surprising the ECOBUS is in the well; we really only need to read it
> when rc6 is getting set up, so it'll be disabled at that point.
>
> But, unless I'm confused, ECOBUS doesn't have any useful information in
> it anyways:
>
> # intel_reg_read 0xa090
> 0xA090 : 0x0
> # intel_reg_read 0xa080
> 0xA080 : 0x0
>
Are you using the forcewaked tool to read it?
bwidawsk@seagal ~/intel-gfx/drm-intel2 (forced-throttling|REBASE-i)$ sudo ../intel-gpu-tools/tools/intel_reg_read 0xa090
0xA090 : 0x88060000
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
2011-11-18 22:48 ` Jesse Barnes
2011-11-18 23:27 ` Keith Packard
@ 2011-11-19 5:33 ` Keith Packard
2011-11-21 15:47 ` Robert Hooker
1 sibling, 1 reply; 11+ messages in thread
From: Keith Packard @ 2011-11-19 5:33 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx
[-- Attachment #1.1: Type: text/plain, Size: 8131 bytes --]
On Fri, 18 Nov 2011 14:48:39 -0800, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> So the ECOBUS reg *is* in the GT power well. Which means in order to
> read it we have to disable RC6 altogether, forcibly, using the 0xa090
> reg, set up force wake, then re-enable RC6.
Here's what I cooked up -- it uses the MT version of the force wake code
to make the ECOBUS value visible. Seems to work for me, but additional
testing is encouraged. In particular, it'd be good to test on your
existing machine which *isn't* using MT forcewake.
From b23581d5c978c96266f690239cc0d5f19480df98 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp@keithp.com>
Date: Fri, 18 Nov 2011 20:39:01 -0800
Subject: [PATCH 1/2] drm/i915: add multi-threaded forcewake support
On IVB C0+ with newer BIOSes, the forcewake handshake has changed. There's
now a bitfield for different driver components to keep the GT powered
on. On Linux, we centralize forcewake handling in one place, so we
still just need a single bit, but we need to use the new registers if MT
forcewake is enabled.
This needs testing on affected machines. Please reply with your
tested-by if you had problems after a BIOS upgrade and this patch fixes
them.
v2: force MT mode. shift by 16
v3: set MT force wake bits then check ECOBUS
Tested-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/i915/i915_drv.c | 35 ++++++++++++++++++++++++++++-----
drivers/gpu/drm/i915/i915_drv.h | 13 ++++++++++-
drivers/gpu/drm/i915/i915_reg.h | 4 +++
drivers/gpu/drm/i915/intel_display.c | 22 +++++++++++++++++++++
4 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 13488be..bd82ef0 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -327,7 +327,7 @@ void intel_detect_pch(struct drm_device *dev)
}
}
-static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
int count;
@@ -343,6 +343,22 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
udelay(10);
}
+void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
+{
+ int count;
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
+ udelay(10);
+
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1);
+ POSTING_READ(FORCEWAKE_MT);
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
+ udelay(10);
+}
+
/*
* 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
@@ -355,15 +371,21 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
/* Forcewake is atomic in case we get in here without the lock */
if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
- __gen6_gt_force_wake_get(dev_priv);
+ dev_priv->display.force_wake_get(dev_priv);
}
-static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE, 0);
POSTING_READ(FORCEWAKE);
}
+void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
+{
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
+ POSTING_READ(FORCEWAKE_MT);
+}
+
/*
* see gen6_gt_force_wake_get()
*/
@@ -372,7 +394,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
if (atomic_dec_and_test(&dev_priv->forcewake_count))
- __gen6_gt_force_wake_put(dev_priv);
+ dev_priv->display.force_wake_put(dev_priv);
}
void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
@@ -902,8 +924,9 @@ MODULE_LICENSE("GPL and additional rights");
/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
(((dev_priv)->info->gen >= 6) && \
- ((reg) < 0x40000) && \
- ((reg) != FORCEWAKE))
+ ((reg) < 0x40000) && \
+ ((reg) != FORCEWAKE) && \
+ ((reg) != ECOBUS))
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4a9c1b9..8ba88cf 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -107,6 +107,7 @@ struct opregion_header;
struct opregion_acpi;
struct opregion_swsci;
struct opregion_asle;
+struct drm_i915_private;
struct intel_opregion {
struct opregion_header *header;
@@ -221,6 +222,8 @@ struct drm_i915_display_funcs {
struct drm_i915_gem_object *obj);
int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y);
+ void (*force_wake_get)(struct drm_i915_private *dev_priv);
+ void (*force_wake_put)(struct drm_i915_private *dev_priv);
/* clock updates for mode set */
/* cursor updates */
/* render clock increase/decrease */
@@ -1308,6 +1311,11 @@ extern void gen6_set_rps(struct drm_device *dev, u8 val);
extern void intel_detect_pch(struct drm_device *dev);
extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
+extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv);
+
/* overlay */
#ifdef CONFIG_DEBUG_FS
extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
@@ -1352,8 +1360,9 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
(((dev_priv)->info->gen >= 6) && \
- ((reg) < 0x40000) && \
- ((reg) != FORCEWAKE))
+ ((reg) < 0x40000) && \
+ ((reg) != FORCEWAKE) && \
+ ((reg) != ECOBUS))
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b080cc8..8990057 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3449,6 +3449,10 @@
#define FORCEWAKE 0xA18C
#define FORCEWAKE_ACK 0x130090
+#define FORCEWAKE_MT 0xa188 /* multi-threaded */
+#define FORCEWAKE_MT_ACK 0x130040
+#define ECOBUS 0xa180
+#define FORCEWAKE_MT_ENABLE (1<<5)
#define GT_FIFO_FREE_ENTRIES 0x120008
#define GT_FIFO_NUM_RESERVED_ENTRIES 20
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e77a863..633c693 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8491,6 +8491,28 @@ static void intel_init_display(struct drm_device *dev)
/* For FIFO watermark updates */
if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->display.force_wake_get = __gen6_gt_force_wake_get;
+ dev_priv->display.force_wake_put = __gen6_gt_force_wake_put;
+
+ /* IVB configs may use multi-threaded forcewake */
+ if (IS_IVYBRIDGE(dev)) {
+ u32 ecobus;
+
+ mutex_lock(&dev->struct_mutex);
+ __gen6_gt_force_wake_mt_get(dev_priv);
+ ecobus = I915_READ(ECOBUS);
+ __gen6_gt_force_wake_mt_put(dev_priv);
+ mutex_unlock(&dev->struct_mutex);
+
+ if (ecobus & FORCEWAKE_MT_ENABLE) {
+ DRM_DEBUG_KMS("Using MT version of forcewake\n");
+ dev_priv->display.force_wake_get =
+ __gen6_gt_force_wake_mt_get;
+ dev_priv->display.force_wake_put =
+ __gen6_gt_force_wake_mt_put;
+ }
+ }
+
if (HAS_PCH_IBX(dev))
dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating;
else if (HAS_PCH_CPT(dev))
--
1.7.7.3
--
keith.packard@intel.com
[-- Attachment #1.2: Type: application/pgp-signature, Size: 827 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
[not found] <B32E3D5F1713054290B4FF257B89C51A2E8F496B66@shsmsx502.ccr.corp.intel.com>
@ 2011-11-21 6:55 ` Fang, XunX
2011-12-05 22:42 ` Jesse Barnes
0 siblings, 1 reply; 11+ messages in thread
From: Fang, XunX @ 2011-11-21 6:55 UTC (permalink / raw)
To: keithp@keithp.com; +Cc: intel-gfx@lists.freedesktop.org
This patch works for me.
Tested-by: Fang Xun<xunx.fang@intel.com>
-----Original Message-----
From: intel-gfx-bounces+gordon.jin=intel.com@lists.freedesktop.org [mailto:intel-gfx-bounces+gordon.jin=intel.com@lists.freedesktop.org] On Behalf Of Keith Packard
Sent: Saturday, November 19, 2011 1:34 PM
To: Jesse Barnes
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH] drm/i915: add multi-threaded forcewake support
On Fri, 18 Nov 2011 14:48:39 -0800, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> So the ECOBUS reg *is* in the GT power well. Which means in order to
> read it we have to disable RC6 altogether, forcibly, using the 0xa090
> reg, set up force wake, then re-enable RC6.
Here's what I cooked up -- it uses the MT version of the force wake code
to make the ECOBUS value visible. Seems to work for me, but additional
testing is encouraged. In particular, it'd be good to test on your
existing machine which *isn't* using MT forcewake.
>From b23581d5c978c96266f690239cc0d5f19480df98 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp@keithp.com>
Date: Fri, 18 Nov 2011 20:39:01 -0800
Subject: [PATCH 1/2] drm/i915: add multi-threaded forcewake support
On IVB C0+ with newer BIOSes, the forcewake handshake has changed. There's
now a bitfield for different driver components to keep the GT powered
on. On Linux, we centralize forcewake handling in one place, so we
still just need a single bit, but we need to use the new registers if MT
forcewake is enabled.
This needs testing on affected machines. Please reply with your
tested-by if you had problems after a BIOS upgrade and this patch fixes
them.
v2: force MT mode. shift by 16
v3: set MT force wake bits then check ECOBUS
Tested-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Keith Packard <keithp@keithp.com>
---
drivers/gpu/drm/i915/i915_drv.c | 35 ++++++++++++++++++++++++++++-----
drivers/gpu/drm/i915/i915_drv.h | 13 ++++++++++-
drivers/gpu/drm/i915/i915_reg.h | 4 +++
drivers/gpu/drm/i915/intel_display.c | 22 +++++++++++++++++++++
4 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 13488be..bd82ef0 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -327,7 +327,7 @@ void intel_detect_pch(struct drm_device *dev)
}
}
-static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
{
int count;
@@ -343,6 +343,22 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
udelay(10);
}
+void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
+{
+ int count;
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
+ udelay(10);
+
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1);
+ POSTING_READ(FORCEWAKE_MT);
+
+ count = 0;
+ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
+ udelay(10);
+}
+
/*
* 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
@@ -355,15 +371,21 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
/* Forcewake is atomic in case we get in here without the lock */
if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
- __gen6_gt_force_wake_get(dev_priv);
+ dev_priv->display.force_wake_get(dev_priv);
}
-static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
+void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
{
I915_WRITE_NOTRACE(FORCEWAKE, 0);
POSTING_READ(FORCEWAKE);
}
+void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
+{
+ I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
+ POSTING_READ(FORCEWAKE_MT);
+}
+
/*
* see gen6_gt_force_wake_get()
*/
@@ -372,7 +394,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
if (atomic_dec_and_test(&dev_priv->forcewake_count))
- __gen6_gt_force_wake_put(dev_priv);
+ dev_priv->display.force_wake_put(dev_priv);
}
void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
@@ -902,8 +924,9 @@ MODULE_LICENSE("GPL and additional rights");
/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
(((dev_priv)->info->gen >= 6) && \
- ((reg) < 0x40000) && \
- ((reg) != FORCEWAKE))
+ ((reg) < 0x40000) && \
+ ((reg) != FORCEWAKE) && \
+ ((reg) != ECOBUS))
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4a9c1b9..8ba88cf 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -107,6 +107,7 @@ struct opregion_header;
struct opregion_acpi;
struct opregion_swsci;
struct opregion_asle;
+struct drm_i915_private;
struct intel_opregion {
struct opregion_header *header;
@@ -221,6 +222,8 @@ struct drm_i915_display_funcs {
struct drm_i915_gem_object *obj);
int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
int x, int y);
+ void (*force_wake_get)(struct drm_i915_private *dev_priv);
+ void (*force_wake_put)(struct drm_i915_private *dev_priv);
/* clock updates for mode set */
/* cursor updates */
/* render clock increase/decrease */
@@ -1308,6 +1311,11 @@ extern void gen6_set_rps(struct drm_device *dev, u8 val);
extern void intel_detect_pch(struct drm_device *dev);
extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
+extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
+extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv);
+
/* overlay */
#ifdef CONFIG_DEBUG_FS
extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
@@ -1352,8 +1360,9 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
(((dev_priv)->info->gen >= 6) && \
- ((reg) < 0x40000) && \
- ((reg) != FORCEWAKE))
+ ((reg) < 0x40000) && \
+ ((reg) != FORCEWAKE) && \
+ ((reg) != ECOBUS))
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b080cc8..8990057 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3449,6 +3449,10 @@
#define FORCEWAKE 0xA18C
#define FORCEWAKE_ACK 0x130090
+#define FORCEWAKE_MT 0xa188 /* multi-threaded */
+#define FORCEWAKE_MT_ACK 0x130040
+#define ECOBUS 0xa180
+#define FORCEWAKE_MT_ENABLE (1<<5)
#define GT_FIFO_FREE_ENTRIES 0x120008
#define GT_FIFO_NUM_RESERVED_ENTRIES 20
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e77a863..633c693 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8491,6 +8491,28 @@ static void intel_init_display(struct drm_device *dev)
/* For FIFO watermark updates */
if (HAS_PCH_SPLIT(dev)) {
+ dev_priv->display.force_wake_get = __gen6_gt_force_wake_get;
+ dev_priv->display.force_wake_put = __gen6_gt_force_wake_put;
+
+ /* IVB configs may use multi-threaded forcewake */
+ if (IS_IVYBRIDGE(dev)) {
+ u32 ecobus;
+
+ mutex_lock(&dev->struct_mutex);
+ __gen6_gt_force_wake_mt_get(dev_priv);
+ ecobus = I915_READ(ECOBUS);
+ __gen6_gt_force_wake_mt_put(dev_priv);
+ mutex_unlock(&dev->struct_mutex);
+
+ if (ecobus & FORCEWAKE_MT_ENABLE) {
+ DRM_DEBUG_KMS("Using MT version of forcewake\n");
+ dev_priv->display.force_wake_get =
+ __gen6_gt_force_wake_mt_get;
+ dev_priv->display.force_wake_put =
+ __gen6_gt_force_wake_mt_put;
+ }
+ }
+
if (HAS_PCH_IBX(dev))
dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating;
else if (HAS_PCH_CPT(dev))
--
1.7.7.3
--
keith.packard@intel.com
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
2011-11-19 5:33 ` Keith Packard
@ 2011-11-21 15:47 ` Robert Hooker
0 siblings, 0 replies; 11+ messages in thread
From: Robert Hooker @ 2011-11-21 15:47 UTC (permalink / raw)
To: Keith Packard; +Cc: intel-gfx
On Sat, Nov 19, 2011 at 12:33 AM, Keith Packard <keithp@keithp.com> wrote:
> On Fri, 18 Nov 2011 14:48:39 -0800, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
>
>> So the ECOBUS reg *is* in the GT power well. Which means in order to
>> read it we have to disable RC6 altogether, forcibly, using the 0xa090
>> reg, set up force wake, then re-enable RC6.
>
> Here's what I cooked up -- it uses the MT version of the force wake code
> to make the ECOBUS value visible. Seems to work for me, but additional
> testing is encouraged. In particular, it'd be good to test on your
> existing machine which *isn't* using MT forcewake.
>
> From b23581d5c978c96266f690239cc0d5f19480df98 Mon Sep 17 00:00:00 2001
> From: Keith Packard <keithp@keithp.com>
> Date: Fri, 18 Nov 2011 20:39:01 -0800
> Subject: [PATCH 1/2] drm/i915: add multi-threaded forcewake support
>
> On IVB C0+ with newer BIOSes, the forcewake handshake has changed. There's
> now a bitfield for different driver components to keep the GT powered
> on. On Linux, we centralize forcewake handling in one place, so we
> still just need a single bit, but we need to use the new registers if MT
> forcewake is enabled.
>
> This needs testing on affected machines. Please reply with your
> tested-by if you had problems after a BIOS upgrade and this patch fixes
> them.
>
> v2: force MT mode. shift by 16
> v3: set MT force wake bits then check ECOBUS
>
> Tested-by: Keith Packard <keithp@keithp.com>
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
> drivers/gpu/drm/i915/i915_drv.c | 35 ++++++++++++++++++++++++++++-----
> drivers/gpu/drm/i915/i915_drv.h | 13 ++++++++++-
> drivers/gpu/drm/i915/i915_reg.h | 4 +++
> drivers/gpu/drm/i915/intel_display.c | 22 +++++++++++++++++++++
> 4 files changed, 66 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 13488be..bd82ef0 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -327,7 +327,7 @@ void intel_detect_pch(struct drm_device *dev)
> }
> }
>
> -static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
> +void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
> {
> int count;
>
> @@ -343,6 +343,22 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
> udelay(10);
> }
>
> +void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
> +{
> + int count;
> +
> + count = 0;
> + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
> + udelay(10);
> +
> + I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1);
> + POSTING_READ(FORCEWAKE_MT);
> +
> + count = 0;
> + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
> + udelay(10);
> +}
> +
> /*
> * 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
> @@ -355,15 +371,21 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
>
> /* Forcewake is atomic in case we get in here without the lock */
> if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
> - __gen6_gt_force_wake_get(dev_priv);
> + dev_priv->display.force_wake_get(dev_priv);
> }
>
> -static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
> +void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
> {
> I915_WRITE_NOTRACE(FORCEWAKE, 0);
> POSTING_READ(FORCEWAKE);
> }
>
> +void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
> +{
> + I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
> + POSTING_READ(FORCEWAKE_MT);
> +}
> +
> /*
> * see gen6_gt_force_wake_get()
> */
> @@ -372,7 +394,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
> WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
>
> if (atomic_dec_and_test(&dev_priv->forcewake_count))
> - __gen6_gt_force_wake_put(dev_priv);
> + dev_priv->display.force_wake_put(dev_priv);
> }
>
> void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
> @@ -902,8 +924,9 @@ MODULE_LICENSE("GPL and additional rights");
> /* We give fast paths for the really cool registers */
> #define NEEDS_FORCE_WAKE(dev_priv, reg) \
> (((dev_priv)->info->gen >= 6) && \
> - ((reg) < 0x40000) && \
> - ((reg) != FORCEWAKE))
> + ((reg) < 0x40000) && \
> + ((reg) != FORCEWAKE) && \
> + ((reg) != ECOBUS))
>
> #define __i915_read(x, y) \
> u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 4a9c1b9..8ba88cf 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -107,6 +107,7 @@ struct opregion_header;
> struct opregion_acpi;
> struct opregion_swsci;
> struct opregion_asle;
> +struct drm_i915_private;
>
> struct intel_opregion {
> struct opregion_header *header;
> @@ -221,6 +222,8 @@ struct drm_i915_display_funcs {
> struct drm_i915_gem_object *obj);
> int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> int x, int y);
> + void (*force_wake_get)(struct drm_i915_private *dev_priv);
> + void (*force_wake_put)(struct drm_i915_private *dev_priv);
> /* clock updates for mode set */
> /* cursor updates */
> /* render clock increase/decrease */
> @@ -1308,6 +1311,11 @@ extern void gen6_set_rps(struct drm_device *dev, u8 val);
> extern void intel_detect_pch(struct drm_device *dev);
> extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
>
> +extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
> +extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
> +extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
> +extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv);
> +
> /* overlay */
> #ifdef CONFIG_DEBUG_FS
> extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
> @@ -1352,8 +1360,9 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
> /* We give fast paths for the really cool registers */
> #define NEEDS_FORCE_WAKE(dev_priv, reg) \
> (((dev_priv)->info->gen >= 6) && \
> - ((reg) < 0x40000) && \
> - ((reg) != FORCEWAKE))
> + ((reg) < 0x40000) && \
> + ((reg) != FORCEWAKE) && \
> + ((reg) != ECOBUS))
>
> #define __i915_read(x, y) \
> u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index b080cc8..8990057 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3449,6 +3449,10 @@
>
> #define FORCEWAKE 0xA18C
> #define FORCEWAKE_ACK 0x130090
> +#define FORCEWAKE_MT 0xa188 /* multi-threaded */
> +#define FORCEWAKE_MT_ACK 0x130040
> +#define ECOBUS 0xa180
> +#define FORCEWAKE_MT_ENABLE (1<<5)
>
> #define GT_FIFO_FREE_ENTRIES 0x120008
> #define GT_FIFO_NUM_RESERVED_ENTRIES 20
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index e77a863..633c693 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -8491,6 +8491,28 @@ static void intel_init_display(struct drm_device *dev)
>
> /* For FIFO watermark updates */
> if (HAS_PCH_SPLIT(dev)) {
> + dev_priv->display.force_wake_get = __gen6_gt_force_wake_get;
> + dev_priv->display.force_wake_put = __gen6_gt_force_wake_put;
> +
> + /* IVB configs may use multi-threaded forcewake */
> + if (IS_IVYBRIDGE(dev)) {
> + u32 ecobus;
> +
> + mutex_lock(&dev->struct_mutex);
> + __gen6_gt_force_wake_mt_get(dev_priv);
> + ecobus = I915_READ(ECOBUS);
> + __gen6_gt_force_wake_mt_put(dev_priv);
> + mutex_unlock(&dev->struct_mutex);
> +
> + if (ecobus & FORCEWAKE_MT_ENABLE) {
> + DRM_DEBUG_KMS("Using MT version of forcewake\n");
> + dev_priv->display.force_wake_get =
> + __gen6_gt_force_wake_mt_get;
> + dev_priv->display.force_wake_put =
> + __gen6_gt_force_wake_mt_put;
> + }
> + }
> +
> if (HAS_PCH_IBX(dev))
> dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating;
> else if (HAS_PCH_CPT(dev))
> --
> 1.7.7.3
>
> --
> keith.packard@intel.com
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>
Keith's version works here as well on 2 ivybridge platforms, thank you!
Tested-by: Robert Hooker <robert.hooker@canonical.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] drm/i915: add multi-threaded forcewake support
2011-11-21 6:55 ` Fang, XunX
@ 2011-12-05 22:42 ` Jesse Barnes
0 siblings, 0 replies; 11+ messages in thread
From: Jesse Barnes @ 2011-12-05 22:42 UTC (permalink / raw)
To: Fang, XunX; +Cc: intel-gfx@lists.freedesktop.org
[-- Attachment #1.1: Type: text/plain, Size: 4769 bytes --]
On Mon, 21 Nov 2011 14:55:51 +0800
"Fang, XunX" <xunx.fang@intel.com> wrote:
> void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
> @@ -902,8 +924,9 @@ MODULE_LICENSE("GPL and additional rights");
> /* We give fast paths for the really cool registers */
> #define NEEDS_FORCE_WAKE(dev_priv, reg) \
> (((dev_priv)->info->gen >= 6) && \
> - ((reg) < 0x40000) && \
> - ((reg) != FORCEWAKE))
> + ((reg) < 0x40000) && \
> + ((reg) != FORCEWAKE) && \
> + ((reg) != ECOBUS))
Both instances of this macro need to drop the ECOBUS check now that we
know it's in the GT power well.
>
> #define __i915_read(x, y) \
> u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 4a9c1b9..8ba88cf 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -107,6 +107,7 @@ struct opregion_header;
> struct opregion_acpi;
> struct opregion_swsci;
> struct opregion_asle;
> +struct drm_i915_private;
>
> struct intel_opregion {
> struct opregion_header *header;
> @@ -221,6 +222,8 @@ struct drm_i915_display_funcs {
> struct drm_i915_gem_object *obj);
> int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> int x, int y);
> + void (*force_wake_get)(struct drm_i915_private *dev_priv);
> + void (*force_wake_put)(struct drm_i915_private *dev_priv);
> /* clock updates for mode set */
> /* cursor updates */
> /* render clock increase/decrease */
> @@ -1308,6 +1311,11 @@ extern void gen6_set_rps(struct drm_device *dev, u8 val);
> extern void intel_detect_pch(struct drm_device *dev);
> extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
>
> +extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
> +extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv);
> +extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
> +extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv);
> +
> /* overlay */
> #ifdef CONFIG_DEBUG_FS
> extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev);
> @@ -1352,8 +1360,9 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
> /* We give fast paths for the really cool registers */
> #define NEEDS_FORCE_WAKE(dev_priv, reg) \
> (((dev_priv)->info->gen >= 6) && \
> - ((reg) < 0x40000) && \
> - ((reg) != FORCEWAKE))
> + ((reg) < 0x40000) && \
> + ((reg) != FORCEWAKE) && \
> + ((reg) != ECOBUS))
>
> #define __i915_read(x, y) \
> u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index b080cc8..8990057 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3449,6 +3449,10 @@
>
> #define FORCEWAKE 0xA18C
> #define FORCEWAKE_ACK 0x130090
> +#define FORCEWAKE_MT 0xa188 /* multi-threaded */
> +#define FORCEWAKE_MT_ACK 0x130040
> +#define ECOBUS 0xa180
> +#define FORCEWAKE_MT_ENABLE (1<<5)
>
> #define GT_FIFO_FREE_ENTRIES 0x120008
> #define GT_FIFO_NUM_RESERVED_ENTRIES 20
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index e77a863..633c693 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -8491,6 +8491,28 @@ static void intel_init_display(struct drm_device *dev)
>
> /* For FIFO watermark updates */
> if (HAS_PCH_SPLIT(dev)) {
> + dev_priv->display.force_wake_get = __gen6_gt_force_wake_get;
> + dev_priv->display.force_wake_put = __gen6_gt_force_wake_put;
> +
> + /* IVB configs may use multi-threaded forcewake */
> + if (IS_IVYBRIDGE(dev)) {
> + u32 ecobus;
> +
> + mutex_lock(&dev->struct_mutex);
> + __gen6_gt_force_wake_mt_get(dev_priv);
> + ecobus = I915_READ(ECOBUS);
> + __gen6_gt_force_wake_mt_put(dev_priv);
> + mutex_unlock(&dev->struct_mutex);
> +
> + if (ecobus & FORCEWAKE_MT_ENABLE) {
> + DRM_DEBUG_KMS("Using MT version of forcewake\n");
> + dev_priv->display.force_wake_get =
> + __gen6_gt_force_wake_mt_get;
> + dev_priv->display.force_wake_put =
> + __gen6_gt_force_wake_mt_put;
> + }
> + }
I think we need:
I915_WRITE(GEN6_RC_STATE, 0);
I915_WRITE(GEN6_RC_SLEEP, 0);
above the force_wake_get here. And as long as it comes before
enable_rps, we'll properly re-enable RC6 and turbo later.
Anyone want to test with the suggested changes and report back?
Thanks,
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-12-05 22:40 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-18 19:36 [PATCH] drm/i915: add multi-threaded forcewake support Jesse Barnes
2011-11-18 22:01 ` Keith Packard
2011-11-18 22:12 ` Jesse Barnes
2011-11-18 22:35 ` Keith Packard
2011-11-18 22:48 ` Jesse Barnes
2011-11-18 23:27 ` Keith Packard
2011-11-18 23:34 ` Ben Widawsky
2011-11-19 5:33 ` Keith Packard
2011-11-21 15:47 ` Robert Hooker
[not found] <B32E3D5F1713054290B4FF257B89C51A2E8F496B66@shsmsx502.ccr.corp.intel.com>
2011-11-21 6:55 ` Fang, XunX
2011-12-05 22:42 ` Jesse Barnes
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.