qca: ipq40xx: Configure u-boot environment in nand

Change-Id: Ic7849ca28adcebf24f376900abd22e409194cd3e
Signed-off-by: Akila N <akilan@codeaurora.org>
This commit is contained in:
Akila N 2016-04-05 22:31:28 +05:30 committed by Gerrit - the friendly Code Review server
parent 1aa59e6721
commit da1841647b
4 changed files with 116 additions and 21 deletions

View file

@ -19,6 +19,7 @@
#include <configs/ipq40xx.h> #include <configs/ipq40xx.h>
#include "ipq40xx.h" #include "ipq40xx.h"
#include "ipq40xx_board_param.h" #include "ipq40xx_board_param.h"
#include <nand.h>
#include <part.h> #include <part.h>
#include <asm/arch-ipq40xx/smem.h> #include <asm/arch-ipq40xx/smem.h>
@ -27,7 +28,15 @@ DECLARE_GLOBAL_DATA_PTR;
loff_t board_env_offset; loff_t board_env_offset;
loff_t board_env_range; loff_t board_env_range;
loff_t board_env_size; loff_t board_env_size;
extern int nand_env_device;
char *env_name_spec;
extern char *nand_env_name_spec;
int (*saveenv)(void);
env_t *env_ptr;
extern env_t *nand_env_ptr;
extern int nand_env_init(void);
extern int nand_saveenv(void);
extern void nand_env_relocate_spec(void);
/* /*
* Don't have this as a '.bss' variable. The '.bss' and '.rel.dyn' * Don't have this as a '.bss' variable. The '.bss' and '.rel.dyn'
* sections seem to overlap. * sections seem to overlap.
@ -82,6 +91,47 @@ static board_ipq40xx_params_t *get_board_param(unsigned int machid)
for (;;); for (;;);
} }
int env_init(void)
{
int ret;
qca_smem_flash_info_t sfi;
smem_get_boot_flash(&sfi.flash_type,
&sfi.flash_index,
&sfi.flash_chip_select,
&sfi.flash_block_size,
&sfi.flash_density);
if (sfi.flash_type != SMEM_BOOT_MMC_FLASH) {
ret = nand_env_init();
#ifdef CONFIG_QCA_MMC
} else {
ret = mmc_env_init();
#endif
}
return ret;
}
void env_relocate_spec(void)
{
qca_smem_flash_info_t sfi;
smem_get_boot_flash(&sfi.flash_type,
&sfi.flash_index,
&sfi.flash_chip_select,
&sfi.flash_block_size,
&sfi.flash_density);
if (sfi.flash_type != SMEM_BOOT_MMC_FLASH) {
nand_env_relocate_spec();
#ifdef CONFIG_QCA_MMC
} else {
mmc_env_relocate_spec();
#endif
}
};
int board_init(void) int board_init(void)
{ {
@ -116,6 +166,15 @@ int board_init(void)
} }
} }
if (sfi->flash_type == SMEM_BOOT_NAND_FLASH) {
nand_env_device = CONFIG_QPIC_NAND_NAND_INFO_IDX;
} else if (sfi->flash_type == SMEM_BOOT_SPI_FLASH) {
nand_env_device = CONFIG_IPQ_SPI_NOR_INFO_IDX;
} else if (sfi->flash_type != SMEM_BOOT_MMC_FLASH) {
printf("BUG: unsupported flash type : %d\n", sfi->flash_type);
BUG();
}
if (sfi->flash_type != SMEM_BOOT_MMC_FLASH) { if (sfi->flash_type != SMEM_BOOT_MMC_FLASH) {
ret = smem_getpart("0:APPSBLENV", &start_blocks, &size_blocks); ret = smem_getpart("0:APPSBLENV", &start_blocks, &size_blocks);
if (ret < 0) { if (ret < 0) {
@ -141,6 +200,18 @@ int board_init(void)
printf("BUG: unsupported flash type : %d\n", sfi->flash_type); printf("BUG: unsupported flash type : %d\n", sfi->flash_type);
BUG(); BUG();
} }
if (sfi->flash_type != SMEM_BOOT_MMC_FLASH) {
saveenv = nand_saveenv;
env_ptr = nand_env_ptr;
env_name_spec = nand_env_name_spec;
#ifdef CONFIG_QCA_MMC
} else {
saveenv = mmc_saveenv;
env_ptr = mmc_env_ptr;
env_name_spec = mmc_env_name_spec;
#endif
}
return 0; return 0;
} }
@ -239,6 +310,10 @@ int dram_init(void)
return 0; return 0;
} }
void board_nand_init(void)
{
}
int board_eth_init(bd_t *bis) int board_eth_init(bd_t *bis)
{ {
return 0; return 0;

View file

@ -39,18 +39,19 @@
#define CONFIG_ENV_RANGE CONFIG_ENV_SIZE #define CONFIG_ENV_RANGE CONFIG_ENV_SIZE
#endif #endif
char *env_name_spec = "NAND"; char *nand_env_name_spec = "NAND";
#if defined(ENV_IS_EMBEDDED) #if defined(ENV_IS_EMBEDDED)
env_t *env_ptr = &environment; env_t *nand_env_ptr = &environment;
#elif defined(CONFIG_NAND_ENV_DST) #elif defined(CONFIG_NAND_ENV_DST)
env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST; env_t *nand_env_ptr = (env_t *)CONFIG_NAND_ENV_DST;
#else /* ! ENV_IS_EMBEDDED */ #else /* ! ENV_IS_EMBEDDED */
env_t *env_ptr; env_t *nand_env_ptr;
#endif /* ENV_IS_EMBEDDED */ #endif /* ENV_IS_EMBEDDED */
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
int nand_env_device = 0;
/* /*
* This is called before nand_init() so we can't read NAND to * This is called before nand_init() so we can't read NAND to
* validate env data. * validate env data.
@ -63,7 +64,7 @@ DECLARE_GLOBAL_DATA_PTR;
* This way the SPL loads not only the U-Boot image from NAND but * This way the SPL loads not only the U-Boot image from NAND but
* also the environment. * also the environment.
*/ */
int env_init(void) int nand_env_init(void)
{ {
#if defined(ENV_IS_EMBEDDED) || defined(CONFIG_NAND_ENV_DST) #if defined(ENV_IS_EMBEDDED) || defined(CONFIG_NAND_ENV_DST)
int crc1_ok = 0, crc2_ok = 0; int crc1_ok = 0, crc2_ok = 0;
@ -132,15 +133,16 @@ static int writeenv(size_t offset, u_char *buf)
size_t blocksize, len; size_t blocksize, len;
u_char *char_ptr; u_char *char_ptr;
blocksize = nand_info[0].erasesize; blocksize = nand_info[nand_env_device].erasesize;
len = min(blocksize, (size_t)CONFIG_ENV_SIZE); len = min(blocksize, (size_t)CONFIG_ENV_SIZE);
while (amount_saved < CONFIG_ENV_SIZE && offset < end) { while (amount_saved < CONFIG_ENV_SIZE && offset < end) {
if (nand_block_isbad(&nand_info[0], offset)) { if (nand_block_isbad(&nand_info[nand_env_device], offset)) {
offset += blocksize; offset += blocksize;
} else { } else {
char_ptr = &buf[amount_saved]; char_ptr = &buf[amount_saved];
if (nand_write(&nand_info[0], offset, &len, char_ptr)) if (nand_write(&nand_info[nand_env_device],
offset, &len, char_ptr))
return 1; return 1;
offset += blocksize; offset += blocksize;
@ -155,7 +157,7 @@ static int writeenv(size_t offset, u_char *buf)
struct env_location { struct env_location {
const char *name; const char *name;
const nand_erase_options_t erase_opts; nand_erase_options_t erase_opts;
}; };
static int erase_and_write_env(const struct env_location *location, static int erase_and_write_env(const struct env_location *location,
@ -164,7 +166,7 @@ static int erase_and_write_env(const struct env_location *location,
int ret = 0; int ret = 0;
printf("Erasing %s...\n", location->name); printf("Erasing %s...\n", location->name);
if (nand_erase_opts(&nand_info[0], &location->erase_opts)) if (nand_erase_opts(&nand_info[nand_env_device], &location->erase_opts))
return 1; return 1;
printf("Writing to %s... ", location->name); printf("Writing to %s... ", location->name);
@ -178,12 +180,12 @@ static int erase_and_write_env(const struct env_location *location,
static unsigned char env_flags; static unsigned char env_flags;
#endif #endif
int saveenv(void) int nand_saveenv(void)
{ {
int ret = 0; int ret = 0;
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
int env_idx = 0; int env_idx = 0;
static const struct env_location location[] = { struct env_location location[] = {
{ {
.name = "NAND", .name = "NAND",
.erase_opts = { .erase_opts = {
@ -247,20 +249,20 @@ static int readenv(size_t offset, u_char *buf)
size_t blocksize, len; size_t blocksize, len;
u_char *char_ptr; u_char *char_ptr;
blocksize = nand_info[0].erasesize; blocksize = nand_info[nand_env_device].erasesize;
if (!blocksize) if (!blocksize)
return 1; return 1;
len = min(blocksize, (size_t)CONFIG_ENV_SIZE); len = min(blocksize, (size_t)CONFIG_ENV_SIZE);
while (amount_loaded < CONFIG_ENV_SIZE && offset < end) { while (amount_loaded < CONFIG_ENV_SIZE && offset < end) {
if (nand_block_isbad(&nand_info[0], offset)) { if (nand_block_isbad(&nand_info[nand_env_device], offset)) {
offset += blocksize; offset += blocksize;
} else { } else {
char_ptr = &buf[amount_loaded]; char_ptr = &buf[amount_loaded];
if (nand_read_skip_bad(&nand_info[0], offset, if (nand_read_skip_bad(&nand_info[nand_env_device], offset,
&len, NULL, &len, NULL,
nand_info[0].size, char_ptr)) nand_info[nand_env_device].size, char_ptr))
return 1; return 1;
offset += blocksize; offset += blocksize;
@ -308,7 +310,7 @@ int get_nand_env_oob(nand_info_t *nand, unsigned long *result)
#endif #endif
#ifdef CONFIG_ENV_OFFSET_REDUND #ifdef CONFIG_ENV_OFFSET_REDUND
void env_relocate_spec(void) void nand_env_relocate_spec(void)
{ {
#if !defined(ENV_IS_EMBEDDED) #if !defined(ENV_IS_EMBEDDED)
int read1_fail = 0, read2_fail = 0; int read1_fail = 0, read2_fail = 0;
@ -380,14 +382,14 @@ done:
* device i.e., nand_dev_desc + 0. This is also the behaviour using * device i.e., nand_dev_desc + 0. This is also the behaviour using
* the new NAND code. * the new NAND code.
*/ */
void env_relocate_spec(void) void nand_env_relocate_spec(void)
{ {
#if !defined(ENV_IS_EMBEDDED) #if !defined(ENV_IS_EMBEDDED)
int ret; int ret;
ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
#if defined(CONFIG_ENV_OFFSET_OOB) #if defined(CONFIG_ENV_OFFSET_OOB)
ret = get_nand_env_oob(&nand_info[0], &nand_env_oob_offset); ret = get_nand_env_oob(&nand_info[nand_env_device], &nand_env_oob_offset);
/* /*
* If unable to read environment offset from NAND OOB then fall through * If unable to read environment offset from NAND OOB then fall through
* to the normal environment reading code below * to the normal environment reading code below

View file

@ -386,7 +386,11 @@ ulong getenv_hex(const char *varname, ulong default_val);
* Return -1 if variable does not exist (default to true) * Return -1 if variable does not exist (default to true)
*/ */
int getenv_yesno(const char *var); int getenv_yesno(const char *var);
#ifdef CONFIG_IPQ40XX_ENV
extern int (*saveenv)(void);
#else
int saveenv (void); int saveenv (void);
#endif
int setenv (const char *, const char *); int setenv (const char *, const char *);
int setenv_ulong(const char *varname, ulong value); int setenv_ulong(const char *varname, ulong value);
int setenv_hex(const char *varname, ulong value); int setenv_hex(const char *varname, ulong value);

View file

@ -30,7 +30,6 @@
#define CONFIG_SYS_CACHELINE_SIZE 64 #define CONFIG_SYS_CACHELINE_SIZE 64
#define CONFIG_SKIP_LOWLEVEL_INIT #define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_HZ 1000 #define CONFIG_SYS_HZ 1000
#define CONFIG_ENV_IS_NOWHERE 1
#define CONFIG_IPQ40XX_UART #define CONFIG_IPQ40XX_UART
#define CONFIG_CONS_INDEX 1 #define CONFIG_CONS_INDEX 1
@ -56,6 +55,8 @@
#define CONFIG_IPQ_APPSBL_IMG_TYPE 0x5 #define CONFIG_IPQ_APPSBL_IMG_TYPE 0x5
#define CONFIG_IPQ40XX_ENV
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_EXTRA_ENV_SETTINGS \ #define CONFIG_EXTRA_ENV_SETTINGS \
"fdtcontroladdr=0x84000000\0" "fdtcontroladdr=0x84000000\0"
@ -114,6 +115,19 @@ typedef struct {
* size is configured to 64 */ * size is configured to 64 */
#define CONFIG_SYS_CACHELINE_SIZE 64 #define CONFIG_SYS_CACHELINE_SIZE 64
#define CONFIG_CMD_NAND
#define CONFIG_SYS_MAX_NAND_DEVICE (CONFIG_IPQ_MAX_NAND_DEVICE + \
CONFIG_IPQ_MAX_SPI_DEVICE)
#define CONFIG_IPQ_MAX_SPI_DEVICE 2
#define CONFIG_IPQ_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_SELF_INIT
#define CONFIG_IPQ_NAND_NAND_INFO_IDX 0
#define CONFIG_QPIC_NAND_NAND_INFO_IDX 0
#define CONFIG_IPQ_SPI_NAND_INFO_IDX 1
#define CONFIG_IPQ_SPI_NOR_INFO_IDX 2
/* /*
* SPI Flash Configs * SPI Flash Configs
*/ */