xref: /rk3399_rockchip-uboot/common/spl/spl_nand.c (revision 483ab3dc8037878ae5dc7af5f0af7bf7ecc36897)
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
99