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