summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2015-06-09 09:26:44 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2015-06-09 09:26:44 +0200
commit3a32e7acd4867705f0b2b822f3dd88b25cae987a (patch)
tree0e932fd49debf707f4f514be693f84fb2642760e /arch/arm
parent61c79464481936281c83ad6a11e6df8c1c4d7743 (diff)
parent04a2c84fda15659f1ad594c88ff67f239ab9f5a6 (diff)
downloadbarebox-3a32e7acd4867705f0b2b822f3dd88b25cae987a.tar.gz
barebox-3a32e7acd4867705f0b2b822f3dd88b25cae987a.tar.xz
Merge branch 'for-next/spi-nor'
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/dts/socfpga.dtsi14
-rw-r--r--arch/arm/dts/socfpga_cyclone5_socdk.dts20
-rw-r--r--arch/arm/dts/socfpga_cyclone5_sockit.dts20
-rw-r--r--arch/arm/dts/socfpga_cyclone5_socrates.dts20
-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
7 files changed, 137 insertions, 2 deletions
diff --git a/arch/arm/dts/socfpga.dtsi b/arch/arm/dts/socfpga.dtsi
index afac867c99..14c0654b2a 100644
--- a/arch/arm/dts/socfpga.dtsi
+++ b/arch/arm/dts/socfpga.dtsi
@@ -587,6 +587,20 @@
status = "disabled";
};
+ qspi: spi@ff705000 {
+ compatible = "cdns,qspi-nor";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xff705000 0x1000>,
+ <0xffa00000 0x1000>;
+ interrupts = <0 151 4>;
+ ext-decoder = <0>; /* external decoder */
+ fifo-depth = <128>;
+ clocks = <&qspi_clk>;
+ clock-names = "qspi_clk";
+ status = "disabled";
+ };
+
/* Local timer */
timer@fffec600 {
compatible = "arm,cortex-a9-twd-timer";
diff --git a/arch/arm/dts/socfpga_cyclone5_socdk.dts b/arch/arm/dts/socfpga_cyclone5_socdk.dts
index 025d07c18c..fec321a9d5 100644
--- a/arch/arm/dts/socfpga_cyclone5_socdk.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socdk.dts
@@ -61,3 +61,23 @@
vmmc-supply = <&regulator_3_3v>;
vqmmc-supply = <&regulator_3_3v>;
};
+
+&qspi {
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q00";
+ reg = <0>;
+ spi-max-frequency = <108000000>;
+ m25p,fast-read;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+ };
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_sockit.dts b/arch/arm/dts/socfpga_cyclone5_sockit.dts
index e8e00aedfc..1c3fb4d39c 100644
--- a/arch/arm/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sockit.dts
@@ -119,3 +119,23 @@
interrupts = <0x0 0xa6 0x4>;
};
};
+
+&qspi {
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q00";
+ reg = <0>;
+ spi-max-frequency = <108000000>;
+ m25p,fast-read;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+ };
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_socrates.dts b/arch/arm/dts/socfpga_cyclone5_socrates.dts
index 7fa5e63076..125ad1b850 100644
--- a/arch/arm/dts/socfpga_cyclone5_socrates.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socrates.dts
@@ -62,3 +62,23 @@
&mmc {
status = "okay";
};
+
+&qspi {
+ status = "okay";
+
+ flash: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q00";
+ reg = <0>;
+ spi-max-frequency = <100000000>;
+ m25p,fast-read;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <4>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+ };
+};
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;