On Thu, Jun 28, 2012 at 03:55:40PM -0300, Eugeni Dodonov wrote: > On Haswell, there is a different register for reading force wake ACKs, and > all the writes should go into the multi-threaded register, even for the > legacy force wake. > > Also, we have a theorical possibility for the force wake sequence to > awaken the GT, but return while it hasn't finished bringing up the queue. > So we properly check those bits as well, to ensure we won't end up in > half-woken situation. > > Signed-off-by: Eugeni Dodonov <eugeni.dodonov at intel.com> This patch didn't survive review with the *shhh* intel top secret *ssshhh* power docs ;-) It looks like we're supposed to poll for the ack from the hw on the _same_ reg as we've used in the MT forcewake register until the bit is set (for get) or cleared (for put). Also, calling the helper function hsw_wait_gt_ack makes more sense then. -Daniel > --- > drivers/gpu/drm/i915/i915_drv.c | 36 +++++++++++++++++++++++++++++++++++- > drivers/gpu/drm/i915/i915_drv.h | 3 +++ > drivers/gpu/drm/i915/i915_reg.h | 1 + > drivers/gpu/drm/i915/intel_pm.c | 4 +++- > 4 files changed, 42 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c > index 79be879..73fd38a 100644 > --- a/drivers/gpu/drm/i915/i915_drv.c > +++ b/drivers/gpu/drm/i915/i915_drv.c > @@ -536,6 +536,39 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) > return ret; > } > > +static inline void __hsw_wait_gt_awake(struct drm_i915_private *dev_priv) > +{ > + int count = 0; > + > + while (count++ < 50) { > + u32 tmp = I915_READ_NOTRACE(FORCEWAKE_ACK_HSW); > + if ((tmp & 1) && !(tmp & _MASKED_BIT_ENABLE(~7))) > + break; > + udelay(10); > + } > +} > + > + > +void hsw_gt_force_wake_get(struct drm_i915_private *dev_priv) > +{ > + __hsw_wait_gt_awake(dev_priv); > + > + I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); > + POSTING_READ(FORCEWAKE_MT); > + > + __hsw_wait_gt_awake(dev_priv); > +} > + > +void hsw_gt_force_wake_put(struct drm_i915_private *dev_priv) > +{ > + I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); > + > + __hsw_wait_gt_awake(dev_priv); > + > + /* The below doubles as a POSTING_READ */ > + gen6_gt_check_fifodbg(dev_priv); > +} > + > void vlv_force_wake_get(struct drm_i915_private *dev_priv) > { > int count; > @@ -1161,7 +1194,8 @@ MODULE_LICENSE("GPL and additional rights"); > #define NEEDS_FORCE_WAKE(dev_priv, reg) \ > ((HAS_FORCE_WAKE((dev_priv)->dev)) && \ > ((reg) < 0x40000) && \ > - ((reg) != FORCEWAKE)) > + ((reg) != FORCEWAKE) && \ > + ((reg) != FORCEWAKE_MT)) > > static bool IS_DISPLAYREG(u32 reg) > { > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index a0c15ab..e4916a0 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1525,6 +1525,9 @@ extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv); > extern void vlv_force_wake_get(struct drm_i915_private *dev_priv); > extern void vlv_force_wake_put(struct drm_i915_private *dev_priv); > > +extern void hsw_gt_force_wake_get(struct drm_i915_private *dev_priv); > +extern void hsw_gt_force_wake_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); > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 284965b..2c4be2e 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -4070,6 +4070,7 @@ > #define FORCEWAKE 0xA18C > #define FORCEWAKE_VLV 0x1300b0 > #define FORCEWAKE_ACK_VLV 0x1300b4 > +#define FORCEWAKE_ACK_HSW 0x130044 > #define FORCEWAKE_ACK 0x130090 > #define FORCEWAKE_MT 0xa188 /* multi-threaded */ > #define FORCEWAKE_MT_ACK 0x130040 > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c > index 99bc1f3..0334e42 100644 > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -3769,7 +3769,7 @@ void intel_init_pm(struct drm_device *dev) > dev_priv->display.force_wake_put = __gen6_gt_force_wake_put; > > /* IVB configs may use multi-threaded forcewake */ > - if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { > + if (IS_IVYBRIDGE(dev)) { > u32 ecobus; > > /* A small trick here - if the bios hasn't configured MT forcewake, > @@ -3842,6 +3842,8 @@ void intel_init_pm(struct drm_device *dev) > } > dev_priv->display.init_clock_gating = ivybridge_init_clock_gating; > dev_priv->display.sanitize_pm = gen6_sanitize_pm; > + dev_priv->display.force_wake_get = hsw_gt_force_wake_get; > + dev_priv->display.force_wake_put = hsw_gt_force_wake_put; > } else > dev_priv->display.update_wm = NULL; > } else if (IS_VALLEYVIEW(dev)) { > -- > 1.7.11.1 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Mail: daniel at ffwll.ch Mobile: +41 (0)79 365 57 48