On Mon, Mar 18, 2013 at 04:56:02PM +0100, Jiri Kosina wrote: > Okay, so I think that for 3.9 we want the patch below, and if eventually > hardware root cause / workaround is found for GM45, we can have it merged > later. > > > > From: Jiri Kosina <jkosina@xxxxxxx> > Subject: [PATCH] drm/i915: stop using GMBUS IRQs on Gen4 chips > > Commit 28c70f162 ("drm/i915: use the gmbus irq for waits") switched to > using GMBUS irqs instead of GPIO bit-banging for chipset generations 4 > and above. > > It turns out though that on many systems this leads to spurious interrupts > being generated, long after the register write to disable the IRQs has been > issued. > > Flushing of the register writes by POSTING_READ() directly after the register > write doesn't work either. > > Disable using of GMBUS IRQs on Gen4 systems before the root cause is found and > revert back to old behavior. > > Also be more careful about not issuing GMBUS4 register reads in > gmbus_wait_hw_status() if we are not using GMBUS IRQs. > > Signed-off-by: Jiri Kosina <jkosina@xxxxxxx> > --- > drivers/gpu/drm/i915/intel_i2c.c | 12 ++++++++++-- > 1 files changed, 10 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c > index acf8aec..8638036 100644 > --- a/drivers/gpu/drm/i915/intel_i2c.c > +++ b/drivers/gpu/drm/i915/intel_i2c.c > @@ -58,12 +58,14 @@ to_intel_gmbus(struct i2c_adapter *i2c) > return container_of(i2c, struct intel_gmbus, adapter); > } > > +#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) > void > intel_i2c_reset(struct drm_device *dev) > { > struct drm_i915_private *dev_priv = dev->dev_private; > I915_WRITE(dev_priv->gpio_mmio_base + GMBUS0, 0); > - I915_WRITE(dev_priv->gpio_mmio_base + GMBUS4, 0); > + if (HAS_GMBUS_IRQ(dev)) > + I915_WRITE(dev_priv->gpio_mmio_base + GMBUS4, 0); There should not be any harm in always clearing GMBUS4, it exists on all platforms. > } > > static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable) > @@ -203,7 +205,6 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin) > algo->data = bus; > } > > -#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 4) > static int > gmbus_wait_hw_status(struct drm_i915_private *dev_priv, > u32 gmbus2_status, > @@ -214,6 +215,13 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv, > u32 gmbus2 = 0; > DEFINE_WAIT(wait); > > + if (!HAS_GMBUS_IRQ(dev_priv->dev)) { > + int ret; > + ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) & > + (GMBUS_SATOER | gmbus2_status), > + 50); This should couple up to the normal return code that chooses the appropriate return value based on gmbus2. How about just using: if (!HAS_GMBUS_IRQ(dev_priv->dev)) gmbus4_irq_en = 0; and the existing wait loop? > + return ret; > + } > /* Important: The hw handles only the first bit, so set only one! Since > * we also need to check for NAKs besides the hw ready/idle signal, we > * need to wake up periodically and check that ourselves. */ -- Chris Wilson, Intel Open Source Technology Centre _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel