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