Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2013-03-13 Thread panpan2523
Ash Shoes are one of the leading brands in the modern footwear industry. Lots
of people now prefer to wear shoes from this particular brand because they
become accustom to their high quality and superb fit. Ash has revolutionized
the footwear industry by combining it with the fashion industry.  Check out
this
http://onlyashshoes.com/goods-109-Virgin-Bis-Sneaker-Blue-Denim-312023.html 
These shoes will surely add a new dimension to your wardrobe. The shoes as
well as boots from Ash are manufactured using the most advanced shoe making
technology in combination with high quality materials and expert
craftsmanship. This helps in fulfilling the various requirements of
different people. You will get shoes that are ideal for both formal and
casual occasions. Innovative collections are introduced each season to
satisfy the consumers. Many of the shoes in their collection are both
practical and stylish, making them an excellent choice for day to day
use.br /br /br /



--
View this message in context: 
http://linuxppc.10917.n7.nabble.com/Patch-v2-1-2-5200-mpc-improve-i2c-bus-error-recovery-tp9637p69233.html
Sent from the linuxppc-dev mailing list archive at Nabble.com.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-06-16 Thread Albrecht Dreß

Am 19.05.10 18:02 schrieb(en) Grant Likely:

 That's http://git.secretlab.ca/?p=linux-2.6.git;a=shortlog, isn't it?
  Hmmm, didn't find it there... :-/

Ugh... Stupid typing too fast.  I meant to say, I *don't* think ben
has asked me to take...

Well this leaves a bit of a mess.  I'll make sure it gets in one way or another.


*ping*  Any news about this issue?

Cheers, Albrecht.


pgpzHfLOVT5IJ.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-05-19 Thread Grant Likely
On Sun, May 16, 2010 at 11:47 AM, Albrecht Dreß albrecht.dr...@arcor.de wrote:
 Am 06.05.10 20:06 schrieb(en) Grant Likely:

  I think, though, the whole stuff has been discussed in depth in
  February, so
  I do not understand why it's still pending as new.  Grant, did we miss
  something here?

 I generally let subsystem maintainers pick up the device driver
 patches for embedded platforms I'm responsible for unless I'm asked to
 do otherwise.  I think ben has asked me to take these through my tree.

 That's http://git.secretlab.ca/?p=linux-2.6.git;a=shortlog, isn't it?
  Hmmm, didn't find it there... :-/

Ugh... Stupid typing too fast.  I meant to say, I *don't* think ben
has asked me to take...

Well this leaves a bit of a mess.  I'll make sure it gets in one way or another.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-05-16 Thread Albrecht Dreß

Am 06.05.10 20:06 schrieb(en) Grant Likely:

 I think, though, the whole stuff has been discussed in depth in February, so
 I do not understand why it's still pending as new.  Grant, did we miss
 something here?

I generally let subsystem maintainers pick up the device driver
patches for embedded platforms I'm responsible for unless I'm asked to
do otherwise.  I think ben has asked me to take these through my tree.


That's http://git.secretlab.ca/?p=linux-2.6.git;a=shortlog, isn't it?  Hmmm, 
didn't find it there... :-/

Best, Albrecht.


pgpiayWmxyQC6.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-05-06 Thread Albrecht Dreß

Am 06.05.10 00:09 schrieb(en) Ira W. Snyder:

Did this series get forgotten about? I don't see it in bjdook's next-i2c branch 
or in benh's next branch.


It's not in Grant's 5xxx tree either - as it's specific for those processors, I think he 
might be the responsible person.  The patch is still in a new state in 
patchwork, btw.


I've pulled these into my 2.6.31.13 kernel, and they seem to work fine. You've 
got my Tested-by if you didn't get one from me already.


Tanks a lot!

I think, though, the whole stuff has been discussed in depth in February, so I do not 
understand why it's still pending as new.  Grant, did we miss something here?

Thanks, Albrecht.


