diff options
Diffstat (limited to 'common/spl')
| -rw-r--r-- | common/spl/Makefile | 1 | ||||
| -rw-r--r-- | common/spl/spl_nand.c | 100 | 
2 files changed, 101 insertions, 0 deletions
| diff --git a/common/spl/Makefile b/common/spl/Makefile index b61b43828..b9c9fd852 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -16,6 +16,7 @@ LIB	= $(obj)libspl.o  ifdef CONFIG_SPL_BUILD  COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o  COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o +COBJS-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o  endif  COBJS	:= $(sort $(COBJS-y)) diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c new file mode 100644 index 000000000..61de5a4f0 --- /dev/null +++ b/common/spl/spl_nand.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> + * + * 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 <config.h> +#include <spl.h> +#include <asm/io.h> +#include <nand.h> + +void spl_nand_load_image(void) +{ +	struct image_header *header; +	int *src __attribute__((unused)); +	int *dst __attribute__((unused)); + +	debug("spl: nand - using hw ecc\n"); +	nand_init(); + +	/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ +	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT +	if (!spl_start_uboot()) { +		/* +		 * load parameter image +		 * load to temp position since nand_spl_load_image reads +		 * a whole block which is typically larger than +		 * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite +		 * following sections like BSS +		 */ +		nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, +			CONFIG_CMD_SPL_WRITE_SIZE, +			(void *)CONFIG_SYS_TEXT_BASE); +		/* copy to destintion */ +		for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, +				src = (int *)CONFIG_SYS_TEXT_BASE; +				src < (int *)(CONFIG_SYS_TEXT_BASE + +				CONFIG_CMD_SPL_WRITE_SIZE); +				src++, dst++) { +			writel(readl(src), dst); +		} + +		/* load linux */ +		nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, +			CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); +		spl_parse_image_header(header); +		if (header->ih_os == IH_OS_LINUX) { +			/* happy - was a linux */ +			nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, +				spl_image.size, (void *)spl_image.load_addr); +			nand_deselect(); +			return; +		} else { +			puts("The Expected Linux image was not " +				"found. Please check your NAND " +				"configuration.\n"); +			puts("Trying to start u-boot now...\n"); +		} +	} +#endif +#ifdef CONFIG_NAND_ENV_DST +	nand_spl_load_image(CONFIG_ENV_OFFSET, +		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); +	spl_parse_image_header(header); +	nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, +		(void *)spl_image.load_addr); +#ifdef CONFIG_ENV_OFFSET_REDUND +	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, +		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); +	spl_parse_image_header(header); +	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, +		(void *)spl_image.load_addr); +#endif +#endif +	/* Load u-boot */ +	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, +		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); +	spl_parse_image_header(header); +	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, +		spl_image.size, (void *)spl_image.load_addr); +	nand_deselect(); +} |