Skip to contentSkip to conversation

Powerpc/i2c: Use the same initialize codes

PATCH New Chang-Ming.Huang at freescale.com 4 participants 15 messages Oct 27, 2011 – Nov 4, 2011 I2C

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 Powerpc/i2c: Use the same initialize codes

From: Jerry Huang <[email protected]>

Make the I2C2 and I2C1 use the same initialize codes.

---
 drivers/i2c/fsl_i2c.c |   47 +++++++++++++++++++++++++----------------------
 1 files changed, 25 insertions(+), 22 deletions(-)
drivers/i2c/fsl_i2c.c +25 -22
index cb13dee..258be0a 100644
@@ -214,11 +214,20 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c *dev,
 	return speed;
 }
 
+unsigned int get_i2c_clock(int bus)
+{
+	if (bus)
+		return gd->i2c2_clk;	/* I2C2 clock */
+	else
+		return gd->i2c1_clk;	/* I2C1 clock */
+}
+
 void
 i2c_init(int speed, int slaveadd)
 {
 	struct fsl_i2c *dev;
 	unsigned int temp;
+	int bus_num, i;
 
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 	/* Call board specific i2c bus reset routine before accessing the
@@ -227,29 +236,23 @@ i2c_init(int speed, int slaveadd)
 	*/
 	i2c_init_board();
 #endif
-	dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
-
-	writeb(0, &dev->cr);			/* stop I2C controller */
-	udelay(5);				/* let it shutdown in peace */
-	temp = set_i2c_bus_speed(dev, gd->i2c1_clk, speed);
-	if (gd->flags & GD_FLG_RELOC)
-		i2c_bus_speed[0] = temp;
-	writeb(slaveadd << 1, &dev->adr);	/* write slave address */
-	writeb(0x0, &dev->sr);			/* clear status register */
-	writeb(I2C_CR_MEN, &dev->cr);		/* start I2C controller */
-
-#ifdef	CONFIG_SYS_I2C2_OFFSET
-	dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C2_OFFSET);
-
-	writeb(0, &dev->cr);			/* stop I2C controller */
-	udelay(5);				/* let it shutdown in peace */
-	temp = set_i2c_bus_speed(dev, gd->i2c2_clk, speed);
-	if (gd->flags & GD_FLG_RELOC)
-		i2c_bus_speed[1] = temp;
-	writeb(slaveadd << 1, &dev->adr);	/* write slave address */
-	writeb(0x0, &dev->sr);			/* clear status register */
-	writeb(I2C_CR_MEN, &dev->cr);		/* start I2C controller */
+#ifdef CONFIG_SYS_I2C2_OFFSET
+	bus_num = 2;
+#else
+	bus_num = 1;
 #endif
+	for (i = 0; i < bus_num; i++) {
+		dev = i2c_dev[i];
+
+		writeb(0, &dev->cr);		/* stop I2C controller */
+		udelay(5);			/* let it shutdown in peace */
+		temp = set_i2c_bus_speed(dev, get_i2c_clock(i), speed);
+		if (gd->flags & GD_FLG_RELOC)
+			i2c_bus_speed[i] = temp;
+		writeb(slaveadd << 1, &dev->adr);/* write slave address */
+		writeb(0x0, &dev->sr);		/* clear status register */
+		writeb(I2C_CR_MEN, &dev->cr);	/* start I2C controller */
+	}
 
 #ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT
 	/* Call board specific i2c bus reset routine AFTER the bus has been
Signature · 1 line
1.7.4.1
#1 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

From: Jerry Huang <[email protected]>

It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction.

---
 drivers/i2c/fsl_i2c.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
drivers/i2c/fsl_i2c.c +18 -0
index 258be0a..007db70 100644
@@ -252,6 +252,24 @@ i2c_init(int speed, int slaveadd)
 		writeb(slaveadd << 1, &dev->adr);/* write slave address */
 		writeb(0x0, &dev->sr);		/* clear status register */
 		writeb(I2C_CR_MEN, &dev->cr);	/* start I2C controller */
+
+		/* Force I2C module to become bus master which can occure when
+		 * a system reset does not cause all I2C devices to be reset */
+		udelay(5);
+		if (readb(&dev->sr) & I2C_SR_MBB) {
+			writeb(I2C_CR_MSTA, &dev->cr);
+			udelay(5);
+			writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
+			udelay(5);
+			readb(&dev->dr);
+			udelay(5);
+			writeb(I2C_CR_MEN, &dev->cr);
+			udelay(5);
+			if (readb(&dev->sr) & I2C_SR_MBB)
+				debug("I2C%d: Drive SCL failed\n", i + 1);
+			else
+				debug("I2C%d: Drive SCL succeed\n", i + 1);
+		}
 	}
 
 #ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

Hello Chang-Ming,

Quoted 21 lines · Chang-Ming.Huang at freescale.com

From: Jerry Huang <[email protected]>

It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction.

---
 drivers/i2c/fsl_i2c.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
drivers/i2c/fsl_i2c.c +0 -0
index 258be0a..007db70 100644

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 257

Quoted 6 lines
drivers/i2c/fsl_i2c.c +3 -0
@@ -252,6 +252,24 @@ i2c_init(int speed, int slaveadd)
 		writeb(slaveadd << 1, &dev->adr);/* write slave address */
 		writeb(0x0, &dev->sr);		/* clear status register */
 		writeb(I2C_CR_MEN, &dev->cr);	/* start I2C controller */
+
+		/* Force I2C module to become bus master which can occure when
+		 * a system reset does not cause all I2C devices to be reset */

Checkpatch doesn't warn, but wrong comment style here, please change.

[...]

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#3 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

In reply to Chang-Ming.Huang at freescale.com
Quoted 23 lines

From: <[email protected]>

From: Jerry Huang <[email protected]>

It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction.

---
 drivers/i2c/fsl_i2c.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
drivers/i2c/fsl_i2c.c +0 -0
index 258be0a..007db70 100644

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 259

Quoted 8 lines
drivers/i2c/fsl_i2c.c +5 -0
@@ -252,6 +252,24 @@ i2c_init(int speed, int slaveadd)
       writeb(slaveadd << 1, &dev->adr);/* write slave address */
       writeb(0x0, &dev->sr);      /* clear status register */
       writeb(I2C_CR_MEN, &dev->cr);   /* start I2C controller */
+
+      /* Force I2C module to become bus master which can occure when
+       * a system reset does not cause all I2C devices to be reset */
+      udelay(5);
+      if (readb(&dev->sr) & I2C_SR_MBB) {

You need to the sequence unconditionally, the slave can be stuck without driving SCL.

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 272

Quoted 13 lines
drivers/i2c/fsl_i2c.c +13 -0
+         writeb(I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         readb(&dev->dr);
+         udelay(5);
+         writeb(I2C_CR_MEN, &dev->cr);
+         udelay(5);
+         if (readb(&dev->sr) & I2C_SR_MBB)
+            debug("I2C%d: Drive SCL failed\n", i + 1);
+         else
+            debug("I2C%d: Drive SCL succeed\n", i + 1);
+      }

The above sequence is different than the kernel version, why?

Kernel version below:
static?void?mpc_i2c_fixup(struct?mpc_i2c?*i2c)
{
????????int?k; ????????u32?delay_val?=?1000000?/?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);
????????}
}

#4 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

Thanks and Best Regards
Jerry Huang

Quoted 59 lines

-----Original Message-----
From: Joakim Tjernlund [mailto:joakim.tjernlund at transmode.se]
Sent: Thursday, October 27, 2011 3:26 PM
To: Huang Changming-R66093
Cc: u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH 2/2] Powerpc/i2c: Force i2c to become bus master out of reset

Quoted 8 lines

From: <[email protected]>

From: Jerry Huang <[email protected]>

It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA

can

Quoted 15 lines

be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction.

---
 drivers/i2c/fsl_i2c.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
drivers/i2c/fsl_i2c.c index renamed from drivers/i2c/fsl_i2c.c +0 -0

258be0a..007db70 100644

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 257

Quoted 6 lines
drivers/i2c/fsl_i2c.c +3 -0
@@ -252,6 +252,24 @@ i2c_init(int speed, int slaveadd)
       writeb(slaveadd << 1, &dev->adr);/* write slave address */
       writeb(0x0, &dev->sr);      /* clear status register */
       writeb(I2C_CR_MEN, &dev->cr);   /* start I2C controller */
+
+      /* Force I2C module to become bus master which can occure when
+       * a system reset does not cause all I2C devices to be reset

*/

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 259

