]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
9ea5c6ef SS |
2 | /* |
3 | * Copyright (C) 2011 | |
4 | * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> | |
9ea5c6ef SS |
5 | */ |
6 | #include <common.h> | |
d97b4ce8 | 7 | #include <config.h> |
47f7bcae | 8 | #include <spl.h> |
df163a59 | 9 | #include <asm/io.h> |
9ea5c6ef | 10 | #include <nand.h> |
b08c8c48 | 11 | #include <linux/libfdt_env.h> |
8bd88772 | 12 | #include <fdt.h> |
9ea5c6ef | 13 | |
0c3117b1 | 14 | #if defined(CONFIG_SPL_NAND_RAW_ONLY) |
25dabd73 | 15 | static int spl_nand_load_image(struct spl_image_info *spl_image, |
2a2ee2ac | 16 | struct spl_boot_device *bootdev) |
0c3117b1 HS |
17 | { |
18 | nand_init(); | |
19 | ||
443b3ce5 SR |
20 | printf("Loading U-Boot from 0x%08x (size 0x%08x) to 0x%08x\n", |
21 | CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE, | |
22 | CONFIG_SYS_NAND_U_BOOT_DST); | |
23 | ||
0c3117b1 HS |
24 | nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, |
25 | CONFIG_SYS_NAND_U_BOOT_SIZE, | |
26 | (void *)CONFIG_SYS_NAND_U_BOOT_DST); | |
2a2ee2ac | 27 | spl_set_header_raw_uboot(spl_image); |
0c3117b1 | 28 | nand_deselect(); |
36afd451 NK |
29 | |
30 | return 0; | |
0c3117b1 HS |
31 | } |
32 | #else | |
8bd88772 LV |
33 | |
34 | static ulong spl_nand_fit_read(struct spl_load_info *load, ulong offs, | |
35 | ulong size, void *dst) | |
36 | { | |
37 | int ret; | |
38 | ||
39 | ret = nand_spl_load_image(offs, size, dst); | |
40 | if (!ret) | |
41 | return size; | |
42 | else | |
43 | return 0; | |
44 | } | |
45 | ||
2a2ee2ac SG |
46 | static int spl_nand_load_element(struct spl_image_info *spl_image, |
47 | int offset, struct image_header *header) | |
483ab3dc NK |
48 | { |
49 | int err; | |
50 | ||
51 | err = nand_spl_load_image(offset, sizeof(*header), (void *)header); | |
52 | if (err) | |
53 | return err; | |
54 | ||
8bd88772 LV |
55 | if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && |
56 | image_get_magic(header) == FDT_MAGIC) { | |
57 | struct spl_load_info load; | |
7e0f2267 | 58 | |
8bd88772 LV |
59 | debug("Found FIT\n"); |
60 | load.dev = NULL; | |
61 | load.priv = NULL; | |
62 | load.filename = NULL; | |
63 | load.bl_len = 1; | |
64 | load.read = spl_nand_fit_read; | |
f4d7d859 | 65 | return spl_load_simple_fit(spl_image, &load, offset, header); |
8bd88772 | 66 | } else { |
2a2ee2ac | 67 | err = spl_parse_image_header(spl_image, header); |
8bd88772 LV |
68 | if (err) |
69 | return err; | |
2a2ee2ac SG |
70 | return nand_spl_load_image(offset, spl_image->size, |
71 | (void *)(ulong)spl_image->load_addr); | |
8bd88772 | 72 | } |
483ab3dc NK |
73 | } |
74 | ||
2a2ee2ac SG |
75 | static int spl_nand_load_image(struct spl_image_info *spl_image, |
76 | struct spl_boot_device *bootdev) | |
9ea5c6ef | 77 | { |
36afd451 | 78 | int err; |
9ea5c6ef | 79 | struct image_header *header; |
df163a59 SS |
80 | int *src __attribute__((unused)); |
81 | int *dst __attribute__((unused)); | |
82 | ||
8122d216 ASK |
83 | #ifdef CONFIG_SPL_NAND_SOFTECC |
84 | debug("spl: nand - using sw ecc\n"); | |
85 | #else | |
8082fda9 | 86 | debug("spl: nand - using hw ecc\n"); |
8122d216 | 87 | #endif |
8082fda9 | 88 | nand_init(); |
9ea5c6ef | 89 | |
04ce5427 MV |
90 | header = spl_get_load_buffer(0, sizeof(*header)); |
91 | ||
df163a59 | 92 | #ifdef CONFIG_SPL_OS_BOOT |
379c19ab | 93 | if (!spl_start_uboot()) { |
df163a59 SS |
94 | /* |
95 | * load parameter image | |
96 | * load to temp position since nand_spl_load_image reads | |
97 | * a whole block which is typically larger than | |
b6e95fd4 | 98 | * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite |
df163a59 SS |
99 | * following sections like BSS |
100 | */ | |
101 | nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, | |
102 | CONFIG_CMD_SPL_WRITE_SIZE, | |
103 | (void *)CONFIG_SYS_TEXT_BASE); | |
104 | /* copy to destintion */ | |
105 | for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, | |
106 | src = (int *)CONFIG_SYS_TEXT_BASE; | |
107 | src < (int *)(CONFIG_SYS_TEXT_BASE + | |
108 | CONFIG_CMD_SPL_WRITE_SIZE); | |
109 | src++, dst++) { | |
110 | writel(readl(src), dst); | |
111 | } | |
9ea5c6ef | 112 | |
df163a59 SS |
113 | /* load linux */ |
114 | nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, | |
c13bb167 | 115 | sizeof(*header), (void *)header); |
2a2ee2ac | 116 | err = spl_parse_image_header(spl_image, header); |
7e0f2267 MV |
117 | if (err) |
118 | return err; | |
379c19ab SS |
119 | if (header->ih_os == IH_OS_LINUX) { |
120 | /* happy - was a linux */ | |
36afd451 NK |
121 | err = nand_spl_load_image( |
122 | CONFIG_SYS_NAND_SPL_KERNEL_OFFS, | |
2a2ee2ac SG |
123 | spl_image->size, |
124 | (void *)spl_image->load_addr); | |
379c19ab | 125 | nand_deselect(); |
36afd451 | 126 | return err; |
379c19ab | 127 | } else { |
d97b4ce8 TR |
128 | puts("The Expected Linux image was not " |
129 | "found. Please check your NAND " | |
379c19ab | 130 | "configuration.\n"); |
d97b4ce8 | 131 | puts("Trying to start u-boot now...\n"); |
379c19ab SS |
132 | } |
133 | } | |
df163a59 | 134 | #endif |
9ea5c6ef | 135 | #ifdef CONFIG_NAND_ENV_DST |
2a2ee2ac | 136 | spl_nand_load_element(spl_image, CONFIG_ENV_OFFSET, header); |
9ea5c6ef | 137 | #ifdef CONFIG_ENV_OFFSET_REDUND |
2a2ee2ac | 138 | spl_nand_load_element(spl_image, CONFIG_ENV_OFFSET_REDUND, header); |
9ea5c6ef SS |
139 | #endif |
140 | #endif | |
379c19ab | 141 | /* Load u-boot */ |
2a2ee2ac SG |
142 | err = spl_nand_load_element(spl_image, CONFIG_SYS_NAND_U_BOOT_OFFS, |
143 | header); | |
80ef700f BB |
144 | #ifdef CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND |
145 | #if CONFIG_SYS_NAND_U_BOOT_OFFS != CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND | |
146 | if (err) | |
2a2ee2ac SG |
147 | err = spl_nand_load_element(spl_image, |
148 | CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND, | |
80ef700f BB |
149 | header); |
150 | #endif | |
151 | #endif | |
9ea5c6ef | 152 | nand_deselect(); |
36afd451 | 153 | return err; |
9ea5c6ef | 154 | } |
0c3117b1 | 155 | #endif |
d5c2b11c | 156 | /* Use priorty 1 so that Ubi can override this */ |
ebc4ef61 | 157 | SPL_LOAD_IMAGE_METHOD("NAND", 1, BOOT_DEVICE_NAND, spl_nand_load_image); |