[U-Boot-Users] NAND driver question

Craig Millen
2008-02-04T20:46:57Z

>I may have noted this before, but I suggest you move the CFG_NAND_ADDR
to 0x90000000 as done on Bamboo, since 0xd0000000 is reserved for PCI
memory on 440EP.

I have done this and it didn't make any difference, same
exception

>How is SDR0_CUST0 configured. Please read is in a running system and
send me the value. And how is the GPIO/multiplexing configured?

a0200004

>BTW: It would be much easier to help you here, if you board port was
available in the official U-Boot repository. I suggest you submit this
support soon.
I would love to, but I am not sure how to add all of our code to
the repository because it is rather heavily customized and there are a
lot of files that would conflict with what is in the u-boot git
repository.

>> We have noticed however that when reading from the nand in u-boot,
>> that the /CE line is never deasserted between page reads, but in the
>> linux kernel user mode, it is. We have yet to figure out why this
is.

>That's possible. Could be that the U-Boot NAND driver doesn't deassert
the CE line.
This turned out to be the culprit. The NAND data sheet
stipulates that the CE line "should" deassert after a sequential read
for 100ns. I ported the code from the NDFC drive in linux and added it
to ndfc.c and we no longer see any missed bytes even on huge files
(80Mb). I would highly suggest merging it into the u-boot ndfc driver.
Perhaps the NAND chips that you are testing on aren't susceptible to
this, but there are some that are.

static void ndfc_select_chip(struct mtd_info *mtdinfo, int chip)
{
uint32_t ccr;
struct nand_chip *this = mtdinfo->priv;
ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc;
int cs = (ulong)this->IO_ADDR_W & 0x00000003;

ccr = in_be32((u32 *)(base + NDFC_CCR));

if (chip >= 0) {
ccr &= ~NDFC_CCR_BS_MASK;
ccr |= NDFC_CCR_BS(chip + cs);
} else
ccr |= NDFC_CCR_RESET_CE;
out_be32((u32 *)(base + NDFC_CCR), ccr);
}

Then in board_nand_init add the "select_chip" pointer to point to the
ndfc_select_chip function
int board_nand_init(struct nand_chip *nand)
{
int cs = (ulong)nand->IO_ADDR_W & 0x00000003;
ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc;

nand->hwcontrol = ndfc_hwcontrol;
nand->read_byte = ndfc_read_byte;
nand->read_buf = ndfc_read_buf;
nand->write_byte = ndfc_write_byte;
nand->dev_ready = ndfc_dev_ready;
nand->select_chip = ndfc_select_chip;
...
...

All of the code to actually use the "selec_chip" is already there in
nand_base.c

>What frequency is your EBC clocked? Did you try lower access speeds,
something
>like:

We use a 66MHz EBC clock
> out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), 0x80007777);

Yes, I did try this and it gave me a machine check exception as
well. This doesn't change the EBC frequency though, it is just
"supposed" to change the number of EBC ticks that it waits for.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de
=====================================================================