[U-Boot-Users] Freescale MPC8349EMDS BCSR corruption

Ira Snyder
2008-07-23T17:25:28Z

On Wed, Jul 23, 2008 at 02:16:42PM +0800, Dave Liu wrote:
>
> I believe it is timing issue.
> The BCSR read(#LOE) has not enough setup time.
> You may try the two solutions:
> (a) slow down local bus clock
> If you are using default configuration, the local bus clock is
> 66MHz. change the LCRR from div 4 to div 8 to make the local bus clock
> as 33MHz. you can find it in the MPC8349EMDS.h
>
> (b) Tuning the #CS1 timing, such as
> change the OR1 from 0xFFFFE8F0 to 0xFFFFE9F7
>
> Let us know the result.
>

I tried both changes, one at a time and both together. None of the
combinations helped.

I've attached a patch which demonstrates that the BCSR 0 value changes
with a write to the flash. The patch has Timur's i2c patch rolled in,
since it has not hit mainline yet. The modification to lib_ppc/board.c
writes the hard reset value back to BCSR 0, which makes the serial port
and ethernet start working again.

Here is the output of U-Boot head + the attached patch:
==========================================================================
U-Boot 1.3.4-rc1-00014-gcacee6b-dirty (Jul 23 2008 - 10:11:52) MPC83XX

Reset Status: Software Hard, External/Internal Soft, External/Internal
Hard

CPU: e300c1, MPC8349E, Rev: 1.1 at 528 MHz, CSB: 264 MHz
Board: Freescale MPC8349EMDS
I2C: ready
SPI: ready
DRAM: 256 MB (DDR1, 64-bit, ECC off, 264 MHz)
FLASH:
BCSR READ1 2f
BCSR READ2 f0

BCSR READ1 ff
BCSR READ2 f0

BCSR READ1 ff
BCSR READ2 00
8 MB
In: serial
Out: serial
Err: serial
Net: TSEC0, TSEC1
BCSR FIXUP: was 00 now 2f

Type "run flash_nfs" to mount root filesystem over NFS

Hit any key to stop autoboot: 0

Thanks for the help,
Ira

diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index 9f2c1ec..9d5df8a 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -143,12 +143,15 @@ void
i2c_init(int speed, int slaveadd)
{
struct fsl_i2c *dev;
+ unsigned int temp;

dev = (struct fsl_i2c *) (CFG_IMMR + CFG_I2C_OFFSET);

writeb(0, &dev->cr); /* stop I2C controller */
udelay(5); /* let it shutdown in peace */
- i2c_bus_speed[0] = set_i2c_bus_speed(dev, gd->i2c1_clk, speed);
+ 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 */
@@ -158,7 +161,9 @@ i2c_init(int speed, int slaveadd)

writeb(0, &dev->cr); /* stop I2C controller */
udelay(5); /* let it shutdown in peace */
- i2c_bus_speed[1] = set_i2c_bus_speed(dev, gd->i2c2_clk, speed);
+ 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 */
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 12647ef..12c794e 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -1617,7 +1617,11 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
/* We do not yet know what kind of commandset to use, so we issue
the reset command in both Intel and AMD variants, in the hope
that AMD flash roms ignore the Intel command. */
+ printf("\nBCSR READ1 %.2x\n", readb(CFG_BCSR));
+ udelay(1000);
flash_write_cmd (info, 0, 0, AMD_CMD_RESET);
+ printf("BCSR READ2 %.2x\n", readb(CFG_BCSR));
+ udelay(1000);
flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);

for (cfi_offset=0;
diff --git a/lib_ppc/board.c b/lib_ppc/board.c
index 71a70db..1f10a0d 100644
--- a/lib_ppc/board.c
+++ b/lib_ppc/board.c
@@ -26,6 +26,7 @@
#include <command.h>
#include <malloc.h>
#include <devices.h>
+#include <asm/io.h>
#ifdef CONFIG_8xx
#include <mpc8xx.h>
#endif
@@ -1179,6 +1180,9 @@ void board_init_r (gd_t *id, ulong dest_addr)
}
#endif

+ printf("BCSR FIXUP: was %.2x now 2f\n", readb(CFG_BCSR));
+ writeb(0x2f, CFG_BCSR);
+
/* Initialization complete - start the monitor */

/* main_loop() can return to retry autoboot, if so just run it again. */