summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorYing Zhang <b40530@freescale.com>2013-08-16 15:16:13 +0800
committerYork Sun <yorksun@freescale.com>2013-08-20 09:47:47 -0700
commitfdf8529afc39b9d096159b7d3287d7e29e51ec3a (patch)
treeb343eabaaddeafeb8345ab5dc621037d5d5a09e8 /drivers
parent7c8eea59b8c3b124d23b41f887bc525cf2adec30 (diff)
downloadblackbird-obmc-uboot-fdf8529afc39b9d096159b7d3287d7e29e51ec3a.tar.gz
blackbird-obmc-uboot-fdf8529afc39b9d096159b7d3287d7e29e51ec3a.zip
powerpc : spi flash : Support to start from eSPI with SPL
This patch introduces SPL to enable a loader stub that being loaded by the code from the internal on-chip ROM. It loads the final uboot image into DDR, then jump to it to begin execution. The SPL's size is sizeable, the maximum size must not exceed the size of L2 SRAM. It initializes the DDR through SPD code, and copys final uboot image to DDR. So there are two stage uboot images: * spl_boot, 96KB size. The env variables are copied to L2 SRAM, so that ddr spd code can get the interleaving mode setting in env. It loads final uboot image from offset 96KB. * final uboot image, size is variable depends on the functions enabled. Signed-off-by: Ying Zhang <b40530@freescale.com> Acked-by: York Sun <yorksun@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/spi/Makefile1
-rw-r--r--drivers/mtd/spi/fsl_espi_spl.c77
-rw-r--r--drivers/mtd/spi/spi_flash.c2
3 files changed, 80 insertions, 0 deletions
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index e537fcf54c..191138ad18 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -11,6 +11,7 @@ LIB := $(obj)libspi_flash.o
ifdef CONFIG_SPL_BUILD
COBJS-$(CONFIG_SPL_SPI_LOAD) += spi_spl_load.o
+COBJS-$(CONFIG_SPL_SPI_BOOT) += fsl_espi_spl.o
endif
COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o
diff --git a/drivers/mtd/spi/fsl_espi_spl.c b/drivers/mtd/spi/fsl_espi_spl.c
new file mode 100644
index 0000000000..9e216a6940
--- /dev/null
+++ b/drivers/mtd/spi/fsl_espi_spl.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <spi_flash.h>
+#include <malloc.h>
+
+#define ESPI_BOOT_IMAGE_SIZE 0x48
+#define ESPI_BOOT_IMAGE_ADDR 0x50
+#define CONFIG_CFG_DATA_SECTOR 0
+
+/*
+ * The main entry for SPI booting. It's necessary that SDRAM is already
+ * configured and available since this code loads the main U-Boot image
+ * from SPI into SDRAM and starts it from there.
+ */
+void spi_boot(void)
+{
+ void (*uboot)(void) __noreturn;
+ u32 offset, code_len;
+ unsigned char *buf = NULL;
+ struct spi_flash *flash;
+
+ flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
+ CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
+ if (flash == NULL) {
+ puts("\nspi_flash_probe failed");
+ hang();
+ }
+
+ /*
+ * Load U-Boot image from SPI flash into RAM
+ */
+ buf = malloc(flash->page_size);
+ if (buf == NULL) {
+ puts("\nmalloc failed");
+ hang();
+ }
+ memset(buf, 0, flash->page_size);
+
+ spi_flash_read(flash, CONFIG_CFG_DATA_SECTOR,
+ flash->page_size, (void *)buf);
+ offset = *(u32 *)(buf + ESPI_BOOT_IMAGE_ADDR);
+ /* Skip spl code */
+ offset += CONFIG_SYS_SPI_FLASH_U_BOOT_OFFS;
+ /* Get the code size from offset 0x48 */
+ code_len = *(u32 *)(buf + ESPI_BOOT_IMAGE_SIZE);
+ /* Skip spl code */
+ code_len = code_len - CONFIG_SPL_MAX_SIZE;
+ /* copy code to DDR */
+ spi_flash_read(flash, offset, code_len,
+ (void *)CONFIG_SYS_SPI_FLASH_U_BOOT_DST);
+ /*
+ * Jump to U-Boot image
+ */
+ flush_cache(CONFIG_SYS_SPI_FLASH_U_BOOT_DST, code_len);
+ uboot = (void *)CONFIG_SYS_SPI_FLASH_U_BOOT_START;
+ (*uboot)();
+}
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 9814395b93..5d5055ff38 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -555,12 +555,14 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
goto err_manufacturer_probe;
}
#endif
+#ifndef CONFIG_SPL_BUILD
printf("SF: Detected %s with page size ", flash->name);
print_size(flash->sector_size, ", total ");
print_size(flash->size, "");
if (flash->memory_map)
printf(", mapped at %p", flash->memory_map);
puts("\n");
+#endif
#ifndef CONFIG_SPI_FLASH_BAR
if (flash->size > SPI_FLASH_16MB_BOUN) {
puts("SF: Warning - Only lower 16MiB accessible,");
OpenPOWER on IntegriCloud