diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-06-09 09:26:44 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-06-09 09:26:44 +0200 |
commit | 3a32e7acd4867705f0b2b822f3dd88b25cae987a (patch) | |
tree | 0e932fd49debf707f4f514be693f84fb2642760e /arch | |
parent | 61c79464481936281c83ad6a11e6df8c1c4d7743 (diff) | |
parent | 04a2c84fda15659f1ad594c88ff67f239ab9f5a6 (diff) | |
download | barebox-3a32e7acd4867705f0b2b822f3dd88b25cae987a.tar.gz barebox-3a32e7acd4867705f0b2b822f3dd88b25cae987a.tar.xz |
Merge branch 'for-next/spi-nor'
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/dts/socfpga.dtsi | 14 | ||||
-rw-r--r-- | arch/arm/dts/socfpga_cyclone5_socdk.dts | 20 | ||||
-rw-r--r-- | arch/arm/dts/socfpga_cyclone5_sockit.dts | 20 | ||||
-rw-r--r-- | arch/arm/dts/socfpga_cyclone5_socrates.dts | 20 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/generic.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/include/mach/socfpga-regs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-socfpga/xload.c | 58 |
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 = <®ulator_3_3v>; vqmmc-supply = <®ulator_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; |