[Intel-gfx] [PATCH 1/4] drm/i915: extract gmbus_wait_hw_status
Ben Widawsky
ben at bwidawsk.net
Sat Sep 8 19:11:17 CEST 2012
On 2012-09-06 00:09, Daniel Vetter wrote:
> The gmbus interrupt generation is rather fiddly: We can only ever
> enable one interrupt source (but we always want to check for NAK
> in addition to the real bit). And the bits in the gmbus status
> register don't map at all to the bis in the irq register.
>
> To prepare for this mess, start by extracting the hw status wait
> loop into it's own function, consolidate the NAK error handling a
> bit. To keep things flexible, pass in the status bit we care about
> (in addition to any NAK signalling).
>
> v2: I've failed to notice that the sens of GMBUS_ACTIVE is inverted,
> Chris Wilson gladly pointed that out for me. To keep things simple,
> ignore that case for now (we only need to idle the gmbus controller
> at the end of an entire i2c transaction, not after every message).
>
> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> ---
> drivers/gpu/drm/i915/intel_i2c.c | 46
> ++++++++++++++++++++++------------------
> 1 file changed, 25 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_i2c.c
> b/drivers/gpu/drm/i915/intel_i2c.c
> index b9755f6..57decac 100644
> --- a/drivers/gpu/drm/i915/intel_i2c.c
> +++ b/drivers/gpu/drm/i915/intel_i2c.c
> @@ -204,6 +204,24 @@ intel_gpio_setup(struct intel_gmbus *bus, u32
> pin)
> }
>
> static int
> +gmbus_wait_hw_status(struct drm_i915_private *dev_priv,
> + u32 gmbus2_status)
> +{
> + int ret;
> + int reg_offset = dev_priv->gpio_mmio_base;
> + u32 gmbus2;
> +
> + ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) &
> + (GMBUS_SATOER | gmbus2_status),
> + 50);
> +
> + if (gmbus2 & GMBUS_SATOER)
> + return -ENXIO;
> +
> + return ret;
> +}
> +
> +static int
> gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg
> *msg,
> u32 gmbus1_index)
> {
I know this isn't new to your patch, but the consolidation leaves a
good opportunity for clarification of the timeout via a comment.
I started digging in to the math a bit here for the 50ms timeout and
was left confused. I believe we're off by a factor of 10 here for a
worst case which would be a 50KHz bus speed. Comments?
> @@ -220,15 +238,10 @@ gmbus_xfer_read(struct drm_i915_private
> *dev_priv, struct i2c_msg *msg,
> while (len) {
> int ret;
> u32 val, loop = 0;
> - u32 gmbus2;
>
> - ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) &
> - (GMBUS_SATOER | GMBUS_HW_RDY),
> - 50);
> + ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY);
> if (ret)
> - return -ETIMEDOUT;
> - if (gmbus2 & GMBUS_SATOER)
> - return -ENXIO;
> + return ret;
>
> val = I915_READ(GMBUS3 + reg_offset);
> do {
> @@ -262,7 +275,6 @@ gmbus_xfer_write(struct drm_i915_private
> *dev_priv, struct i2c_msg *msg)
> GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
> while (len) {
> int ret;
> - u32 gmbus2;
>
> val = loop = 0;
> do {
> @@ -271,13 +283,9 @@ gmbus_xfer_write(struct drm_i915_private
> *dev_priv, struct i2c_msg *msg)
>
> I915_WRITE(GMBUS3 + reg_offset, val);
>
> - ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) &
> - (GMBUS_SATOER | GMBUS_HW_RDY),
> - 50);
> + ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY);
> if (ret)
> - return -ETIMEDOUT;
> - if (gmbus2 & GMBUS_SATOER)
> - return -ENXIO;
> + return ret;
> }
> return 0;
> }
> @@ -346,8 +354,6 @@ gmbus_xfer(struct i2c_adapter *adapter,
> I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
>
> for (i = 0; i < num; i++) {
> - u32 gmbus2;
> -
> if (gmbus_is_index_read(msgs, i, num)) {
> ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
> i += 1; /* set i to the index of the read xfer */
> @@ -362,13 +368,11 @@ gmbus_xfer(struct i2c_adapter *adapter,
> if (ret == -ENXIO)
> goto clear_err;
>
> - ret = wait_for((gmbus2 = I915_READ(GMBUS2 + reg_offset)) &
> - (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE),
> - 50);
> + ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_WAIT_PHASE);
> + if (ret == -ENXIO)
> + goto clear_err;
> if (ret)
> goto timeout;
> - if (gmbus2 & GMBUS_SATOER)
> - goto clear_err;
> }
>
> /* Generate a STOP condition on the bus. Note that gmbus can't
> generata
--
Ben Widawsky, Intel Open Source Technology Center
More information about the Intel-gfx
mailing list