pgpNIA6G1dPFQ.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-05-06 Thread Grant Likely
On Thu, May 6, 2010 at 7:54 PM, Albrecht Dreß albrecht.dr...@arcor.de wrote:
 Am 06.05.10 00:09 schrieb(en) Ira W. Snyder:

 Did this series get forgotten about? I don't see it in bjdook's next-i2c
 branch or in benh's next branch.

 It's not in Grant's 5xxx tree either - as it's specific for those
 processors, I think he might be the responsible person.  The patch is still
 in a new state in patchwork, btw.

 I've pulled these into my 2.6.31.13 kernel, and they seem to work fine.
 You've got my Tested-by if you didn't get one from me already.

 Tanks a lot!

 I think, though, the whole stuff has been discussed in depth in February, so
 I do not understand why it's still pending as new.  Grant, did we miss
 something here?

I generally let subsystem maintainers pick up the device driver
patches for embedded platforms I'm responsible for unless I'm asked to
do otherwise.  I think ben has asked me to take these through my tree.

g.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-05-05 Thread Ira W. Snyder
On Wed, Feb 17, 2010 at 07:59:14PM +0100, Albrecht Dreß wrote:
 This patch improves the recovery of the MPC's I2C bus from errors like bus
 hangs resulting in timeouts:
 1. make the bus timeout configurable, as it depends on the bus clock and
 the attached slave chip(s); default is still 1 second;
 2. detect any of the cases indicated by the CF, BB and RXAK MSR flags if a
 timeout occurs, and add a missing (required) MAL reset;
 3. use a more reliable method to fixup the bus if a hang has been detected.
 The sequence is sent 9 times which seems to be necessary if a slave
 misses more than one clock cycle.  For 400 kHz bus speed, the fixup is
 also ~70us (81us vs. 150us) faster.
 
 Tested on a custom Lite5200b derived board, with a Dallas RTC, AD sensors
 and NXP IO expander chips attached to the i2c.
 
 Changes vs. v1:
 - use improved bus fixup sequence for all chips (not only the 5200)
 - calculate real clock from defaults if no clock is given in the device tree
 - better description (I hope) of the changes.
 
 I didn't split the changes in this file into three parts as recommended by
 Grant, as they actually belong together (i.e. they address one single
 problem, just in three places of one single source file).
 
 Signed-off-by: Albrecht Dreß albrecht.dr...@arcor.de
 
 ---
 
 Note about the reset sequence: I verified the waveforms for 18.4kHz, 85.9kHz
 and 375kHz (drop me a note if you want to see scope screen shots).  Not
 verified on other mpc chips yet.
 @Ira: thanks in advance for giving it a try on your box!
 

Did this series get forgotten about? I don't see it in bjdook's next-i2c
branch or in benh's next branch.

I've pulled these into my 2.6.31.13 kernel, and they seem to work fine.
You've got my Tested-by if you didn't get one from me already.

Ira

 --- linux-2.6.32-orig/drivers/i2c/busses/i2c-mpc.c2009-12-03 
 04:51:21.0 +0100
 +++ linux-2.6.32/drivers/i2c/busses/i2c-mpc.c 2010-02-17 16:23:11.0 
 +0100
 @@ -59,6 +59,7 @@ struct mpc_i2c {
   wait_queue_head_t queue;
   struct i2c_adapter adap;
   int irq;
 + u32 real_clk;
   };
 
   struct mpc_i2c_divider {
 @@ -93,20 +94,23 @@ static irqreturn_t mpc_i2c_isr(int irq,
   /* Sometimes 9th clock pulse isn't generated, and slave doesn't release
* the bus, because it wants to send ACK.
* Following sequence of enabling/disabling and sending start/stop generates
 - * the pulse, so it's all OK.
 + * the 9 pulses, so it's all OK.
*/
   static void mpc_i2c_fixup(struct mpc_i2c *i2c)
   {
 - writeccr(i2c, 0);
 - udelay(30);
 - writeccr(i2c, CCR_MEN);
 - udelay(30);
 - writeccr(i2c, CCR_MSTA | CCR_MTX);
 - udelay(30);
 - writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
 - udelay(30);
 - writeccr(i2c, CCR_MEN);
 - udelay(30);
 + int k;
 + u32 delay_val = 100 / i2c-real_clk + 1;
 +
 + if (delay_val  2)
 + delay_val = 2;
 +
 + for (k = 9; k; k--) {
 + writeccr(i2c, 0);
 + writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
 + udelay(delay_val);
 + writeccr(i2c, CCR_MEN);
 + udelay(delay_val  1);
 + }
   }
 
   static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
 @@ -186,15 +190,19 @@ static const struct mpc_i2c_divider mpc_
   {10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
   };
 
 -int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
 +int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler,
 +  u32 *real_clk)
   {
   const struct mpc_i2c_divider *div = NULL;
   unsigned int pvr = mfspr(SPRN_PVR);
   u32 divider;
   int i;
 
 - if (!clock)
 + if (!clock) {
 + /* see below - default fdr = 0x3f - div = 2048 */
 + *real_clk = mpc5xxx_get_bus_frequency(node) / 2048;
   return -EINVAL;
 + }
 
   /* Determine divider value */
   divider = mpc5xxx_get_bus_frequency(node) / clock;
 @@ -212,7 +220,8 @@ int mpc_i2c_get_fdr_52xx(struct device_n
   break;
   }
 
 - return div ? (int)div-fdr : -EINVAL;
 + *real_clk = mpc5xxx_get_bus_frequency(node) / div-divider;
 + return (int)div-fdr;
   }
 
   static void mpc_i2c_setclock_52xx(struct device_node *node,
 @@ -221,13 +230,14 @@ static void mpc_i2c_setclock_52xx(struct
   {
   int ret, fdr;
 
 - ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
 + ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, i2c-real_clk);
   fdr = (ret = 0) ? ret : 0x3f; /* backward compatibility */
 
   writeb(fdr  0xff, i2c-base + MPC_I2C_FDR);
 
   if (ret = 0)
 - dev_info(i2c-dev, clock %d Hz (fdr=%d)\n, clock, fdr);
 + dev_info(i2c-dev, clock %u Hz (fdr=%d)\n, i2c-real_clk,
 +  fdr);
   }
   #else /* !CONFIG_PPC_MPC52xx */
   static void mpc_i2c_setclock_52xx(struct device_node *node,
 @@ 

Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-18 Thread Joakim Tjernlund

 This patch improves the recovery of the MPC's I2C bus from errors like bus
 hangs resulting in timeouts:
 1. make the bus timeout configurable, as it depends on the bus clock and
 the attached slave chip(s); default is still 1 second;
 2. detect any of the cases indicated by the CF, BB and RXAK MSR flags if a
 timeout occurs, and add a missing (required) MAL reset;
 3. use a more reliable method to fixup the bus if a hang has been detected.
 The sequence is sent 9 times which seems to be necessary if a slave
 misses more than one clock cycle.  For 400 kHz bus speed, the fixup is
 also ~70us (81us vs. 150us) faster.

 Tested on a custom Lite5200b derived board, with a Dallas RTC, AD sensors
 and NXP IO expander chips attached to the i2c.

 Changes vs. v1:
 - use improved bus fixup sequence for all chips (not only the 5200)
 - calculate real clock from defaults if no clock is given in the device tree
 - better description (I hope) of the changes.

 I didn't split the changes in this file into three parts as recommended by
 Grant, as they actually belong together (i.e. they address one single
 problem, just in three places of one single source file).

 Signed-off-by: Albrecht Dreß albrecht.dr...@arcor.de

 ---

 Note about the reset sequence: I verified the waveforms for 18.4kHz, 85.9kHz
 and 375kHz (drop me a note if you want to see scope screen shots).  Not
 verified on other mpc chips yet.
 @Ira: thanks in advance for giving it a try on your box!

Does this reset sequence also send a START condition for every clock?
The ideal I2C reset sequence should look like this:

for(j = 0; j  9; j++) {
if(I2C_READ)
send_start();
I2C_SCL(0);
I2C_DELAY;
I2C_TRISTATE;
I2C_SDA(1);
I2C_DELAY;
I2C_SCL(1);
I2C_DELAY;
I2C_DELAY;
}
send_stop();

static void send_start(void)
{
I2C_DELAY;
I2C_TRISTATE;
I2C_SDA(1);
I2C_DELAY;
I2C_SCL(1);
I2C_DELAY;
I2C_SDA(0);
I2C_ACTIVE;
I2C_DELAY;
}

static void send_stop(void)
{
I2C_SCL(0);
I2C_DELAY;
I2C_SDA(0);
I2C_ACTIVE;
I2C_DELAY;
I2C_SCL(1);
I2C_DELAY;
I2C_TRISTATE;
I2C_SDA(1);
I2C_DELAY;
}

 Jocke

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-18 Thread Albrecht Dre�
Hi Joakim:

 Does this reset sequence also send a START condition for every clock?

Please see the attached scan from a scope output, showing the first two out of 
the 9 sequences at 375 kHz (that's what the 5200's divider makes from 400 kHz 
requested).  Resolution is 2us/div and 1V/div for both signals.  The waveform 
itself for each of the 9 sequences is exactly the same we had before with the 
old solution, just the timing is faster and adjusted to the ii2c clock, i.e. 
the /relative/ waveforms look identical for slower clocks.

Any insight if this is *really* correct would be great, as I'm not an i2c 
expert.  I can only say it reliably fixes the bus hangs I saw!

Thanks,
Albrecht.

Immer auf dem Laufenden! Sport, Auto, Reise, Politik und Promis. Von uns für 
Sie: der neue Arcor.de-Newsletter!
Jetzt anmelden und einfach alles wissen: 
http://www.arcor.de/rd/footer.newsletterattachment: i2c-fixup.png___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-18 Thread Joakim Tjernlund
Albrecht Dreß albrecht.dr...@arcor.de wrote on 2010/02/18 10:09:23:

 Hi Joakim:

  Does this reset sequence also send a START condition for every clock?

 Please see the attached scan from a scope output, showing the first two out of
 the 9 sequences at 375 kHz (that's what the 5200's divider makes from 400 kHz
 requested).  Resolution is 2us/div and 1V/div for both signals.  The waveform
 itself for each of the 9 sequences is exactly the same we had before with the
 old solution, just the timing is faster and adjusted to the ii2c clock, i.e.
 the /relative/ waveforms look identical for slower clocks.

 Any insight if this is *really* correct would be great, as I'm not an i2c
 expert.  I can only say it reliably fixes the bus hangs I saw!

Looks like you do a STOP then START each time SCL is high so yes you
do a START each SCL and a STOP too. Don't think the STOP will hurt though.

Timing is OK for FAST-MODE(400kHz), cannot say for STANDARD-MODE though
need a 100Khz scope img for that.

The times to look for are:
tHD;STA, tSU;STA, tSU;STO and tBUF
at least that is what I have identified.

   Jocke

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-18 Thread Joakim Tjernlund

 @@ -93,20 +94,23 @@ static irqreturn_t mpc_i2c_isr(int irq,
   /* Sometimes 9th clock pulse isn't generated, and slave doesn't release
* the bus, because it wants to send ACK.
* Following sequence of enabling/disabling and sending start/stop generates
 - * the pulse, so it's all OK.
 + * the 9 pulses, so it's all OK.
*/
   static void mpc_i2c_fixup(struct mpc_i2c *i2c)
   {
 -   writeccr(i2c, 0);
 -   udelay(30);
 -   writeccr(i2c, CCR_MEN);
 -   udelay(30);
 -   writeccr(i2c, CCR_MSTA | CCR_MTX);
 -   udelay(30);
 -   writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
 -   udelay(30);
 -   writeccr(i2c, CCR_MEN);
 -   udelay(30);
 +   int k;
 +   u32 delay_val = 100 / i2c-real_clk + 1;
 +
 +   if (delay_val  2)
 +  delay_val = 2;
 +
 +   for (k = 9; k; k--) {
 +  writeccr(i2c, 0);
 +  writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
 +  udelay(delay_val);
 +  writeccr(i2c, CCR_MEN);
 +  udelay(delay_val  1);
 +   }
   }

I am curious, didn't old method work with by just wrapping
a for(k=9; k; k--) around it? How did the wave form look?

   Jocke

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-18 Thread Albrecht Dre�
Hi Joakim:

[snip]
static void mpc_i2c_fixup(struct mpc_i2c *i2c)
{
  -   writeccr(i2c, 0);
  -   udelay(30);
  -   writeccr(i2c, CCR_MEN);
  -   udelay(30);
  -   writeccr(i2c, CCR_MSTA | CCR_MTX);
  -   udelay(30);
  -   writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
  -   udelay(30);
  -   writeccr(i2c, CCR_MEN);
  -   udelay(30);
  +   int k;
  +   u32 delay_val = 100 / i2c-real_clk + 1;
  +
  +   if (delay_val  2)
  +  delay_val = 2;
  +
  +   for (k = 9; k; k--) {
  +  writeccr(i2c, 0);
  +  writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
  +  udelay(delay_val);
  +  writeccr(i2c, CCR_MEN);
  +  udelay(delay_val  1);
  +   }
}
 
 I am curious, didn't old method work with by just wrapping
 a for(k=9; k; k--) around it? How did the wave form look?

Sure does that work!  The waveform was somewhat streched, mainly due to the 
delays between some of the writeccr() calls which don't change the sda/scl 
lines.  Unfortunately I didn't take shots from the scope.

However, for *one* cycle, the old code needed (only counting the udelay's) 150 
us.  For 9 cycles, it's 1.35 ms, which isn't really nice ;-).  At 375 kHz real 
clock rate, delay_val is 3, i.e. each cycle consumes 9 us, or 81 us for the 
whole fixup procedure.  If the clock is slower, the gain is of course a lot 
smaller, and at 20.5 kHz each cycle again needs 150 us...

My feeling is that the delays used in the old code are just some values which 
work for sure, to if you like, my change is basically optimisation...

BTW, related to your earlier question, I checked the timings recorded with the 
scope at 100 and at 20 kHz against the nxp's I2C bus specification and user 
manual, rev. 03 - everything seems to be fine.

Thanks, Albrecht.

Immer auf dem Laufenden! Sport, Auto, Reise, Politik und Promis. Von uns für 
Sie: der neue Arcor.de-Newsletter!
Jetzt anmelden und einfach alles wissen: 
http://www.arcor.de/rd/footer.newsletter
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-18 Thread Joakim Tjernlund
Albrecht Dreß albrecht.dr...@arcor.de wrote on 2010/02/18 16:04:16:

 Hi Joakim:

 [snip]
 static void mpc_i2c_fixup(struct mpc_i2c *i2c)
 {
   -   writeccr(i2c, 0);
   -   udelay(30);
   -   writeccr(i2c, CCR_MEN);
   -   udelay(30);
   -   writeccr(i2c, CCR_MSTA | CCR_MTX);
   -   udelay(30);
   -   writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
   -   udelay(30);
   -   writeccr(i2c, CCR_MEN);
   -   udelay(30);
   +   int k;
   +   u32 delay_val = 100 / i2c-real_clk + 1;
   +
   +   if (delay_val  2)
   +  delay_val = 2;
   +
   +   for (k = 9; k; k--) {
   +  writeccr(i2c, 0);
   +  writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
   +  udelay(delay_val);
   +  writeccr(i2c, CCR_MEN);
   +  udelay(delay_val  1);
   +   }
 }
 
  I am curious, didn't old method work with by just wrapping
  a for(k=9; k; k--) around it? How did the wave form look?

 Sure does that work!  The waveform was somewhat streched, mainly due to the
 delays between some of the writeccr() calls which don't change the sda/scl
 lines.  Unfortunately I didn't take shots from the scope.

Yeah, the long delays has to go. So the wave form was the same but more 
stretched
in time? I ask because I don't understand the writeccr(i2c, CCR_MSTA | CCR_MTX);
is supposed to do.


 However, for *one* cycle, the old code needed (only counting the udelay's) 150
 us.  For 9 cycles, it's 1.35 ms, which isn't really nice ;-).  At 375 kHz real
 clock rate, delay_val is 3, i.e. each cycle consumes 9 us, or 81 us for the
 whole fixup procedure.  If the clock is slower, the gain is of course a lot
 smaller, and at 20.5 kHz each cycle again needs 150 us...

 My feeling is that the delays used in the old code are just some values
 which work for sure, to if you like, my change is basically optimisation...

The old code only works when the device is stuck at the last bit. To cope
with any bit (worst case is the first bit) you need 9 cycles, 8 bits + ack = 9

Just toggling the clock 9 cycles should unlock any slave stuck in a read 
operation.
To unlock slaves stuck in a write operation you also need to generate a START in
every cycle too.

As far as I can tell your patch does all of the above so

Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se


 BTW, related to your earlier question, I checked the timings recorded with the
 scope at 100 and at 20 kHz against the nxp's I2C bus specification and user
 manual, rev. 03 - everything seems to be fine.

Good, thanks.

 Jocke

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-18 Thread Grant Likely
On Thu, Feb 18, 2010 at 10:14 AM, Joakim Tjernlund
joakim.tjernl...@transmode.se wrote:
 Albrecht Dreß albrecht.dr...@arcor.de wrote on 2010/02/18 16:04:16:
 As far as I can tell your patch does all of the above so

 Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se

Thanks Joakim.  On a point of process; Signed-off-by means that
you've actually handled the patch and forwarded it on, either by
reposting or putting it in a git tree for someone to pull.  The
Signed-off-by trail collects a history of all the people who have
touched a patch during its development and merging.

Reviewers can use Acked-by: or Reviewed-by: to indicate their consent.
 Ben can add your annotation when he merges the patch into his i2c
tree.

Cheers,
g.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-18 Thread Joakim Tjernlund
glik...@secretlab.ca wrote on 2010/02/18 18:41:40:

 On Thu, Feb 18, 2010 at 10:14 AM, Joakim Tjernlund
 joakim.tjernl...@transmode.se wrote:
  Albrecht Dreß albrecht.dr...@arcor.de wrote on 2010/02/18 16:04:16:
  As far as I can tell your patch does all of the above so
 
  Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se

 Thanks Joakim.  On a point of process; Signed-off-by means that
 you've actually handled the patch and forwarded it on, either by
 reposting or putting it in a git tree for someone to pull.  The
 Signed-off-by trail collects a history of all the people who have
 touched a patch during its development and merging.

 Reviewers can use Acked-by: or Reviewed-by: to indicate their consent.
  Ben can add your annotation when he merges the patch into his i2c
 tree.

I see, then please change that to
Acked-by: Joakim Tjernlund joakim.tjernl...@transmode.se


Thanks,
Jocke

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-18 Thread Albrecht Dreß

Hi Joakim:

Am 18.02.10 18:14 schrieb(en) Joakim Tjernlund:

 [snip]
 static void mpc_i2c_fixup(struct mpc_i2c *i2c)
 {
   -   writeccr(i2c, 0);
   -   udelay(30);
   -   writeccr(i2c, CCR_MEN);
   -   udelay(30);
   -   writeccr(i2c, CCR_MSTA | CCR_MTX);
   -   udelay(30);
   -   writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
   -   udelay(30);
   -   writeccr(i2c, CCR_MEN);
   -   udelay(30);
   +   int k;
   +   u32 delay_val = 100 / i2c-real_clk + 1;
   +
   +   if (delay_val  2)
   +  delay_val = 2;
   +
   +   for (k = 9; k; k--) {
   +  writeccr(i2c, 0);
   +  writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
   +  udelay(delay_val);
   +  writeccr(i2c, CCR_MEN);
   +  udelay(delay_val  1);
   +   }
 }
 

I am curious, didn't old method work with by just wrapping a for(k=9; k; k--) 
around it? How did the wave form look?



Sure does that work!  The waveform was somewhat streched, mainly due to the 
delays between some of the writeccr() calls which don't change the sda/scl lines.  
Unfortunately I didn't take shots from the scope.


Yeah, the long delays has to go. So the wave form was the same but more 
stretched in time? I ask because I don't understand the writeccr(i2c, CCR_MSTA 
| CCR_MTX); is supposed to do.


Afaict, this is really a no-op.  The '5200 user's manual says about MEN

snip
* 0 module is reset and disabled. This is the Power-ON reset. When low the 
interface is held in reset, but registers can still be accessed.
* 1 I2C module is enabled. Bit must be set before other CR bits have any effect.
/snip

The change in the MSTA is needed -with the proper delays- as to generate the 
START and STOP conditions.

Unfortunately, the data sheet is not very clear (or my English too bad), but 
reading it *after* seeing the signals on the scope, I can at least guess what 
they mean :-/

Thus, the old code will probably produce SDA and SCL held high for ~90us, then 
a SDA/SCL low for ~30us (plus/minus the delays the hw adds internally according 
to the clock setting), and then a ~30us SDA/SCL high.  It is not possible to 
get the necessary delays from the data sheet, but as I said I empirically 
verified some cases to be safe.


The old code only works when the device is stuck at the last bit. To cope with 
any bit (worst case is the first bit) you need 9 cycles, 8 bits + ack = 9

Just toggling the clock 9 cycles should unlock any slave stuck in a read 
operation. To unlock slaves stuck in a write operation you also need to 
generate a START in every cycle too.


Yes, of course...  this was the initial motivation of the patch, as I *have* a 
slave which sometimes needs more than one cycle!


As far as I can tell your patch does all of the above so

Signed-off-by: Joakim Tjernlund joakim.tjernl...@transmode.se


Thanks a lot again for your time, and your helpful comments!

Best, Albrecht.


pgpmK1BnBMsNC.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [Patch v2 1/2] 5200/mpc: improve i2c bus error recovery

2010-02-17 Thread Grant Likely
On Wed, Feb 17, 2010 at 11:59 AM, Albrecht Dreß albrecht.dr...@arcor.de wrote:
 This patch improves the recovery of the MPC's I2C bus from errors like bus
 hangs resulting in timeouts:
 1. make the bus timeout configurable, as it depends on the bus clock and
   the attached slave chip(s); default is still 1 second;
 2. detect any of the cases indicated by the CF, BB and RXAK MSR flags if a
   timeout occurs, and add a missing (required) MAL reset;
 3. use a more reliable method to fixup the bus if a hang has been detected.
   The sequence is sent 9 times which seems to be necessary if a slave
   misses more than one clock cycle.  For 400 kHz bus speed, the fixup is
   also ~70us (81us vs. 150us) faster.

 Tested on a custom Lite5200b derived board, with a Dallas RTC, AD sensors
 and NXP IO expander chips attached to the i2c.

 Changes vs. v1:
 - use improved bus fixup sequence for all chips (not only the 5200)
 - calculate real clock from defaults if no clock is given in the device tree
 - better description (I hope) of the changes.

 I didn't split the changes in this file into three parts as recommended by
 Grant, as they actually belong together (i.e. they address one single
 problem, just in three places of one single source file).

 Signed-off-by: Albrecht Dreß albrecht.dr...@arcor.de

Acked-by: Grant Likely grant.lik...@secretlab.ca


 ---

 Note about the reset sequence: I verified the waveforms for 18.4kHz, 85.9kHz
 and 375kHz (drop me a note if you want to see scope screen shots).  Not
 verified on other mpc chips yet.
 @Ira: thanks in advance for giving it a try on your box!


 --- linux-2.6.32-orig/drivers/i2c/busses/i2c-mpc.c      2009-12-03
 04:51:21.0 +0100
 +++ linux-2.6.32/drivers/i2c/busses/i2c-mpc.c   2010-02-17
 16:23:11.0 +0100
 @@ -59,6 +59,7 @@ struct mpc_i2c {
        wait_queue_head_t queue;
        struct i2c_adapter adap;
        int irq;
 +       u32 real_clk;
  };

  struct mpc_i2c_divider {
 @@ -93,20 +94,23 @@ static irqreturn_t mpc_i2c_isr(int irq,
  /* Sometimes 9th clock pulse isn't generated, and slave doesn't release
  * the bus, because it wants to send ACK.
  * Following sequence of enabling/disabling and sending start/stop generates
 - * the pulse, so it's all OK.
 + * the 9 pulses, so it's all OK.
  */
  static void mpc_i2c_fixup(struct mpc_i2c *i2c)
  {
 -       writeccr(i2c, 0);
 -       udelay(30);
 -       writeccr(i2c, CCR_MEN);
 -       udelay(30);
 -       writeccr(i2c, CCR_MSTA | CCR_MTX);
 -       udelay(30);
 -       writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
 -       udelay(30);
 -       writeccr(i2c, CCR_MEN);
 -       udelay(30);
 +       int k;
 +       u32 delay_val = 100 / i2c-real_clk + 1;
 +
 +       if (delay_val  2)
 +               delay_val = 2;
 +
 +       for (k = 9; k; k--) {
 +               writeccr(i2c, 0);
 +               writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
 +               udelay(delay_val);
 +               writeccr(i2c, CCR_MEN);
 +               udelay(delay_val  1);
 +       }
  }

  static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
 @@ -186,15 +190,19 @@ static const struct mpc_i2c_divider mpc_
        {10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
  };

 -int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int
 prescaler)
 +int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int
 prescaler,
 +                        u32 *real_clk)
  {
        const struct mpc_i2c_divider *div = NULL;
        unsigned int pvr = mfspr(SPRN_PVR);
        u32 divider;
        int i;

 -       if (!clock)
 +       if (!clock) {
 +               /* see below - default fdr = 0x3f - div = 2048 */
 +               *real_clk = mpc5xxx_get_bus_frequency(node) / 2048;
                return -EINVAL;
 +       }

        /* Determine divider value */
        divider = mpc5xxx_get_bus_frequency(node) / clock;
 @@ -212,7 +220,8 @@ int mpc_i2c_get_fdr_52xx(struct device_n
                        break;
        }

 -       return div ? (int)div-fdr : -EINVAL;
 +       *real_clk = mpc5xxx_get_bus_frequency(node) / div-divider;
 +       return (int)div-fdr;
  }

  static void mpc_i2c_setclock_52xx(struct device_node *node,
 @@ -221,13 +230,14 @@ static void mpc_i2c_setclock_52xx(struct
  {
        int ret, fdr;

 -       ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
 +       ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, i2c-real_clk);
        fdr = (ret = 0) ? ret : 0x3f; /* backward compatibility */

        writeb(fdr  0xff, i2c-base + MPC_I2C_FDR);

        if (ret = 0)
 -               dev_info(i2c-dev, clock %d Hz (fdr=%d)\n, clock, fdr);
 +               dev_info(i2c-dev, clock %u Hz (fdr=%d)\n, i2c-real_clk,
 +                        fdr);
  }
  #else /* !CONFIG_PPC_MPC52xx */
  static void mpc_i2c_setclock_52xx(struct device_node *node,
 @@ -287,14 +297,18 @@ u32 mpc_i2c_get_sec_cfg_8xxx(void)
        return val;
  }

 -int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32