xref: /openbmc/u-boot/drivers/mtd/spi/fsl_espi_spl.c (revision 997399fa42b098d0a4163e1a3461bd9a34aab8ac)
1 /*
2  * Copyright 2013 Freescale Semiconductor, Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  *
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA
19  *
20  */
21 
22 #include <common.h>
23 #include <spi_flash.h>
24 #include <malloc.h>
25 
26 #define ESPI_BOOT_IMAGE_SIZE	0x48
27 #define ESPI_BOOT_IMAGE_ADDR	0x50
28 #define CONFIG_CFG_DATA_SECTOR	0
29 
30 /*
31  * The main entry for SPI booting. It's necessary that SDRAM is already
32  * configured and available since this code loads the main U-Boot image
33  * from SPI into SDRAM and starts it from there.
34  */
35 void spi_boot(void)
36 {
37 	void (*uboot)(void) __noreturn;
38 	u32 offset, code_len;
39 	unsigned char *buf = NULL;
40 	struct spi_flash *flash;
41 
42 	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
43 			CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
44 	if (flash == NULL) {
45 		puts("\nspi_flash_probe failed");
46 		hang();
47 	}
48 
49 	/*
50 	* Load U-Boot image from SPI flash into RAM
51 	*/
52 	buf = malloc(flash->page_size);
53 	if (buf == NULL) {
54 		puts("\nmalloc failed");
55 		hang();
56 	}
57 	memset(buf, 0, flash->page_size);
58 
59 	spi_flash_read(flash, CONFIG_CFG_DATA_SECTOR,
60 		       flash->page_size, (void *)buf);
61 	offset = *(u32 *)(buf + ESPI_BOOT_IMAGE_ADDR);
62 	/* Skip spl code */
63 	offset += CONFIG_SYS_SPI_FLASH_U_BOOT_OFFS;
64 	/* Get the code size from offset 0x48 */
65 	code_len = *(u32 *)(buf + ESPI_BOOT_IMAGE_SIZE);
66 	/* Skip spl code */
67 	code_len = code_len - CONFIG_SPL_MAX_SIZE;
68 	/* copy code to DDR */
69 	spi_flash_read(flash, offset, code_len,
70 		       (void *)CONFIG_SYS_SPI_FLASH_U_BOOT_DST);
71 	/*
72 	* Jump to U-Boot image
73 	*/
74 	flush_cache(CONFIG_SYS_SPI_FLASH_U_BOOT_DST, code_len);
75 	uboot = (void *)CONFIG_SYS_SPI_FLASH_U_BOOT_START;
76 	(*uboot)();
77 }
78