Quoted 2 lines
drivers/i2c/fsl_i2c.c +2 -0
+      udelay(5);
+      if (readb(&dev->sr) & I2C_SR_MBB) {

You need to the sequence unconditionally, the slave can be stuck without driving SCL.

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 272

Quoted 13 lines
drivers/i2c/fsl_i2c.c +13 -0
+         writeb(I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         readb(&dev->dr);
+         udelay(5);
+         writeb(I2C_CR_MEN, &dev->cr);
+         udelay(5);
+         if (readb(&dev->sr) & I2C_SR_MBB)
+            debug("I2C%d: Drive SCL failed\n", i + 1);
+         else
+            debug("I2C%d: Drive SCL succeed\n", i + 1);
+      }
Quoted 1 line

The above sequence is different than the kernel version, why?

I don't know the kernel version, but I write the u-boot code according to the Reference Manual of PowerPC, e.g p1022:
11.5.6 Generation of SCL When SDA Low
It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction:
1. Disable the I2C module and set the master bit by setting I2CCR to 0x20
2. Enable the I2C module by setting I2CCR to 0xA0
3. Read the I2CDR
4. Return the I2C module to slave mode by setting I2CCR to 0x80

#5 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

Thanks and Best Regards
Jerry Huang

Quoted 81 lines

-----Original Message-----
From: u-boot-bounces at lists.denx.de [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Huang Changming-R66093
Sent: Thursday, October 27, 2011 3:40 PM
To: Joakim Tjernlund
Cc: u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH 2/2] Powerpc/i2c: Force i2c to become bus master out of reset

Thanks and Best Regards
Jerry Huang

Quoted 6 lines

-----Original Message-----
From: Joakim Tjernlund [mailto:joakim.tjernlund at transmode.se]
Sent: Thursday, October 27, 2011 3:26 PM
To: Huang Changming-R66093
Cc: u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH 2/2] Powerpc/i2c: Force i2c to become

bus

Quoted 8 lines

master out of reset

Quoted 6 lines

From: <[email protected]>

From: Jerry Huang <[email protected]>

It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already

be

Quoted 1 line
Quoted 1 line

driven, which indicates that the bus is busy). This can occur when

a

Quoted 4 lines
Quoted 1 line

system reset does not cause all I2C devices to be reset. Thus, SDA

can

Quoted 2 lines

be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure

can

Quoted 8 lines
Quoted 8 lines

be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction.

---
 drivers/i2c/fsl_i2c.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
Quoted 10 lines

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 256

Quoted 10 lines
drivers/i2c/fsl_i2c.c index renamed from drivers/i2c/fsl_i2c.c +0 -0

258be0a..007db70 100644

drivers/i2c/fsl_i2c.c +2 -0
@@ -252,6 +252,24 @@ i2c_init(int speed, int slaveadd)
       writeb(slaveadd << 1, &dev->adr);/* write slave address */
       writeb(0x0, &dev->sr);      /* clear status register */
       writeb(I2C_CR_MEN, &dev->cr);   /* start I2C controller */
+
+      /* Force I2C module to become bus master which can occure

when

Quoted 22 lines

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 257

Quoted 1 line
drivers/i2c/fsl_i2c.c +1 -0
+       * a system reset does not cause all I2C devices to be reset

*/

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 259

Quoted 2 lines
drivers/i2c/fsl_i2c.c +2 -0
+      udelay(5);
+      if (readb(&dev->sr) & I2C_SR_MBB) {

You need to the sequence unconditionally, the slave can be stuck without driving SCL.

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 272

Quoted 13 lines
drivers/i2c/fsl_i2c.c +13 -0
+         writeb(I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         readb(&dev->dr);
+         udelay(5);
+         writeb(I2C_CR_MEN, &dev->cr);
+         udelay(5);
+         if (readb(&dev->sr) & I2C_SR_MBB)
+            debug("I2C%d: Drive SCL failed\n", i + 1);
+         else
+            debug("I2C%d: Drive SCL succeed\n", i + 1);
+      }
Quoted 1 line

The above sequence is different than the kernel version, why?

Quoted 17 lines

I don't know the kernel version, but I write the u-boot code according to the Reference Manual of PowerPC, e.g p1022:
11.5.6 Generation of SCL When SDA Low
It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction:
1. Disable the I2C module and set the master bit by setting I2CCR to 0x20
2. Enable the I2C module by setting I2CCR to 0xA0
3. Read the I2CDR
4. Return the I2C module to slave mode by setting I2CCR to 0x80

Compare with kernel version, the difference is one line:
Uboot: readb(&dev->dr);
Kernel has no any operation.
But, I check the comment of kernel, because the 9th clock pulse isn't generated, the sequence of function mpc_i2c_fixup is needed to generate 9th clock pulse.

#6 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

Huang Changming-R66093 <[email protected]> wrote on 2011/10/27 09:51:49:

Quoted 105 lines

Thanks and Best Regards
Jerry Huang

Quoted 81 lines

-----Original Message-----
From: u-boot-bounces at lists.denx.de [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Huang Changming-R66093
Sent: Thursday, October 27, 2011 3:40 PM
To: Joakim Tjernlund
Cc: u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH 2/2] Powerpc/i2c: Force i2c to become bus master out of reset

Thanks and Best Regards
Jerry Huang

Quoted 6 lines

-----Original Message-----
From: Joakim Tjernlund [mailto:joakim.tjernlund at transmode.se]
Sent: Thursday, October 27, 2011 3:26 PM
To: Huang Changming-R66093
Cc: u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH 2/2] Powerpc/i2c: Force i2c to become

bus

Quoted 8 lines

master out of reset

Quoted 6 lines

From: <[email protected]>

From: Jerry Huang <[email protected]>

It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already

be

Quoted 1 line
Quoted 1 line

driven, which indicates that the bus is busy). This can occur when

a

Quoted 4 lines
Quoted 1 line

system reset does not cause all I2C devices to be reset. Thus, SDA

can

Quoted 2 lines

be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure

can

Quoted 8 lines
Quoted 8 lines

be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction.

---
 drivers/i2c/fsl_i2c.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
Quoted 10 lines

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 256

Quoted 10 lines
drivers/i2c/fsl_i2c.c index renamed from drivers/i2c/fsl_i2c.c +0 -0

258be0a..007db70 100644

drivers/i2c/fsl_i2c.c +2 -0
@@ -252,6 +252,24 @@ i2c_init(int speed, int slaveadd)
       writeb(slaveadd << 1, &dev->adr);/* write slave address */
       writeb(0x0, &dev->sr);      /* clear status register */
       writeb(I2C_CR_MEN, &dev->cr);   /* start I2C controller */
+
+      /* Force I2C module to become bus master which can occure

when

Quoted 22 lines

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 257

Quoted 1 line
drivers/i2c/fsl_i2c.c +1 -0
+       * a system reset does not cause all I2C devices to be reset

*/

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 259

Quoted 2 lines
drivers/i2c/fsl_i2c.c +2 -0
+      udelay(5);
+      if (readb(&dev->sr) & I2C_SR_MBB) {

You need to the sequence unconditionally, the slave can be stuck without driving SCL.

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 272

Quoted 13 lines
drivers/i2c/fsl_i2c.c +13 -0
+         writeb(I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         readb(&dev->dr);
+         udelay(5);
+         writeb(I2C_CR_MEN, &dev->cr);
+         udelay(5);
+         if (readb(&dev->sr) & I2C_SR_MBB)
+            debug("I2C%d: Drive SCL failed\n", i + 1);
+         else
+            debug("I2C%d: Drive SCL succeed\n", i + 1);
+      }
Quoted 1 line

The above sequence is different than the kernel version, why?

Quoted 17 lines

I don't know the kernel version, but I write the u-boot code according to the Reference Manual of PowerPC, e.g p1022:
11.5.6 Generation of SCL When SDA Low
It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction:
1. Disable the I2C module and set the master bit by setting I2CCR to 0x20
2. Enable the I2C module by setting I2CCR to 0xA0
3. Read the I2CDR
4. Return the I2C module to slave mode by setting I2CCR to 0x80

Quoted 5 lines

Compare with kernel version, the difference is one line:
Uboot: readb(&dev->dr);
Kernel has no any operation.
But, I check the comment of kernel, because the 9th clock pulse isn't generated, the sequence of function mpc_i2c_fixup is needed to generate 9th clock pulse.

Not so, there is more than that if you look closer. The description in the kernel is a bit misleading(or so I think). I prefer the kernel version for 2 reasons:
1) It has been there for quite some time so if there were something wrong with, it should have been noticed by now.
2) I have a vauge memory of checking it again the mpc8321 manual and I was happy with it.

Jocke

#7 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

Quoted 35 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines

The above sequence is different than the kernel version, why?

I don't know the kernel version, but I write the u-boot code

according

Quoted 3 lines
Quoted 3 lines

to the Reference Manual of PowerPC, e.g p1022:
11.5.6 Generation of SCL When SDA Low
It is sometimes necessary to force the I2C module to become the I2C

bus

Quoted 1 line
Quoted 1 line

