1 // SPDX-License-Identifier: GPL-2.0+
4 * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
8 #include <fdt_support.h>
14 #include <linux/libfdt_env.h>
17 uint32_t __weak
spl_nand_get_uboot_raw_page(void)
19 return CONFIG_SYS_NAND_U_BOOT_OFFS
;
22 #if defined(CONFIG_SPL_NAND_RAW_ONLY)
23 static int spl_nand_load_image(struct spl_image_info
*spl_image
,
24 struct spl_boot_device
*bootdev
)
28 printf("Loading U-Boot from 0x%08x (size 0x%08x) to 0x%08x\n",
29 CONFIG_SYS_NAND_U_BOOT_OFFS
, CFG_SYS_NAND_U_BOOT_SIZE
,
30 CFG_SYS_NAND_U_BOOT_DST
);
32 nand_spl_load_image(spl_nand_get_uboot_raw_page(),
33 CFG_SYS_NAND_U_BOOT_SIZE
,
34 (void *)CFG_SYS_NAND_U_BOOT_DST
);
35 spl_set_header_raw_uboot(spl_image
);
42 static ulong
spl_nand_fit_read(struct spl_load_info
*load
, ulong offs
,
43 ulong size
, void *dst
)
48 sector
= *(int *)load
->priv
;
51 offs
= sector
+ nand_spl_adjust_offset(sector
, offs
- sector
);
52 err
= nand_spl_load_image(offs
, size
, dst
);
56 return size
/ load
->bl_len
;
59 static ulong
spl_nand_legacy_read(struct spl_load_info
*load
, ulong offs
,
60 ulong size
, void *dst
)
64 debug("%s: offs %lx, size %lx, dst %p\n",
65 __func__
, offs
, size
, dst
);
67 err
= nand_spl_load_image(offs
, size
, dst
);
74 struct mtd_info
* __weak
nand_get_mtd(void)
79 static int spl_nand_load_element(struct spl_image_info
*spl_image
,
80 struct spl_boot_device
*bootdev
,
81 int offset
, struct legacy_img_hdr
*header
)
83 struct mtd_info
*mtd
= nand_get_mtd();
84 int bl_len
= mtd
? mtd
->writesize
: 1;
87 err
= nand_spl_load_image(offset
, sizeof(*header
), (void *)header
);
91 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT
) &&
92 image_get_magic(header
) == FDT_MAGIC
) {
93 struct spl_load_info load
;
100 load
.read
= spl_nand_fit_read
;
101 return spl_load_simple_fit(spl_image
, &load
, offset
/ bl_len
, header
);
102 } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER
)) {
103 struct spl_load_info load
;
107 load
.filename
= NULL
;
108 load
.bl_len
= bl_len
;
109 load
.read
= spl_nand_fit_read
;
110 return spl_load_imx_container(spl_image
, &load
, offset
/ bl_len
);
111 } else if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_FORMAT
) &&
112 image_get_magic(header
) == IH_MAGIC
) {
113 struct spl_load_info load
;
115 debug("Found legacy image\n");
118 load
.filename
= NULL
;
120 load
.read
= spl_nand_legacy_read
;
122 return spl_load_legacy_img(spl_image
, bootdev
, &load
, offset
, header
);
124 err
= spl_parse_image_header(spl_image
, bootdev
, header
);
127 return nand_spl_load_image(offset
, spl_image
->size
,
128 (void *)(ulong
)spl_image
->load_addr
);
132 static int spl_nand_load_image(struct spl_image_info
*spl_image
,
133 struct spl_boot_device
*bootdev
)
136 struct legacy_img_hdr
*header
;
137 int *src
__attribute__((unused
));
138 int *dst
__attribute__((unused
));
140 #ifdef CONFIG_SPL_NAND_SOFTECC
141 debug("spl: nand - using sw ecc\n");
143 debug("spl: nand - using hw ecc\n");
147 header
= spl_get_load_buffer(0, sizeof(*header
));
149 #if CONFIG_IS_ENABLED(OS_BOOT)
150 if (!spl_start_uboot()) {
152 * load parameter image
153 * load to temp position since nand_spl_load_image reads
154 * a whole block which is typically larger than
155 * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite
156 * following sections like BSS
158 nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS
,
159 CONFIG_CMD_SPL_WRITE_SIZE
,
160 (void *)CONFIG_TEXT_BASE
);
161 /* copy to destintion */
162 for (dst
= (int *)CONFIG_SYS_SPL_ARGS_ADDR
,
163 src
= (int *)CONFIG_TEXT_BASE
;
164 src
< (int *)(CONFIG_TEXT_BASE
+
165 CONFIG_CMD_SPL_WRITE_SIZE
);
167 writel(readl(src
), dst
);
171 nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS
,
172 sizeof(*header
), (void *)header
);
173 err
= spl_parse_image_header(spl_image
, bootdev
, header
);
176 if (header
->ih_os
== IH_OS_LINUX
) {
177 /* happy - was a linux */
178 err
= nand_spl_load_image(
179 CONFIG_SYS_NAND_SPL_KERNEL_OFFS
,
181 (void *)spl_image
->load_addr
);
185 puts("The Expected Linux image was not "
186 "found. Please check your NAND "
188 puts("Trying to start u-boot now...\n");
192 #ifdef CONFIG_NAND_ENV_DST
193 spl_nand_load_element(spl_image
, bootdev
, CONFIG_ENV_OFFSET
, header
);
194 #ifdef CONFIG_ENV_OFFSET_REDUND
195 spl_nand_load_element(spl_image
, bootdev
, CONFIG_ENV_OFFSET_REDUND
, header
);
199 err
= spl_nand_load_element(spl_image
, bootdev
, spl_nand_get_uboot_raw_page(),
201 #ifdef CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND
202 #if CONFIG_SYS_NAND_U_BOOT_OFFS != CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND
204 err
= spl_nand_load_element(spl_image
, bootdev
,
205 CONFIG_SYS_NAND_U_BOOT_OFFS_REDUND
,
213 /* Use priorty 1 so that Ubi can override this */
214 SPL_LOAD_IMAGE_METHOD("NAND", 1, BOOT_DEVICE_NAND
, spl_nand_load_image
);