xref: /openbmc/u-boot/common/spl/spl_nand.c (revision 29b103c7)
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 #if defined(CONFIG_SPL_NAND_RAW_ONLY)
14 void spl_nand_load_image(void)
15 {
16 	nand_init();
17 
18 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
19 			    CONFIG_SYS_NAND_U_BOOT_SIZE,
20 			    (void *)CONFIG_SYS_NAND_U_BOOT_DST);
21 	spl_set_header_raw_uboot();
22 	nand_deselect();
23 }
24 #else
25 void spl_nand_load_image(void)
26 {
27 	struct image_header *header;
28 	int *src __attribute__((unused));
29 	int *dst __attribute__((unused));
30 
31 	debug("spl: nand - using hw ecc\n");
32 	nand_init();
33 
34 	/*use CONFIG_SYS_TEXT_BASE as temporary storage area */
35 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
36 #ifdef CONFIG_SPL_OS_BOOT
37 	if (!spl_start_uboot()) {
38 		/*
39 		 * load parameter image
40 		 * load to temp position since nand_spl_load_image reads
41 		 * a whole block which is typically larger than
42 		 * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite
43 		 * following sections like BSS
44 		 */
45 		nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS,
46 			CONFIG_CMD_SPL_WRITE_SIZE,
47 			(void *)CONFIG_SYS_TEXT_BASE);
48 		/* copy to destintion */
49 		for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR,
50 				src = (int *)CONFIG_SYS_TEXT_BASE;
51 				src < (int *)(CONFIG_SYS_TEXT_BASE +
52 				CONFIG_CMD_SPL_WRITE_SIZE);
53 				src++, dst++) {
54 			writel(readl(src), dst);
55 		}
56 
57 		/* load linux */
58 		nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
59 			sizeof(*header), (void *)header);
60 		spl_parse_image_header(header);
61 		if (header->ih_os == IH_OS_LINUX) {
62 			/* happy - was a linux */
63 			nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
64 				spl_image.size, (void *)spl_image.load_addr);
65 			nand_deselect();
66 			return;
67 		} else {
68 			puts("The Expected Linux image was not "
69 				"found. Please check your NAND "
70 				"configuration.\n");
71 			puts("Trying to start u-boot now...\n");
72 		}
73 	}
74 #endif
75 #ifdef CONFIG_NAND_ENV_DST
76 	nand_spl_load_image(CONFIG_ENV_OFFSET,
77 		sizeof(*header), (void *)header);
78 	spl_parse_image_header(header);
79 	nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
80 		(void *)spl_image.load_addr);
81 #ifdef CONFIG_ENV_OFFSET_REDUND
82 	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
83 		sizeof(*header), (void *)header);
84 	spl_parse_image_header(header);
85 	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
86 		(void *)spl_image.load_addr);
87 #endif
88 #endif
89 	/* Load u-boot */
90 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
91 		sizeof(*header), (void *)header);
92 	spl_parse_image_header(header);
93 	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
94 		spl_image.size, (void *)(unsigned long)spl_image.load_addr);
95 	nand_deselect();
96 }
97 #endif
98