9e216a69405c1102ae5f680ff9c03ad60558330f
[oweals/u-boot.git] / drivers / mtd / spi / fsl_espi_spl.c
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 }