* [PATCH v4 0/3] Altera Cyclone Passive Serial SPI FPGA Manager @ 2016-12-01 17:04 Joshua Clayton 2016-12-01 17:04 ` [PATCH v4 1/3] lib: add bitrev8x4() Joshua Clayton ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Joshua Clayton @ 2016-12-01 17:04 UTC (permalink / raw) To: Alan Tull, Moritz Fischer, Rob Herring, Mark Rutland, Russell King Cc: Joshua Clayton, devicetree, linux-kernel, linux-arm-kernel This series adds an FPGA manager for Altera cyclone FPGAs that can program them using an spi port and a couple of gpios, using Alteras passive serial protocol. Changes from v3: - Fixed up the state() function to return the state of the status pin reqested by Alan Tull - Switched the pin to ACTIVE_LOW and coresponding logic level, and updated the corresponding documentation. Thanks Rob Herring for pointing out my mistake. - Per Rob Herring, switched from "gpio" to "gpios" in dts Changes from v2: - Merged patch 3 and 4 as suggested in review by Moritz Fischer - Changed FPGA_MIN_DELAY from 250 to 50 ms is the time advertized by Altera. This now works, as we don't assume it is done Changes from v1: - Changed the name from cyclone-spi-fpga-mgr to cyclone-ps-spi-fpga-mgr This name change was requested by Alan Tull, to be specific about which programming method is being employed on the fpga. - Changed the name of the reset-gpio to config-gpio to closer match the way the pins are described in the Altera manual - Moved MODULE_LICENCE, _AUTHOR, and _DESCRIPTION to the bottom - Added a bitrev8x4() function to the bitrev headers and implemented ARM const, runtime, and ARM specific faster versions (This may end up needing to be a standalone patch) - Moved the bitswapping into cyclonespi_write(), as requested. This falls short of my desired generic lsb first spi support, but is a step in that direction. - Fixed whitespace problems introduced during refactoring - Replaced magic number for initial delay with a descriptive macro - Poll the fpga to see when it is ready rather than a fixed 1 ms sleep Joshua Clayton (3): lib: add bitrev8x4() doc: dt: add cyclone-spi binding document fpga manager: Add cyclone-ps-spi driver for Altera FPGAs .../bindings/fpga/cyclone-ps-spi-fpga-mgr.txt | 25 +++ arch/arm/include/asm/bitrev.h | 5 + drivers/fpga/Kconfig | 7 + drivers/fpga/Makefile | 1 + drivers/fpga/cyclone-ps-spi.c | 181 +++++++++++++++++++++ include/linux/bitrev.h | 26 +++ 6 files changed, 245 insertions(+) create mode 100644 Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt create mode 100644 drivers/fpga/cyclone-ps-spi.c -- 2.9.3 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v4 1/3] lib: add bitrev8x4() 2016-12-01 17:04 [PATCH v4 0/3] Altera Cyclone Passive Serial SPI FPGA Manager Joshua Clayton @ 2016-12-01 17:04 ` Joshua Clayton 2016-12-01 22:45 ` Anatolij Gustschin 2016-12-01 17:04 ` [PATCH v4 2/3] doc: dt: add cyclone-spi binding document Joshua Clayton 2016-12-01 17:04 ` [PATCH v4 3/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs Joshua Clayton 2 siblings, 1 reply; 9+ messages in thread From: Joshua Clayton @ 2016-12-01 17:04 UTC (permalink / raw) To: Alan Tull, Moritz Fischer, Rob Herring, Mark Rutland, Russell King Cc: Joshua Clayton, devicetree, linux-kernel, linux-arm-kernel Add a function to reverse bytes within a 32 bit word. This function is more efficient than using the 8 bit version when iterating over an array Signed-off-by: Joshua Clayton <stillcompiling@gmail.com> --- Looking for an ACK from Russell King on this patch (or at least the arm specific implementation) arch/arm/include/asm/bitrev.h | 5 +++++ include/linux/bitrev.h | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/arch/arm/include/asm/bitrev.h b/arch/arm/include/asm/bitrev.h index ec291c3..6d2e9ca 100644 --- a/arch/arm/include/asm/bitrev.h +++ b/arch/arm/include/asm/bitrev.h @@ -17,4 +17,9 @@ static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x) return __arch_bitrev32((u32)x) >> 24; } +static __always_inline __attribute_const__ u32 __arch_bitrev8x4(u32 x) +{ + __asm__ ("rbit %0, %1; rev %0, %0" : "=r" (x) : "r" (x)); +} + #endif diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h index fb790b8..b1cfa1a 100644 --- a/include/linux/bitrev.h +++ b/include/linux/bitrev.h @@ -9,6 +9,7 @@ #define __bitrev32 __arch_bitrev32 #define __bitrev16 __arch_bitrev16 #define __bitrev8 __arch_bitrev8 +#define __bitrev8x4 __arch_bitrev8x4 #else extern u8 const byte_rev_table[256]; @@ -27,6 +28,14 @@ static inline u32 __bitrev32(u32 x) return (__bitrev16(x & 0xffff) << 16) | __bitrev16(x >> 16); } +static inline u32 __bitrev8x4(u32 x) +{ + return(__bitrev8(x & 0xff) | + (__bitrev8((x >> 8) & 0xff) << 8) | + (__bitrev8((x >> 16) & 0xff) << 16) | + (__bitrev8((x >> 24) & 0xff) << 24)); +} + #endif /* CONFIG_HAVE_ARCH_BITREVERSE */ #define __constant_bitrev32(x) \ @@ -50,6 +59,15 @@ static inline u32 __bitrev32(u32 x) __x; \ }) +#define __constant_bitrev8x4(x) \ +({ \ + u32 __x = x; \ + __x = ((__x & (u32)0xF0F0F0F0UL) >> 4) | ((__x & (u32)0x0F0F0F0FUL) << 4); \ + __x = ((__x & (u32)0xCCCCCCCCUL) >> 2) | ((__x & (u32)0x33333333UL) << 2); \ + __x = ((__x & (u32)0xAAAAAAAAUL) >> 1) | ((__x & (u32)0x55555555UL) << 1); \ + __x; \ +}) + #define __constant_bitrev8(x) \ ({ \ u8 __x = x; \ @@ -75,6 +93,14 @@ static inline u32 __bitrev32(u32 x) __bitrev16(__x); \ }) +#define bitrev8x4(x) \ +({ \ + u32 __x = x; \ + __builtin_constant_p(__x) ? \ + __constant_bitrev8x4(__x) : \ + __bitrev8x4(__x); \ +}) + #define bitrev8(x) \ ({ \ u8 __x = x; \ -- 2.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/3] lib: add bitrev8x4() 2016-12-01 17:04 ` [PATCH v4 1/3] lib: add bitrev8x4() Joshua Clayton @ 2016-12-01 22:45 ` Anatolij Gustschin 2016-12-02 0:04 ` Joshua Clayton 0 siblings, 1 reply; 9+ messages in thread From: Anatolij Gustschin @ 2016-12-01 22:45 UTC (permalink / raw) To: Joshua Clayton Cc: Mark Rutland, Moritz Fischer, devicetree, Alan Tull, Russell King, linux-kernel, Rob Herring, linux-arm-kernel On Thu, 1 Dec 2016 09:04:50 -0800 Joshua Clayton stillcompiling@gmail.com wrote: ... >diff --git a/arch/arm/include/asm/bitrev.h b/arch/arm/include/asm/bitrev.h >index ec291c3..6d2e9ca 100644 >--- a/arch/arm/include/asm/bitrev.h >+++ b/arch/arm/include/asm/bitrev.h >@@ -17,4 +17,9 @@ static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x) > return __arch_bitrev32((u32)x) >> 24; > } > >+static __always_inline __attribute_const__ u32 __arch_bitrev8x4(u32 x) >+{ >+ __asm__ ("rbit %0, %1; rev %0, %0" : "=r" (x) : "r" (x)); return x; >+} otherwise you get In function '__arch_bitrev8x4': warning: no return statement in function returning non-void [-Wreturn-type] -- Anatolij ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/3] lib: add bitrev8x4() 2016-12-01 22:45 ` Anatolij Gustschin @ 2016-12-02 0:04 ` Joshua Clayton [not found] ` <8fb2f1c2-c39c-b74f-d5c8-d6731cbd67c8-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 0 siblings, 1 reply; 9+ messages in thread From: Joshua Clayton @ 2016-12-02 0:04 UTC (permalink / raw) To: Anatolij Gustschin Cc: Alan Tull, Moritz Fischer, Rob Herring, Mark Rutland, Russell King, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r Hello Anatolij, Thanks for the review. On 12/01/2016 02:45 PM, Anatolij Gustschin wrote: > On Thu, 1 Dec 2016 09:04:50 -0800 > Joshua Clayton stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote: > ... >> diff --git a/arch/arm/include/asm/bitrev.h b/arch/arm/include/asm/bitrev.h >> index ec291c3..6d2e9ca 100644 >> --- a/arch/arm/include/asm/bitrev.h >> +++ b/arch/arm/include/asm/bitrev.h >> @@ -17,4 +17,9 @@ static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x) >> return __arch_bitrev32((u32)x) >> 24; >> } >> >> +static __always_inline __attribute_const__ u32 __arch_bitrev8x4(u32 x) >> +{ >> + __asm__ ("rbit %0, %1; rev %0, %0" : "=r" (x) : "r" (x)); > return x; Oops thats a little embarrassing; I'll add a return. >> +} > otherwise you get > > In function '__arch_bitrev8x4': > warning: no return statement in function returning non-void [-Wreturn-type] > > -- > Anatolij I wonder why I do not see this warning when compiling. The inlining, maybe? Joshua -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <8fb2f1c2-c39c-b74f-d5c8-d6731cbd67c8-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>]
* Re: [PATCH v4 1/3] lib: add bitrev8x4() [not found] ` <8fb2f1c2-c39c-b74f-d5c8-d6731cbd67c8-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> @ 2016-12-02 7:51 ` Anatolij Gustschin 0 siblings, 0 replies; 9+ messages in thread From: Anatolij Gustschin @ 2016-12-02 7:51 UTC (permalink / raw) To: Joshua Clayton Cc: Alan Tull, Moritz Fischer, Rob Herring, Mark Rutland, Russell King, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r Hi Joshua, On Thu, 1 Dec 2016 16:04:09 -0800 Joshua Clayton stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote: ... >>> +static __always_inline __attribute_const__ u32 __arch_bitrev8x4(u32 x) >>> +{ >>> + __asm__ ("rbit %0, %1; rev %0, %0" : "=r" (x) : "r" (x)); >> return x; >Oops thats a little embarrassing; >I'll add a return. >>> +} >> otherwise you get >> >> In function '__arch_bitrev8x4': >> warning: no return statement in function returning non-void [-Wreturn-type] >> > >I wonder why I do not see this warning when compiling. The inlining, maybe? do you have CONFIG_HAVE_ARCH_BITREVERSE=y in your .config? Probably not optimized code is used, otherwise you will send wrong data to FPGA (due to wrong return values from __arch_bitrev8x4). Anatolij -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v4 2/3] doc: dt: add cyclone-spi binding document 2016-12-01 17:04 [PATCH v4 0/3] Altera Cyclone Passive Serial SPI FPGA Manager Joshua Clayton 2016-12-01 17:04 ` [PATCH v4 1/3] lib: add bitrev8x4() Joshua Clayton @ 2016-12-01 17:04 ` Joshua Clayton [not found] ` <137f03de76e5f865430b17ca247e8f73e3315c8d.1480551148.git.stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2016-12-01 17:04 ` [PATCH v4 3/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs Joshua Clayton 2 siblings, 1 reply; 9+ messages in thread From: Joshua Clayton @ 2016-12-01 17:04 UTC (permalink / raw) To: Alan Tull, Moritz Fischer, Rob Herring, Mark Rutland, Russell King Cc: Joshua Clayton, devicetree, linux-kernel, linux-arm-kernel Describe a cyclonei-ps-spi devicetree entry, required features Signed-off-by: Joshua Clayton <stillcompiling@gmail.com> --- .../bindings/fpga/cyclone-ps-spi-fpga-mgr.txt | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt diff --git a/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt new file mode 100644 index 0000000..3f515c7 --- /dev/null +++ b/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt @@ -0,0 +1,25 @@ +Altera Cyclone Passive Serial SPI FPGA Manager + +Altera Cyclone FPGAs support a method of loading the bitstream over what is +referred to as "passive serial". +The passive serial link is not technically spi, and might require extra +circuits in order to play nicely with other spi slaves on the same bus. + +See https://www.altera.com/literature/hb/cyc/cyc_c51013.pdf + +Required properties: +- compatible : should contain "altr,cyclone-ps-spi-fpga-mgr" +- reg : spi slave id of the fpga +- config-gpios : config pin (referred to as nCONFIG in the cyclone manual) +- status-gpios : status pin (referred to as nSTATUS in the cyclone manual) + +both gpio pins are normally active low open drain. + +Example: + fpga_spi: evi-fpga-spi@0 { + compatible = "altr,cyclone-ps-spi-fpga-mgr"; + spi-max-frequency = <20000000>; + reg = <0>; + config-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; + status-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; + }; -- 2.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
[parent not found: <137f03de76e5f865430b17ca247e8f73e3315c8d.1480551148.git.stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>]
* Re: [PATCH v4 2/3] doc: dt: add cyclone-spi binding document [not found] ` <137f03de76e5f865430b17ca247e8f73e3315c8d.1480551148.git.stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> @ 2016-12-01 17:41 ` Moritz Fischer 2016-12-06 16:05 ` Rob Herring 1 sibling, 0 replies; 9+ messages in thread From: Moritz Fischer @ 2016-12-01 17:41 UTC (permalink / raw) To: Joshua Clayton Cc: Alan Tull, Rob Herring, Mark Rutland, Russell King, Devicetree List, Linux Kernel Mailing List, linux-arm-kernel On Thu, Dec 1, 2016 at 9:04 AM, Joshua Clayton <stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > Describe a cyclonei-ps-spi devicetree entry, required features > > Signed-off-by: Joshua Clayton <stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> Acked-by: Moritz Fischer <moritz.fischer-+aYTwkv1SeIAvxtiuMwx3w@public.gmane.org> > --- > > .../bindings/fpga/cyclone-ps-spi-fpga-mgr.txt | 25 ++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > create mode 100644 Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt > > diff --git a/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt b/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt > new file mode 100644 > index 0000000..3f515c7 > --- /dev/null > +++ b/Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt > @@ -0,0 +1,25 @@ > +Altera Cyclone Passive Serial SPI FPGA Manager > + > +Altera Cyclone FPGAs support a method of loading the bitstream over what is > +referred to as "passive serial". > +The passive serial link is not technically spi, and might require extra > +circuits in order to play nicely with other spi slaves on the same bus. > + > +See https://www.altera.com/literature/hb/cyc/cyc_c51013.pdf > + > +Required properties: > +- compatible : should contain "altr,cyclone-ps-spi-fpga-mgr" > +- reg : spi slave id of the fpga > +- config-gpios : config pin (referred to as nCONFIG in the cyclone manual) > +- status-gpios : status pin (referred to as nSTATUS in the cyclone manual) > + > +both gpio pins are normally active low open drain. > + > +Example: > + fpga_spi: evi-fpga-spi@0 { > + compatible = "altr,cyclone-ps-spi-fpga-mgr"; > + spi-max-frequency = <20000000>; > + reg = <0>; > + config-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; > + status-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; > + }; > -- > 2.9.3 > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 2/3] doc: dt: add cyclone-spi binding document [not found] ` <137f03de76e5f865430b17ca247e8f73e3315c8d.1480551148.git.stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2016-12-01 17:41 ` Moritz Fischer @ 2016-12-06 16:05 ` Rob Herring 1 sibling, 0 replies; 9+ messages in thread From: Rob Herring @ 2016-12-06 16:05 UTC (permalink / raw) To: Joshua Clayton Cc: Alan Tull, Moritz Fischer, Mark Rutland, Russell King, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r On Thu, Dec 01, 2016 at 09:04:51AM -0800, Joshua Clayton wrote: > Describe a cyclonei-ps-spi devicetree entry, required features cyclonei? > > Signed-off-by: Joshua Clayton <stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > --- > > .../bindings/fpga/cyclone-ps-spi-fpga-mgr.txt | 25 ++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > create mode 100644 Documentation/devicetree/bindings/fpga/cyclone-ps-spi-fpga-mgr.txt Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v4 3/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs 2016-12-01 17:04 [PATCH v4 0/3] Altera Cyclone Passive Serial SPI FPGA Manager Joshua Clayton 2016-12-01 17:04 ` [PATCH v4 1/3] lib: add bitrev8x4() Joshua Clayton 2016-12-01 17:04 ` [PATCH v4 2/3] doc: dt: add cyclone-spi binding document Joshua Clayton @ 2016-12-01 17:04 ` Joshua Clayton 2 siblings, 0 replies; 9+ messages in thread From: Joshua Clayton @ 2016-12-01 17:04 UTC (permalink / raw) To: Alan Tull, Moritz Fischer, Rob Herring, Mark Rutland, Russell King Cc: Joshua Clayton, devicetree, linux-kernel, linux-arm-kernel cyclone-ps-spi loads FPGA firmware over spi, using the "passive serial" interface on Altera Cyclone FPGAS. This is one of the simpler ways to set up an FPGA at runtime. The signal interface is close to unidirectional spi with lsb first. Signed-off-by: Joshua Clayton <stillcompiling@gmail.com> --- drivers/fpga/Kconfig | 7 ++ drivers/fpga/Makefile | 1 + drivers/fpga/cyclone-ps-spi.c | 181 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 drivers/fpga/cyclone-ps-spi.c diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index cd84934..2462707 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -13,6 +13,13 @@ config FPGA if FPGA +config FPGA_MGR_CYCLONE_PS_SPI + tristate "Altera Cyclone FPGA Passive Serial over SPI" + depends on SPI + help + FPGA manager driver support for Altera Cyclone using the + passive serial interface over SPI + config FPGA_MGR_SOCFPGA tristate "Altera SOCFPGA FPGA Manager" depends on ARCH_SOCFPGA diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile index 8d83fc6..8f93930 100644 --- a/drivers/fpga/Makefile +++ b/drivers/fpga/Makefile @@ -6,5 +6,6 @@ obj-$(CONFIG_FPGA) += fpga-mgr.o # FPGA Manager Drivers +obj-$(CONFIG_FPGA_MGR_CYCLONE_PS_SPI) += cyclone-ps-spi.o obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA) += zynq-fpga.o diff --git a/drivers/fpga/cyclone-ps-spi.c b/drivers/fpga/cyclone-ps-spi.c new file mode 100644 index 0000000..82a754a --- /dev/null +++ b/drivers/fpga/cyclone-ps-spi.c @@ -0,0 +1,181 @@ +/** + * Copyright (c) 2015 United Western Technologies, Corporation + * + * Joshua Clayton <stillcompiling@gmail.com> + * + * Manage Altera fpga firmware that is loaded over spi. + * Firmware must be in binary "rbf" format. + * Works on Cyclone V. Should work on cyclone series. + * May work on other Altera fpgas. + * + */ + +#include <linux/bitrev.h> +#include <linux/delay.h> +#include <linux/fpga/fpga-mgr.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/of_gpio.h> +#include <linux/spi/spi.h> +#include <linux/sizes.h> + +#define FPGA_RESET_TIME 50 /* time in usecs to trigger FPGA config */ +#define FPGA_MIN_DELAY 50 /* min usecs to wait for config status */ +#define FPGA_MAX_DELAY 1000 /* max usecs to wait for config status */ + +struct cyclonespi_conf { + struct gpio_desc *config; + struct gpio_desc *status; + struct spi_device *spi; +}; + +static const struct of_device_id of_ef_match[] = { + { .compatible = "altr,cyclone-ps-spi-fpga-mgr", }, + {} +}; +MODULE_DEVICE_TABLE(of, of_ef_match); + +static enum fpga_mgr_states cyclonespi_state(struct fpga_manager *mgr) +{ + struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv; + + if (gpiod_get_value(conf->status)) + return FPGA_MGR_STATE_RESET; + + return FPGA_MGR_STATE_UNKNOWN; +} + +static int cyclonespi_write_init(struct fpga_manager *mgr, u32 flags, + const char *buf, size_t count) +{ + struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv; + int i; + + if (flags & FPGA_MGR_PARTIAL_RECONFIG) { + dev_err(&mgr->dev, "Partial reconfiguration not supported.\n"); + return -EINVAL; + } + + gpiod_set_value(conf->config, 1); + usleep_range(FPGA_RESET_TIME, FPGA_RESET_TIME + 20); + if (!gpiod_get_value(conf->status)) { + dev_err(&mgr->dev, "Status pin should be low.\n"); + return -EIO; + } + + gpiod_set_value(conf->config, 0); + for (i = 0; i < (FPGA_MAX_DELAY / FPGA_MIN_DELAY); i++) { + usleep_range(FPGA_MIN_DELAY, FPGA_MIN_DELAY + 20); + if (!gpiod_get_value(conf->status)) + return 0; + } + + dev_err(&mgr->dev, "Status pin not ready.\n"); + return -EIO; +} + +static void rev_buf(void *buf, size_t len) +{ + u32 *fw32 = (u32 *)buf; + const u32 *fw_end = (u32 *)(buf + len); + + /* set buffer to lsb first */ + while (fw32 < fw_end) { + *fw32 = bitrev8x4(*fw32); + fw32++; + } +} + +static int cyclonespi_write(struct fpga_manager *mgr, const char *buf, + size_t count) +{ + struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv; + const char *fw_data = buf; + const char *fw_data_end = fw_data + count; + + while (fw_data < fw_data_end) { + int ret; + size_t stride = min(fw_data_end - fw_data, SZ_4K); + + rev_buf((void *)fw_data, stride); + ret = spi_write(conf->spi, fw_data, stride); + if (ret) { + dev_err(&mgr->dev, "spi error in firmware write: %d\n", + ret); + return ret; + } + fw_data += stride; + } + + return 0; +} + +static int cyclonespi_write_complete(struct fpga_manager *mgr, u32 flags) +{ + struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv; + + if (gpiod_get_value(conf->status)) { + dev_err(&mgr->dev, "Error during configuration.\n"); + return -EIO; + } + + return 0; +} + +static const struct fpga_manager_ops cyclonespi_ops = { + .state = cyclonespi_state, + .write_init = cyclonespi_write_init, + .write = cyclonespi_write, + .write_complete = cyclonespi_write_complete, +}; + +static int cyclonespi_probe(struct spi_device *spi) +{ + struct cyclonespi_conf *conf = devm_kzalloc(&spi->dev, sizeof(*conf), + GFP_KERNEL); + + if (!conf) + return -ENOMEM; + + conf->spi = spi; + conf->config = devm_gpiod_get(&spi->dev, "config", GPIOD_OUT_HIGH); + if (IS_ERR(conf->config)) { + dev_err(&spi->dev, "Failed to get config gpio: %ld\n", + PTR_ERR(conf->config)); + return PTR_ERR(conf->config); + } + + conf->status = devm_gpiod_get(&spi->dev, "status", GPIOD_IN); + if (IS_ERR(conf->status)) { + dev_err(&spi->dev, "Failed to get status gpio: %ld\n", + PTR_ERR(conf->status)); + return PTR_ERR(conf->status); + } + + return fpga_mgr_register(&spi->dev, + "Altera Cyclone PS SPI FPGA Manager", + &cyclonespi_ops, conf); +} + +static int cyclonespi_remove(struct spi_device *spi) +{ + fpga_mgr_unregister(&spi->dev); + + return 0; +} + +static struct spi_driver cyclonespi_driver = { + .driver = { + .name = "cyclone-ps-spi", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(of_ef_match), + }, + .probe = cyclonespi_probe, + .remove = cyclonespi_remove, +}; + +module_spi_driver(cyclonespi_driver) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Joshua Clayton <stillcompiling@gmail.com>"); +MODULE_DESCRIPTION("Module to load Altera FPGA firmware over spi"); -- 2.9.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-12-06 16:05 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-12-01 17:04 [PATCH v4 0/3] Altera Cyclone Passive Serial SPI FPGA Manager Joshua Clayton 2016-12-01 17:04 ` [PATCH v4 1/3] lib: add bitrev8x4() Joshua Clayton 2016-12-01 22:45 ` Anatolij Gustschin 2016-12-02 0:04 ` Joshua Clayton [not found] ` <8fb2f1c2-c39c-b74f-d5c8-d6731cbd67c8-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2016-12-02 7:51 ` Anatolij Gustschin 2016-12-01 17:04 ` [PATCH v4 2/3] doc: dt: add cyclone-spi binding document Joshua Clayton [not found] ` <137f03de76e5f865430b17ca247e8f73e3315c8d.1480551148.git.stillcompiling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> 2016-12-01 17:41 ` Moritz Fischer 2016-12-06 16:05 ` Rob Herring 2016-12-01 17:04 ` [PATCH v4 3/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs Joshua Clayton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).