Re: [U-Boot-Users] NAND driver question

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 =====================================================================

On Monday 04 February 2008, Craig Millen wrote:
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
I know. But I still recommend to make this address switch, since this area *is* reserved for PCI memory.
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.
And you can't implement your changes in a more "clean way"? What exactly is the problem? The 440EP is already supported, so changes to the common files shouldn't be that big. And all board specific stuff should go into your board directory anyways.
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.
So with this change, 32bit access is working too?
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.
Which NAND chips are you using? And could you please send this fix as a "real" patch with Signed-off-by etc? That would be helpful.
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.
Understood.
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 =====================================================================
participants (2)
-
Craig Millen
-
Stefan Roese