[U-Boot-Users] NAND driver question

Craig Millen craig.millen at pikatech.com
Mon Feb 4 21:46:57 CET 2008


>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 at denx.de
=====================================================================




More information about the U-Boot mailing list