This patch provides a fix for a single binary image for NAND/ONENAND based EVM boards. It does not make any assumption on whether the board has NAND/ ONENAND boards. During board initialization, the flash is scanned for and the first available flash is used to store the environement variables. The fix is also provided for Beagle and Overo boards. From abd1aad78abb4045c636aed92db637a5000d9d31 Mon Sep 17 00:00:00 2001 From: Manikandan Pillai Date: Tue, 9 Sep 2008 15:56:13 +0530 Subject: [PATCH] Fix for single binary image for NAND/OneNAND EVMS. Signed-off-by: Manikandan Pillai --- board/omap3/evm/evm.c | 1 - common/cmd_nvedit.c | 5 ++ common/env_common.c | 9 ++- common/env_nand.c | 36 ++++++++++++- common/env_onenand.c | 28 ++++++++++- cpu/omap3/board.c | 16 ++++++ cpu/omap3/mem.c | 114 ++++++++++++++++++++++++----------------- cpu/omap3/nand.c | 1 + cpu/omap3/sys_info.c | 10 ++-- drivers/mtd/nand/nand_base.c | 1 + include/common.h | 11 +++- include/configs/omap3_evm.h | 3 +- lib_arm/board.c | 20 +++++++ 13 files changed, 192 insertions(+), 63 deletions(-) diff --git a/board/omap3/evm/evm.c b/board/omap3/evm/evm.c index 88f249d..5f1930a 100644 --- a/board/omap3/evm/evm.c +++ b/board/omap3/evm/evm.c @@ -52,7 +52,6 @@ int board_init(void) { DECLARE_GLOBAL_DATA_PTR; - gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ /* board id for Linux */ gd->bd->bi_arch_number = MACH_TYPE_OMAP3EVM; /* boot param addr */ diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 7089706..d4a5d04 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -59,6 +59,7 @@ DECLARE_GLOBAL_DATA_PTR; !defined(CFG_ENV_IS_IN_NAND) && \ !defined(CFG_ENV_IS_IN_ONENAND) && \ !defined(CFG_ENV_IS_IN_SPI_FLASH) && \ + !defined(CFG_ENV_IS_IN_SEL_RUN) && \ !defined(CFG_ENV_IS_NOWHERE) # error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|ONENAND|SPI_FLASH|NOWHERE} #endif @@ -66,6 +67,10 @@ DECLARE_GLOBAL_DATA_PTR; #define XMK_STR(x) #x #define MK_STR(x) XMK_STR(x) +#if defined(CFG_ENV_IS_IN_SEL_RUN) +extern saveenv_p saveenv; +#endif + /************************************************************************ ************************************************************************/ diff --git a/common/env_common.c b/common/env_common.c index d51c211..8960062 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -46,8 +46,13 @@ DECLARE_GLOBAL_DATA_PTR; extern env_t *env_ptr; -extern void env_relocate_spec (void); +#if defined(CFG_ENV_IS_IN_SEL_RUN) +extern env_get_char_spec_p env_get_char_spec; +extern env_relocate_spec_p env_relocate_spec; +#else extern uchar env_get_char_spec(int); +extern void env_relocate_spec(void); +#endif static uchar env_get_char_init (int index); @@ -191,7 +196,6 @@ uchar env_get_char (int index) c = env_get_char_memory(index); else c = env_get_char_init(index); - return (c); } @@ -258,7 +262,6 @@ void env_relocate (void) env_relocate_spec (); } gd->env_addr = (ulong)&(env_ptr->data); - #ifdef CONFIG_AMIGAONEG3SE disable_nvram(); #endif diff --git a/common/env_nand.c b/common/env_nand.c index a8f0de7..4561202 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -34,7 +34,9 @@ #include -#if defined(CFG_ENV_IS_IN_NAND) /* Environment is in Nand Flash */ +/* Environment is in Nand Flash */ +#if defined(CFG_ENV_IS_IN_NAND) || (defined(CONFIG_CMD_NAND) && \ + defined(CFG_ENV_IS_IN_SEL_RUN)) #include #include @@ -68,12 +70,18 @@ int nand_legacy_rw (struct nand_chip* nand, int cmd, extern uchar default_environment[]; extern int default_environment_size; +#if defined(CFG_ENV_IS_IN_SEL_RUN) +char *nand_env_name_spec = "NAND"; +#else char * env_name_spec = "NAND"; - +#endif #ifdef ENV_IS_EMBEDDED extern uchar environment[]; env_t *env_ptr = (env_t *)(&environment[0]); +#elif defined(CFG_ENV_IS_IN_SEL_RUN) +env_t *nand_env_ptr; +extern env_t *env_ptr; #else /* ! ENV_IS_EMBEDDED */ env_t *env_ptr = 0; #endif /* ENV_IS_EMBEDDED */ @@ -86,7 +94,11 @@ static void use_default(void); DECLARE_GLOBAL_DATA_PTR; +#if defined(CFG_ENV_IS_IN_SEL_RUN) +uchar nand_env_get_char_spec(int index) +#else uchar env_get_char_spec (int index) +#endif { return ( *((uchar *)(gd->env_addr + index)) ); } @@ -103,7 +115,11 @@ uchar env_get_char_spec (int index) * the SPL loads not only the U-Boot image from NAND but also the * environment. */ +#if defined(CFG_ENV_IS_IN_SEL_RUN) +int nand_env_init(void) +#else int env_init(void) +#endif { #if defined(ENV_IS_EMBEDDED) size_t total; @@ -184,7 +200,11 @@ int writeenv(size_t offset, u_char *buf) return 0; } #ifdef CFG_ENV_OFFSET_REDUND +#if defined(CFG_ENV_IS_IN_SEL_RUN) +int nand_saveenv(void) +#else int saveenv(void) +#endif { size_t total; int ret = 0; @@ -227,7 +247,11 @@ int saveenv(void) return ret; } #else /* ! CFG_ENV_OFFSET_REDUND */ +#if defined(CFG_ENV_IS_IN_SEL_RUN) +int nand_saveenv(void) +#else int saveenv(void) +#endif { size_t total; int ret = 0; @@ -287,7 +311,11 @@ int readenv (size_t offset, u_char * buf) } #ifdef CFG_ENV_OFFSET_REDUND +#if defined(CFG_ENV_IS_IN_SEL_RUN) +void nand_env_relocate_spec(void) +#else void env_relocate_spec (void) +#endif { #if !defined(ENV_IS_EMBEDDED) size_t total; @@ -344,7 +372,11 @@ void env_relocate_spec (void) * The legacy NAND code saved the environment in the first NAND device i.e., * nand_dev_desc + 0. This is also the behaviour using the new NAND code. */ +#if defined(CFG_ENV_IS_IN_SEL_RUN) +void nand_env_relocate_spec(void) +#else void env_relocate_spec (void) +#endif { #if !defined(ENV_IS_EMBEDDED) int ret; diff --git a/common/env_onenand.c b/common/env_onenand.c index d5c907c..d776955 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -23,7 +23,9 @@ #include -#if defined(CFG_ENV_IS_IN_ONENAND) /* Environment is in OneNAND */ +/* Environment is in OneNAND */ +#if defined(CFG_ENV_IS_IN_ONENAND) || (defined(CONFIG_CMD_ONENAND) && \ + defined(CFG_ENV_IS_IN_SEL_RUN)) #include #include @@ -42,11 +44,19 @@ extern uchar default_environment[]; #define ONENAND_ENV_SIZE(mtd) (mtd.writesize - ENV_HEADER_SIZE) +#if defined(CFG_ENV_IS_IN_SEL_RUN) +char *onenand_env_name_spec = "OneNAND"; +#else char *env_name_spec = "OneNAND"; +#endif #ifdef ENV_IS_EMBEDDED extern uchar environment[]; env_t *env_ptr = (env_t *) (&environment[0]); +#elif defined(CFG_ENV_IS_IN_SEL_RUN) +static unsigned char onenand_env[MAX_ONENAND_PAGESIZE]; +env_t *onenand_env_ptr = (env_t *)&onenand_env[0]; +extern env_t *env_ptr; #else /* ! ENV_IS_EMBEDDED */ static unsigned char onenand_env[MAX_ONENAND_PAGESIZE]; env_t *env_ptr = (env_t *) onenand_env; @@ -54,12 +64,20 @@ env_t *env_ptr = (env_t *) onenand_env; DECLARE_GLOBAL_DATA_PTR; +#if defined(CFG_ENV_IS_IN_SEL_RUN) +uchar onenand_env_get_char_spec(int index) +#else uchar env_get_char_spec(int index) +#endif { return (*((uchar *) (gd->env_addr + index))); } +#if defined(CFG_ENV_IS_IN_SEL_RUN) +void onenand_env_relocate_spec(void) +#else void env_relocate_spec(void) +#endif { unsigned long env_addr; int use_default = 0; @@ -90,7 +108,11 @@ void env_relocate_spec(void) gd->env_valid = 1; } +#if defined(CFG_ENV_IS_IN_SEL_RUN) +int onenand_saveenv(void) +#else int saveenv(void) +#endif { unsigned long env_addr = CFG_ENV_ADDR; struct erase_info instr = { @@ -118,7 +140,11 @@ int saveenv(void) return 0; } +#if defined(CFG_ENV_IS_IN_SEL_RUN) +int onenand_env_init(void) +#else int env_init(void) +#endif { /* use default */ gd->env_addr = (ulong) & default_environment[0]; diff --git a/cpu/omap3/board.c b/cpu/omap3/board.c index 0ca4128..1dea66f 100644 --- a/cpu/omap3/board.c +++ b/cpu/omap3/board.c @@ -310,6 +310,20 @@ void nand_init(void) #endif /****************************************************************************** + * Routine: print_board_info + * Description: Displays cpu and memory information for the board + *****************************************************************************/ +void print_board_info(void) +{ + u32 mtype, btype; + + btype = get_board_type(); + mtype = get_mem_type(); + + display_board_info(btype); +} + +/****************************************************************************** * Dummy function to handle errors for EABI incompatibility *****************************************************************************/ void raise(void) @@ -322,3 +336,5 @@ void raise(void) void abort(void) { } + + diff --git a/cpu/omap3/mem.c b/cpu/omap3/mem.c index 8ad4b33..7191f60 100644 --- a/cpu/omap3/mem.c +++ b/cpu/omap3/mem.c @@ -26,11 +26,13 @@ */ #include +#include #include #include #include #include #include +#include /* Only One NAND allowed on board at a time. * The GPMC CS Base for the same @@ -40,33 +42,42 @@ unsigned int boot_flash_off; unsigned int boot_flash_sec; unsigned int boot_flash_type; volatile unsigned int boot_flash_env_addr; +char *env_name_spec; +env_t *env_ptr; +extern char *nand_env_name_spec; +extern char *onenand_env_name_spec; +extern env_t *nand_env_ptr; +extern env_t *onenand_env_ptr; + +/* if 1 = NAND, 2 = ONENAND */ +unsigned int env_in_storage; +extern void onenand_init(void); +extern int nand_scan_ident(struct mtd_info *mtd, int maxchips); /* help common/env_flash.c */ -#ifdef ENV_IS_VARIABLE - -uchar(*boot_env_get_char_spec) (int index); -int (*boot_env_init) (void); -int (*boot_saveenv) (void); -void (*boot_env_relocate_spec) (void); - -/* 16 bit NAND */ +#if defined(CFG_ENV_IS_IN_SEL_RUN) +env_get_char_spec_p env_get_char_spec; +env_init_p env_init; +saveenv_p saveenv; +env_relocate_spec_p env_relocate_spec; +extern uchar nand_env_get_char_spec(int index); +extern int nand_env_init(void); +extern int nand_saveenv(void); +extern void nand_env_relocate_spec(void); +extern uchar onenand_env_get_char_spec(int index); +extern int onenand_env_init(void); +extern int onenand_saveenv(void); +extern void onenand_env_relocate_spec(void); +#else uchar env_get_char_spec(int index); int env_init(void); int saveenv(void); void env_relocate_spec(void); -extern char *env_name_spec; - -#if defined(CONFIG_CMD_NAND) -u8 is_nand; #endif -#if defined(CONFIG_CMD_ONENAND) -u8 is_onenand; -#endif - -#endif /* ENV_IS_VARIABLE */ - #if defined(CONFIG_CMD_NAND) +u8 is_nand; +extern nand_info_t nand_info[CFG_MAX_NAND_DEVICE]; static u32 gpmc_m_nand[GPMC_MAX_REG] = { M_NAND_GPMC_CONFIG1, M_NAND_GPMC_CONFIG2, @@ -79,6 +90,8 @@ unsigned int nand_cs_base; #endif #if defined(CONFIG_CMD_ONENAND) +u8 is_onenand; +extern struct mtd_info onenand_mtd; static u32 gpmc_onenand[GPMC_MAX_REG] = { ONENAND_GPMC_CONFIG1, ONENAND_GPMC_CONFIG2, @@ -223,6 +236,7 @@ void gpmc_init(void) u32 mux = 0, mwidth; u32 *gpmc_config = NULL; u32 gpmc_base = 0; + u32 gpmc_index = 0; u32 base = 0; u32 size = 0; u32 f_off = CFG_MONITOR_LEN; @@ -248,40 +262,46 @@ void gpmc_init(void) #if defined(CONFIG_CMD_NAND) /* CS 0 */ gpmc_config = gpmc_m_nand; -#if defined(CFG_ENV_IS_IN_NAND) - gpmc_base = GPMC_CONFIG_CS0 + (0 * GPMC_CONFIG_WIDTH); -#else - gpmc_base = GPMC_CONFIG_CS0 + (1 * GPMC_CONFIG_WIDTH); -#endif + gpmc_base = GPMC_CONFIG_CS0 + (gpmc_index * GPMC_CONFIG_WIDTH); base = PISMO1_NAND_BASE; size = PISMO1_NAND_SIZE; enable_gpmc_config(gpmc_config, gpmc_base, base, size); - is_nand = 1; - nand_cs_base = gpmc_base; -#if defined(CFG_ENV_IS_IN_NAND) - f_off = SMNAND_ENV_OFFSET; - f_sec = SZ_128K; - /* env setup */ - boot_flash_base = base; - boot_flash_off = f_off; - boot_flash_sec = f_sec; - boot_flash_env_addr = f_off; -#endif + /* NAND and/or ONENAND is to be scanned */ + is_nand = 0; + nand_init(); + if (nand_info[0].size) { + is_nand = 1; + nand_cs_base = gpmc_base; + f_off = SMNAND_ENV_OFFSET; + f_sec = SZ_128K; + /* env setup */ + boot_flash_base = base; + boot_flash_off = f_off; + boot_flash_sec = f_sec; + boot_flash_env_addr = f_off; + + env_name_spec = nand_env_name_spec; + env_ptr = nand_env_ptr; + env_get_char_spec = nand_env_get_char_spec; + env_init = nand_env_init; + saveenv = nand_saveenv; + env_relocate_spec = nand_env_relocate_spec; + gpmc_index++; + } #endif #if defined(CONFIG_CMD_ONENAND) gpmc_config = gpmc_onenand; -#if defined(CFG_ENV_IS_IN_ONENAND) - gpmc_base = GPMC_CONFIG_CS0 + (0 * GPMC_CONFIG_WIDTH); -#else - gpmc_base = GPMC_CONFIG_CS0 + (1 * GPMC_CONFIG_WIDTH); -#endif + gpmc_base = GPMC_CONFIG_CS0 + (gpmc_index * GPMC_CONFIG_WIDTH); base = PISMO1_ONEN_BASE; size = PISMO1_ONEN_SIZE; enable_gpmc_config(gpmc_config, gpmc_base, base, size); + /* NAND and/or ONENAND is to be scanned */ + is_onenand = 0; + onenand_init(); + if (onenand_mtd.size) { is_onenand = 1; onenand_cs_base = gpmc_base; -#if defined(CFG_ENV_IS_IN_ONENAND) f_off = ONENAND_ENV_OFFSET; f_sec = SZ_128K; /* env setup */ @@ -289,13 +309,13 @@ void gpmc_init(void) boot_flash_off = f_off; boot_flash_sec = f_sec; boot_flash_env_addr = f_off; -#endif + env_name_spec = onenand_env_name_spec; + env_ptr = onenand_env_ptr; + env_get_char_spec = onenand_env_get_char_spec; + env_init = onenand_env_init; + saveenv = onenand_saveenv; + env_relocate_spec = onenand_env_relocate_spec; + } #endif -#ifdef ENV_IS_VARIABLE - boot_env_get_char_spec = env_get_char_spec; - boot_env_init = env_init; - boot_saveenv = saveenv; - boot_env_relocate_spec = env_relocate_spec; -#endif } diff --git a/cpu/omap3/nand.c b/cpu/omap3/nand.c index 149ca12..be5a1c8 100644 --- a/cpu/omap3/nand.c +++ b/cpu/omap3/nand.c @@ -32,6 +32,7 @@ unsigned char cs; volatile unsigned long gpmc_cs_base_add; +extern int nand_switch_ecc(struct mtd_info *mtd); #define GPMC_BUF_EMPTY 0 #define GPMC_BUF_FULL 1 diff --git a/cpu/omap3/sys_info.c b/cpu/omap3/sys_info.c index dde57a9..dc90722 100644 --- a/cpu/omap3/sys_info.c +++ b/cpu/omap3/sys_info.c @@ -33,17 +33,17 @@ #include extern omap3_sysinfo sysinfo; +extern u8 is_onenand; /************************************************************************** * get_gpmc0_type() ***************************************************************************/ u32 get_gpmc0_type(void) { -#if defined(CFG_ENV_IS_IN_ONENAND) - return 1; /* OneNAND */ -#else - return 2; /* NAND */ -#endif + if (is_onenand) + return 1; /* OneNAND */ + else + return 2; /* NAND */ } /**************************************************** diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 7fcd79e..7658a86 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2869,6 +2869,7 @@ int nand_switch_ecc(struct mtd_info *mtd) if (chip->options & NAND_SKIP_BBTSCAN) chip->options |= NAND_BBT_SCANNED; + return 0; } /* module_text_address() isn't exported, and it's mostly a pointless diff --git a/include/common.h b/include/common.h index de3d595..6f47a76 100644 --- a/include/common.h +++ b/include/common.h @@ -237,12 +237,19 @@ int autoscript (ulong addr, const char *fit_uname); extern ulong load_addr; /* Default Load Address */ /* common/cmd_nvedit.c */ -int env_init (void); +#if defined(CFG_ENV_IS_IN_SEL_RUN) +typedef uchar (*env_get_char_spec_p)(int index); +typedef int (*env_init_p)(void); +typedef int (*saveenv_p)(void); +typedef void (*env_relocate_spec_p)(void); +#else +int env_init(void); +int saveenv(void); +#endif void env_relocate (void); int envmatch (uchar *, int); char *getenv (char *); int getenv_r (char *name, char *buf, unsigned len); -int saveenv (void); #ifdef CONFIG_PPC /* ARM version to be fixed! */ int inline setenv (char *, char *); #else diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h index 0abfbed..975d17c 100644 --- a/include/configs/omap3_evm.h +++ b/include/configs/omap3_evm.h @@ -255,7 +255,6 @@ #define CFG_MONITOR_BASE CFG_FLASH_BASE /* Monitor at start of flash */ #define CFG_ONENAND_BASE ONENAND_MAP -#define CFG_ENV_IS_IN_NAND 1 #define ONENAND_ENV_OFFSET 0x240000 /* environment starts here */ #define SMNAND_ENV_OFFSET 0x240000 /* environment starts here */ @@ -276,7 +275,7 @@ #define CFG_JFFS2_FIRST_BANK CFG_MAX_FLASH_BANKS /* use flash_info[2] */ #define CFG_JFFS2_NUM_BANKS 1 -#define ENV_IS_VARIABLE 1 +#define CFG_ENV_IS_IN_SEL_RUN 1 /* Sel NAND/OneNAND on fly */ #ifndef __ASSEMBLY__ extern unsigned int nand_cs_base; diff --git a/lib_arm/board.c b/lib_arm/board.c index 6e3ef08..7b7c5e0 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -58,12 +58,17 @@ DECLARE_GLOBAL_DATA_PTR; ulong monitor_flash_len; +#if defined(CFG_ENV_IS_IN_SEL_RUN) +extern void gpmc_init(void); +extern void print_board_info(void); +#endif #ifdef CONFIG_HAS_DATAFLASH extern int AT91F_DataflashInit(void); extern void dataflash_print_info(void); #endif + #ifndef CONFIG_IDENT_STRING #define CONFIG_IDENT_STRING "" #endif @@ -258,6 +263,7 @@ static int reloc_init(void) typedef int (init_fnc_t) (void); int print_cpuinfo (void); /* test-only */ +extern env_init_p env_init; init_fnc_t *init_sequence[] = { cpu_init, /* basic cpu dependent setup */ @@ -268,7 +274,11 @@ init_fnc_t *init_sequence[] = { #endif board_init, /* basic board dependent setup */ interrupt_init, /* set up exceptions */ +#if defined(CFG_ENV_IS_IN_SEL_RUN) + NULL, /* initialize environment */ +#else env_init, /* initialize environment */ +#endif init_baudrate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ @@ -353,6 +363,11 @@ void start_armboot (void) /* armboot_start is defined in the board-specific linker script */ mem_malloc_init (_armboot_start - CFG_MALLOC_LEN); +#if defined(CFG_ENV_IS_IN_SEL_RUN) + gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ + env_init(); +#endif + #if defined(CONFIG_CMD_NAND) puts ("NAND: "); nand_init(); /* go init the NAND */ @@ -379,6 +394,11 @@ void start_armboot (void) serial_initialize(); #endif +#if defined(CFG_ENV_IS_IN_SEL_RUN) + display_banner(); + print_board_info(); +#endif + /* IP Address */ gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); -- 1.5.6