summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-layerscape/Makefile1
-rw-r--r--arch/arm/mach-layerscape/include/mach/xload.h2
-rw-r--r--arch/arm/mach-layerscape/xload-qspi.c37
-rw-r--r--images/Makefile.layerscape6
-rw-r--r--scripts/pblimage.c17
5 files changed, 62 insertions, 1 deletions
diff --git a/arch/arm/mach-layerscape/Makefile b/arch/arm/mach-layerscape/Makefile
index ad4e2f7af3..4705154fb1 100644
--- a/arch/arm/mach-layerscape/Makefile
+++ b/arch/arm/mach-layerscape/Makefile
@@ -3,3 +3,4 @@ lwl-y += lowlevel.o errata.o
lwl-$(CONFIG_ARCH_LS1046) += lowlevel-ls1046a.o
obj-y += icid.o
obj-pbl-y += boot.o
+pbl-y += xload-qspi.o
diff --git a/arch/arm/mach-layerscape/include/mach/xload.h b/arch/arm/mach-layerscape/include/mach/xload.h
index fedd36e020..94756ed13d 100644
--- a/arch/arm/mach-layerscape/include/mach/xload.h
+++ b/arch/arm/mach-layerscape/include/mach/xload.h
@@ -2,5 +2,7 @@
#define __MACH_XLOAD_H
int ls1046a_esdhc_start_image(unsigned long r0, unsigned long r1, unsigned long r2);
+int ls1046a_qspi_start_image(unsigned long r0, unsigned long r1,
+ unsigned long r2);
#endif /* __MACH_XLOAD_H */
diff --git a/arch/arm/mach-layerscape/xload-qspi.c b/arch/arm/mach-layerscape/xload-qspi.c
new file mode 100644
index 0000000000..c76780a0e8
--- /dev/null
+++ b/arch/arm/mach-layerscape/xload-qspi.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <common.h>
+#include <soc/fsl/immap_lsch2.h>
+#include <asm-generic/sections.h>
+#include <asm/cache.h>
+#include <mach/xload.h>
+#include <mach/layerscape.h>
+
+/*
+ * The offset of the 2nd stage image in the output file. This must match with the
+ * offset the pblimage tool puts barebox to.
+ */
+#define BAREBOX_START (128 * 1024)
+
+int ls1046a_qspi_start_image(unsigned long r0, unsigned long r1,
+ unsigned long r2)
+{
+ void *qspi_reg_base = IOMEM(LSCH2_QSPI0_BASE_ADDR);
+ void *membase = (void *)LS1046A_DDR_SDRAM_BASE;
+ void *qspi_mem_base = IOMEM(0x40000000);
+ void (*barebox)(unsigned long, unsigned long, unsigned long) = membase;
+
+ /* Switch controller into little endian mode */
+ out_be32(qspi_reg_base, 0x000f400c);
+
+ memcpy(membase, qspi_mem_base + BAREBOX_START, barebox_image_size);
+ icache_invalidate();
+
+ printf("Starting barebox\n");
+
+ barebox(r0, r1, r2);
+
+ printf("failed\n");
+
+ return -EIO;
+}
diff --git a/images/Makefile.layerscape b/images/Makefile.layerscape
index 59f672791b..38e6648729 100644
--- a/images/Makefile.layerscape
+++ b/images/Makefile.layerscape
@@ -14,6 +14,12 @@ quiet_cmd_lspbl_image = LSPBL-IMG $@
$(objtree)/scripts/pblimage -o $@ -r $(lspbl-rcw-tmp) \
-m $($(patsubst $(obj)/%.pblb,PBL_CODE_SIZE_%,$<)) -p $(lspbl-pbi-tmp) -i $<
+quiet_cmd_lspbl_spi_image = LSPBL-SPI-IMG $@
+ cmd_lspbl_spi_image = $(CPP) $(lspbl_cfg_cpp_flags) -o $(lspbl-rcw-tmp) $(word 2,$^) ; \
+ $(CPP) $(lspbl_cfg_cpp_flags) -o $(lspbl-pbi-tmp) $(word 3,$^) ; \
+ $(objtree)/scripts/pblimage -o $@ -r $(lspbl-rcw-tmp) -s \
+ -m $($(patsubst $(obj)/%.pblb,PBL_CODE_SIZE_%,$<)) -p $(lspbl-pbi-tmp) -i $<
+
pbl-$(CONFIG_MACH_LS1046ARDB) += start_ls1046ardb.pbl
$(obj)/barebox-ls1046ardb-2nd.image: $(obj)/start_ls1046ardb.pblb
$(call if_changed,shipped)
diff --git a/scripts/pblimage.c b/scripts/pblimage.c
index 56256260c8..73c0169ac1 100644
--- a/scripts/pblimage.c
+++ b/scripts/pblimage.c
@@ -13,6 +13,7 @@
#include <stdint.h>
#include <getopt.h>
#include <endian.h>
+#include <byteswap.h>
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
#define PBL_ACS_CONT_CMD 0x81000000
@@ -49,6 +50,7 @@ static int pbl_end;
static int image_size;
static int out_fd;
static int in_fd;
+static int spiimage;
static uint32_t pbl_cmd_initaddr;
static uint32_t pbi_crc_cmd1;
@@ -229,6 +231,7 @@ static void add_end_cmd(void)
static void pbl_load_image(void)
{
int size;
+ uint64_t *buf64 = (void *)mem_buf;
/* parse the rcw.cfg file. */
pbl_parser(rcwfile);
@@ -245,6 +248,15 @@ static void pbl_load_image(void)
add_end_cmd();
+ if (spiimage) {
+ int i;
+
+ pbl_size = roundup(pbl_size, 8);
+
+ for (i = 0; i < pbl_size / 8; i++)
+ buf64[i] = bswap_64(buf64[i]);
+ }
+
size = pbl_size;
if (write(out_fd, (const void *)&mem_buf, size) != size) {
@@ -338,7 +350,7 @@ int main(int argc, char *argv[])
int opt, ret;
off_t pos;
- while ((opt = getopt(argc, argv, "i:r:p:o:m:")) != -1) {
+ while ((opt = getopt(argc, argv, "i:r:p:o:m:s")) != -1) {
switch (opt) {
case 'i':
infile = optarg;
@@ -355,6 +367,9 @@ int main(int argc, char *argv[])
case 'm':
pbl_end = atoi(optarg);
break;
+ case 's':
+ spiimage = 1;
+ break;
default:
exit(EXIT_FAILURE);
}