[U-Boot-Users] NAND driver question

Stefan Roese
2008-02-02T07:49:00Z

On Friday 01 February 2008, Craig Millen wrote:
> 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.

<snip>

> 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).

1k should be enough but this difference is definitely not our problem. And the
1 in ERPN must be used on 440EPx, since 440EPx has the EBC at 0x1.xxxx.xxxx,
so above 4GB. This is not the case for the 440EP. So this difference is ok
too.

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.

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

Looks good.

> 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

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

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.

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

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

Right. This would be a good extension. Patches are always welcome. :)

> What frequency is all of this based on?

EBC, since the NAND is connected to the EBC.

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

out_be32((u32 *)(base + NDFC_BCFG0 + (cs << 2)), 0x80007777);

And when you get this exception upon NAND access, did you even measure the
NAND signals while doing this lword access? Do you see something on those
signals at all on lword accesses?

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