summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-layerscape
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-layerscape')
-rw-r--r--arch/arm/mach-layerscape/Makefile2
-rw-r--r--arch/arm/mach-layerscape/boot.c39
-rw-r--r--arch/arm/mach-layerscape/include/mach/bbu.h22
-rw-r--r--arch/arm/mach-layerscape/include/mach/layerscape.h2
-rw-r--r--arch/arm/mach-layerscape/include/mach/xload.h4
-rw-r--r--arch/arm/mach-layerscape/xload-qspi.c37
-rw-r--r--arch/arm/mach-layerscape/xload.c24
7 files changed, 130 insertions, 0 deletions
diff --git a/arch/arm/mach-layerscape/Makefile b/arch/arm/mach-layerscape/Makefile
index 269839254b..73cd61a7cf 100644
--- a/arch/arm/mach-layerscape/Makefile
+++ b/arch/arm/mach-layerscape/Makefile
@@ -2,3 +2,5 @@ obj- := __dummy__.o
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 xload.o
diff --git a/arch/arm/mach-layerscape/boot.c b/arch/arm/mach-layerscape/boot.c
new file mode 100644
index 0000000000..c804977d22
--- /dev/null
+++ b/arch/arm/mach-layerscape/boot.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <common.h>
+#include <init.h>
+#include <bootsource.h>
+#include <mach/layerscape.h>
+#include <soc/fsl/immap_lsch2.h>
+
+enum bootsource ls1046_bootsource_get(void)
+{
+ void __iomem *dcfg = IOMEM(LSCH2_DCFG_ADDR);
+ uint32_t rcw_src;
+
+ rcw_src = in_be32(dcfg) >> 23;
+
+ if (rcw_src == 0x40)
+ return BOOTSOURCE_MMC;
+ if ((rcw_src & 0x1fe) == 0x44)
+ return BOOTSOURCE_SPI_NOR;
+ if ((rcw_src & 0x1f0) == 0x10)
+ /* 8bit NOR Flash */
+ return BOOTSOURCE_NOR;
+ if ((rcw_src & 0x1f0) == 0x20)
+ /* 16bit NOR Flash */
+ return BOOTSOURCE_NOR;
+
+ return BOOTSOURCE_UNKNOWN;
+}
+
+static int ls1046a_bootsource_init(void)
+{
+ if (!of_machine_is_compatible("fsl,ls1046a"))
+ return 0;
+
+ bootsource_set(ls1046_bootsource_get());
+
+ return 0;
+}
+coredevice_initcall(ls1046a_bootsource_init); \ No newline at end of file
diff --git a/arch/arm/mach-layerscape/include/mach/bbu.h b/arch/arm/mach-layerscape/include/mach/bbu.h
new file mode 100644
index 0000000000..1ea0cbb11f
--- /dev/null
+++ b/arch/arm/mach-layerscape/include/mach/bbu.h
@@ -0,0 +1,22 @@
+#ifndef __MACH_LAYERSCAPE_BBU_H
+#define __MACH_LAYERSCAPE_BBU_H
+
+#include <bbu.h>
+
+static inline int ls1046a_bbu_mmc_register_handler(const char *name,
+ const char *devicefile,
+ unsigned long flags)
+{
+ return bbu_register_std_file_update(name, flags, devicefile,
+ filetype_layerscape_image);
+}
+
+static inline int ls1046a_bbu_qspi_register_handler(const char *name,
+ const char *devicefile,
+ unsigned long flags)
+{
+ return bbu_register_std_file_update(name, flags, devicefile,
+ filetype_layerscape_qspi_image);
+}
+
+#endif /* __MACH_LAYERSCAPE_BBU_H */ \ No newline at end of file
diff --git a/arch/arm/mach-layerscape/include/mach/layerscape.h b/arch/arm/mach-layerscape/include/mach/layerscape.h
index 55e0b7bc96..3366e7f258 100644
--- a/arch/arm/mach-layerscape/include/mach/layerscape.h
+++ b/arch/arm/mach-layerscape/include/mach/layerscape.h
@@ -4,4 +4,6 @@
#define LS1046A_DDR_SDRAM_BASE 0x80000000
#define LS1046A_DDR_FREQ 2100000000
+enum bootsource ls1046_bootsource_get(void);
+
#endif /* __MACH_LAYERSCAPE_H */
diff --git a/arch/arm/mach-layerscape/include/mach/xload.h b/arch/arm/mach-layerscape/include/mach/xload.h
index fedd36e020..eb2d998865 100644
--- a/arch/arm/mach-layerscape/include/mach/xload.h
+++ b/arch/arm/mach-layerscape/include/mach/xload.h
@@ -2,5 +2,9 @@
#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);
+int ls1046a_xload_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/arch/arm/mach-layerscape/xload.c b/arch/arm/mach-layerscape/xload.c
new file mode 100644
index 0000000000..54495d7f97
--- /dev/null
+++ b/arch/arm/mach-layerscape/xload.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <common.h>
+#include <bootsource.h>
+#include <mach/layerscape.h>
+#include <mach/xload.h>
+
+int ls1046a_xload_start_image(unsigned long r0, unsigned long r1,
+ unsigned long r2)
+{
+ enum bootsource src;
+
+ src = ls1046_bootsource_get();
+
+ switch (src) {
+ case BOOTSOURCE_SPI_NOR:
+ return ls1046a_qspi_start_image(r0, r1, r2);
+ case BOOTSOURCE_MMC:
+ return ls1046a_esdhc_start_image(r0, r1, r2);
+ default:
+ pr_err("Unknown bootsource\n");
+ return -EINVAL;
+ }
+}