diff options
45 files changed, 708 insertions, 661 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 705bac5..0041112 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -583,6 +583,10 @@ Prakash Kumar <prakash@embedx.com> cerf250 xscale +Sergey Lapin <slapin@ossfans.org> + + afeb9260 ARM926EJS (AT91SAM9260 SoC) + Guennadi Liakhovetski <g.liakhovetski@gmx.de> imx31_phycore_eet i.MX31 @@ -682,10 +686,6 @@ Alex Züpke <azu@sysgo.de> lart SA1100 dnp1110 SA1110 -Sergey Lapin <slapin@ossfans.org> - - afeb9260 ARM926EJS (AT91SAM9260 SoC) - ------------------------------------------------------------------------- Unknown / orphaned boards: @@ -782,14 +782,14 @@ Michal Simek <monstr@monstr.eu> # Board CPU # ######################################################################### -Matthias Fuchs <matthias.fuchs@esd-electronics.com> - - TASREG MCF5249 - Hayden Fraser <Hayden.Fraser@freescale.com> M5253EVBE mcf52x2 +Matthias Fuchs <matthias.fuchs@esd-electronics.com> + + TASREG MCF5249 + TsiChung Liew <Tsi-Chung.Liew@freescale.com> M52277EVB mcf5227x @@ -862,10 +862,6 @@ Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> MS7720SE SH7720 R0P77850011RL SH7785 -Yusuke Goda <goda.yusuke@renesas.com> - - MIGO-R SH7722 - ######################################################################### # Blackfin Systems: # # # @@ -2428,6 +2428,12 @@ to save the current settings. to a block boundary, and CONFIG_ENV_SIZE must be a multiple of the NAND devices block size. +- CONFIG_NAND_ENV_DST + + Defines address in RAM to which the nand_spl code should copy the + environment. If redundant environment is used, it will be copied to + CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE. + - CONFIG_SYS_SPI_INIT_OFFSET Defines offset to the initial SPI buffer area in DPRAM. The diff --git a/board/amcc/canyonlands/canyonlands.c b/board/amcc/canyonlands/canyonlands.c index 2b74689..cfc1023 100644 --- a/board/amcc/canyonlands/canyonlands.c +++ b/board/amcc/canyonlands/canyonlands.c @@ -575,15 +575,17 @@ int misc_init_r(void) #endif /* !defined(CONFIG_ARCHES) */ #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +extern void __ft_board_setup(void *blob, bd_t *bd); + void ft_board_setup(void *blob, bd_t *bd) { u32 val[4]; int rc; - ft_cpu_setup(blob, bd); + __ft_board_setup(blob, bd); /* Fixup NOR mapping */ - val[0] = 0; /* chip select number */ + val[0] = CONFIG_SYS_NOR_CS; /* chip select number */ val[1] = 0; /* always 0 */ val[2] = CONFIG_SYS_FLASH_BASE_PHYS_L; /* we fixed up this address */ val[3] = gd->bd->bi_flashsize; diff --git a/board/bf537-stamp/Makefile b/board/bf537-stamp/Makefile index 4c9e015..f728e2c 100644 --- a/board/bf537-stamp/Makefile +++ b/board/bf537-stamp/Makefile @@ -32,7 +32,6 @@ LIB = $(obj)lib$(BOARD).a COBJS-y := $(BOARD).o cmd_bf537led.o COBJS-$(CONFIG_BFIN_IDE) += ide-cf.o COBJS-$(CONFIG_CMD_EEPROM) += spi_flash.o -COBJS-$(CONFIG_CMD_NAND) += nand.o COBJS-$(CONFIG_POST) += post.o post-memory.o SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c deleted file mode 100644 index 181e83d..0000000 --- a/board/bf537-stamp/nand.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2006-2007 Analog Devices Inc. - * - * 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 - */ - -#include <common.h> -#include <asm/io.h> - -#include <nand.h> - -#define CONCAT(a,b,c,d) a ## b ## c ## d -#define PORT(a,b) CONCAT(pPORT,a,b,) - -#ifndef CONFIG_NAND_GPIO_PORT -#define CONFIG_NAND_GPIO_PORT F -#endif - -/* - * hardware specific access to control-lines - */ -static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ - register struct nand_chip *this = mtd->priv; - u32 IO_ADDR_W = (u32) this->IO_ADDR_W; - - if (ctrl & NAND_CTRL_CHANGE) { - if (ctrl & NAND_CLE) - IO_ADDR_W = CONFIG_SYS_NAND_BASE + BFIN_NAND_CLE; - else - IO_ADDR_W = CONFIG_SYS_NAND_BASE; - if (ctrl & NAND_ALE) - IO_ADDR_W = CONFIG_SYS_NAND_BASE + BFIN_NAND_ALE; - else - IO_ADDR_W = CONFIG_SYS_NAND_BASE; - this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; - } - this->IO_ADDR_R = this->IO_ADDR_W; - - /* Drain the writebuffer */ - SSYNC(); - - if (cmd != NAND_CMD_NONE) - writeb(cmd, this->IO_ADDR_W); -} - -int bfin_device_ready(struct mtd_info *mtd) -{ - int ret = (*PORT(CONFIG_NAND_GPIO_PORT, IO) & BFIN_NAND_READY) ? 1 : 0; - SSYNC(); - return ret; -} - -/* - * Board-specific NAND initialization. The following members of the - * argument are board-specific (per include/linux/mtd/nand.h): - * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device - * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device - * - cmd_ctrl: hardwarespecific function for accesing control-lines - * - dev_ready: hardwarespecific function for accesing device ready/busy line - * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must - * only be provided if a hardware ECC is available - * - ecc.mode: mode of ecc, see defines - * - chip_delay: chip dependent delay for transfering data from array to - * read regs (tR) - * - options: various chip options. They can partly be set to inform - * nand_scan about special functionality. See the defines for further - * explanation - * Members with a "?" were not set in the merged testing-NAND branch, - * so they are not set here either. - */ -int board_nand_init(struct nand_chip *nand) -{ - *PORT(CONFIG_NAND_GPIO_PORT, _FER) &= ~BFIN_NAND_READY; - *PORT(CONFIG_NAND_GPIO_PORT, IO_DIR) &= ~BFIN_NAND_READY; - *PORT(CONFIG_NAND_GPIO_PORT, IO_INEN) |= BFIN_NAND_READY; - - nand->cmd_ctrl = bfin_hwcontrol; - nand->ecc.mode = NAND_ECC_SOFT; - nand->dev_ready = bfin_device_ready; - nand->chip_delay = 30; - - return 0; -} diff --git a/board/davinci/sonata/sonata.c b/board/davinci/sonata/sonata.c index 7f9d9bb..817970a 100644 --- a/board/davinci/sonata/sonata.c +++ b/board/davinci/sonata/sonata.c @@ -25,6 +25,8 @@ */ #include <common.h> +#include <nand.h> +#include <asm/arch/nand_defs.h> #include <asm/arch/hardware.h> #include "../common/misc.h" @@ -72,3 +74,29 @@ int misc_init_r(void) return(0); } + +#ifdef CONFIG_NAND_DAVINCI + +/* Set WP on deselect, write enable on select */ +static void nand_sonata_select_chip(struct mtd_info *mtd, int chip) +{ +#define GPIO_SET_DATA01 0x01c67018 +#define GPIO_CLR_DATA01 0x01c6701c +#define GPIO_NAND_WP (1 << 4) +#ifdef SONATA_BOARD_GPIOWP + if (chip < 0) { + REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP; + } else { + REG(GPIO_SET_DATA01) |= GPIO_NAND_WP; + } +#endif +} + +int board_nand_init(struct nand_chip *nand) +{ + davinci_nand_init(nand); + nand->select_chip = nand_sonata_select_chip; + return 0; +} + +#endif /* CONFIG_NAND_DAVINCI */ diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 9451416..2f70521 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -414,18 +414,29 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (strcmp(cmd, "markbad") == 0) { - addr = (ulong)simple_strtoul(argv[2], NULL, 16); + argc -= 2; + argv += 2; - int ret = nand->block_markbad(nand, addr); - if (ret == 0) { - printf("block 0x%08lx successfully marked as bad\n", - (ulong) addr); - return 0; - } else { - printf("block 0x%08lx NOT marked as bad! ERROR %d\n", - (ulong) addr, ret); + if (argc <= 0) + goto usage; + + while (argc > 0) { + addr = simple_strtoul(*argv, NULL, 16); + + if (nand->block_markbad(nand, addr)) { + printf("block 0x%08lx NOT marked " + "as bad! ERROR %d\n", + addr, ret); + ret = 1; + } else { + printf("block 0x%08lx successfully " + "marked as bad\n", + addr); + } + --argc; + ++argv; } - return 1; + return ret; } if (strcmp(cmd, "biterr") == 0) { diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 85bd2cb..9090940 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -340,7 +340,7 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) int blocksize; ulong addr, ofs; size_t len, retlen = 0; - int ret; + int ret = 0; char *cmd, *s; mtd = &onenand_mtd; @@ -434,18 +434,29 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (strcmp(cmd, "markbad") == 0) { - addr = (ulong)simple_strtoul(argv[2], NULL, 16); + argc -= 2; + argv += 2; - int ret = mtd->block_markbad(mtd, addr); - if (ret == 0) { - printf("block 0x%08lx successfully marked as bad\n", - (ulong) addr); - return 0; - } else { - printf("block 0x%08lx NOT marked as bad! ERROR %d\n", - (ulong) addr, ret); + if (argc <= 0) + goto usage; + + while (argc > 0) { + addr = simple_strtoul(*argv, NULL, 16); + + if (mtd->block_markbad(mtd, addr)) { + printf("block 0x%08lx NOT marked " + "as bad! ERROR %d\n", + addr, ret); + ret = 1; + } else { + printf("block 0x%08lx successfully " + "marked as bad\n", + addr); + } + --argc; + ++argv; } - return 1; + return ret; } if (strncmp(cmd, "dump", 4) == 0) { @@ -474,7 +485,7 @@ usage: } U_BOOT_CMD( - onenand, 6, 1, do_onenand, + onenand, CONFIG_SYS_MAXARGS, 1, do_onenand, "OneNAND sub-system", "info - show available OneNAND devices\n" "onenand bad - show bad blocks\n" diff --git a/common/cmd_ubi.c b/common/cmd_ubi.c index bbca389..05893f5 100644 --- a/common/cmd_ubi.c +++ b/common/cmd_ubi.c @@ -395,11 +395,13 @@ static int ubi_volume_read(char *volume, char *buf, size_t size) return err ? err : count_save - size; } -static int ubi_dev_scan(struct mtd_info *info, char *ubidev) +static int ubi_dev_scan(struct mtd_info *info, char *ubidev, + const char *vid_header_offset) { struct mtd_device *dev; struct part_info *part; struct mtd_partition mtd_part; + char ubi_mtd_param_buffer[80]; u8 pnum; int err; @@ -413,7 +415,11 @@ static int ubi_dev_scan(struct mtd_info *info, char *ubidev) mtd_part.offset = part->offset; add_mtd_partitions(info, &mtd_part, 1); - err = ubi_mtd_param_parse(buffer, NULL); + strcpy(ubi_mtd_param_buffer, buffer); + if (vid_header_offset) + sprintf(ubi_mtd_param_buffer, "mtd=%d,%s", pnum, + vid_header_offset); + err = ubi_mtd_param_parse(ubi_mtd_param_buffer, NULL); if (err) { del_mtd_partitions(info); return err; @@ -450,6 +456,7 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) char mtd_dev[16]; struct mtd_device *dev; struct part_info *part; + const char *vid_header_offset = NULL; u8 pnum; /* Print current partition */ @@ -497,8 +504,11 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) ubi_dev.selected = 1; + if (argc > 3) + vid_header_offset = argv[3]; strcpy(ubi_dev.part_name, argv[2]); - err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name); + err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name, + vid_header_offset); if (err) { printf("UBI init error %d\n", err); ubi_dev.selected = 0; @@ -594,8 +604,9 @@ static int do_ubi(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD(ubi, 6, 1, do_ubi, "ubi commands", - "part [part]" - " - Show or set current partition\n" + "part [part] [offset]\n" + " - Show or set current partition (with optional VID" + " header offset)\n" "ubi info [l[ayout]]" " - Display volume and ubi layout information\n" "ubi create[vol] volume [size] [type]" diff --git a/common/cmd_ubifs.c b/common/cmd_ubifs.c index d9f60d5..ed0e9db 100644 --- a/common/cmd_ubifs.c +++ b/common/cmd_ubifs.c @@ -47,6 +47,10 @@ int do_ubifs_mount(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *vol_name; int ret; + if (argc != 2) { + cmd_usage(cmdtp); + return 1; + } vol_name = argv[1]; debug("Using volume %s\n", vol_name); @@ -88,6 +92,7 @@ int do_ubifs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) int do_ubifs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *filename; + char *endp; int ret; u32 addr; u32 size = 0; @@ -98,15 +103,25 @@ int do_ubifs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } if (argc < 3) { - printf("Usage:\n%s\n", cmdtp->usage); + cmd_usage(cmdtp); return -1; } - addr = simple_strtoul(argv[1], NULL, 16); + addr = simple_strtoul(argv[1], &endp, 16); + if (endp == argv[1]) { + cmd_usage(cmdtp); + return 1; + } + filename = argv[2]; - if (argc == 4) - size = simple_strtoul(argv[3], NULL, 16); + if (argc == 4) { + size = simple_strtoul(argv[3], &endp, 16); + if (endp == argv[3]) { + cmd_usage(cmdtp); + return 1; + } + } debug("Loading file '%s' to address 0x%08x (size %d)\n", filename, addr, size); ret = ubifs_load(filename, addr, size); @@ -119,7 +134,8 @@ int do_ubifs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) U_BOOT_CMD( ubifsmount, 2, 0, do_ubifs_mount, "mount UBIFS volume", - "" + "<volume-name>\n" + " - mount 'volume-name' volume" ); U_BOOT_CMD(ubifsls, 2, 0, do_ubifs_ls, diff --git a/common/env_nand.c b/common/env_nand.c index 76569da..90a1c45 100644 --- a/common/env_nand.c +++ b/common/env_nand.c @@ -68,9 +68,11 @@ extern int default_environment_size; char * env_name_spec = "NAND"; -#ifdef ENV_IS_EMBEDDED +#if defined(ENV_IS_EMBEDDED) extern uchar environment[]; env_t *env_ptr = (env_t *)(&environment[0]); +#elif defined(CONFIG_NAND_ENV_DST) +env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST; #else /* ! ENV_IS_EMBEDDED */ env_t *env_ptr = 0; #endif /* ENV_IS_EMBEDDED */ @@ -102,26 +104,33 @@ uchar env_get_char_spec (int index) */ int env_init(void) { -#if defined(ENV_IS_EMBEDDED) - size_t total; +#if defined(ENV_IS_EMBEDDED) || defined(CONFIG_NAND_ENV_DST) int crc1_ok = 0, crc2_ok = 0; - env_t *tmp_env1, *tmp_env2; + env_t *tmp_env1; - total = CONFIG_ENV_SIZE; +#ifdef CONFIG_ENV_OFFSET_REDUND + env_t *tmp_env2; - tmp_env1 = env_ptr; tmp_env2 = (env_t *)((ulong)env_ptr + CONFIG_ENV_SIZE); + crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); +#endif + + tmp_env1 = env_ptr; crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); - crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); - if (!crc1_ok && !crc2_ok) + if (!crc1_ok && !crc2_ok) { + gd->env_addr = 0; gd->env_valid = 0; - else if(crc1_ok && !crc2_ok) + + return 0; + } else if (crc1_ok && !crc2_ok) { gd->env_valid = 1; - else if(!crc1_ok && crc2_ok) + } +#ifdef CONFIG_ENV_OFFSET_REDUND + else if (!crc1_ok && crc2_ok) { gd->env_valid = 2; - else { + } else { /* both ok - check serial */ if(tmp_env1->flags == 255 && tmp_env2->flags == 0) gd->env_valid = 2; @@ -135,14 +144,19 @@ int env_init(void) gd->env_valid = 1; } + if (gd->env_valid == 2) + env_ptr = tmp_env2; + else +#endif if (gd->env_valid == 1) env_ptr = tmp_env1; - else if (gd->env_valid == 2) - env_ptr = tmp_env2; -#else /* ENV_IS_EMBEDDED */ + + gd->env_addr = (ulong)env_ptr->data; + +#else /* ENV_IS_EMBEDDED || CONFIG_NAND_ENV_DST */ gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 1; -#endif /* ENV_IS_EMBEDDED */ +#endif /* ENV_IS_EMBEDDED || CONFIG_NAND_ENV_DST */ return (0); } @@ -183,12 +197,10 @@ int writeenv(size_t offset, u_char *buf) #ifdef CONFIG_ENV_OFFSET_REDUND int saveenv(void) { - size_t total; int ret = 0; nand_erase_options_t nand_erase_options; env_ptr->flags++; - total = CONFIG_ENV_SIZE; nand_erase_options.length = CONFIG_ENV_RANGE; nand_erase_options.quiet = 0; @@ -226,7 +238,6 @@ int saveenv(void) #else /* ! CONFIG_ENV_OFFSET_REDUND */ int saveenv(void) { - size_t total; int ret = 0; nand_erase_options_t nand_erase_options; @@ -243,7 +254,6 @@ int saveenv(void) return 1; puts ("Writing to Nand... "); - total = CONFIG_ENV_SIZE; if (writeenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr)) { puts("FAILED!\n"); return 1; @@ -287,12 +297,9 @@ int readenv (size_t offset, u_char * buf) void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) - size_t total; int crc1_ok = 0, crc2_ok = 0; env_t *tmp_env1, *tmp_env2; - total = CONFIG_ENV_SIZE; - tmp_env1 = (env_t *) malloc(CONFIG_ENV_SIZE); tmp_env2 = (env_t *) malloc(CONFIG_ENV_SIZE); diff --git a/common/env_onenand.c b/common/env_onenand.c index ed77051..48089a9 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -58,7 +58,7 @@ uchar env_get_char_spec(int index) void env_relocate_spec(void) { - unsigned long env_addr; + loff_t env_addr; int use_default = 0; size_t retlen; diff --git a/cpu/mpc83xx/cpu_init.c b/cpu/mpc83xx/cpu_init.c index 414565c..03b6c86 100644 --- a/cpu/mpc83xx/cpu_init.c +++ b/cpu/mpc83xx/cpu_init.c @@ -303,11 +303,11 @@ void cpu_init_f (volatile immap_t * im) struct usb_ehci *ehci = (struct usb_ehci *)CONFIG_SYS_MPC8xxx_USB_ADDR; /* Configure interface. */ - setbits_be32((void *)ehci->control, REFSEL_16MHZ | UTMI_PHY_EN); + setbits_be32(&ehci->control, REFSEL_16MHZ | UTMI_PHY_EN); /* Wait for clock to stabilize */ do { - temp = in_be32((void *)ehci->control); + temp = in_be32(&ehci->control); udelay(1000); } while (!(temp & PHY_CLK_VALID)); #endif diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index 33788cc..2ab2336 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -60,6 +60,14 @@ "SDRAM_" #mnemonic, SDRAM_##mnemonic, data); \ } while (0) +#define PPC4xx_IBM_DDR2_DUMP_MQ_REGISTER(mnemonic) \ + do { \ + u32 data; \ + data = mfdcr(SDRAM_##mnemonic); \ + printf("%20s[%02x] = 0x%08X\n", \ + "SDRAM_" #mnemonic, SDRAM_##mnemonic, data); \ + } while (0) + #if defined(CONFIG_440) /* * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 @@ -714,11 +722,11 @@ static void check_mem_type(unsigned long *dimm_populated, spd_ddr_init_hang (); break; case 7: - debug("DIMM slot %d: DDR1 SDRAM detected\n", dimm_num); + debug("DIMM slot %lu: DDR1 SDRAM detected\n", dimm_num); dimm_populated[dimm_num] = SDRAM_DDR1; break; case 8: - debug("DIMM slot %d: DDR2 SDRAM detected\n", dimm_num); + debug("DIMM slot %lu: DDR2 SDRAM detected\n", dimm_num); dimm_populated[dimm_num] = SDRAM_DDR2; break; default: @@ -796,7 +804,7 @@ static void check_frequency(unsigned long *dimm_populated, else cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + ((tcyc_reg & 0x0F)*10); - debug("cycle_time=%d [10 picoseconds]\n", cycle_time); + debug("cycle_time=%lu [10 picoseconds]\n", cycle_time); if (cycle_time > (calc_cycle_time + 10)) { /* @@ -1407,7 +1415,7 @@ static void program_mode(unsigned long *dimm_populated, mfsdr(SDR0_DDR0, sdr_ddrpll); sdram_freq = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(sdr_ddrpll), 1); - debug("sdram_freq=%d\n", sdram_freq); + debug("sdram_freq=%lu\n", sdram_freq); /*------------------------------------------------------------------ * Handle the timing. We need to find the worst case timing of all @@ -1437,7 +1445,7 @@ static void program_mode(unsigned long *dimm_populated, /* t_wr_ns = max(t_wr_ns, (unsigned long)dimm_spd[dimm_num][36] >> 2); */ /* not used in this loop. */ cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18); - debug("cas_bit[SPD byte 18]=%02x\n", cas_bit); + debug("cas_bit[SPD byte 18]=%02lx\n", cas_bit); /* For a particular DIMM, grab the three CAS values it supports */ for (cas_index = 0; cas_index < 3; cas_index++) { @@ -1469,7 +1477,7 @@ static void program_mode(unsigned long *dimm_populated, (((tcyc_reg & 0xF0) >> 4) * 100) + ((tcyc_reg & 0x0F)*10); } - debug("cas_index=%d: cycle_time_ns_x_100=%d\n", cas_index, + debug("cas_index=%lu: cycle_time_ns_x_100=%lu\n", cas_index, cycle_time_ns_x_100[cas_index]); } @@ -1580,9 +1588,9 @@ static void program_mode(unsigned long *dimm_populated, cycle_3_0_clk = MULDIV64(ONE_BILLION, 100, max_3_0_tcyc_ns_x_100) + 10; cycle_4_0_clk = MULDIV64(ONE_BILLION, 100, max_4_0_tcyc_ns_x_100) + 10; cycle_5_0_clk = MULDIV64(ONE_BILLION, 100, max_5_0_tcyc_ns_x_100) + 10; - debug("cycle_3_0_clk=%d\n", cycle_3_0_clk); - debug("cycle_4_0_clk=%d\n", cycle_4_0_clk); - debug("cycle_5_0_clk=%d\n", cycle_5_0_clk); + debug("cycle_3_0_clk=%lu\n", cycle_3_0_clk); + debug("cycle_4_0_clk=%lu\n", cycle_4_0_clk); + debug("cycle_5_0_clk=%lu\n", cycle_5_0_clk); if (sdram_ddr1 == TRUE) { /* DDR1 */ if ((cas_2_0_available == TRUE) && (sdram_freq <= cycle_2_0_clk)) { @@ -2797,13 +2805,13 @@ calibration_loop: } mfsdram(SDRAM_DLCR, val); - debug("%s[%d] DLCR: 0x%08X\n", __FUNCTION__, __LINE__, val); + debug("%s[%d] DLCR: 0x%08lX\n", __FUNCTION__, __LINE__, val); mfsdram(SDRAM_RQDC, val); - debug("%s[%d] RQDC: 0x%08X\n", __FUNCTION__, __LINE__, val); + debug("%s[%d] RQDC: 0x%08lX\n", __FUNCTION__, __LINE__, val); mfsdram(SDRAM_RFDC, val); - debug("%s[%d] RFDC: 0x%08X\n", __FUNCTION__, __LINE__, val); + debug("%s[%d] RFDC: 0x%08lX\n", __FUNCTION__, __LINE__, val); mfsdram(SDRAM_RDCC, val); - debug("%s[%d] RDCC: 0x%08X\n", __FUNCTION__, __LINE__, val); + debug("%s[%d] RDCC: 0x%08lX\n", __FUNCTION__, __LINE__, val); } #else /* calibration test with hardvalues */ /*-----------------------------------------------------------------------------+ @@ -3196,10 +3204,10 @@ inline void ppc4xx_ibm_ddr2_register_dump(void) #if (defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ defined(CONFIG_460EX) || defined(CONFIG_460GT)) - PPC4xx_IBM_DDR2_DUMP_REGISTER(R0BAS); - PPC4xx_IBM_DDR2_DUMP_REGISTER(R1BAS); - PPC4xx_IBM_DDR2_DUMP_REGISTER(R2BAS); - PPC4xx_IBM_DDR2_DUMP_REGISTER(R3BAS); + PPC4xx_IBM_DDR2_DUMP_MQ_REGISTER(R0BAS); + PPC4xx_IBM_DDR2_DUMP_MQ_REGISTER(R1BAS); + PPC4xx_IBM_DDR2_DUMP_MQ_REGISTER(R2BAS); + PPC4xx_IBM_DDR2_DUMP_MQ_REGISTER(R3BAS); #endif /* (defined(CONFIG_440SP) || ... */ #if defined(CONFIG_405EX) PPC4xx_IBM_DDR2_DUMP_REGISTER(BESR); diff --git a/cpu/ppc4xx/4xx_pci.c b/cpu/ppc4xx/4xx_pci.c index 99b8e2f..4b5d636 100644 --- a/cpu/ppc4xx/4xx_pci.c +++ b/cpu/ppc4xx/4xx_pci.c @@ -87,6 +87,20 @@ DECLARE_GLOBAL_DATA_PTR; */ int __pci_pre_init(struct pci_controller *hose) { +#if defined (CONFIG_405EP) + /* + * Enable the internal PCI arbiter by default. + * + * On 405EP CPUs the internal arbiter can be controlled + * by the I2C strapping EEPROM. If you want to do so + * or if you want to disable the arbiter pci_pre_init() + * must be reimplemented without enabling the arbiter. + * The arbiter is enabled in this place because of + * compatibility reasons. + */ + mtdcr(cpc0_pci, mfdcr(cpc0_pci) | CPC0_PCI_ARBIT_EN); +#endif /* CONFIG_405EP */ + return 1; } int pci_pre_init(struct pci_controller *hose) __attribute__((weak, alias("__pci_pre_init"))); @@ -99,6 +113,19 @@ ushort pmc405_pci_subsys_deviceid(void); /*#define DEBUG*/ +int __is_pci_host(struct pci_controller *hose) +{ +#if defined(CONFIG_405GP) + if (mfdcr(strap) & PSR_PCI_ARBIT_EN) + return 1; +#elif defined (CONFIG_405EP) + if (mfdcr(cpc0_pci) & CPC0_PCI_ARBIT_EN) + return 1; +#endif + return 0; +} +int is_pci_host(struct pci_controller *hose) __attribute__((weak, alias("__is_pci_host"))); + /*-----------------------------------------------------------------------------+ * pci_init. Initializes the 405GP PCI Configuration regs. *-----------------------------------------------------------------------------*/ @@ -270,7 +297,7 @@ void pci_405gp_init(struct pci_controller *hose) */ pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_VENDOR_ID, CONFIG_SYS_PCI_SUBSYS_VENDORID); #ifdef CONFIG_CPCI405 - if (mfdcr(strap) & PSR_PCI_ARBIT_EN) + if (is_pci_host(hose)) pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_DEVICEID); else pci_write_config_word(PCIDEVID_405GP, PCI_SUBSYSTEM_ID, CONFIG_SYS_PCI_SUBSYS_DEVICEID2); @@ -295,7 +322,7 @@ void pci_405gp_init(struct pci_controller *hose) #if (CONFIG_PCI_HOST != PCI_HOST_ADAPTER) #if (CONFIG_PCI_HOST == PCI_HOST_AUTO) - if ((mfdcr(strap) & PSR_PCI_ARBIT_EN) || + if (is_pci_host(hose) || (((s = getenv("pciscan")) != NULL) && (strcmp(s, "yes") == 0))) #endif { @@ -310,8 +337,15 @@ void pci_405gp_init(struct pci_controller *hose) } #endif -#if defined(CONFIG_405EP) /* on ppc405ep vendor id is not set */ - pci_write_config_word(PCIDEVID_405GP, PCI_VENDOR_ID, 0x1014); /* IBM */ +#if defined(CONFIG_405EP) + /* + * on ppc405ep vendor/device id is not set + * The user manual says 0x1014 (IBM) / 0x0156 (405GP!) + * are the correct values. + */ + pci_write_config_word(PCIDEVID_405GP, PCI_VENDOR_ID, PCI_VENDOR_ID_IBM); + pci_write_config_word(PCIDEVID_405GP, + PCI_DEVICE_ID, PCI_DEVICE_ID_IBM_405GP); #endif /* @@ -325,7 +359,7 @@ void pci_405gp_init(struct pci_controller *hose) * Scan the PCI bus and configure devices found. *--------------------------------------------------------------------------*/ #if (CONFIG_PCI_HOST == PCI_HOST_AUTO) - if ((mfdcr(strap) & PSR_PCI_ARBIT_EN) || + if (is_pci_host(hose) || (((s = getenv("pciscan")) != NULL) && (strcmp(s, "yes") == 0))) #endif { diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 06f44ad..fb3837c 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -54,6 +54,7 @@ int __get_cpu_num(void) } int get_cpu_num(void) __attribute__((weak, alias("__get_cpu_num"))); +#if defined(CONFIG_PCI) #if defined(CONFIG_405GP) || \ defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) @@ -76,6 +77,7 @@ static int pci_async_enabled(void) #endif } #endif +#endif /* CONFIG_PCI */ #if defined(CONFIG_PCI) && !defined(CONFIG_IOP480) && \ !defined(CONFIG_405) && !defined(CONFIG_405EX) diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c index 577d33f..bbd795d 100644 --- a/cpu/ppc4xx/cpu_init.c +++ b/cpu/ppc4xx/cpu_init.c @@ -174,11 +174,6 @@ cpu_init_f (void) * Set EMAC noise filter bits */ mtdcr(cpc0_epctl, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE); - - /* - * Enable the internal PCI arbiter - */ - mtdcr(cpc0_pci, mfdcr(cpc0_pci) | CPC0_PCI_HOST_CFG_EN | CPC0_PCI_ARBIT_EN); #endif /* CONFIG_405EP */ #if defined(CONFIG_SYS_4xx_GPIO_TABLE) diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index ac96fc2..582c781 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -2021,6 +2021,7 @@ pci_wait: ! Output r3 = none !----------------------------------------------------------------------------- */ + .globl pll_write pll_write: mfdcr r5, CPC0_UCR andis. r5,r5,0xFFFF diff --git a/cpu/ppc4xx/uic.c b/cpu/ppc4xx/uic.c index a95d1cb..d298b31 100644 --- a/cpu/ppc4xx/uic.c +++ b/cpu/ppc4xx/uic.c @@ -164,7 +164,7 @@ void pic_irq_enable(unsigned int vec) else if (vec >= 96) mtdcr(uic3er, mfdcr(uic3er) | UIC_MASK(vec)); - debug("Install interrupt for vector %d ==> %p\n", vec, handler); + debug("Install interrupt vector %d\n", vec); } void pic_irq_disable(unsigned int vec) diff --git a/doc/README.nand b/doc/README.nand index bb72289..b077d9a 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -101,15 +101,6 @@ Configuration Options: CONFIG_SYS_NAND_MAX_CHIPS The maximum number of NAND chips per device to be supported. - CONFIG_SYS_DAVINCI_BROKEN_ECC - Versions of U-Boot <= 1.3.3 and Montavista Linux kernels - generated bogus ECCs on large-page NAND. Both large and small page - NAND ECCs were incompatible with the Linux davinci git tree (since - NAND was integrated in 2.6.24). - Turn this ON if you want backwards compatibility. - Turn this OFF if you want U-Boot and the Linux davinci git kernel - to use the same ECC format. - NOTE: ===== diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 71dd5b9..c1325b9 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -42,9 +42,10 @@ COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o -COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.c +COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o +COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o endif COBJS := $(COBJS-y) diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 8ef18b8..ca40c6a 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -47,7 +47,7 @@ #include <asm/arch/nand_defs.h> #include <asm/arch/emif_defs.h> -extern struct nand_chip nand_dev_desc[CONFIG_SYS_MAX_NAND_DEVICE]; +static emif_registers *const emif_regs = (void *) DAVINCI_ASYNC_EMIF_CNTRL_BASE; static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { @@ -68,81 +68,30 @@ static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c writeb(cmd, this->IO_ADDR_W); } -/* Set WP on deselect, write enable on select */ -static void nand_davinci_select_chip(struct mtd_info *mtd, int chip) -{ -#define GPIO_SET_DATA01 0x01c67018 -#define GPIO_CLR_DATA01 0x01c6701c -#define GPIO_NAND_WP (1 << 4) -#ifdef SONATA_BOARD_GPIOWP - if (chip < 0) { - REG(GPIO_CLR_DATA01) |= GPIO_NAND_WP; - } else { - REG(GPIO_SET_DATA01) |= GPIO_NAND_WP; - } -#endif -} - #ifdef CONFIG_SYS_NAND_HW_ECC -#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC -/* Linux-compatible ECC uses MTD defaults. */ -/* These layouts are not compatible with Linux or RBL/UBL. */ -#ifdef CONFIG_SYS_NAND_LARGEPAGE -static struct nand_ecclayout davinci_nand_ecclayout = { - .eccbytes = 12, - .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, - .oobfree = { - {.offset = 2, .length = 6}, - {.offset = 12, .length = 12}, - {.offset = 28, .length = 12}, - {.offset = 44, .length = 12}, - {.offset = 60, .length = 4} - } -}; -#elif defined(CONFIG_SYS_NAND_SMALLPAGE) -static struct nand_ecclayout davinci_nand_ecclayout = { - .eccbytes = 3, - .eccpos = {0, 1, 2}, - .oobfree = { - {.offset = 6, .length = 2}, - {.offset = 8, .length = 8} - } -}; -#else -#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!" -#endif -#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */ static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode) { - emifregs emif_addr; int dummy; - emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE; + dummy = emif_regs->NANDF1ECC; - dummy = emif_addr->NANDF1ECC; - dummy = emif_addr->NANDF2ECC; - dummy = emif_addr->NANDF3ECC; - dummy = emif_addr->NANDF4ECC; - - emif_addr->NANDFCR |= (1 << 8); + /* FIXME: only chipselect 0 is supported for now */ + emif_regs->NANDFCR |= 1 << 8; } static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region) { u_int32_t ecc = 0; - emifregs emif_base_addr; - - emif_base_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE; if (region == 1) - ecc = emif_base_addr->NANDF1ECC; + ecc = emif_regs->NANDF1ECC; else if (region == 2) - ecc = emif_base_addr->NANDF2ECC; + ecc = emif_regs->NANDF2ECC; else if (region == 3) - ecc = emif_base_addr->NANDF3ECC; + ecc = emif_regs->NANDF3ECC; else if (region == 4) - ecc = emif_base_addr->NANDF4ECC; + ecc = emif_regs->NANDF4ECC; return(ecc); } @@ -150,29 +99,6 @@ static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region) static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { u_int32_t tmp; -#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC - /* - * This is not how you should read ECCs on large page Davinci devices. - * The region parameter gets you ECCs for flash chips on different chip - * selects, not the 4x512 byte pages in a 2048 byte page. - * - * Preserved for backwards compatibility though. - */ - - int region, n; - struct nand_chip *this = mtd->priv; - - n = (this->ecc.size/512); - - region = 1; - while (n--) { - tmp = nand_davinci_readecc(mtd, region); - *ecc_code++ = tmp; - *ecc_code++ = tmp >> 16; - *ecc_code++ = ((tmp >> 8) & 0x0f) | ((tmp >> 20) & 0xf0); - region++; - } -#else const int region = 1; tmp = nand_davinci_readecc(mtd, region); @@ -187,148 +113,26 @@ static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u *ecc_code++ = tmp; *ecc_code++ = tmp >> 8; *ecc_code++ = tmp >> 16; -#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */ - return(0); -} - -#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC -static void nand_davinci_gen_true_ecc(u_int8_t *ecc_buf) -{ - u_int32_t tmp = ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xf0) << 20) | ((ecc_buf[2] & 0x0f) << 8); - - ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) | P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp)); - ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) | P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp)); - ecc_buf[2] = ~( P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) | P1e(tmp) | P2048o(tmp) | P2048e(tmp)); -} - -static int nand_davinci_compare_ecc(u_int8_t *ecc_nand, u_int8_t *ecc_calc, u_int8_t *page_data) -{ - u_int32_t i; - u_int8_t tmp0_bit[8], tmp1_bit[8], tmp2_bit[8]; - u_int8_t comp0_bit[8], comp1_bit[8], comp2_bit[8]; - u_int8_t ecc_bit[24]; - u_int8_t ecc_sum = 0; - u_int8_t find_bit = 0; - u_int32_t find_byte = 0; - int is_ecc_ff; - - is_ecc_ff = ((*ecc_nand == 0xff) && (*(ecc_nand + 1) == 0xff) && (*(ecc_nand + 2) == 0xff)); - - nand_davinci_gen_true_ecc(ecc_nand); - nand_davinci_gen_true_ecc(ecc_calc); - - for (i = 0; i <= 2; i++) { - *(ecc_nand + i) = ~(*(ecc_nand + i)); - *(ecc_calc + i) = ~(*(ecc_calc + i)); - } - for (i = 0; i < 8; i++) { - tmp0_bit[i] = *ecc_nand % 2; - *ecc_nand = *ecc_nand / 2; - } - - for (i = 0; i < 8; i++) { - tmp1_bit[i] = *(ecc_nand + 1) % 2; - *(ecc_nand + 1) = *(ecc_nand + 1) / 2; - } - - for (i = 0; i < 8; i++) { - tmp2_bit[i] = *(ecc_nand + 2) % 2; - *(ecc_nand + 2) = *(ecc_nand + 2) / 2; - } - - for (i = 0; i < 8; i++) { - comp0_bit[i] = *ecc_calc % 2; - *ecc_calc = *ecc_calc / 2; - } - - for (i = 0; i < 8; i++) { - comp1_bit[i] = *(ecc_calc + 1) % 2; - *(ecc_calc + 1) = *(ecc_calc + 1) / 2; - } - - for (i = 0; i < 8; i++) { - comp2_bit[i] = *(ecc_calc + 2) % 2; - *(ecc_calc + 2) = *(ecc_calc + 2) / 2; - } - - for (i = 0; i< 6; i++) - ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2]; - - for (i = 0; i < 8; i++) - ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i]; - - for (i = 0; i < 8; i++) - ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i]; - - ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0]; - ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1]; - - for (i = 0; i < 24; i++) - ecc_sum += ecc_bit[i]; + /* NOTE: the above code matches mainline Linux: + * .PQR.stu ==> ~PQRstu + * + * MontaVista/TI kernels encode those bytes differently, use + * complicated (and allegedly sometimes-wrong) correction code, + * and usually shipped with U-Boot that uses software ECC: + * .PQR.stu ==> PsQRtu + * + * If you need MV/TI compatible NAND I/O in U-Boot, it should + * be possible to (a) change the mangling above, (b) reverse + * that mangling in nand_davinci_correct_data() below. + */ - switch (ecc_sum) { - case 0: - /* Not reached because this function is not called if - ECC values are equal */ - return 0; - case 1: - /* Uncorrectable error */ - MTDDEBUG (MTD_DEBUG_LEVEL0, - "ECC UNCORRECTED_ERROR 1\n"); - return(-1); - case 12: - /* Correctable error */ - find_byte = (ecc_bit[23] << 8) + - (ecc_bit[21] << 7) + - (ecc_bit[19] << 6) + - (ecc_bit[17] << 5) + - (ecc_bit[15] << 4) + - (ecc_bit[13] << 3) + - (ecc_bit[11] << 2) + - (ecc_bit[9] << 1) + - ecc_bit[7]; - - find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1]; - - MTDDEBUG (MTD_DEBUG_LEVEL0, "Correcting single bit ECC " - "error at offset: %d, bit: %d\n", - find_byte, find_bit); - - page_data[find_byte] ^= (1 << find_bit); - - return(0); - default: - if (is_ecc_ff) { - if (ecc_calc[0] == 0 && ecc_calc[1] == 0 && ecc_calc[2] == 0) - return(0); - } - MTDDEBUG (MTD_DEBUG_LEVEL0, - "UNCORRECTED_ERROR default\n"); - return(-1); - } + return 0; } -#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { struct nand_chip *this = mtd->priv; -#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC - int block_count = 0, i, rc; - - block_count = (this->ecc.size/512); - for (i = 0; i < block_count; i++) { - if (memcmp(read_ecc, calc_ecc, 3) != 0) { - rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat); - if (rc < 0) { - return(rc); - } - } - read_ecc += 3; - calc_ecc += 3; - dat += 512; - } -#else u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) | (read_ecc[2] << 16); u_int32_t ecc_calc = calc_ecc[0] | (calc_ecc[1] << 8) | @@ -362,31 +166,24 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char * return -1; } } -#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */ return(0); } #endif /* CONFIG_SYS_NAND_HW_ECC */ static int nand_davinci_dev_ready(struct mtd_info *mtd) { - emifregs emif_addr; - - emif_addr = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE; - - return(emif_addr->NANDFSR & 0x1); -} - -static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this) -{ - while(!nand_davinci_dev_ready(mtd)) {;} - *NAND_CE0CLE = NAND_STATUS; - return(*NAND_CE0DATA); + return emif_regs->NANDFSR & 0x1; } static void nand_flash_init(void) { + /* This is for DM6446 EVM and *very* similar. DO NOT GROW THIS! + * Instead, have your board_init() set EMIF timings, based on its + * knowledge of the clocks and what devices are hooked up ... and + * don't even do that unless no UBL handled it. + */ +#ifdef CONFIG_SOC_DM6446 u_int32_t acfg1 = 0x3ffffffc; - emifregs emif_regs; /*------------------------------------------------------------------* * NAND FLASH CHIP TIMEOUT @ 459 MHz * @@ -408,39 +205,22 @@ static void nand_flash_init(void) | (0 << 0 ) /* asyncSize 8-bit bus */ ; - emif_regs = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE; - emif_regs->AB1CR = acfg1; /* CS2 */ emif_regs->NANDFCR = 0x00000101; /* NAND flash on CS2 */ +#endif } -int board_nand_init(struct nand_chip *nand) +void davinci_nand_init(struct nand_chip *nand) { - nand->IO_ADDR_R = (void __iomem *)NAND_CE0DATA; - nand->IO_ADDR_W = (void __iomem *)NAND_CE0DATA; nand->chip_delay = 0; - nand->select_chip = nand_davinci_select_chip; #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT nand->options = NAND_USE_FLASH_BBT; #endif #ifdef CONFIG_SYS_NAND_HW_ECC nand->ecc.mode = NAND_ECC_HW; -#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC - nand->ecc.layout = &davinci_nand_ecclayout; -#ifdef CONFIG_SYS_NAND_LARGEPAGE - nand->ecc.size = 2048; - nand->ecc.bytes = 12; -#elif defined(CONFIG_SYS_NAND_SMALLPAGE) nand->ecc.size = 512; nand->ecc.bytes = 3; -#else -#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!" -#endif -#else - nand->ecc.size = 512; - nand->ecc.bytes = 3; -#endif /* CONFIG_SYS_DAVINCI_BROKEN_ECC */ nand->ecc.calculate = nand_davinci_calculate_ecc; nand->ecc.correct = nand_davinci_correct_data; nand->ecc.hwctl = nand_davinci_enable_hwecc; @@ -452,9 +232,14 @@ int board_nand_init(struct nand_chip *nand) nand->cmd_ctrl = nand_davinci_hwcontrol; nand->dev_ready = nand_davinci_dev_ready; - nand->waitfunc = nand_davinci_waitfunc; nand_flash_init(); +} - return(0); +int board_nand_init(struct nand_chip *chip) __attribute__((weak)); + +int board_nand_init(struct nand_chip *chip) +{ + davinci_nand_init(chip); + return 0; } diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 3f318e0..77a33c0 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -766,6 +766,9 @@ int board_nand_init(struct nand_chip *nand) nand->waitfunc = fsl_elbc_wait; /* set up nand options */ + /* redirect the pointer of bbt pattern to RAM */ + bbt_main_descr.pattern = bbt_pattern; + bbt_mirror_descr.pattern = mirror_pattern; nand->bbt_td = &bbt_main_descr; nand->bbt_md = &bbt_mirror_descr; @@ -812,6 +815,7 @@ int board_nand_init(struct nand_chip *nand) /* Large-page-specific setup */ if (or & OR_FCM_PGS) { priv->page_size = 1; + largepage_memorybased.pattern = scan_ff_pattern; nand->badblock_pattern = &largepage_memorybased; /* adjust ecc setup if needed */ diff --git a/drivers/mtd/nand/nand_plat.c b/drivers/mtd/nand/nand_plat.c new file mode 100644 index 0000000..b35492b --- /dev/null +++ b/drivers/mtd/nand/nand_plat.c @@ -0,0 +1,53 @@ +/* + * Genericish driver for memory mapped NAND devices + * + * Copyright (c) 2006-2009 Analog Devices Inc. + * Licensed under the GPL-2 or later. + */ + +/* Your board must implement the following macros: + * NAND_PLAT_WRITE_CMD(chip, cmd) + * NAND_PLAT_WRITE_ADR(chip, cmd) + * NAND_PLAT_INIT() + * + * It may also implement the following: + * NAND_PLAT_DEV_READY(chip) + */ + +#include <common.h> +#include <asm/io.h> + +#include <nand.h> + +static void plat_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + NAND_PLAT_WRITE_CMD(this, cmd); + else + NAND_PLAT_WRITE_ADR(this, cmd); +} + +#ifdef NAND_PLAT_DEV_READY +static int plat_dev_ready(struct mtd_info *mtd) +{ + return NAND_PLAT_DEV_READY((struct nand_chip *)mtd->priv); +} +#else +# define plat_dev_ready NULL +#endif + +int board_nand_init(struct nand_chip *nand) +{ + NAND_PLAT_INIT(); + + nand->cmd_ctrl = plat_cmd_ctrl; + nand->dev_ready = plat_dev_ready; + nand->ecc.mode = NAND_ECC_SOFT; + + return 0; +} diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 88206d0..fc16282 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -315,7 +315,7 @@ int nand_lock(struct mtd_info *mtd, int tight) * NAND_LOCK_STATUS_UNLOCK: page unlocked * */ -int nand_get_lock_status(struct mtd_info *mtd, ulong offset) +int nand_get_lock_status(struct mtd_info *mtd, loff_t offset) { int ret = 0; int chipnr; @@ -436,7 +436,7 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length) * @param length image length * @return image length including bad blocks */ -static size_t get_len_incl_bad (nand_info_t *nand, size_t offset, +static size_t get_len_incl_bad (nand_info_t *nand, loff_t offset, const size_t length) { size_t len_incl_bad = 0; @@ -473,7 +473,7 @@ static size_t get_len_incl_bad (nand_info_t *nand, size_t offset, * @param buf buffer to read from * @return 0 in case of success */ -int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, +int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer) { int rval; @@ -498,7 +498,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, if (len_incl_bad == *length) { rval = nand_write (nand, offset, length, buffer); if (rval != 0) - printf ("NAND write to offset %zx failed %d\n", + printf ("NAND write to offset %llx failed %d\n", offset, rval); return rval; @@ -509,7 +509,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, size_t write_size; if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) { - printf ("Skip bad block 0x%08zx\n", + printf ("Skip bad block 0x%08llx\n", offset & ~(nand->erasesize - 1)); offset += nand->erasesize - block_offset; continue; @@ -522,7 +522,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, rval = nand_write (nand, offset, &write_size, p_buffer); if (rval != 0) { - printf ("NAND write to offset %zx failed %d\n", + printf ("NAND write to offset %llx failed %d\n", offset, rval); *length -= left_to_write; return rval; @@ -550,7 +550,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, * @param buffer buffer to write to * @return 0 in case of success */ -int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, +int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer) { int rval; @@ -568,7 +568,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, if (len_incl_bad == *length) { rval = nand_read (nand, offset, length, buffer); if (rval != 0) - printf ("NAND read from offset %zx failed %d\n", + printf ("NAND read from offset %llx failed %d\n", offset, rval); return rval; @@ -579,7 +579,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, size_t read_length; if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) { - printf ("Skipping bad block 0x%08zx\n", + printf ("Skipping bad block 0x%08llx\n", offset & ~(nand->erasesize - 1)); offset += nand->erasesize - block_offset; continue; @@ -592,7 +592,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, rval = nand_read (nand, offset, &read_length, p_buffer); if (rval != 0) { - printf ("NAND read from offset %zx failed %d\n", + printf ("NAND read from offset %llx failed %d\n", offset, rval); *length -= left_to_read; return rval; diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index ec1d689..940d4a8 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -37,6 +37,7 @@ COBJS-$(CONFIG_USB_SL811HS) += sl811-hcd.o COBJS-$(CONFIG_USB_EHCI) += ehci-hcd.o COBJS-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o COBJS-$(CONFIG_USB_EHCI_IXP4XX) += ehci-ixp.o +COBJS-$(CONFIG_USB_EHCI_KIRKWOOD) += ehci-kirkwood.o COBJS-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o COBJS-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index bf148c4..c674929 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -41,15 +41,15 @@ int ehci_hcd_init(void) struct usb_ehci *ehci; ehci = (struct usb_ehci *)CONFIG_SYS_MPC8xxx_USB_ADDR; - hccr = (struct ehci_hccr *)((uint32_t)ehci->caplength); + hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); hcor = (struct ehci_hcor *)((uint32_t) hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); /* Set to Host mode */ - setbits_le32((void *)ehci->usbmode, CM_HOST); + setbits_le32(&ehci->usbmode, CM_HOST); - out_be32((void *)ehci->snoop1, SNOOP_SIZE_2GB); - out_be32((void *)ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB); + out_be32(&ehci->snoop1, SNOOP_SIZE_2GB); + out_be32(&ehci->snoop2, 0x80000000 | SNOOP_SIZE_2GB); /* Init phy */ if (!strcmp(getenv("usb_phy_type"), "utmi")) @@ -58,13 +58,13 @@ int ehci_hcd_init(void) out_le32(&(hcor->or_portsc[0]), PORT_PTS_ULPI); /* Enable interface. */ - setbits_be32((void *)ehci->control, USB_EN); + setbits_be32(&ehci->control, USB_EN); - out_be32((void *)ehci->prictrl, 0x0000000c); - out_be32((void *)ehci->age_cnt_limit, 0x00000040); - out_be32((void *)ehci->sictrl, 0x00000001); + out_be32(&ehci->prictrl, 0x0000000c); + out_be32(&ehci->age_cnt_limit, 0x00000040); + out_be32(&ehci->sictrl, 0x00000001); - in_le32((void *)ehci->usbmode); + in_le32(&ehci->usbmode); return 0; } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index bbd547b..423ea5d 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -716,7 +716,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, goto unknown; } /* unblock posted writes */ - ehci_readl(&hcor->or_usbcmd); + (void) ehci_readl(&hcor->or_usbcmd); break; case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8): reg = ehci_readl(status_reg); @@ -745,7 +745,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer, } ehci_writel(status_reg, reg); /* unblock posted write */ - ehci_readl(&hcor->or_usbcmd); + (void) ehci_readl(&hcor->or_usbcmd); break; default: debug("Unknown request\n"); diff --git a/drivers/usb/host/ehci-kirkwood.c b/drivers/usb/host/ehci-kirkwood.c new file mode 100644 index 0000000..64997b8 --- /dev/null +++ b/drivers/usb/host/ehci-kirkwood.c @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2009 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar <prafulla@marvell.com> + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <usb.h> +#include "ehci.h" +#include "ehci-core.h" +#include <asm/arch/kirkwood.h> + +#define rdl(off) readl(KW_USB20_BASE + (off)) +#define wrl(off, val) writel((val), KW_USB20_BASE + (off)) + +#define USB_WINDOW_CTRL(i) (0x320 + ((i) << 4)) +#define USB_WINDOW_BASE(i) (0x324 + ((i) << 4)) +#define USB_TARGET_DRAM 0x0 + +/* + * USB 2.0 Bridge Address Decoding registers setup + */ +static void usb_brg_adrdec_setup(void) +{ + int i; + u32 size, attrib; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + + /* Enable DRAM bank */ + switch (i) { + case 0: + attrib = KWCPU_ATTR_DRAM_CS0; + break; + case 1: + attrib = KWCPU_ATTR_DRAM_CS1; + break; + case 2: + attrib = KWCPU_ATTR_DRAM_CS2; + break; + case 3: + attrib = KWCPU_ATTR_DRAM_CS3; + break; + default: + /* invalide bank, disable access */ + attrib = 0; + break; + } + + size = kw_sdram_bs(i); + if ((size) && (attrib)) + wrl(USB_WINDOW_CTRL(i), + KWCPU_WIN_CTRL_DATA(size, USB_TARGET_DRAM, + attrib, KWCPU_WIN_ENABLE)); + else + wrl(USB_WINDOW_CTRL(i), KWCPU_WIN_DISABLE); + + wrl(USB_WINDOW_BASE(i), kw_sdram_bar(i)); + } +} + +/* + * Create the appropriate control structures to manage + * a new EHCI host controller. + */ +int ehci_hcd_init(void) +{ + usb_brg_adrdec_setup(); + + hccr = (struct ehci_hccr *)(KW_USB20_BASE + 0x100); + hcor = (struct ehci_hcor *)((uint32_t) hccr + + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + + debug("Kirkwood-ehci: init hccr %x and hcor %x hc_length %d\n", + (uint32_t)hccr, (uint32_t)hcor, + (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); + + return 0; +} + +/* + * Destroy the appropriate control structures corresponding + * the the EHCI host controller. + */ +int ehci_hcd_stop(void) +{ + return 0; +} + diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index b81c536..f9da3f0 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -307,10 +307,4 @@ extern void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt); extern void write_fifo(u8 ep, u32 length, void *fifo_data); extern void read_fifo(u8 ep, u32 length, void *fifo_data); -/* extern functions */ -extern inline void musb_writew(u32 offset, u16 value); -extern inline void musb_writeb(u32 offset, u8 value); -extern inline u16 musb_readw(u32 offset); -extern inline u8 musb_readb(u32 offset); - #endif /* __MUSB_HDRC_DEFS_H__ */ diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c index 352a0d4..19d978b 100644 --- a/drivers/usb/musb/musb_hcd.c +++ b/drivers/usb/musb/musb_hcd.c @@ -111,6 +111,7 @@ static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask) { u16 csr; int result = 1; + int timeout = CONFIG_MUSB_TIMEOUT; while (result > 0) { csr = readw(&musbr->txcsr); @@ -152,7 +153,17 @@ static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask) } break; } + + /* Check the timeout */ + if (--timeout) + udelay(1); + else { + dev->status = USB_ST_CRC_ERR; + result = -1; + break; + } } + return result; } @@ -162,6 +173,7 @@ static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask) static u8 wait_until_txep_ready(struct usb_device *dev, u8 ep) { u16 csr; + int timeout = CONFIG_MUSB_TIMEOUT; do { if (check_stall(ep, 1)) { @@ -174,6 +186,15 @@ static u8 wait_until_txep_ready(struct usb_device *dev, u8 ep) dev->status = USB_ST_CRC_ERR; return 0; } + + /* Check the timeout */ + if (--timeout) + udelay(1); + else { + dev->status = USB_ST_CRC_ERR; + return -1; + } + } while (csr & MUSB_TXCSR_TXPKTRDY); return 1; } @@ -184,6 +205,7 @@ static u8 wait_until_txep_ready(struct usb_device *dev, u8 ep) static u8 wait_until_rxep_ready(struct usb_device *dev, u8 ep) { u16 csr; + int timeout = CONFIG_MUSB_TIMEOUT; do { if (check_stall(ep, 0)) { @@ -196,6 +218,15 @@ static u8 wait_until_rxep_ready(struct usb_device *dev, u8 ep) dev->status = USB_ST_CRC_ERR; return 0; } + + /* Check the timeout */ + if (--timeout) + udelay(1); + else { + dev->status = USB_ST_CRC_ERR; + return -1; + } + } while (!(csr & MUSB_RXCSR_RXPKTRDY)); return 1; } diff --git a/drivers/usb/musb/musb_hcd.h b/drivers/usb/musb/musb_hcd.h index bb83311..b7f571d 100644 --- a/drivers/usb/musb/musb_hcd.h +++ b/drivers/usb/musb/musb_hcd.h @@ -30,6 +30,10 @@ extern unsigned char new[]; #endif +#ifndef CONFIG_MUSB_TIMEOUT +# define CONFIG_MUSB_TIMEOUT 100000 +#endif + /* This defines the endpoint number used for control transfers */ #define MUSB_CONTROL_EP 0 diff --git a/include/asm-arm/arch-davinci/nand_defs.h b/include/asm-arm/arch-davinci/nand_defs.h index 187d3c3..386540e 100644 --- a/include/asm-arm/arch-davinci/nand_defs.h +++ b/include/asm-arm/arch-davinci/nand_defs.h @@ -28,134 +28,18 @@ #include <asm/arch/hardware.h> +#ifdef CONFIG_SOC_DM646x +#define MASK_CLE 0x80000 +#define MASK_ALE 0x40000 +#else #define MASK_CLE 0x10 -#define MASK_ALE 0x0a - -#define NAND_CE0CLE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x10)) -#define NAND_CE0ALE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x0a)) -#define NAND_CE0DATA ((volatile u_int8_t *)CONFIG_SYS_NAND_BASE) - -typedef struct { - u_int32_t NRCSR; - u_int32_t AWCCR; - u_int8_t RSVD0[8]; - u_int32_t AB1CR; - u_int32_t AB2CR; - u_int32_t AB3CR; - u_int32_t AB4CR; - u_int8_t RSVD1[32]; - u_int32_t NIRR; - u_int32_t NIMR; - u_int32_t NIMSR; - u_int32_t NIMCR; - u_int8_t RSVD2[16]; - u_int32_t NANDFCR; - u_int32_t NANDFSR; - u_int8_t RSVD3[8]; - u_int32_t NANDF1ECC; - u_int32_t NANDF2ECC; - u_int32_t NANDF3ECC; - u_int32_t NANDF4ECC; - u_int8_t RSVD4[4]; - u_int32_t IODFTECR; - u_int32_t IODFTGCR; - u_int8_t RSVD5[4]; - u_int32_t IODFTMRLR; - u_int32_t IODFTMRMR; - u_int32_t IODFTMRMSBR; - u_int8_t RSVD6[20]; - u_int32_t MODRNR; - u_int8_t RSVD7[76]; - u_int32_t CE0DATA; - u_int32_t CE0ALE; - u_int32_t CE0CLE; - u_int8_t RSVD8[4]; - u_int32_t CE1DATA; - u_int32_t CE1ALE; - u_int32_t CE1CLE; - u_int8_t RSVD9[4]; - u_int32_t CE2DATA; - u_int32_t CE2ALE; - u_int32_t CE2CLE; - u_int8_t RSVD10[4]; - u_int32_t CE3DATA; - u_int32_t CE3ALE; - u_int32_t CE3CLE; -} nand_registers; - -typedef volatile nand_registers *nandregs; +#define MASK_ALE 0x08 +#endif #define NAND_READ_START 0x00 #define NAND_READ_END 0x30 #define NAND_STATUS 0x70 -#ifdef CONFIG_SYS_NAND_HW_ECC -#define NAND_Ecc_P1e (1 << 0) -#define NAND_Ecc_P2e (1 << 1) -#define NAND_Ecc_P4e (1 << 2) -#define NAND_Ecc_P8e (1 << 3) -#define NAND_Ecc_P16e (1 << 4) -#define NAND_Ecc_P32e (1 << 5) -#define NAND_Ecc_P64e (1 << 6) -#define NAND_Ecc_P128e (1 << 7) -#define NAND_Ecc_P256e (1 << 8) -#define NAND_Ecc_P512e (1 << 9) -#define NAND_Ecc_P1024e (1 << 10) -#define NAND_Ecc_P2048e (1 << 11) - -#define NAND_Ecc_P1o (1 << 16) -#define NAND_Ecc_P2o (1 << 17) -#define NAND_Ecc_P4o (1 << 18) -#define NAND_Ecc_P8o (1 << 19) -#define NAND_Ecc_P16o (1 << 20) -#define NAND_Ecc_P32o (1 << 21) -#define NAND_Ecc_P64o (1 << 22) -#define NAND_Ecc_P128o (1 << 23) -#define NAND_Ecc_P256o (1 << 24) -#define NAND_Ecc_P512o (1 << 25) -#define NAND_Ecc_P1024o (1 << 26) -#define NAND_Ecc_P2048o (1 << 27) - -#define TF(v) (v ? 1 : 0) - -#define P2048e(a) (TF(a & NAND_Ecc_P2048e) << 0) -#define P2048o(a) (TF(a & NAND_Ecc_P2048o) << 1) -#define P1e(a) (TF(a & NAND_Ecc_P1e) << 2) -#define P1o(a) (TF(a & NAND_Ecc_P1o) << 3) -#define P2e(a) (TF(a & NAND_Ecc_P2e) << 4) -#define P2o(a) (TF(a & NAND_Ecc_P2o) << 5) -#define P4e(a) (TF(a & NAND_Ecc_P4e) << 6) -#define P4o(a) (TF(a & NAND_Ecc_P4o) << 7) - -#define P8e(a) (TF(a & NAND_Ecc_P8e) << 0) -#define P8o(a) (TF(a & NAND_Ecc_P8o) << 1) -#define P16e(a) (TF(a & NAND_Ecc_P16e) << 2) -#define P16o(a) (TF(a & NAND_Ecc_P16o) << 3) -#define P32e(a) (TF(a & NAND_Ecc_P32e) << 4) -#define P32o(a) (TF(a & NAND_Ecc_P32o) << 5) -#define P64e(a) (TF(a & NAND_Ecc_P64e) << 6) -#define P64o(a) (TF(a & NAND_Ecc_P64o) << 7) - -#define P128e(a) (TF(a & NAND_Ecc_P128e) << 0) -#define P128o(a) (TF(a & NAND_Ecc_P128o) << 1) -#define P256e(a) (TF(a & NAND_Ecc_P256e) << 2) -#define P256o(a) (TF(a & NAND_Ecc_P256o) << 3) -#define P512e(a) (TF(a & NAND_Ecc_P512e) << 4) -#define P512o(a) (TF(a & NAND_Ecc_P512o) << 5) -#define P1024e(a) (TF(a & NAND_Ecc_P1024e) << 6) -#define P1024o(a) (TF(a & NAND_Ecc_P1024o) << 7) - -#define P8e_s(a) (TF(a & NAND_Ecc_P8e) << 0) -#define P8o_s(a) (TF(a & NAND_Ecc_P8o) << 1) -#define P16e_s(a) (TF(a & NAND_Ecc_P16e) << 2) -#define P16o_s(a) (TF(a & NAND_Ecc_P16o) << 3) -#define P1e_s(a) (TF(a & NAND_Ecc_P1e) << 4) -#define P1o_s(a) (TF(a & NAND_Ecc_P1o) << 5) -#define P2e_s(a) (TF(a & NAND_Ecc_P2e) << 6) -#define P2o_s(a) (TF(a & NAND_Ecc_P2o) << 7) - -#define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0) -#define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1) -#endif +extern void davinci_nand_init(struct nand_chip *nand); #endif diff --git a/include/common.h b/include/common.h index 6284b8a..a6c7c07 100644 --- a/include/common.h +++ b/include/common.h @@ -275,7 +275,8 @@ void pci_init_board(void); void pciinfo (int, int); #if defined(CONFIG_PCI) && (defined(CONFIG_4xx) && !defined(CONFIG_AP1000)) - int pci_pre_init (struct pci_controller * ); + int pci_pre_init (struct pci_controller *); + int is_pci_host (struct pci_controller *); #endif #if defined(CONFIG_PCI) && (defined(CONFIG_440) || defined(CONFIG_405EX)) @@ -285,7 +286,6 @@ void pciinfo (int, int); # if defined(CONFIG_SYS_PCI_MASTER_INIT) void pci_master_init (struct pci_controller *); # endif - int is_pci_host (struct pci_controller *); #if defined(CONFIG_440SPE) || \ defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ defined(CONFIG_405EX) @@ -688,7 +688,7 @@ int pcmcia_init (void); /* * Board-specific Platform code can reimplement show_boot_progress () if needed */ -void __attribute__((weak)) show_boot_progress (int val); +void show_boot_progress(int val); #ifdef CONFIG_INIT_CRITICAL #error CONFIG_INIT_CRITICAL is deprecated! diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h index 0a86e83..98300db 100644 --- a/include/configs/bf537-stamp.h +++ b/include/configs/bf537-stamp.h @@ -151,36 +151,28 @@ /* * NAND Settings */ -/* #define CONFIG_BF537_NAND */ -#ifdef CONFIG_BF537_NAND -# define CONFIG_CMD_NAND -#endif - -#define CONFIG_SYS_NAND_ADDR 0x20212000 -#define CONFIG_SYS_NAND_BASE CONFIG_SYS_NAND_ADDR +/* #define CONFIG_NAND_PLAT */ +#define CONFIG_SYS_NAND_BASE 0x20212000 #define CONFIG_SYS_MAX_NAND_DEVICE 1 -#define SECTORSIZE 512 -#define ADDR_COLUMN 1 -#define ADDR_PAGE 2 -#define ADDR_COLUMN_PAGE 3 -#define NAND_ChipID_UNKNOWN 0x00 -#define NAND_MAX_FLOORS 1 -#define BFIN_NAND_READY PF3 - -#define NAND_WAIT_READY(nand) \ + +#define BFIN_NAND_CLE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 2)) +#define BFIN_NAND_ALE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 1)) +#define BFIN_NAND_READY PF3 +#define BFIN_NAND_WRITE(addr, cmd) \ do { \ - int timeout = 0; \ - while (!(*pPORTFIO & PF3)) \ - if (timeout++ > 100000) \ - break; \ + bfin_write8(addr, cmd); \ + SSYNC(); \ } while (0) -#define BFIN_NAND_CLE (1 << 2) /* A2 -> Command Enable */ -#define BFIN_NAND_ALE (1 << 1) /* A1 -> Address Enable */ -#define WRITE_NAND_COMMAND(d, adr) bfin_write8(adr | BFIN_NAND_CLE, d) -#define WRITE_NAND_ADDRESS(d, adr) bfin_write8(adr | BFIN_NAND_ALE, d) -#define WRITE_NAND(d, adr) bfin_write8(adr, d) -#define READ_NAND(adr) bfin_read8(adr) +#define NAND_PLAT_WRITE_CMD(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_CLE(chip), cmd) +#define NAND_PLAT_WRITE_ADR(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_ALE(chip), cmd) +#define NAND_PLAT_DEV_READY(chip) (bfin_read_PORTFIO() & BFIN_NAND_READY) +#define NAND_PLAT_INIT() \ + do { \ + bfin_write_PORTF_FER(bfin_read_PORTF_FER() & ~BFIN_NAND_READY); \ + bfin_write_PORTFIO_DIR(bfin_read_PORTFIO_DIR() & ~BFIN_NAND_READY); \ + bfin_write_PORTFIO_INEN(bfin_read_PORTFIO_INEN() | BFIN_NAND_READY); \ + } while (0) /* diff --git a/include/configs/bfin_adi_common.h b/include/configs/bfin_adi_common.h index 4149a29..1ca2e51 100644 --- a/include/configs/bfin_adi_common.h +++ b/include/configs/bfin_adi_common.h @@ -38,6 +38,9 @@ # define CONFIG_CMD_USB_STORAGE # define CONFIG_DOS_PARTITION # endif +# ifdef CONFIG_NAND_PLAT +# define CONFIG_CMD_NAND +# endif # ifdef CONFIG_POST # define CONFIG_CMD_DIAG # endif diff --git a/include/configs/blackstamp.h b/include/configs/blackstamp.h index 1e4c716..887f3fb 100644 --- a/include/configs/blackstamp.h +++ b/include/configs/blackstamp.h @@ -83,10 +83,9 @@ #endif #define CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_OFFSET 0x4000 +#define CONFIG_ENV_OFFSET 0x40000 #define CONFIG_ENV_SIZE 0x2000 #define CONFIG_ENV_SECT_SIZE 0x40000 -#define ENV_IS_EMBEDDED_CUSTOM /* * SDRAM settings & memory map @@ -245,9 +244,9 @@ * Serial Flash Infomation */ #define CONFIG_BFIN_SPI -/* For the M25P64 SCK Should be Kept < 20Mhz */ -#define CONFIG_ENV_SPI_MAX_HZ 20000000 -#define CONFIG_SF_DEFAULT_SPEED 20000000 +/* For the M25P64 SCK Should be Kept < 15Mhz */ +#define CONFIG_ENV_SPI_MAX_HZ 15000000 +#define CONFIG_SF_DEFAULT_SPEED 15000000 #define CONFIG_SPI_FLASH #define CONFIG_SPI_FLASH_STMICRO diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h index d814012..48c5198 100644 --- a/include/configs/canyonlands.h +++ b/include/configs/canyonlands.h @@ -132,9 +132,11 @@ */ #if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) #define CONFIG_ENV_IS_IN_FLASH 1 /* use FLASH for environment vars */ +#define CONFIG_SYS_NOR_CS 0 /* NOR chip connected to CSx */ #define CONFIG_SYS_NAND_CS 3 /* NAND chip connected to CSx */ #else #define CONFIG_ENV_IS_IN_NAND 1 /* use NAND for environment vars */ +#define CONFIG_SYS_NOR_CS 3 /* NOR chip connected to CSx */ #define CONFIG_SYS_NAND_CS 0 /* NAND chip connected to CSx */ #define CONFIG_ENV_IS_EMBEDDED 1 /* use embedded environment */ #endif diff --git a/include/configs/cm-bf561.h b/include/configs/cm-bf561.h index 53a2580..1153f11 100644 --- a/include/configs/cm-bf561.h +++ b/include/configs/cm-bf561.h @@ -60,8 +60,13 @@ * Network Settings */ #define ADI_CMDS_NETWORK 1 +/* The next 2 lines are for use with DEV-BF5xx */ #define CONFIG_DRIVER_SMC91111 1 #define CONFIG_SMC91111_BASE 0x28000300 +/* The next 3 lines are for use with EXT-BF5xx-USB-ETH2 */ +/* #define CONFIG_DRIVER_SMC911X 1 */ +/* #define CONFIG_DRIVER_SMC911X_BASE 0x24080000 // AMS1 */ +/* #define CONFIG_DRIVER_SMC911X_32_BIT 1 */ #define CONFIG_HOSTNAME cm-bf561 /* Uncomment next line to use fixed MAC address */ /* #define CONFIG_ETHADDR 02:80:ad:20:31:cf */ diff --git a/include/configs/smdk6400.h b/include/configs/smdk6400.h index cac58cf..018f576 100644 --- a/include/configs/smdk6400.h +++ b/include/configs/smdk6400.h @@ -209,6 +209,9 @@ /* total memory available to uboot */ #define CONFIG_SYS_UBOOT_SIZE (1024 * 1024) +/* Put environment copies after the end of U-Boot owned RAM */ +#define CONFIG_NAND_ENV_DST (CONFIG_SYS_UBOOT_BASE + CONFIG_SYS_UBOOT_SIZE) + #ifdef CONFIG_ENABLE_MMU #define CONFIG_SYS_MAPPED_RAM_BASE 0xc0000000 #define CONFIG_BOOTCOMMAND "nand read 0xc0018000 0x60000 0x1c0000;" \ diff --git a/include/nand.h b/include/nand.h index 065a42c..23f3ca1 100644 --- a/include/nand.h +++ b/include/nand.h @@ -38,22 +38,22 @@ typedef struct mtd_info nand_info_t; extern int nand_curr_device; extern nand_info_t nand_info[]; -static inline int nand_read(nand_info_t *info, off_t ofs, size_t *len, u_char *buf) +static inline int nand_read(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf) { return info->read(info, ofs, *len, (size_t *)len, buf); } -static inline int nand_write(nand_info_t *info, off_t ofs, size_t *len, u_char *buf) +static inline int nand_write(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf) { return info->write(info, ofs, *len, (size_t *)len, buf); } -static inline int nand_block_isbad(nand_info_t *info, off_t ofs) +static inline int nand_block_isbad(nand_info_t *info, loff_t ofs) { return info->block_isbad(info, ofs); } -static inline int nand_erase(nand_info_t *info, off_t off, size_t size) +static inline int nand_erase(nand_info_t *info, loff_t off, size_t size) { struct erase_info instr; @@ -110,9 +110,9 @@ struct nand_erase_options { typedef struct nand_erase_options nand_erase_options_t; -int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, +int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer); -int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, +int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer); int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); @@ -122,7 +122,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); int nand_lock( nand_info_t *meminfo, int tight ); int nand_unlock( nand_info_t *meminfo, ulong start, ulong length ); -int nand_get_lock_status(nand_info_t *meminfo, ulong offset); +int nand_get_lock_status(nand_info_t *meminfo, loff_t offset); #ifdef CONFIG_SYS_NAND_SELECT_DEVICE void board_nand_select_device(struct nand_chip *nand, int chip); diff --git a/include/usb/ehci-fsl.h b/include/usb/ehci-fsl.h index 1140561..3b99456 100644 --- a/include/usb/ehci-fsl.h +++ b/include/usb/ehci-fsl.h @@ -85,7 +85,7 @@ #define MPC83XX_SCCR_USB_DRCM_01 0x00100000 #define MPC83XX_SCCR_USB_DRCM_10 0x00200000 -#if defined(CONFIG_MPC83XX) +#if defined(CONFIG_MPC83xx) #define CONFIG_SYS_MPC8xxx_USB_ADDR CONFIG_SYS_MPC83xx_USB_ADDR #elif defined(CONFIG_MPC85xx) #define CONFIG_SYS_MPC8xxx_USB_ADDR CONFIG_SYS_MPC85xx_USB_ADDR diff --git a/lib_blackfin/Makefile b/lib_blackfin/Makefile index e32ecc9..4bdf6d3 100644 --- a/lib_blackfin/Makefile +++ b/lib_blackfin/Makefile @@ -40,6 +40,7 @@ COBJS-y += board.o COBJS-y += boot.o COBJS-y += cache.o COBJS-y += clocks.o +COBJS-$(CONFIG_CMD_CACHE_DUMP) += cmd_cache_dump.o COBJS-y += muldi3.o COBJS-$(CONFIG_POST) += post.o tests.o COBJS-y += string.o diff --git a/lib_blackfin/cmd_cache_dump.c b/lib_blackfin/cmd_cache_dump.c new file mode 100644 index 0000000..de5840e --- /dev/null +++ b/lib_blackfin/cmd_cache_dump.c @@ -0,0 +1,145 @@ +/* + * U-boot - cmd_cache_dump.c + * + * Copyright (c) 2007-2008 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <config.h> +#include <common.h> +#include <command.h> + +#include <asm/blackfin.h> +#include <asm/mach-common/bits/mpu.h> + +static int check_limit(const char *type, size_t start_limit, size_t end_limit, size_t start, size_t end) +{ + if (start >= start_limit && start <= end_limit && \ + end <= end_limit && end >= start_limit && \ + start <= end) + return 0; + + printf("%s limit violation: %zu <= (user:%zu) <= (user:%zu) <= %zu\n", + type, start_limit, start, end, end_limit); + return 1; +} + +int do_icache_dump(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int cache_status = icache_status(); + + if (cache_status) + icache_disable(); + + uint32_t cmd_base, tag, cache_upper, cache_lower; + + size_t way, way_start = 0, way_end = 3; + size_t sbnk, sbnk_start = 0, sbnk_end = 3; + size_t set, set_start = 0, set_end = 31; + size_t dw; + + if (argc > 1) { + way_start = way_end = simple_strtoul(argv[1], NULL, 10); + if (argc > 2) { + sbnk_start = sbnk_end = simple_strtoul(argv[2], NULL, 10); + if (argc > 3) + set_start = set_end = simple_strtoul(argv[3], NULL, 10); + } + } + + if (check_limit("way", 0, 3, way_start, way_end) || \ + check_limit("subbank", 0, 3, sbnk_start, sbnk_end) || \ + check_limit("set", 0, 31, set_start, set_end)) + return 1; + + puts("Way:Subbank:Set: [valid-tag lower upper] {invalid-tag lower upper}...\n"); + + for (way = way_start; way <= way_end; ++way) { + for (sbnk = sbnk_start; sbnk <= sbnk_end; ++sbnk) { + for (set = set_start; set <= set_end; ++set) { + printf("%zu:%zu:%2zu: ", way, sbnk, set); + for (dw = 0; dw < 4; ++dw) { + if (ctrlc()) + return 1; + + cmd_base = \ + (way << 26) | \ + (sbnk << 16) | \ + (set << 5) | \ + (dw << 3); + + /* first read the tag */ + bfin_write_ITEST_COMMAND(cmd_base | 0x0); + SSYNC(); + tag = bfin_read_ITEST_DATA0(); + printf("%c%08x ", (tag & 0x1 ? ' ' : '{'), tag); + + /* grab the data at this loc */ + bfin_write_ITEST_COMMAND(cmd_base | 0x4); + SSYNC(); + cache_lower = bfin_read_ITEST_DATA0(); + cache_upper = bfin_read_ITEST_DATA1(); + printf("%08x %08x%c ", cache_lower, cache_upper, (tag & 0x1 ? ' ' : '}')); + } + puts("\n"); + } + } + } + + if (cache_status) + icache_enable(); + + return 0; +} + +U_BOOT_CMD(icache_dump, 4, 0, do_icache_dump, + "icache_dump - dump current instruction cache\n", + "[way] [subbank] [set]"); + +int do_dcache_dump(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + u32 way, bank, subbank, set; + u32 status, addr; + u32 dmem_ctl = bfin_read_DMEM_CONTROL(); + + for (bank = 0; bank < 2; ++bank) { + if (!(dmem_ctl & (1 << (DMC1_P - bank)))) + continue; + + for (way = 0; way < 2; ++way) + for (subbank = 0; subbank < 4; ++subbank) { + printf("%i:%i:%i:\t", bank, way, subbank); + for (set = 0; set < 64; ++set) { + + if (ctrlc()) + return 1; + + /* retrieve a cache tag */ + bfin_write_DTEST_COMMAND( + way << 26 | + bank << 23 | + subbank << 16 | + set << 5 + ); + CSYNC(); + status = bfin_read_DTEST_DATA0(); + + /* construct the address using the tag */ + addr = (status & 0xFFFFC800) | (subbank << 12) | (set << 5); + + /* show it */ + if (set && !(set % 4)) + puts("\n\t"); + printf("%c%08x%c%08x%c ", (status & 0x1 ? '[' : '{'), status, (status & 0x2 ? 'd' : ' '), addr, (status & 0x1 ? ']' : '}')); + } + puts("\n"); + } + } + + return 0; +} + +U_BOOT_CMD(dcache_dump, 4, 0, do_dcache_dump, + "dcache_dump - dump current data cache\n", + "[bank] [way] [subbank] [set]"); diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c index c7eadad..b9fd6f5 100644 --- a/nand_spl/nand_boot.c +++ b/nand_spl/nand_boot.c @@ -47,11 +47,13 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8 /* Set ALE and clear CLE to start address cycle */ /* Column address */ this->cmd_ctrl(mtd, offs, NAND_CTRL_ALE | NAND_CTRL_CHANGE); - this->cmd_ctrl(mtd, page_addr & 0xff, 0); /* A[16:9] */ - this->cmd_ctrl(mtd, (page_addr >> 8) & 0xff, 0); /* A[24:17] */ + this->cmd_ctrl(mtd, page_addr & 0xff, NAND_CTRL_ALE); /* A[16:9] */ + this->cmd_ctrl(mtd, (page_addr >> 8) & 0xff, + NAND_CTRL_ALE); /* A[24:17] */ #ifdef CONFIG_SYS_NAND_4_ADDR_CYCLE /* One more address cycle for devices > 32MiB */ - this->cmd_ctrl(mtd, (page_addr >> 16) & 0x0f, 0); /* A[28:25] */ + this->cmd_ctrl(mtd, (page_addr >> 16) & 0x0f, + NAND_CTRL_ALE); /* A[28:25] */ #endif /* Latch in address */ this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); @@ -94,13 +96,15 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8 /* Column address */ this->cmd_ctrl(mtd, offs & 0xff, NAND_CTRL_ALE | NAND_CTRL_CHANGE); /* A[7:0] */ - this->cmd_ctrl(mtd, (offs >> 8) & 0xff, 0); /* A[11:9] */ + this->cmd_ctrl(mtd, (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */ /* Row address */ - this->cmd_ctrl(mtd, (page_addr & 0xff), 0); /* A[19:12] */ - this->cmd_ctrl(mtd, ((page_addr >> 8) & 0xff), 0); /* A[27:20] */ + this->cmd_ctrl(mtd, (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */ + this->cmd_ctrl(mtd, ((page_addr >> 8) & 0xff), + NAND_CTRL_ALE); /* A[27:20] */ #ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE /* One more address cycle for devices > 128MiB */ - this->cmd_ctrl(mtd, (page_addr >> 16) & 0x0f, 0); /* A[31:28] */ + this->cmd_ctrl(mtd, (page_addr >> 16) & 0x0f, + NAND_CTRL_ALE); /* A[31:28] */ #endif /* Latch in address */ this->cmd_ctrl(mtd, NAND_CMD_READSTART, @@ -246,6 +250,16 @@ void nand_boot(void) ret = nand_load(&nand_info, CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE, (uchar *)CONFIG_SYS_NAND_U_BOOT_DST); +#ifdef CONFIG_NAND_ENV_DST + nand_load(&nand_info, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, + (uchar *)CONFIG_NAND_ENV_DST); + +#ifdef CONFIG_ENV_OFFSET_REDUND + nand_load(&nand_info, CONFIG_ENV_OFFSET_REDUND, CONFIG_ENV_SIZE, + (uchar *)CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE); +#endif +#endif + if (nand_chip.select_chip) nand_chip.select_chip(&nand_info, -1); |