
2009/5/29 Scott Wood scottwood@freescale.com:
On Sun, May 03, 2009 at 09:56:57PM +0200, Magnus Lilja wrote:
This patch adds the NAND SPL framework needed to boot i.MX31 boards from NAND.
Sorry for the delay...
Well, better now than the next time I post these patches.
diff --git a/include/asm-arm/arch-mx31/mx31-regs.h b/include/asm-arm/arch-mx31/mx31-regs.h index a8a05c8..3d811d7 100644 --- a/include/asm-arm/arch-mx31/mx31-regs.h +++ b/include/asm-arm/arch-mx31/mx31-regs.h @@ -194,4 +194,94 @@ #define CS5_BASE 0xB6000000 #define PCMCIA_MEM_BASE 0xC0000000
+/*
- NAND controller
- */
+#define NFC_BASE_ADDR 0xB8000000
+/*
- Addresses for NFC registers
- */
+#define NFC_BUF_SIZE (NFC_BASE_ADDR + 0xE00) +#define NFC_BUF_ADDR (NFC_BASE_ADDR + 0xE04) +#define NFC_FLASH_ADDR (NFC_BASE_ADDR + 0xE06) +#define NFC_FLASH_CMD (NFC_BASE_ADDR + 0xE08)
The NFC register info should go in its own header, as it exists on more than just MX31 (e.g. mpc5xxx). Should probably use register structs rather than #defines.
Yes, will do that. I'm converting the #define's to struct {} and all accesses will be in the readl/writel(&nfc->flash_cmd) format.
diff --git a/nand_spl/nand_boot_mx31.c b/nand_spl/nand_boot_mx31.c new file mode 100644 index 0000000..d698d2a --- /dev/null +++ b/nand_spl/nand_boot_mx31.c
What in this file is MX31-specific? Even if you don't have other chips to test on, please try to provide a framework for generic NFC support so the next chip only needs to tweak the details. That may be as simple as s/mx31/nfc/.
I'll look into that.
+static void mx31_wait_ready(void) +{
- while (1) {
- if (readw(NFC_CONFIG2) & NFC_INT) {
- uint32_t tmp;
- /* Reset interrupt flag */
- tmp = readw(NFC_CONFIG2);
- tmp &= ~NFC_INT;
- writew(tmp, NFC_CONFIG2);
- break;
- }
- }
+}
while (!(readw(NFC_CONFIG2) & NFC_INT)) ;
tmp = readw(NFC_CONFIG2); ...
Ok.
+static void mx31_nand_page_address(unsigned int page_address) +{
- unsigned int page_count;
- writew(0x00, NFC_FLASH_ADDR);
- writew(NFC_ADDR, NFC_CONFIG2);
- mx31_wait_ready();
- /* code only for 2kb flash */
- if (CFG_NAND_PAGE_SIZE == 0x800) {
- writew(0x00, NFC_FLASH_ADDR);
- writew(NFC_ADDR, NFC_CONFIG2);
- mx31_wait_ready();
- }
- page_count = CFG_NAND_CHIP_SIZE / CFG_NAND_PAGE_SIZE;
- if (page_address <= page_count) {
- page_count--; /* transform 0x01000000 to 0x00ffffff */
- do {
- writew(page_address & 0xff, NFC_FLASH_ADDR);
- writew(NFC_ADDR, NFC_CONFIG2);
- mx31_wait_ready();
- page_address = page_address >> 8;
- page_count = page_count >> 8;
- } while (page_count);
- }
Does the number of address bytes really need to depend on the size of the flash chip, or can you base it on the number of non-zero bytes in page_address (the chip will know when the address phase is over because ALE drops)?
Ok, will try to look into it.
+static int mx31_nand_check_ecc(void) +{
- unsigned short ecc_status_register;
- ecc_status_register = readw(NFC_ECC_STATUS_RESULT);
- if (ecc_status_register != 0)
- return 1; /* error */
- return 0;
+}
How about just "return readw(NFC_ECC_STATUS_RESULT);"?
ok
+static int mx31_read_page(unsigned int page_address, unsigned char *buf) +{
- int i;
- volatile u32 *p1;
- volatile u32 *p2;
- u32 a;
s/p1/src/ s/p2/dest/
s/a/something (just a little) more descriptive/ -- my first guess was "address", but that doesn't seem right...
Ok
No volatile; use I/O accessors.
Yes, already on todo-list.
- writew(0, NFC_BUF_ADDR); /* read in first 0 buffer */
- mx31_nand_command(NAND_CMD_READ0);
- mx31_nand_page_address(page_address);
- if (CFG_NAND_CHIP_SIZE >= 0x08000000)
- mx31_nand_command(NAND_CMD_READSTART);
Is it guaranteed that all NAND chips above that size will be large page and all chips below that size will be small page?
No, I'll change to use the CONFIG_SYS_NAND_PAGE_SIZE to do different stuff depending on the page size.
- /* it is hardware specific code for 8-bit 512B NAND-flash spare area */
- p1++;
- a = *p1;
- a = (a & 0x0000ff00) >> 8;
- if (a != 0xff) /* bad block marker verify */
- return 1; /* potential bad block */
- return 0;
The bad block location is typically different (offset 0 rather than 5) with large page flash.
I think that's because of the non-standard imlementation of large page support in the i.MX31 NFC.
- /* checking first page of each block */
I believe some NAND chips may mark a block bad in its second page...
I'll see what I can do.
/Magnus