summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Trumtrar <s.trumtrar@pengutronix.de>2015-05-28 17:56:06 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2015-05-29 09:08:49 +0200
commit1849bfb9c13b7f91159c0722bad4d16520990958 (patch)
treedfb0e18fdd0c247ba03e847a14697c21ce0feeda
parentd96a4672e88a1d79c1f5dd54fb10ba55c283accd (diff)
downloadbarebox-1849bfb9c13b7f91159c0722bad4d16520990958.tar.gz
barebox-1849bfb9c13b7f91159c0722bad4d16520990958.tar.xz
ARM: socfpga: xload: support qspi bootsource
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--Documentation/boards/socfpga.rst56
-rw-r--r--arch/arm/mach-socfpga/include/mach/generic.h5
-rw-r--r--arch/arm/mach-socfpga/include/mach/socfpga-regs.h2
-rw-r--r--arch/arm/mach-socfpga/xload.c58
4 files changed, 115 insertions, 6 deletions
diff --git a/Documentation/boards/socfpga.rst b/Documentation/boards/socfpga.rst
index e956bccbe2..358e5ab910 100644
--- a/Documentation/boards/socfpga.rst
+++ b/Documentation/boards/socfpga.rst
@@ -11,10 +11,34 @@ build the ``socfpga-xload_defconfig``; for second stage use the normal
Bootstrapping
-------------
-The supported bootsource is a SD card. The Boot ROM searches for a partition of
-type A2 and loads what it finds there. When barebox is placed in such a partition
-it will then itself try and mount the second partition of the SD card, which must
-be of type FAT32. On this partition barebox searches for a file called barebox.bin.
+The supported bootsources are: SD card and QSPI.
+
+Bootsource selection
+^^^^^^^^^^^^^^^^^^^^
+
++--------------+-----------+-----------+
+| Board | BSEL[2:0] | CSEL[1:0] |
++==============+===========+===========+
+| Sockit SD | 0b100 | 0b00 |
++--------------+-----------+-----------+
+| Sockit QSPI | 0b110 | 0b00 |
++--------------+-----------+-----------+
+| Socrates SD | 0b101 | 0b11 |
++--------------+-----------+-----------+
+| Socrates QSPI| 0b111 | 0b11 |
++--------------+-----------+-----------+
+| SocDK SD | 0b100 | 0b00 |
++--------------+-----------+-----------+
+| SocDK QSPI | 0b110 | 0b00 |
++--------------+-----------+-----------+
+
+SD card
+^^^^^^^
+
+The Boot ROM searches for a partition of type A2 and loads what it finds there.
+When barebox is placed in such a partition it will then itself try and mount the
+second partition of the SD card, which must be of type FAT32. On this partition
+barebox searches for a file called barebox.bin.
To boot barebox on a Terasic SoCkit, the procedure is as follows (sdb1 is the A2 and
sdb2 the FAT32 partition)::
@@ -34,6 +58,30 @@ proceed with::
For the EBV Socrates use ``images/barebox-socfpga-socrates(-xload).img`` instead.
+QSPI
+^^^^
+
+The Boot ROM loads the preloader starting from address 0x0 on the QSPI flash.
+barebox then searches for a barebox image at the 256K offset and loads it.
+
+The default bootsource is SD card, so to change that to QSPI, you have to::
+
+ make socfpga-xload_defconfig
+ make menuconfig
+
+And then select the options `MTD` and `SPI_CADENCE_QUADSPI`. Now::
+
+ make
+ cat images/barebox-socfpga-<board>-xload.img > /dev/mtd0
+
+For barebox itself, the build step is like for SD card. The resulting image has to be
+written to the offset 256K.
+
+Warning! There is a known issue with booting from QSPI and doing Cold/Warm-Resets.
+Please consult `Rocketboards <http://rocketboards.org/foswiki/Documentation/SocBoardQspiBoot#Serial_Flash_Challenges>`_
+to see how to fix this.
+
+
Updating handoff files
----------------------
diff --git a/arch/arm/mach-socfpga/include/mach/generic.h b/arch/arm/mach-socfpga/include/mach/generic.h
index 2f5cda0d02..1f4247f803 100644
--- a/arch/arm/mach-socfpga/include/mach/generic.h
+++ b/arch/arm/mach-socfpga/include/mach/generic.h
@@ -15,4 +15,9 @@ static inline void __udelay(unsigned us)
for (i = 0; i < us * 3; i++);
}
+struct socfpga_barebox_part {
+ unsigned int nor_offset;
+ unsigned int nor_size;
+};
+
#endif /* __MACH_SOCFPGA_GENERIC_H */
diff --git a/arch/arm/mach-socfpga/include/mach/socfpga-regs.h b/arch/arm/mach-socfpga/include/mach/socfpga-regs.h
index b124ed675c..e88daf7189 100644
--- a/arch/arm/mach-socfpga/include/mach/socfpga-regs.h
+++ b/arch/arm/mach-socfpga/include/mach/socfpga-regs.h
@@ -2,6 +2,8 @@
#define __MACH_SOCFPGA_REGS_H
#define CYCLONE5_SDMMC_ADDRESS 0xff704000
+#define CYCLONE5_QSPI_CTRL_ADDRESS 0xff705000
+#define CYCLONE5_QSPI_DATA_ADDRESS 0xffa00000
#define CYCLONE5_FPGAMGRREGS_ADDRESS 0xff706000
#define CYCLONE5_GPIO0_BASE 0xff708000
#define CYCLONE5_GPIO1_BASE 0xff709000
diff --git a/arch/arm/mach-socfpga/xload.c b/arch/arm/mach-socfpga/xload.c
index 3380092168..272896b6bd 100644
--- a/arch/arm/mach-socfpga/xload.c
+++ b/arch/arm/mach-socfpga/xload.c
@@ -1,3 +1,4 @@
+#include <platform_data/cadence_qspi.h>
#include <platform_data/dw_mmc.h>
#include <bootsource.h>
#include <bootstrap.h>
@@ -14,11 +15,19 @@
#include <linux/stat.h>
#include <linux/clk.h>
+#include <mach/generic.h>
#include <mach/system-manager.h>
#include <mach/socfpga-regs.h>
+struct socfpga_barebox_part *barebox_part;
+
+static struct socfpga_barebox_part default_part = {
+ .nor_offset = SZ_256K,
+ .nor_size = SZ_1M,
+};
+
enum socfpga_clks {
- timer, mmc, uart, clk_max
+ timer, mmc, qspi_clk, uart, clk_max
};
static struct clk *clks[clk_max];
@@ -35,6 +44,43 @@ static void socfpga_mmc_init(void)
IORESOURCE_MEM, &mmc_pdata);
}
+#if defined(CONFIG_SPI_CADENCE_QUADSPI)
+static struct cadence_qspi_platform_data qspi_pdata = {
+ .ext_decoder = 0,
+ .fifo_depth = 128,
+};
+
+static __maybe_unused void add_cadence_qspi_device(int id, resource_size_t ctrl,
+ resource_size_t data, void *pdata)
+{
+ struct resource *res;
+
+ res = xzalloc(sizeof(struct resource) * 2);
+ res[0].start = ctrl;
+ res[0].end = ctrl + 0x100 - 1;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = data;
+ res[1].end = data + 0x100 - 1;
+ res[1].flags = IORESOURCE_MEM;
+
+ add_generic_device_res("cadence_qspi", id, res, 2, pdata);
+}
+
+static __maybe_unused void socfpga_qspi_init(void)
+{
+ clks[qspi_clk] = clk_fixed("qspi_clk", 370000000);
+ clkdev_add_physbase(clks[qspi_clk], CYCLONE5_QSPI_CTRL_ADDRESS, NULL);
+ clkdev_add_physbase(clks[qspi_clk], CYCLONE5_QSPI_DATA_ADDRESS, NULL);
+ add_cadence_qspi_device(0, CYCLONE5_QSPI_CTRL_ADDRESS,
+ CYCLONE5_QSPI_DATA_ADDRESS, &qspi_pdata);
+}
+#else
+static void socfpga_qspi_init(void)
+{
+ return;
+}
+#endif
+
static struct NS16550_plat uart_pdata = {
.clock = 100000000,
.shift = 2,
@@ -62,10 +108,19 @@ static __noreturn int socfpga_xload(void)
enum bootsource bootsource = bootsource_get();
void *buf;
+ if (!barebox_part)
+ barebox_part = &default_part;
+
switch (bootsource) {
case BOOTSOURCE_MMC:
+ socfpga_mmc_init();
buf = bootstrap_read_disk("disk0.1", "fat");
break;
+ case BOOTSOURCE_SPI:
+ socfpga_qspi_init();
+ buf = bootstrap_read_devfs("mtd0", false, barebox_part->nor_offset,
+ barebox_part->nor_size, SZ_1M);
+ break;
default:
pr_err("unknown bootsource %d\n", bootsource);
hang();
@@ -88,7 +143,6 @@ static int socfpga_devices_init(void)
barebox_set_model("SoCFPGA");
socfpga_timer_init();
socfpga_uart_init();
- socfpga_mmc_init();
barebox_main = socfpga_xload;