master out of reset and drive SCL(even though SDA may already be

driven,

Quoted 3 lines
Quoted 3 lines

which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming

out of

Quoted 1 line
Quoted 1 line

reset and stays low indefinitely. The following procedure can be

used

Quoted 1 line
Quoted 1 line

to force this I2C module to generate SCL so that the device driving

SDA

Quoted 2 lines
Quoted 2 lines

can finish its transaction:
1. Disable the I2C module and set the master bit by setting I2CCR

to

Quoted 9 lines
Quoted 5 lines

0x20
2. Enable the I2C module by setting I2CCR to 0xA0
3. Read the I2CDR
4. Return the I2C module to slave mode by setting I2CCR to 0x80

Compare with kernel version, the difference is one line:
Uboot: readb(&dev->dr);
Kernel has no any operation.
But, I check the comment of kernel, because the 9th clock pulse isn't

generated,

Quoted 1 line

the sequence of function mpc_i2c_fixup is needed to generate 9th

clock pulse.

Quoted 11 lines

Not so, there is more than that if you look closer. The description in the kernel
is a bit misleading(or so I think). I prefer the kernel version for 2 reasons:
1) It has been there for quite some time so if there were something wrong with,
it should have been noticed by now.
2) I have a vauge memory of checking it again the mpc8321 manual and I was happy
with it.

These tow part codes are doing the different thing due to the different reason:
1. Kernel's code:
because Sometimes 9th clock pulse isn't generated, that code is to generate the 9th clock pulse.
It happens in the DATA transfer stage.
2. My code:
because the system reset does not cause all I2C devices to be reset, the code force the i2c to become the master and drive the SCL. It happens in the i2c controller initialize stage
So, I think these code is reasonable.

BTW: My codes has been verified on Emerson's board.

#8 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

In reply to Joakim Tjernlund
Quoted 34 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line

The above sequence is different than the kernel version, why?

I don't know the kernel version, but I write the u-boot code

according

Quoted 3 lines
Quoted 3 lines

to the Reference Manual of PowerPC, e.g p1022:
11.5.6 Generation of SCL When SDA Low
It is sometimes necessary to force the I2C module to become the I2C

bus

Quoted 1 line
Quoted 1 line

master out of reset and drive SCL(even though SDA may already be

driven,

Quoted 3 lines
Quoted 3 lines

which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming

out of

Quoted 1 line
Quoted 1 line

reset and stays low indefinitely. The following procedure can be

used

Quoted 1 line
Quoted 1 line

to force this I2C module to generate SCL so that the device driving

SDA

Quoted 2 lines
Quoted 2 lines

can finish its transaction:
1. Disable the I2C module and set the master bit by setting I2CCR

to

Quoted 9 lines
Quoted 5 lines

0x20
2. Enable the I2C module by setting I2CCR to 0xA0
3. Read the I2CDR
4. Return the I2C module to slave mode by setting I2CCR to 0x80

Compare with kernel version, the difference is one line:
Uboot: readb(&dev->dr);
Kernel has no any operation.
But, I check the comment of kernel, because the 9th clock pulse isn't

generated,

Quoted 1 line

the sequence of function mpc_i2c_fixup is needed to generate 9th

clock pulse.

Quoted 11 lines

Not so, there is more than that if you look closer. The description in the kernel
is a bit misleading(or so I think). I prefer the kernel version for 2 reasons:
1) It has been there for quite some time so if there were something wrong with,
it should have been noticed by now.
2) I have a vauge memory of checking it again the mpc8321 manual and I was happy
with it.

These tow part codes are doing the different thing due to the different reason:
1. Kernel's code:
because Sometimes 9th clock pulse isn't generated, that code is to generate the 9th clock pulse.
It happens in the DATA transfer stage.
2. My code:
because the system reset does not cause all I2C devices to be reset, the code force the i2c to become the master and drive the SCL. It happens in the i2c controller initialize stage So, I think these code is reasonable.

BTW: My codes has been verified on Emerson's board.

#9 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

Huang Changming-R66093 <[email protected]> wrote on 2011/10/27 11:26:04:

Quoted 46 lines
Quoted 35 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines

The above sequence is different than the kernel version, why?

I don't know the kernel version, but I write the u-boot code

according

Quoted 3 lines
Quoted 3 lines

to the Reference Manual of PowerPC, e.g p1022:
11.5.6 Generation of SCL When SDA Low
It is sometimes necessary to force the I2C module to become the I2C

bus

Quoted 1 line
Quoted 1 line

