xref: /openbmc/u-boot/common/spl/spl_nand.c (revision c346e466)
1 /*
2  * Copyright (C) 2011
3  * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 #include <common.h>
8 #include <config.h>
9 #include <spl.h>
10 #include <asm/io.h>
11 #include <nand.h>
12 
13 void spl_nand_load_image(void)
14 {
15 	struct image_header *header;
16 	int *src __attribute__((unused));
17 	int *dst __attribute__((unused));
18 
19 	debug("spl: nand - using hw ecc\n");
20 	nand_init();
21 
22 	/*use CONFIG_SYS_TEXT_BASE as temporary storage area */
23 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
24 #ifdef CONFIG_SPL_OS_BOOT
25 	if (!spl_start_uboot()) {
26 		/*
27 		 * load parameter image
28 		 * load to temp position since nand_spl_load_image reads
29 		 * a whole block which is typically larger than
30 		 * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite
31 		 * following sections like BSS
32 		 */
33 		nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS,
34 			CONFIG_CMD_SPL_WRITE_SIZE,
35 			(void *)CONFIG_SYS_TEXT_BASE);
36 		/* copy to destintion */
37 		for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR,
38 				src = (int *)CONFIG_SYS_TEXT_BASE;
39 				src < (int *)(CONFIG_SYS_TEXT_BASE +
40 				CONFIG_CMD_SPL_WRITE_SIZE);
41 				src++, dst++) {
42 			writel(readl(src), dst);
43 		}
44 
45 		/* load linux */
46 		nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
47 			CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
48 		spl_parse_image_header(header);
49 		if (header->ih_os == IH_OS_LINUX) {
50 			/* happy - was a linux */
51 			nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
52 				spl_image.size, (void *)spl_image.load_addr);
53 			nand_deselect();
54 			return;
55 		} else {
56 			puts("The Expected Linux image was not "
57 				"found. Please check your NAND "
58 				"configuration.\n");
59 			puts("Trying to start u-boot now...\n");
60 		}
61 	}
62 #endif
63 #ifdef CONFIG_NAND_ENV_DST
64 	nand_spl_load_image(CONFIG_ENV_OFFSET,
65 		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
66 	spl_parse_image_header(header);
67 	nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
68 		(void *)spl_image.load_addr);
69 #ifdef CONFIG_ENV_OFFSET_REDUND
70 	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
71 		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
72 	spl_parse_image_header(header);
73 	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
74 		(void *)spl_image.load_addr);
75 #endif
76 #endif
77 	/* Load u-boot */
78 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
79 		sizeof(*header), (void *)header);
80 	spl_parse_image_header(header);
81 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
82 		spl_image.size, (void *)spl_image.load_addr);
83 	nand_deselect();
84 }
85