xref: /OK3568_Linux_fs/u-boot/common/spl/spl_spi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2011 OMICRON electronics GmbH
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * based on drivers/mtd/nand/raw/nand_spl_load.c
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2011
7*4882a593Smuzhiyun  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <common.h>
13*4882a593Smuzhiyun #include <spi.h>
14*4882a593Smuzhiyun #include <spi_flash.h>
15*4882a593Smuzhiyun #include <errno.h>
16*4882a593Smuzhiyun #include <spl.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #ifdef CONFIG_SPL_OS_BOOT
21*4882a593Smuzhiyun /*
22*4882a593Smuzhiyun  * Load the kernel, check for a valid header we can parse, and if found load
23*4882a593Smuzhiyun  * the kernel and then device tree.
24*4882a593Smuzhiyun  */
spi_load_image_os(struct spl_image_info * spl_image,struct spi_flash * flash,struct image_header * header)25*4882a593Smuzhiyun static int spi_load_image_os(struct spl_image_info *spl_image,
26*4882a593Smuzhiyun 			     struct spi_flash *flash,
27*4882a593Smuzhiyun 			     struct image_header *header)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun 	int err;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	/* Read for a header, parse or error out. */
32*4882a593Smuzhiyun 	spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS, 0x40,
33*4882a593Smuzhiyun 		       (void *)header);
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	if (image_get_magic(header) != IH_MAGIC)
36*4882a593Smuzhiyun 		return -1;
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	err = spl_parse_image_header(spl_image, header);
39*4882a593Smuzhiyun 	if (err)
40*4882a593Smuzhiyun 		return err;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 	spi_flash_read(flash, CONFIG_SYS_SPI_KERNEL_OFFS,
43*4882a593Smuzhiyun 		       spl_image->size, (void *)spl_image->load_addr);
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	/* Read device tree. */
46*4882a593Smuzhiyun 	spi_flash_read(flash, CONFIG_SYS_SPI_ARGS_OFFS,
47*4882a593Smuzhiyun 		       CONFIG_SYS_SPI_ARGS_SIZE,
48*4882a593Smuzhiyun 		       (void *)CONFIG_SYS_SPL_ARGS_ADDR);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	return 0;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun #endif
53*4882a593Smuzhiyun 
spl_spi_fit_read(struct spl_load_info * load,ulong sector,ulong count,void * buf)54*4882a593Smuzhiyun static ulong spl_spi_fit_read(struct spl_load_info *load, ulong sector,
55*4882a593Smuzhiyun 			      ulong count, void *buf)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun 	struct spi_flash *flash = load->dev;
58*4882a593Smuzhiyun 	ulong ret;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	ret = spi_flash_read(flash, sector, count, buf);
61*4882a593Smuzhiyun 	if (!ret)
62*4882a593Smuzhiyun 		return count;
63*4882a593Smuzhiyun 	else
64*4882a593Smuzhiyun 		return 0;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun /*
67*4882a593Smuzhiyun  * The main entry for SPI booting. It's necessary that SDRAM is already
68*4882a593Smuzhiyun  * configured and available since this code loads the main U-Boot image
69*4882a593Smuzhiyun  * from SPI into SDRAM and starts it from there.
70*4882a593Smuzhiyun  */
spl_spi_load_image(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)71*4882a593Smuzhiyun static int spl_spi_load_image(struct spl_image_info *spl_image,
72*4882a593Smuzhiyun 			      struct spl_boot_device *bootdev)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	int err = 0;
75*4882a593Smuzhiyun 	unsigned payload_offs = CONFIG_SYS_SPI_U_BOOT_OFFS;
76*4882a593Smuzhiyun 	struct spi_flash *flash;
77*4882a593Smuzhiyun 	struct image_header *header;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	/*
80*4882a593Smuzhiyun 	 * Load U-Boot image from SPI flash into RAM
81*4882a593Smuzhiyun 	 * In DM mode: defaults speed and mode will be
82*4882a593Smuzhiyun 	 * taken from DT when available
83*4882a593Smuzhiyun 	 */
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS,
86*4882a593Smuzhiyun 				CONFIG_SF_DEFAULT_CS,
87*4882a593Smuzhiyun 				CONFIG_SF_DEFAULT_SPEED,
88*4882a593Smuzhiyun 				CONFIG_SF_DEFAULT_MODE);
89*4882a593Smuzhiyun 	if (!flash) {
90*4882a593Smuzhiyun 		puts("SPI probe failed.\n");
91*4882a593Smuzhiyun 		return -ENODEV;
92*4882a593Smuzhiyun 	}
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	/* use CONFIG_SYS_TEXT_BASE as temporary storage area */
95*4882a593Smuzhiyun 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
98*4882a593Smuzhiyun 	payload_offs = fdtdec_get_config_int(gd->fdt_blob,
99*4882a593Smuzhiyun 					     "u-boot,spl-payload-offset",
100*4882a593Smuzhiyun 					     payload_offs);
101*4882a593Smuzhiyun #endif
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun #ifdef CONFIG_SPL_OS_BOOT
104*4882a593Smuzhiyun 	if (spl_start_uboot() || spi_load_image_os(spl_image, flash, header))
105*4882a593Smuzhiyun #endif
106*4882a593Smuzhiyun 	{
107*4882a593Smuzhiyun 		/* Load u-boot, mkimage header is 64 bytes. */
108*4882a593Smuzhiyun 		err = spi_flash_read(flash, payload_offs, 0x40,
109*4882a593Smuzhiyun 				     (void *)header);
110*4882a593Smuzhiyun 		if (err) {
111*4882a593Smuzhiyun 			debug("%s: Failed to read from SPI flash (err=%d)\n",
112*4882a593Smuzhiyun 			      __func__, err);
113*4882a593Smuzhiyun 			return err;
114*4882a593Smuzhiyun 		}
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun #ifdef CONFIG_SPL_FIT_IMAGE_MULTIPLE
117*4882a593Smuzhiyun 		if ((IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
118*4882a593Smuzhiyun 		     image_get_magic(header) == FDT_MAGIC) ||
119*4882a593Smuzhiyun 		     CONFIG_SPL_FIT_IMAGE_MULTIPLE > 1) {
120*4882a593Smuzhiyun #else
121*4882a593Smuzhiyun 		if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
122*4882a593Smuzhiyun 		    image_get_magic(header) == FDT_MAGIC) {
123*4882a593Smuzhiyun #endif
124*4882a593Smuzhiyun 			struct spl_load_info load;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 			debug("Found FIT\n");
127*4882a593Smuzhiyun 			load.dev = flash;
128*4882a593Smuzhiyun 			load.priv = NULL;
129*4882a593Smuzhiyun 			load.filename = NULL;
130*4882a593Smuzhiyun 			load.bl_len = 1;
131*4882a593Smuzhiyun 			load.read = spl_spi_fit_read;
132*4882a593Smuzhiyun 			err = spl_load_simple_fit(spl_image, &load,
133*4882a593Smuzhiyun 						  payload_offs,
134*4882a593Smuzhiyun 						  header);
135*4882a593Smuzhiyun 		} else {
136*4882a593Smuzhiyun 			err = spl_parse_image_header(spl_image, header);
137*4882a593Smuzhiyun 			if (err)
138*4882a593Smuzhiyun 				return err;
139*4882a593Smuzhiyun 			err = spi_flash_read(flash, payload_offs,
140*4882a593Smuzhiyun 					     spl_image->size,
141*4882a593Smuzhiyun 					     (void *)spl_image->load_addr);
142*4882a593Smuzhiyun 		}
143*4882a593Smuzhiyun 	}
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	return err;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun /* Use priorty 1 so that boards can override this */
148*4882a593Smuzhiyun SPL_LOAD_IMAGE_METHOD("SPI", 1, BOOT_DEVICE_SPI, spl_spi_load_image);
149