master out of reset and drive SCL(even though SDA may already be

driven,

Quoted 3 lines
Quoted 3 lines

which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by another I2C device while this I2C module is coming

out of

Quoted 1 line
Quoted 1 line

reset and stays low indefinitely. The following procedure can be

used

Quoted 1 line
Quoted 1 line

to force this I2C module to generate SCL so that the device driving

SDA

Quoted 2 lines
Quoted 2 lines

can finish its transaction:
1. Disable the I2C module and set the master bit by setting I2CCR

to

Quoted 9 lines
Quoted 5 lines

0x20
2. Enable the I2C module by setting I2CCR to 0xA0
3. Read the I2CDR
4. Return the I2C module to slave mode by setting I2CCR to 0x80

Compare with kernel version, the difference is one line:
Uboot: readb(&dev->dr);
Kernel has no any operation.
But, I check the comment of kernel, because the 9th clock pulse isn't

generated,

Quoted 1 line

the sequence of function mpc_i2c_fixup is needed to generate 9th

clock pulse.

Quoted 11 lines

Not so, there is more than that if you look closer. The description in the kernel
is a bit misleading(or so I think). I prefer the kernel version for 2 reasons:
1) It has been there for quite some time so if there were something wrong with,
it should have been noticed by now.
2) I have a vauge memory of checking it again the mpc8321 manual and I was happy
with it.

Quoted 3 lines

These tow part codes are doing the different thing due to the different reason:
1. Kernel's code:
because Sometimes 9th clock pulse isn't generated, that code is to generate the 9th clock pulse.

What code are you looking at? Are you just reading the comment?
Look at http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=commit;h=0c2daaafcdec726e89cbccca61d576de8429c537
to get a clue.

Your code isn't complete, you cannot trust the manual to be the whole truth.

Jocke

#10 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

Quoted 7 lines
Quoted 2 lines
Quoted 1 line

These tow part codes are doing the different thing due to the

different reason:

Quoted 2 lines

1. Kernel's code:
because Sometimes 9th clock pulse isn't generated, that code is to

generate the 9th clock pulse.

Quoted 8 lines

What code are you looking at? Are you just reading the comment? Look at http://git.kernel.org/?p=linux/kernel/git/next/linux-
next.git;a=commit;h=0c2daaafcdec726e89cbccca61d576de8429c537 to get a clue.

Your code isn't complete, you cannot trust the manual to be the whole truth.

I am very confused, why do you always say my code isn't complete?
I have described I want to do detailed in comment.
"when a system reset does not cause all I2C devices to be reset",
My codes will force the I2c module to become bus master and drive SCL,
which force this i2c module to generate SCL so that the device driving SDA can finish its transaction.
These codes have been used on Emerson's P1022 board and resolved his issue (board will hang when u-boot booting, with my codes, this issue is resolved and board can boot well) This is one feature of FSL I2C almost cover all 85xx platform, and the code according to the RM has been verified, don't you think the manual can be trust?

Below is the description from your link:
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.

This patch is created because a slave miss more than one clock cycle and can resolve this issue.

So, the kernel's patch and my patch is to resolve the different issue.

#11 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

Hello Huang Changming-R66093,

Quoted 11 lines · Huang Changming-R66093 wrote:
Quoted 11 lines
Quoted 1 line

These tow part codes are doing the different thing due to the

different reason:

Quoted 2 lines

1. Kernel's code:
because Sometimes 9th clock pulse isn't generated, that code is to

generate the 9th clock pulse.

What code are you looking at? Are you just reading the comment? Look at http://git.kernel.org/?p=linux/kernel/git/next/linux-
next.git;a=commit;h=0c2daaafcdec726e89cbccca61d576de8429c537 to get a clue.

Quoted 4 lines
Quoted 3 lines

Your code isn't complete, you cannot trust the manual to be the whole truth.

I am very confused, why do you always say my code isn't complete?

Because it is not complete?

Quoted 2 lines

I have described I want to do detailed in comment. "when a system reset does not cause all I2C devices to be reset",

You wrote:
"So, the kernel's patch and my patch is to resolve the different issue."

Yes! There are more "problems" on i2c bus, as also Joakim described! And if we try to fix them in the common driver (as you did), we should fix all known problems -> so your patch is incomplete.

Quoted 3 lines

My codes will force the I2c module to become bus master and drive SCL,
which force this i2c module to generate SCL so that the device driving SDA can finish its transaction.
These codes have been used on Emerson's P1022 board and resolved his issue (board will hang when u-boot booting, with my codes, this issue is resolved and board can boot well)

Then you maybe define CONFIG_SYS_I2C_BOARD_LATE_INIT for this board and do this in board code.

Quoted 1 line

This is one feature of FSL I2C almost cover all 85xx platform, and the code according to the RM has been verified, don't you think the manual can be trust?

See (for example on a mpc83xx based board) board/keymile/common/common.c functions i2c_write_start_seq() and i2c_make_abort() which solve also a deblocked i2c bus ... and they started with the procedure noted in the RM, but this didn't solved all issues for them.

Quoted 7 lines

Below is the description from your link:
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;
Quoted 8 lines

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.

This patch is created because a slave miss more than one clock cycle and can resolve this issue.

So, the kernel's patch and my patch is to resolve the different issue.

Yes, and if editing a common driver, we should find a solution which fit for all ... did you tried the linux driver code for your board? Maybe it solves your problem too? So we can adapt it to u-boot code?

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#12 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

Thanks and Best Regards
Jerry Huang

Quoted 22 lines

-----Original Message-----
From: Heiko Schocher [mailto:hs at denx.de]
Sent: Friday, October 28, 2011 2:34 PM
To: Huang Changming-R66093
Cc: Joakim Tjernlund; u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH 2/2] Powerpc/i2c: Force i2c to become bus master out of reset

Hello Huang Changming-R66093,

Quoted 11 lines · Huang Changming-R66093 wrote:
Quoted 11 lines
Quoted 1 line

These tow part codes are doing the different thing due to the

different reason:

Quoted 2 lines

1. Kernel's code:
because Sometimes 9th clock pulse isn't generated, that code is to

generate the 9th clock pulse.

What code are you looking at? Are you just reading the comment? Look at http://git.kernel.org/?p=linux/kernel/git/next/linux-
next.git;a=commit;h=0c2daaafcdec726e89cbccca61d576de8429c537 to get a clue.

Quoted 7 lines
Quoted 1 line
Quoted 1 line

Your code isn't complete, you cannot trust the manual to be the

whole

Quoted 3 lines
Quoted 2 lines

truth.

I am very confused, why do you always say my code isn't complete?

Because it is not complete?

I don't think it is not complete, because this patch resolves my issue.

Quoted 10 lines
Quoted 2 lines

I have described I want to do detailed in comment. "when a system reset does not cause all I2C devices to be reset",

You wrote:
"So, the kernel's patch and my patch is to resolve the different issue."

Yes! There are more "problems" on i2c bus, as also Joakim described! And if we try to fix them in the common driver (as you did), we should fix all known problems -> so your patch is incomplete.

Yes, we should fix all known problems, but we should not hope one patch includes everything. it make sense for one patch to resolve one thing, instead of all.

Quoted 9 lines
Quoted 2 lines

My codes will force the I2c module to become bus master and drive SCL, which force this i2c module to generate SCL so that the device

driving SDA can finish its transaction.

Quoted 3 lines

These codes have been used on Emerson's P1022 board and resolved his issue (board will hang when u-boot booting, with my codes, this issue is resolved and board can boot well)

Then you maybe define CONFIG_SYS_I2C_BOARD_LATE_INIT for this board and do this in board code.

I have pointed out, this is one feature of FSL I2C module and almost cover all 85xx platform, we provides one solution to resolve the i2c bus "reset" issue.
So I think it is not necessary to define one macro for one special board.

Quoted 26 lines
Quoted 1 line

This is one feature of FSL I2C almost cover all 85xx platform, and

the code according to the RM has been verified, don't you think the manual can be trust?

See (for example on a mpc83xx based board) board/keymile/common/common.c functions i2c_write_start_seq() and i2c_make_abort() which solve also a deblocked i2c bus ... and they started with the procedure noted in the RM, but this didn't solved all issues for them.

Quoted 2 lines

Below is the description from your link:
This patch improves the recovery of the MPC's I2C bus from errors

like

Quoted 2 lines

bus hangs resulting in timeouts:
1. make the bus timeout configurable, as it depends on the bus clock

and

Quoted 5 lines

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

Quoted 1 line

"misses" more than one clock cycle. For 400 kHz bus speed, the

fixup is

Quoted 2 lines
    also ~70us (81us vs. 150us) faster.
Quoted 9 lines
Quoted 1 line

This patch is created because a slave miss more than one clock cycle

and can resolve this issue.

Quoted 2 lines

So, the kernel's patch and my patch is to resolve the different issue.

