public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot-Users] NAND driver question
@ 2008-02-04 20:46 Craig Millen
  2008-02-05  7:44 ` Stefan Roese
  0 siblings, 1 reply; 7+ messages in thread
From: Craig Millen @ 2008-02-04 20:46 UTC (permalink / raw)
  To: u-boot

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

^ permalink raw reply	[flat|nested] 7+ messages in thread
* [U-Boot-Users] NAND driver question
@ 2008-02-01 19:55 Craig Millen
  2008-02-02  7:49 ` Stefan Roese
  0 siblings, 1 reply; 7+ messages in thread
From: Craig Millen @ 2008-02-01 19:55 UTC (permalink / raw)
  To: u-boot



On Tuesday 29 January 2008, Craig Millen wrote:
> I have been experiencing a few problems when using a NAND flash for 
> storage in u-boot.
>
> When I'm reading large files (7MB) from the NAND, periodically there 
> will be a NAND ECC read error when using the following command:
>
> => nand read 400000 0 154000
> NAND read: device 0 offset 0x0, size 0x154000  1392640 bytes read:
> ERROR.
>
> After turning on debug, the problem is occurring in the nand_read_ecc 
> function whereby the ecc check fails. After running it numerous times,

> there seems to be no correlation between pages that fail and appears 
> to be completely random.
> Has anyone else had these problems?

No. NAND blocks can fail and generate ECC errors. But your description
doesn't really sound like this is a NAND chips related problem. Does
this happen on multiple boards or just s single one? This looks more
like a timing problem or something like this to me.

IIRC, then you had to change the 4xx NDFC driver to access the NAND via
8bit access, correct? I have used this driver on multiple 4xx boards and
on all boards this driver can be used as is, meaning with 32bit access
enabled. 
Perhaps you still have a problem with the interface to the NAND chips.

	Yes, this is correct.  I have never been able to get this line
in ndfc.c:ndfc_read_buf to work:

		*p++ = in_be32((u32 *)(base + NDFC_DATA));

It always gives me a Machine check exception (see below), so I have
changed it to reading 4 bytes instead, which causes no problems.

NAND:  Bus Fault @ 0x0ff89fa8, fixup 0x00000000
Machine Check Exception.
Caused by (from msr): regs 0ff16c90 Data Read PLB Error
NIP: 0FF89FA8 XER: 00000000 LR: 0FF6AC8C REGS: 0ff16c90 TRAP: 0200 DEAR:
0000000
0
MSR: 00021000 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 00

GPR00: 00000000 0FF16D80 0000051B 0FFC7EBC 0FF17210 00000210 00000000
10D8C46D
GPR08: 0FF628C0 90000000 03F940AA 01000000 42000024 00000000 0FFAB300
0FFA7D84
GPR16: 00000200 00000010 0FFA7D84 0FF17210 0FF17210 0000001F 00000010
00000200
GPR24: 00000001 0FFC7EBC 00000210 00000000 00000210 0FF16F38 0FFABB24
0FFAAD84
Call backtrace:
0FF16F38 0FF6AC68 0FF6CA88 0FF6D608 0FF6DA88 0FF6A9A4 0FF69444
0FF6247C 0FF5B6B0
machine check



	From what I can see, there aren't that many things to setup for
NAND though.

1. init.S:  tlbentry(CFG_NAND_ADDR, SZ_4K, CFG_NAND_ADDR, 0,
AC_R|AC_W|AC_X|SA_G|SA_I)
	(which I notice on the sequoia board, page_size is SZ_1K, and
extended real page number (ERPN) is '1' both of wich I don't fully
understand).
2. <board_config>.h where you setup its address and the AP/CR values all
of which seem to be fairly common.
	
	#define CFG_NAND_ADDR			0xD0000000      /* NAND
Flash		*/
	/* Memory Bank 1 (NAND-FLASH) initialization
*/
	#define CFG_EBC_PB1AP		0x018003c0
	#define CFG_EBC_PB1CR		(CFG_NAND_ADDR | 0x1c000)

3. Four long words in SEEPROM for boot option H
Here are our settings and their descriptions:

SDR0_SDSTP0[ENG]:		1		: PLL's VCO is the
source for PLL forward divisors
SDR0_SDSTP0[SRC]:		0		: Feedback originates
from PLLOUTA
SDR0_SDSTP0[SEL]:		000		: Feedback selection is
PLL output
SDR0_SDSTP0[TUNE 5:7]:		101		: 10 <= M <= 22, 600MHz
< VCO <= 900MHz
= 85

SDR0_SDSTP0[TUNE 8:14]: 	0111000
SDR0_SDSTP0[FBDV 15]:		0		: PLL feedback divisor
=70

SDR0_SDSTP0[FBDV 16:19]:	1000		: PLL feedback divisor=8
SDR0_SDSTP0[FBDVA]:		0010		: PLL forward divisor
A=2
=82 

SDR0_SDSTP0[FBDVB]:		100		: PLL forward divisor
B=4
SDR0_SDSTP0[PRBDV0]:		010		: PLL primary divisor
B=2
SDR0_SDSTP0[OPBDV0]:		10		: OPB clock divisor 0=2
= 8A

------------------------------------------------------------------------
-------------------------------

SDR0_SDSTP1[LFBDV]:		000001		: PLL local feedback
divisor
SDR0_SDSTP1[PERDV0 0:1]:	01		: Peripheral clock
divisor 0=2
= 05

SDR0_SDSTP1[PERDV0 2]:		0		: Peripheral clock
divisor 0=2
SDR0_SDSTP1[MALDV0]:		10		: MAL clock divisor 0 =
2
SDR0_SDSTP1[PCIDV0]:		00		: Sync PCI clock divisor
0 = 4
SDR0_SDSTP1[PLLTIMER 0:2]:	111		: PLL locking timer 
= 47

SDR0_SDSTP1[PLLTIMER 3]:	1		: PLL locking timer
SDR0_SDSTP1[RW]:		01		: EBC ROM width: 16-bit
***** should be 0b10 32-bit (Boot from NAND Flash)
SDR0_SDSTP1[RL]:		00		: EBC ROM location: EBC
***** should be 0b10 NDFC
SDR0_SDSTP1[PAE]:		0		: PCI internal arbiter:
disabled
SDR0_SDSTP1[PHCE]:		0		: PCI host
configuration: disabled
SDR0_SDSTP1[ZM 0]:		0		: ZMII mode: MII mode
=a0

SDR0_SDSTP1[ZM 1]:		0		: ZMII mode: RMII mode
100
SDR0_SDSTP1[CTE]:		0		: CPU trace: disabled
SDR0_SDSTP1[Nto1]:		0		: CPU/PLB ratio N/P: not
N to 1
SDR0_SDSTP1[PAME]:		1		: PCI asynchronous mode:
enabled
SDR0_SDSTP1[RSV]:		0000		: Reserved
= 10
------------------------------------------------------------------------
-------------------------------

SDR0_SDSTP2[MEN]:		01		: Multiplex: EMAC
******** should be 0b10 for NDFC
SDR0_SDSTP2[NE]:		0		: NDFC:  ******** should
be 0b1 for NDFC
SDR0_SDSTP2[NBW]:		0		: NDFC boot width: 8-bit

SDR0_SDSTP2[NBP]:		000		: NDFC boot page
selection
=40

SDR0_SDSTP2[NBAC]:		00		: NDFC boot address
selection cycle: ** should be 0b01 4 Addr. Cycles, 1 Col. + 3 Row (512
page size)
SDR0_SDSTP2[NARE]:		0		: NDFC auto read :
disabled  *** should be 1 for NAND booting
SDR0_SDSTP2[NRB]:		0		: NDFC Ready/Busy :
Ready   
SDR0_SDSTP2[NDRSC 0:3]:		1000		: NDFC device reset
counter *** have to figure out this value based on clock 
=08

SDR0_SDSTP2[NDRSC 4:11]:	0010 0011	: NDFC device reset
counter
=23

SDR0_SDSTP2[NDRSC 12:15]:	0101		: NDFC device reset
counter = 16949
						 *** should be 1000 0010
0011 0110 = 33334 for 66MHz
SDR0_SDSTP2[NCG0]:		0		: NDFC/EBC chip select
gating CS0 : EBC  *** should be 1 for NDFC
SDR0_SDSTP2[NCG1]:		0		: NDFC/EBC chip select
gating CS1 : EBC
SDR0_SDSTP2[NCG2]:		0		: NDFC/EBC chip select
gating CS2 : EBC
SDR0_SDSTP2[NCG3]:		0		: NDFC/EBC chip select
gating CS3 : EBC
=50
------------------------------------------------------------------------
-------------------------------
SDR0_SDSTP3[NCRDC]:		0000 1101 0000 0101 : NDFC device read
count
=0d05
SDR0_SDSTP3[RSVD]:		0000 0000 0000 0000 : reserved
=0000


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.


There are only two other spots in the code that I can see where timing
parameters for the NAND are set:

Ndfc.c: board_nand_init:
	out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), 0x80002222);	

Ndfc.c: board_nand_select_device:
	out_be32((u32 *)(base + NDFC_CCR), 0x00000000 | (cs << 24)); 

I am curious to know why the numbers for the NDFC_BCFG0 register aren't
a function of the clock frequency, instead are hard coded.
What frequency is all of this based on?

Thanks, 
Craig

^ permalink raw reply	[flat|nested] 7+ messages in thread
* [U-Boot-Users] NAND driver question
@ 2008-01-29 16:44 Craig Millen
  2008-01-29 19:36 ` Zach Sadecki
  2008-01-30  7:45 ` Stefan Roese
  0 siblings, 2 replies; 7+ messages in thread
From: Craig Millen @ 2008-01-29 16:44 UTC (permalink / raw)
  To: u-boot


I have been experiencing a few problems when using a NAND flash for
storage in u-boot.

When I'm reading large files (7MB) from the NAND, periodically there
will be a NAND ECC read error when using the following command:

=> nand read 400000 0 154000
NAND read: device 0 offset 0x0, size 0x154000  1392640 bytes read:
ERROR.

After turning on debug, the problem is occurring in the nand_read_ecc
function whereby the ecc check fails. After running it numerous times,
there seems to be no correlation between pages that fail and appears to
be completely random.
Has anyone else had these problems?


Furthermore, the "nand write" command doesn't skip bad blocks.  Are you
supposed to use a different command to write files to the NAND that
skips the bad blocks?


Thanks
Craig

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-02-05  7:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-04 20:46 [U-Boot-Users] NAND driver question Craig Millen
2008-02-05  7:44 ` Stefan Roese
  -- strict thread matches above, loose matches on Subject: below --
2008-02-01 19:55 Craig Millen
2008-02-02  7:49 ` Stefan Roese
2008-01-29 16:44 Craig Millen
2008-01-29 19:36 ` Zach Sadecki
2008-01-30  7:45 ` Stefan Roese

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox