From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heiko Schocher Date: Thu, 30 Oct 2014 07:55:10 +0100 Subject: [U-Boot] [PATCH v1 2/2] ppc4xx: Handle i2c stuck on combined xfer In-Reply-To: <1414594604-30219-3-git-send-email-dirk.eibach@gdsys.cc> References: <1414594604-30219-1-git-send-email-dirk.eibach@gdsys.cc> <1414594604-30219-3-git-send-email-dirk.eibach@gdsys.cc> Message-ID: <5451E0CE.7090007@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hello Dirk, Am 29.10.2014 15:56, schrieb dirk.eibach at gdsys.cc: > From: Dirk Eibach > > ppc4xx i2c master gets stuck on errors while repeated start is > active. Can be easily reproduced by "i2c md" on an unpopulated > i2c address. There is not stop condition given, scl remains > pulled low. > The only way out seems to be doing a stop manually and then a > soft reset. > > Signed-off-by: Dirk Eibach > --- > > arch/powerpc/include/asm/ppc4xx-i2c.h | 2 ++ > drivers/i2c/ppc4xx_i2c.c | 21 +++++++++++++++++++++ > 2 files changed, 23 insertions(+) > > diff --git a/arch/powerpc/include/asm/ppc4xx-i2c.h b/arch/powerpc/include/asm/ppc4xx-i2c.h > index 09189cf..df97f17 100644 > --- a/arch/powerpc/include/asm/ppc4xx-i2c.h > +++ b/arch/powerpc/include/asm/ppc4xx-i2c.h > @@ -72,6 +72,8 @@ struct ppc4xx_i2c { > #define IIC_EXTSTS_XFRA 0x01 > #define IIC_EXTSTS_ICT 0x02 > #define IIC_EXTSTS_LA 0x04 > +#define IIC_EXTSTS_BCS_MASK 0x70 > +#define IIC_EXTSTS_BCS_FREE 0x40 > > /* XTCNTLSS Register Bit definition */ > #define IIC_XTCNTLSS_SRST 0x01 > diff --git a/drivers/i2c/ppc4xx_i2c.c b/drivers/i2c/ppc4xx_i2c.c > index d2ff86c..df88885 100644 > --- a/drivers/i2c/ppc4xx_i2c.c > +++ b/drivers/i2c/ppc4xx_i2c.c > @@ -289,6 +289,27 @@ static int _i2c_transfer(struct i2c_adapter *adap, > /* Transfer aborted? */ > if (status& IIC_EXTSTS_XFRA) > result = IIC_NOK_XFRA; > + /* Is bus free? Nitpick only: wrong comment style ... Is it OK for you, if I fix it, when applying this patch? Thanks! bye, Heiko > + * If error happened during combined xfer > + * IIC interface is usually stuck in some strange > + * state without a valid stop condition. > + * Brute, but working: generate stop, then soft reset. > + */ > + if ((status& IIC_EXTSTS_BCS_MASK) > + != IIC_EXTSTS_BCS_FREE){ > + u8 mdcntl = in_8(&i2c->mdcntl); > + > + /* Generate valid stop condition */ > + out_8(&i2c->xtcntlss, IIC_XTCNTLSS_SRST); > + out_8(&i2c->directcntl, IIC_DIRCNTL_SCC); > + udelay(10); > + out_8(&i2c->directcntl, > + IIC_DIRCNTL_SCC | IIC_DIRCNTL_SDAC); > + out_8(&i2c->xtcntlss, 0); > + > + ppc4xx_i2c_init(adap, (mdcntl& IIC_MDCNTL_FSM) > + ? 400000 : 100000, 0); > + } > } else if ( status& IIC_STS_PT) { > result = IIC_NOK_TOUT; > } -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany