@@ -261,6 +261,12 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#ifdef CONFIG_SYS_FSL_ERRATUM_A006593
puts("Work-around for Erratum A006593 enabled\n");
#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+ if ((SVR_SOC_VER(svr) == SVR_8548 && IS_SVR_REV(svr, 3, 1)) ||
+ (SVR_SOC_VER(svr) == SVR_P1010 && IS_SVR_REV(svr, 1, 0)) ||
+ FIT_SVR_REV(svr, CONFIG_SYS_FSL_A004447_VERSION))
+ puts("Work-around for Erratum I2C-A004447 enabled\n");
+#endif
return 0;
}
@@ -81,6 +81,8 @@
#define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM 5
#define CONFIG_SYS_FSL_RMU
#define CONFIG_SYS_FSL_SRIO_MSG_UNIT_NUM 2
+#define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+#define CONFIG_SYS_FSL_A004447_VERSION 0x00
#elif defined(CONFIG_MPC8555)
#define CONFIG_MAX_CPUS 1
@@ -146,6 +148,8 @@
#define CONFIG_SYS_FSL_ERRATUM_IFC_A002769
#define CONFIG_SYS_FSL_ERRATUM_P1010_A003549
#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399
+#define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+#define CONFIG_SYS_FSL_A004447_VERSION 0x00
/* P1011 is single core version of P1020 */
#elif defined(CONFIG_P1011)
@@ -263,6 +267,8 @@
#define CONFIG_SYS_FM_MURAM_SIZE 0x10000
#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2"
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff600000
+#define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+#define CONFIG_SYS_FSL_A004447_VERSION 0x11
/* P1024 is lower end variant of P1020 */
#elif defined(CONFIG_P1024)
@@ -347,6 +353,8 @@
#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000
#define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
#define CONFIG_SYS_FSL_ERRATUM_A004849
+#define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+#define CONFIG_SYS_FSL_A004447_VERSION 0x11
#elif defined(CONFIG_PPC_P3041)
#define CONFIG_SYS_FSL_QORIQ_CHASSIS1
@@ -380,6 +388,8 @@
#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xf0000000
#define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
#define CONFIG_SYS_FSL_ERRATUM_A004849
+#define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+#define CONFIG_SYS_FSL_A004447_VERSION 0x20
#elif defined(CONFIG_PPC_P4080) /* also supports P4040 */
#define CONFIG_SYS_FSL_QORIQ_CHASSIS1
@@ -424,6 +434,8 @@
#define CONFIG_SYS_FSL_ERRATUM_A004849
#define CONFIG_SYS_FSL_ERRATUM_A004580
#define CONFIG_SYS_P4080_ERRATUM_PCIE_A003
+#define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+#define CONFIG_SYS_FSL_A004447_VERSION 0x20
#elif defined(CONFIG_PPC_P5020) /* also supports P5010 */
#define CONFIG_SYS_PPC64 /* 64-bit core */
@@ -454,6 +466,8 @@
#define CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 0x10
#define CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 0xc0000000
#define CONFIG_SYS_FSL_ERRATUM_SRIO_A004034
+#define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+#define CONFIG_SYS_FSL_A004447_VERSION 0x20
#elif defined(CONFIG_PPC_P5040)
#define CONFIG_SYS_PPC64
@@ -512,6 +526,8 @@
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
#define CONFIG_SYS_FSL_ESDHC_P1010_BROKEN_SDCLK
#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.2"
+#define CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+#define CONFIG_SYS_FSL_A004447_VERSION 0x11
#elif defined(CONFIG_PPC_T4240) || defined(CONFIG_PPC_T4160)
#define CONFIG_E6500
@@ -54,6 +54,7 @@ typedef struct fsl_i2c {
#define I2C_CR_MTX 0x10
#define I2C_CR_TXAK 0x08
#define I2C_CR_RSTA 0x04
+#define I2C_CR_BIT6 0x02 /* required for workaround A004447 */
#define I2C_CR_BCST 0x01
u8 sr; /* I2C status register */
@@ -1073,6 +1073,8 @@
#define IS_SVR_REV(svr, maj, min) \
((SVR_MAJ(svr) == maj) && (SVR_MIN(svr) == min))
+#define FIT_SVR_REV(svr, version) ((svr & 0xff) <= version)
+
/*
* SVR_SOC_VER() Version Values
*/
@@ -227,6 +227,15 @@ static int i2c_fixup(const struct fsl_i2c *dev)
const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
unsigned long long timeval = 0;
int ret = -1;
+ unsigned int flags = 0;
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_I2C_A004447
+ unsigned int svr = get_svr();
+ if ((SVR_SOC_VER(svr) == SVR_8548 && IS_SVR_REV(svr, 3, 1)) ||
+ (SVR_SOC_VER(svr) == SVR_P1010 && IS_SVR_REV(svr, 1, 0)) ||
+ FIT_SVR_REV(svr, CONFIG_SYS_FSL_A004447_VERSION))
+ flags = I2C_CR_BIT6;
+#endif
writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
@@ -240,8 +249,8 @@ static int i2c_fixup(const struct fsl_i2c *dev)
/* SDA is stuck low */
writeb(0, &dev->cr);
udelay(100);
- writeb(I2C_CR_MSTA, &dev->cr);
- writeb(I2C_CR_MEN | I2C_CR_MSTA, &dev->cr);
+ writeb(I2C_CR_MSTA | flags, &dev->cr);
+ writeb(I2C_CR_MEN | I2C_CR_MSTA | flags, &dev->cr);
}
readb(&dev->dr);
@@ -254,7 +263,7 @@ static int i2c_fixup(const struct fsl_i2c *dev)
ret = 0;
err:
- writeb(I2C_CR_MEN, &dev->cr);
+ writeb(I2C_CR_MEN | flags, &dev->cr);
writeb(0, &dev->sr);
udelay(100);