Yes, and if editing a common driver, we should find a solution which fit for all ... did you tried the linux driver code for your board? Maybe it solves your problem too? So we can adapt it to u-boot code?

I can't try the Linux driver on my boards, because all boards on my hand has not these two i2c issue.
These codes is generated according to FSL Reference Manual, if you check the RM of FSL, you will find out all 85xx chips(now I know) support this feature. And these code can be work on Emerson's p1022 board, if the code according to the RM can work, I don't think I have any reason to ask customer to use the other codes. And the solution RM provide can resolve the issue, why don't we trust the RM?

#13 lore raw

PATCH 2/2 Powerpc/i2c: Force i2c to become bus master out of reset

In reply to Huang Changming-R66093

Huang Changming-R66093 <[email protected]> wrote on 2011/10/27 09:40:23:

Quoted 65 lines

Thanks and Best Regards
Jerry Huang

Quoted 59 lines

-----Original Message-----
From: Joakim Tjernlund [mailto:joakim.tjernlund at transmode.se]
Sent: Thursday, October 27, 2011 3:26 PM
To: Huang Changming-R66093
Cc: u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH 2/2] Powerpc/i2c: Force i2c to become bus master out of reset

Quoted 8 lines

From: <[email protected]>

From: Jerry Huang <[email protected]>

It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA

can

Quoted 15 lines

be driven low by another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction.

---
 drivers/i2c/fsl_i2c.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
drivers/i2c/fsl_i2c.c index renamed from drivers/i2c/fsl_i2c.c +0 -0

258be0a..007db70 100644

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 257

Quoted 6 lines
drivers/i2c/fsl_i2c.c +3 -0
@@ -252,6 +252,24 @@ i2c_init(int speed, int slaveadd)
       writeb(slaveadd << 1, &dev->adr);/* write slave address */
       writeb(0x0, &dev->sr);      /* clear status register */
       writeb(I2C_CR_MEN, &dev->cr);   /* start I2C controller */
+
+      /* Force I2C module to become bus master which can occure when
+       * a system reset does not cause all I2C devices to be reset

*/

drivers/i2c/fsl_i2c.c i2c_init(int speed, int slaveadd) · line 259

Quoted 2 lines
drivers/i2c/fsl_i2c.c +2 -0
+      udelay(5);
+      if (readb(&dev->sr) & I2C_SR_MBB) {

You need to the sequence unconditionally, the slave can be stuck without driving SCL.

Quoted 13 lines
drivers/i2c/fsl_i2c.c +13 -0
+         writeb(I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
+         udelay(5);
+         readb(&dev->dr);
+         udelay(5);
+         writeb(I2C_CR_MEN, &dev->cr);
+         udelay(5);
+         if (readb(&dev->sr) & I2C_SR_MBB)
+            debug("I2C%d: Drive SCL failed\n", i + 1);
+         else
+            debug("I2C%d: Drive SCL succeed\n", i + 1);
+      }
Quoted 5 lines
Quoted 1 line

The above sequence is different than the kernel version, why?

I don't know the kernel version, but I write the u-boot code according to the Reference Manual of PowerPC, e.g p1022:
11.5.6 Generation of SCL When SDA Low
It is sometimes necessary to force the I2C module to become the I2C bus master out of reset and drive SCL(even though SDA may already be driven, which indicates that the bus is busy). This can occur when a system reset does not cause all I2C devices to be reset. Thus, SDA can be driven low by

another I2C device while this I2C module is coming out of reset and stays low indefinitely. The following procedure can be used to force this I2C module to generate SCL so that the device driving SDA can finish its transaction:

Quoted 5 lines

1. Disable the I2C module and set the master bit by setting I2CCR to 0x20
2. Enable the I2C module by setting I2CCR to 0xA0
3. Read the I2CDR
4. Return the I2C module to slave mode by setting I2CCR to 0x80

I think this is incomplete. Basically you need to generate 9 SCL pulses with a start condition in each, then end with a stop to cover all cases.

Jocke

#14 lore raw

PATCH 1/2 Powerpc/i2c: Use the same initialize codes

In reply to Chang-Ming.Huang at freescale.com

Hello Chang-Ming,

Quoted 8 lines · Chang-Ming.Huang at freescale.com

From: Jerry Huang <[email protected]>

Make the I2C2 and I2C1 use the same initialize codes.

---
 drivers/i2c/fsl_i2c.c |   47 +++++++++++++++++++++++++----------------------
 1 files changed, 25 insertions(+), 22 deletions(-)

Applied to u-boot-i2c, thanks

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany