V2 NAND_SPL support for phycore imx31
Subsystems (3)
PATCH 1/1 V2 NAND_SPL support for phycore imx31
V2 NAND_SPL support for phycore imx31
Changelog:
* Added bad block verify and skip;
* Correct code to codestyle;
* Added few comments;
--- MAKEALL | 1 + Makefile | 9 ++- board/imx31_phycore/config.mk | 10 ++ board/imx31_phycore/lowlevel_init.S | 27 ++++- board/imx31_phycore/u-boot-nand.lds | 62 ++++++++++ cpu/arm1136/start.S | 36 +++++-- include/asm-arm/arch-mx31/mx31-regs.h | 96 ++++++++++++++++ include/configs/imx31_phycore.h | 59 ++++++++-- nand_spl/board/imx31_phycore/Makefile | 95 +++++++++++++++ nand_spl/board/imx31_phycore/config.mk | 33 ++++++ nand_spl/board/imx31_phycore/u-boot.lds | 65 +++++++++++ nand_spl/nand_boot_mx31.c | 190 +++++++++++++++++++++++++++++++ 12 files changed, 661 insertions(+), 22 deletions(-) create mode 100644 board/imx31_phycore/u-boot-nand.lds create mode 100644 nand_spl/board/imx31_phycore/Makefile create mode 100644 nand_spl/board/imx31_phycore/config.mk create mode 100644 nand_spl/board/imx31_phycore/u-boot.lds create mode 100644 nand_spl/nand_boot_mx31.c
MAKEALL +1 -0
@@ -522,6 +522,7 @@ LIST_ARM11=" \ apollon \ imx31_litekit \ imx31_phycore \ + imx31_phycore_nand \ mx31ads \ smdk6400 \ "
Makefile +8 -1
@@ -353,7 +353,7 @@ $(NAND_SPL): $(VERSION_FILE) $(obj)include/autoconf.mk $(MAKE) -C nand_spl/board/$(BOARDDIR) all $(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk - cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin + cat $(obj)nand_spl/u-boot-spl-aligned.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin $(ONENAND_IPL): $(VERSION_FILE) $(obj)include/autoconf.mk $(MAKE) -C onenand_ipl/board/$(BOARDDIR) all
@@ -2805,6 +2805,13 @@ imx31_litekit_config : unconfig imx31_phycore_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm1136 imx31_phycore NULL mx31 +imx31_phycore_nand_config : unconfig + @mkdir -p $(obj)include $(obj)board/imx31_phycore + @mkdir -p $(obj)nand_spl/board/imx31_phycore + @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h + @$(MKCONFIG) -n $@ -a imx31_phycore arm arm1136 imx31_phycore NULL mx31 + @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk + mx31ads_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm1136 mx31ads freescale mx31
board/imx31_phycore/config.mk +10 -0
@@ -1 +1,11 @@ +# +# (C) Copyright 2008 +# was changed by Maxim Artamonov, <[email protected]> +# + +ifndef CONFIG_NAND_SPL TEXT_BASE = 0x87f00000 +else +TEXT_BASE = 0x87ec0000 +endif +
board/imx31_phycore/lowlevel_init.S +26 -1
@@ -1,5 +1,7 @@ /* - * + * (C) Copyright 2008 + * Maxim Artamonov, <[email protected]> + * * (c) 2007 Pengutronix, Sascha Hauer <[email protected]> * * See file CREDITS for list of people who contributed to this
@@ -43,6 +45,20 @@ bcs 1b .endm +#ifdef CONFIG_NAND_SPL +/* somewhat macro to reduce bin size for CONFIG_NAND_SPL*/ +.macro FILLREGS begreg, val, count, step + ldr r2, =\begreg + ldr r3, =\val + ldr r4, =\count +2: + str r3, [r2] + add r2, r2, #\step + subs r4, r4, #1 + bcs 2b +.endm +#endif + .globl lowlevel_init lowlevel_init:
@@ -60,10 +76,18 @@ lowlevel_init: REG CCM_SPCTL, PLL_PD(1) | PLL_MFD(0x43) | PLL_MFI(12) | PLL_MFN(1) +#ifdef CONFIG_NAND_SPL + FILLREGS 0x43FAC26C, 0, 0x3, 0x4 +#else REG 0x43FAC26C, 0 /* SDCLK */ REG 0x43FAC270, 0 /* CAS */ REG 0x43FAC274, 0 /* RAS */ +#endif /* CONFIG_NAND_SPL */ REG 0x43FAC27C, 0x1000 /* CS2 (CSD0) */ + +#ifdef CONFIG_NAND_SPL + FILLREGS 0x43FAC284, 0, 0x17, 0x4 +#else REG 0x43FAC284, 0 /* DQM3 */ REG 0x43FAC288, 0 /* DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2DC) */ REG 0x43FAC28C, 0
@@ -87,6 +111,7 @@ lowlevel_init: REG 0x43FAC2D4, 0 REG 0x43FAC2D8, 0 REG 0x43FAC2DC, 0 +#endif /* CONFIG_NAND_SPL */ REG 0xB8001010, 0x00000004 REG 0xB8001004, 0x006ac73a REG 0xB8001000, 0x92100000
board/imx31_phycore/u-boot-nand.lds new file +62 -0
62 lines not on this page · raw message
cpu/arm1136/start.S +27 -9
@@ -1,6 +1,9 @@ /* * armboot - Startup Code for OMP2420/ARM1136 CPU-core * + * + * Copyright (c) 2008 Maxim Artamonov, <[email protected]> + * * Copyright (c) 2004 Texas Instruments <[email protected]> * * Copyright (c) 2001 Marius Gr?ger <[email protected]>
@@ -32,6 +35,15 @@ #include <version.h> .globl _start _start: b reset +#ifdef CONFIG_NAND_SPL + nop + nop + nop + nop + nop + nop + nop +#else #ifdef CONFIG_ONENAND_IPL ldr pc, _hang ldr pc, _hang
@@ -68,6 +80,7 @@ _irq: .word irq _fiq: .word fiq _pad: .word 0x12345678 /* now 16*4=64 */ #endif /* CONFIG_ONENAND_IPL */ +#endif /* CONFIG_NAND_SPL */ .global _end_vect _end_vect:
@@ -156,9 +169,9 @@ relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ -#ifndef CONFIG_ONENAND_IPL +#if !defined(CONFIG_ONENAND_IPL) && !defined(CONFIG_NAND_SPL) beq stack_setup -#endif /* CONFIG_ONENAND_IPL */ +#endif /* !CONFIG_ONENAND_IPL && !CONFIG_NAND_SPL*/ ldr r2, _armboot_start ldr r3, _bss_start
@@ -175,7 +188,7 @@ copy_loop: /* Set up the stack */ stack_setup: ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ -#ifdef CONFIG_ONENAND_IPL +#if defined(CONFIG_ONENAND_IPL) || defined (CONFIG_NAND_SPL) sub sp, r0, #128 /* leave 32 words for abort-stack */ #else sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
@@ -184,14 +197,14 @@ stack_setup: sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 /* leave 3 words for abort-stack */ -#endif /* CONFIG_ONENAND_IPL */ +#endif /* CONFIG_ONENAND_IPL || CONFIG_NAND_SPL*/ clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ mov r2, #0x00000000 /* clear */ -#ifndef CONFIG_ONENAND_IPL +#if !defined(CONFIG_ONENAND_IPL) && !defined(CONFIG_NAND_SPL) clbss_l:str r2, [r0] /* clear loop... */ add r0, r0, #4 cmp r0, r1
@@ -200,12 +213,15 @@ clbss_l:str r2, [r0] /* clear loop... */ ldr pc, _start_armboot +#ifdef CONFIG_NAND_SPL +_start_armboot: .word nand_boot +#else #ifdef CONFIG_ONENAND_IPL _start_armboot: .word start_oneboot #else _start_armboot: .word start_armboot -#endif - +#endif /* CONFIG_ONENAND_IPL */ +#endif /* CONFIG_NAND_SPL */ /* *************************************************************************
@@ -244,7 +260,7 @@ cpu_init_crit: mov lr, ip /* restore link */ mov pc, lr /* back to my caller */ -#ifndef CONFIG_ONENAND_IPL +#if !defined(CONFIG_ONENAND_IPL) && !defined(CONFIG_NAND_SPL) /* ************************************************************************* *
@@ -357,11 +373,12 @@ cpu_init_crit: .macro get_fiq_stack @ setup FIQ stack ldr sp, FIQ_STACK_START .endm -#endif /* CONFIG_ONENAND_IPL */ +#endif /* !CONFIG_ONENAND_IPL && !CONFIG_NAND_SPL*/ /* * exception handlers */ +#ifndef CONFIG_NAND_SPL #ifdef CONFIG_ONENAND_IPL .align 5 do_hang:
@@ -436,3 +453,4 @@ arm1136_cache_flush: mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache mov pc, lr @ back to caller #endif /* CONFIG_ONENAND_IPL */ +#endif /* !CONFIG_NAND_SPL*/
include/asm-arm/arch-mx31/mx31-regs.h +96 -0
100 lines not on this page · raw message
include/configs/imx31_phycore.h +48 -11
90 lines not on this page · raw message
nand_spl/board/imx31_phycore/Makefile new file +95 -0
95 lines not on this page · raw message
nand_spl/board/imx31_phycore/config.mk new file +33 -0
@@ -0,0 +1,33 @@ +# +# (C) Copyright 2008 +# Maxim Artamonov, <[email protected]> +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# phyCORE-i.MX31 - PHYTEC?s phyCORE Single Board Computer module + +# TEXT_BASE for SPL: = CFG_NAND_U_BOOT_DST-0x40000 is set in board/imx31_phycore/config.mk + +# PAD_TO used to generate a 2kByte binary needed for the combined image +# -> PAD_TO = TEXT_BASE + 2048 +PAD_TO := $(shell expr $$[$(TEXT_BASE) + 2048]) + +ifeq ($(debug),1) +PLATFORM_CPPFLAGS += -DDEBUG +endif
nand_spl/board/imx31_phycore/u-boot.lds new file +65 -0
65 lines not on this page · raw message
nand_spl/nand_boot_mx31.c new file +190 -0
190 lines not on this page · raw message
Signature · 1 line
1.5.2.4
PATCH 1/1 V2 NAND_SPL support for phycore imx31
board/imx31_phycore/lowlevel_init.S line 50
Quoted 3 lines · Maxim Artamonov
board/imx31_phycore/lowlevel_init.S +3
-0+#ifdef CONFIG_NAND_SPL +/* somewhat macro to reduce bin size for CONFIG_NAND_SPL*/ +.macro FILLREGS begreg, val, count, step
Why not use this macro always?
Quoted 4 lines
cpu/arm1136/start.S +0
-0@@ -32,6 +35,15 @@ #include <version.h> .globl _start _start: b reset
cpu/arm1136/start.S line 47
Quoted 10 lines
cpu/arm1136/start.S +9
-0+#ifdef CONFIG_NAND_SPL + nop + nop + nop + nop + nop + nop + nop +#else #ifdef CONFIG_ONENAND_IPL
#elif
Do NAND and OneNAND really have different requirements here?
cpu/arm1136/start.S relocate: /* relocate U-Boot to RAM */ · line 172
Quoted 6 lines
cpu/arm1136/start.S +1
-1@@ -156,9 +169,9 @@ relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ -#ifndef CONFIG_ONENAND_IPL +#if !defined(CONFIG_ONENAND_IPL) && !defined(CONFIG_NAND_SPL)
Should define one symbol that is set if either of the above are set, to simplify the ifdefs.
Quoted 4 lines
include/asm-arm/arch-mx31/mx31-regs.h +4
-0+#define NFC_BUF_SIZE (*((volatile u16 *)(NFC_BASE_ADDR + 0xE00))) +#define NFC_BUF_ADDR (*((volatile u16 *)(NFC_BASE_ADDR + 0xE04))) +#define NFC_FLASH_ADDR (*((volatile u16 *)(NFC_BASE_ADDR + 0xE06))) +#define NFC_FLASH_CMD (*((volatile u16 *)(NFC_BASE_ADDR + 0xE08)))
include/asm-arm/arch-mx31/mx31-regs.h line 192
Quoted 10 lines
include/asm-arm/arch-mx31/mx31-regs.h +10
-0+#define NFC_CONFIG (*((volatile u16 *)(NFC_BASE_ADDR + 0xE0A))) +#define NFC_ECC_STATUS_RESULT (*((volatile u16 *)(NFC_BASE_ADDR + 0xE0C))) +#define NFC_RSLTMAIN_AREA (*((volatile u16 *)(NFC_BASE_ADDR + 0xE0E))) +#define NFC_RSLTSPARE_AREA (*((volatile u16 *)(NFC_BASE_ADDR + 0xE10))) +#define NFC_WRPROT (*((volatile u16 *)(NFC_BASE_ADDR + 0xE12))) +#define NFC_UNLOCKSTART_BLKADDR (*((volatile u16 *)(NFC_BASE_ADDR + 0xE14))) +#define NFC_UNLOCKEND_BLKADDR (*((volatile u16 *)(NFC_BASE_ADDR + 0xE16))) +#define NFC_NF_WRPRST (*((volatile u16 *)(NFC_BASE_ADDR + 0xE18))) +#define NFC_CONFIG1 (*((volatile u16 *)(NFC_BASE_ADDR + 0xE1A))) +#define NFC_CONFIG2 (*((volatile u16 *)(NFC_BASE_ADDR + 0xE1C)))
Use I/O accessors, and move the NFC register layout to a non-arch-specific header file (preferably as a struct), as it's shared with other chips.
Quoted 4 lines
#define
CONFIG_EXTRA_ENV_SETTINGS\include/configs/imx31_phycore.h +0
-3-"bootargs_base=setenv bootargs console=ttySMX0,115200\0" \ -"bootargs_nfs=setenv bootargs $(bootargs) root=/dev/nfs ip=dhcp nfsroot=$(serverip):$(nfsrootfs),v3,tcp\0" \ -"bootargs_flash=setenv bootargs $(bootargs) root=/dev/mtdblock2 rootfstype=jffs2" \
include/configs/imx31_phycore.h line 111
Quoted 10 lines
include/configs/imx31_phycore.h +8
-1-"bootargs_mtd=setenv bootargs $(bootargs) $(mtdparts)" \ +"jffs2=root-pcm037.jffs2\0" \ +"uimage=uImage-pcm037\0" \ +"nfsrootfs=/nfsroot\0" \"bootcmd=run bootcmd_net\0" \ +"mtdids=nor0=phys_mapped_flash\0" \ +"bootargs_base=setenv bootargs console=ttymxc0,115200\0" \ +"bootargs_nfs=setenv bootargs $(bootargs) root=/dev/nfs ip=dhcp nfsroot=$(serverip):$(nfsrootfs),v3,tcp\0" \ +"bootargs_mtd=setenv bootargs $(bootargs) $(mtdparts)\0" \ +"bootargs_flash=setenv bootargs $(bootargs) root=/dev/mtdblock3 rootfstype=jffs2\0" \
There are changes in here that don't seem to be related to nand boot.
nand_spl/nand_boot_mx31.c line 34
Quoted 8 lines
nand_spl/nand_boot_mx31.c new file +8
-0+static void mx31_wait_ready (void ) +{ +while (1 ) +if (NFC_CONFIG2 &NFC_INT ){ +NFC_CONFIG2 =NFC_CONFIG2 & (~NFC_INT );/*int flag reset*/ +break ; + } +}
There's an extra indentation level in the if-body.
Braces around the while-body. Space before and after braces (here and elsewhere).
nand_spl/nand_boot_mx31.c line 42
Quoted 7 lines
nand_spl/nand_boot_mx31.c new file +7
-0+static void mx31_nand_init (void ) +{ +/*unlocking RAM Buff*/ +NFC_CONFIG =0x2 ; + +/*hardware ECC checking and correct*/ +NFC_CONFIG1 =NFC_ECC_EN ;
Space after /*, before */
nand_spl/nand_boot_mx31.c line 117
Quoted 3 lines
nand_spl/nand_boot_mx31.c new file +3
-0+if (mx31_nand_check_ecc ()) +while (1 ){ +break ;};/*!!!!!*/
What is this?
Quoted 35 lines
nand_spl/nand_boot_mx31.c new file +35
-0+ p1 = (u32 *)MAIN_AREA0 ; + p2 = (u32 *)buf; + +/*main copy loop from NAND-buffer to SDRAM memory*/ +for (i=0 ; i < (CFG_NAND_PAGE_SIZE /4 ); i++){ + *p2 = *p1; + p1++; + p2++; + } + + p1 = (u32 *)SPARE_AREA0 ; + +/*it is hardware specific code for 8-bit 512kB 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 ; +} + +static int nand_load (unsigned int from,unsigned int size,unsigned char *buf) +{ +int i, bb; + +mx31_nand_init (); + +/*conver from to page number*/ + from = from /CFG_NAND_PAGE_SIZE ; + + i =0 ; + +while (i < (size/CFG_NAND_PAGE_SIZE )){
nand_spl/nand_boot_mx31.c line 163
Quoted 10 lines
nand_spl/nand_boot_mx31.c new file +10
-0+ +if ((from*CFG_NAND_PAGE_SIZE ) >=CFG_NAND_CHIP_SIZE ) +return 2 ;/*memory segment violation*/ + + bb =mx31_read_page (from, buf); + +/*checking first page of each block*/ +/*if this page has bb marker, then skip whole block*/ +if ((!(from %CFG_NAND_PAGE_COUNT )) && bb){ + from = from +CFG_NAND_PAGE_COUNT ;
CONFIG_NAND_PAGES_PER_BLOCK would probably be a better name.
Review
Quoted 2 lines
(quoted diff) +2
-0+ } + else{
} else {
-Scott
PATCH 1/1 V2 NAND_SPL support for phycore imx31
In reply to Maxim ArtamonovHi
I have used your patch to boot the i.MX31 PDK board from its large page NAND now. I had to modify one function (see below).
2008/12/5 Maxim Artamonov <[email protected]>:
Quoted 8 lines
V2
NAND_SPLsupport for phycore imx31Changelog:
* Added bad block verify and skip;
* Correct code to codestyle;
* Added few comments;
nand_spl/nand_boot_mx31.c line 87
Quoted 7 lines
nand_spl/nand_boot_mx31.c +7
-0+static void mx31_nand_data_output (void ) +{ +NFC_CONFIG1 =NFC_ECC_EN ; +NFC_BUF_ADDR =0 ;/* read in first 0 buffer*/ +NFC_CONFIG2 =NFC_OUTPUT ; +mx31_wait_ready (); +}
I suggest using the following function instead in order to support for small page and large page devices:
static void mx31_nand_data_output(void)
{
int i;
/*
* The NAND controller requires four output commands for
* large page devices.
*/
for (i = 0; i < (CFG_NAND_PAGE_SIZE / 512); i++) {
NFC_CONFIG1 = NFC_ECC_EN;
NFC_BUF_ADDR = i; /* read in i:th buffer */
NFC_CONFIG2 = NFC_OUTPUT;
mx31_wait_ready();
}
}Quoted 20 lines
nand_spl/nand_boot_mx31.c +20
-0+ +static int mx31_nand_check_ecc (void ) +{ +unsigned short ecc_status_registr; + + ecc_status_registr =NFC_ECC_STATUS_RESULT ; + +if (ecc_status_registr !=0 ) +return 1 ;/*error*/ +return 0 ; +} + +static int mx31_read_page (unsigned int page_address,unsigned char *buf) +{ +int i; +volatile u32 *p1, *p2, a; + +mx31_nand_init (); +NFC_BUF_ADDR =0 ;/* read in first 0 buffer*/ +mx31_nand_command (NAND_CMD_READ0 );
nand_spl/nand_boot_mx31.c line 117
Quoted 10 lines
nand_spl/nand_boot_mx31.c +10
-0+mx31_nand_page_address (page_address); + +if (CFG_NAND_CHIP_SIZE >=0x08000000 ) +mx31_nand_command (NAND_CMD_READSTART ); + +mx31_nand_data_output ();/*fill the main buffer 0*/ + +if (mx31_nand_check_ecc ()) +while (1 ){ +break ;};/*!!!!!*/
How about returning an error code and letting the nand_boot() function below just loop forever (or something) if this happens?
Quoted 4 lines
nand_spl/nand_boot_mx31.c +4
-0+ + p1 = (u32 *)MAIN_AREA0 ; + p2 = (u32 *)buf; +
nand_spl/nand_boot_mx31.c line 131
Quoted 10 lines
nand_spl/nand_boot_mx31.c +10
-0+/*main copy loop from NAND-buffer to SDRAM memory*/ +for (i=0 ; i < (CFG_NAND_PAGE_SIZE /4 ); i++){ + *p2 = *p1; + p1++; + p2++; + } + + p1 = (u32 *)SPARE_AREA0 ; + +/*it is hardware specific code for 8-bit 512kB NAND-flash spare area*/
I guess "512kB" should be just "512"?
nand_spl/nand_boot_mx31.c line 135
Quoted 4 lines
nand_spl/nand_boot_mx31.c +4
-0+ p1++; + a = *p1; + a = (a &0x0000ff00 ) >>8 ; +
Is this code valid also for large page NAND devices? I don't know the answer myself.
I hope you have the possibility to update the patch with the above as well as Scott's comments.
Thanks, Magnus