From mboxrd@z Thu Jan 1 00:00:00 1970 From: Keith Packard Subject: Re: [PATCH] drm/i915: add multi-threaded forcewake support Date: Fri, 18 Nov 2011 21:33:55 -0800 Message-ID: <86hb20llq4.fsf@sumi.keithp.com> References: <20111118113632.594717c8@jbarnes-desktop> <86y5vdks4j.fsf@sumi.keithp.com> <20111118141203.14ddde98@jbarnes-desktop> <86pqgpkqj9.fsf@sumi.keithp.com> <20111118144839.21458831@jbarnes-desktop> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1803860227==" Return-path: Received: from keithp.com (home.keithp.com [63.227.221.253]) by gabe.freedesktop.org (Postfix) with ESMTP id DDE3F9E802 for ; Fri, 18 Nov 2011 21:34:06 -0800 (PST) In-Reply-To: <20111118144839.21458831@jbarnes-desktop> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org To: Jesse Barnes Cc: intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org --===============1803860227== Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha256; protocol="application/pgp-signature" --=-=-= Content-Transfer-Encoding: quoted-printable On Fri, 18 Nov 2011 14:48:39 -0800, Jesse Barnes = 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=20b23581d5c978c96266f690239cc0d5f19480df98 Mon Sep 17 00:00:00 2001 From: Keith Packard 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 Signed-off-by: Jesse Barnes Signed-off-by: Keith Packard =2D-- 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_dr= v.c index 13488be..bd82ef0 100644 =2D-- 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) } } =20 =2Dstatic 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; =20 @@ -343,6 +343,22 @@ static void __gen6_gt_force_wake_get(struct drm_i915_p= rivate *dev_priv) udelay(10); } =20 +void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) +{ + int count; + + count =3D 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 =3D 0; + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) =3D=3D 0) + udelay(10); +} + /* * Generally this is called implicitly by the register read function. Howe= ver, * if some sequence requires the GT to not power down then this function s= hould @@ -355,15 +371,21 @@ void gen6_gt_force_wake_get(struct drm_i915_private *= dev_priv) =20 /* Forcewake is atomic in case we get in here without the lock */ if (atomic_add_return(1, &dev_priv->forcewake_count) =3D=3D 1) =2D __gen6_gt_force_wake_get(dev_priv); + dev_priv->display.force_wake_get(dev_priv); } =20 =2Dstatic 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); } =20 +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 *de= v_priv) WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); =20 if (atomic_dec_and_test(&dev_priv->forcewake_count)) =2D __gen6_gt_force_wake_put(dev_priv); + dev_priv->display.force_wake_put(dev_priv); } =20 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 >=3D 6) && \ =2D ((reg) < 0x40000) && \ =2D ((reg) !=3D FORCEWAKE)) + ((reg) < 0x40000) && \ + ((reg) !=3D FORCEWAKE) && \ + ((reg) !=3D ECOBUS)) =20 #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_dr= v.h index 4a9c1b9..8ba88cf 100644 =2D-- 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; =20 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); =20 +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 >=3D 6) && \ =2D ((reg) < 0x40000) && \ =2D ((reg) !=3D FORCEWAKE)) + ((reg) < 0x40000) && \ + ((reg) !=3D FORCEWAKE) && \ + ((reg) !=3D ECOBUS)) =20 #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_re= g.h index b080cc8..8990057 100644 =2D-- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3449,6 +3449,10 @@ =20 #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) =20 #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/in= tel_display.c index e77a863..633c693 100644 =2D-- 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 *de= v) =20 /* For FIFO watermark updates */ if (HAS_PCH_SPLIT(dev)) { + dev_priv->display.force_wake_get =3D __gen6_gt_force_wake_get; + dev_priv->display.force_wake_put =3D __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 =3D 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 =3D + __gen6_gt_force_wake_mt_get; + dev_priv->display.force_wake_put =3D + __gen6_gt_force_wake_mt_put; + } + } + if (HAS_PCH_IBX(dev)) dev_priv->display.init_pch_clock_gating =3D ibx_init_clock_gating; else if (HAS_PCH_CPT(dev)) =2D-=20 1.7.7.3 =2D-=20 keith.packard@intel.com --=-=-= Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIVAwUBTsc/wzYtFsjWk68qAQi22g/9EO1PsW/CsmTb/9qlMA+v1rS1Vj5GC5Dz /nOs49L/nw81qqzP/vXJ07Gdj66d7tUwqC+pDoHC8Ec1zLTAu3m5+1KkFzD9Y7qB uvpI9dBxi7ysfWC6ziQcB/FzHoi1uf4qwsSQgF14s+kRXd9b9HKWSqkrIK080bHd N3KhC8J9UTskDlvzuto3tamj8rlXoql5nbcfYjM60oNr8ya2plmmOawWPGZT0/lF 4b1YlbCX+Zp4Y3cyIRYkuL9Oyx3w6UO8jLmW4JGQcx4elGF0lFs+BEnnQ7cuMUfA EWTocH/pSoKHeiQNl0anm/e9/jQUYgXfrGePFx9l7fI0erPpIH0qeVIJKu5ruBOf 6/3jdRn1Tu1TQXfk6LUg5dz59d+yteRK+P1zCwf30ux+BO+7vX6GiTCUekqhqkzu lKc6k7GfRHAka8RFhk6K7sRT6BI6wvsVQ3upOgJKmgauGscM1GhDnb/JaFDac5VF cuctOSSakpEN8Gy/brgG/u2nkNnIT1HKO0scBkTFo8VVKD1pEDoChAslCmy+Tpud eotF2LPd1GVLdUnzfomKiGOxlFpA+RM5N+lCiICBvdC9COMae6LBazUAbhR6/PmF FdHmFpbM/0n/2IVUggz/COw7rQM5Y8BZaZazP/N1dwKxLaC1C4VVGXAKWcwKrPyP STBboljr/CY= =JjtS -----END PGP SIGNATURE----- --=-=-=-- --===============1803860227== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx --===============1803860227==--