Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1563217 > unrolled thread

[PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs

Started byJoshua Clayton <stillcompiling@gmail.com>
First post2017-01-20 01:30 +0100
Last post2017-01-21 00:50 +0100
Articles 3 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs Joshua Clayton <stillcompiling@gmail.com> - 2017-01-20 01:30 +0100
    Re: [PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for  Altera FPGAs kbuild test robot <lkp@intel.com> - 2017-01-20 13:10 +0100
      Re: [PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for Altera  FPGAs Joshua Clayton <stillcompiling@gmail.com> - 2017-01-21 00:50 +0100

#1563217 — [PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs

FromJoshua Clayton <stillcompiling@gmail.com>
Date2017-01-20 01:30 +0100
Subject[PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs
Message-ID<t1vfA-8d-3@gated-at.bofh.it>
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 | 185 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 193 insertions(+)
 create mode 100644 drivers/fpga/cyclone-ps-spi.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index ce861a2..e6c032d 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -20,6 +20,13 @@ config FPGA_REGION
 	  FPGA Regions allow loading FPGA images under control of
 	  the Device Tree.
 
+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 || COMPILE_TEST
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8df07bc..a112bef 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -6,6 +6,7 @@
 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_SOCFPGA_A10)	+= socfpga-a10.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..ae9c2c8
--- /dev/null
+++ b/drivers/fpga/cyclone-ps-spi.c
@@ -0,0 +1,185 @@
+/**
+ * Altera Cyclone Passive Serial SPI Driver
+ *
+ *  Copyright (c) 2017 United Western Technologies, Corporation
+ *
+ *  Joshua Clayton <stillcompiling@gmail.com>
+ *
+ * Manage Altera FPGA firmware that is loaded over spi using the passive
+ * serial configuration method.
+ * 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,fpga-passive-serial", },
+	{}
+};
+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,
+				 struct fpga_image_info *info,
+				 const char *buf, size_t count)
+{
+	struct cyclonespi_conf *conf = (struct cyclonespi_conf *)mgr->priv;
+	int i;
+
+	if (info->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 failed to show a reset\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(char *buf, size_t len)
+{
+	const u8 *fw_end = (buf + len);
+
+	/* set buffer to lsb first */
+	while (buf < fw_end) {
+		*buf = bitrev8(*buf);
+		buf++;
+	}
+}
+
+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(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,
+				     struct fpga_image_info *info)
+{
+	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, "nconfig", 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, "nstat", 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

[toc] | [next] | [standalone]


#1563517 — Re: [PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs

Fromkbuild test robot <lkp@intel.com>
Date2017-01-20 13:10 +0100
SubjectRe: [PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs
Message-ID<t1Gb0-74R-19@gated-at.bofh.it>
In reply to#1563217
Hi Joshua,

[auto build test WARNING on linus/master]
[also build test WARNING on v4.10-rc4 next-20170120]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Joshua-Clayton/Altera-Cyclone-Passive-Serial-SPI-FPGA-Manager/20170120-172349
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   include/linux/compiler.h:253:8: sparse: attribute 'no_sanitize_address': unknown attribute
>> drivers/fpga/cyclone-ps-spi.c:86:20: sparse: incompatible types in comparison expression (different signedness)
   drivers/fpga/cyclone-ps-spi.c:101:33: sparse: incompatible types in comparison expression (different type sizes)
   drivers/fpga/cyclone-ps-spi.c: In function 'rev_buf':
   drivers/fpga/cyclone-ps-spi.c:86:13: warning: comparison of distinct pointer types lacks a cast
     while (buf < fw_end) {
                ^
   In file included from include/linux/delay.h:10:0,
                    from drivers/fpga/cyclone-ps-spi.c:17:
   drivers/fpga/cyclone-ps-spi.c: In function 'cyclonespi_write':
   include/linux/kernel.h:753:16: warning: comparison of distinct pointer types lacks a cast
     (void) (&min1 == &min2);   \
                   ^
   include/linux/kernel.h:756:2: note: in expansion of macro '__min'
     __min(typeof(x), typeof(y),   \
     ^~~~~
   drivers/fpga/cyclone-ps-spi.c:101:19: note: in expansion of macro 'min'
      size_t stride = min(fw_data_end - fw_data, SZ_4K);
                      ^~~
   drivers/fpga/cyclone-ps-spi.c:103:11: warning: passing argument 1 of 'rev_buf' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
      rev_buf(fw_data, stride);
              ^~~~~~~
   drivers/fpga/cyclone-ps-spi.c:81:13: note: expected 'char *' but argument is of type 'const char *'
    static void rev_buf(char *buf, size_t len)
                ^~~~~~~

vim +86 drivers/fpga/cyclone-ps-spi.c

    70		gpiod_set_value(conf->config, 0);
    71		for (i = 0; i < (FPGA_MAX_DELAY / FPGA_MIN_DELAY); i++) {
    72			usleep_range(FPGA_MIN_DELAY, FPGA_MIN_DELAY + 20);
    73			if (!gpiod_get_value(conf->status))
    74				return 0;
    75		}
    76	
    77		dev_err(&mgr->dev, "Status pin not ready.\n");
    78		return -EIO;
    79	}
    80	
    81	static void rev_buf(char *buf, size_t len)
    82	{
    83		const u8 *fw_end = (buf + len);
    84	
    85		/* set buffer to lsb first */
  > 86		while (buf < fw_end) {
    87			*buf = bitrev8(*buf);
    88			buf++;
    89		}
    90	}
    91	
    92	static int cyclonespi_write(struct fpga_manager *mgr, const char *buf,
    93				    size_t count)
    94	{

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[toc] | [prev] | [next] | [standalone]


#1563996 — Re: [PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs

FromJoshua Clayton <stillcompiling@gmail.com>
Date2017-01-21 00:50 +0100
SubjectRe: [PATCH v7 2/3] fpga manager: Add cyclone-ps-spi driver for Altera FPGAs
Message-ID<t1R6p-5hF-11@gated-at.bofh.it>
In reply to#1563517
Sigh...
On 01/20/2017 04:07 AM, kbuild test robot wrote:
> Hi Joshua,
>
> [auto build test WARNING on linus/master]
> [also build test WARNING on v4.10-rc4 next-20170120]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Joshua-Clayton/Altera-Cyclone-Passive-Serial-SPI-FPGA-Manager/20170120-172349
> reproduce:
>         # apt-get install sparse
>         make ARCH=x86_64 allmodconfig
>         make C=1 CF=-D__CHECK_ENDIAN__
>
>
> sparse warnings: (new ones prefixed by >>)
>
>    include/linux/compiler.h:253:8: sparse: attribute 'no_sanitize_address': unknown attribute
>>> drivers/fpga/cyclone-ps-spi.c:86:20: sparse: incompatible types in comparison expression (different signedness)
>    drivers/fpga/cyclone-ps-spi.c:101:33: sparse: incompatible types in comparison expression (different type sizes)
>    drivers/fpga/cyclone-ps-spi.c: In function 'rev_buf':
>    drivers/fpga/cyclone-ps-spi.c:86:13: warning: comparison of distinct pointer types lacks a cast
>      while (buf < fw_end) {
>                 ^
>    In file included from include/linux/delay.h:10:0,
>                     from drivers/fpga/cyclone-ps-spi.c:17:
>    drivers/fpga/cyclone-ps-spi.c: In function 'cyclonespi_write':
>    include/linux/kernel.h:753:16: warning: comparison of distinct pointer types lacks a cast
>      (void) (&min1 == &min2);   \
>                    ^
>    include/linux/kernel.h:756:2: note: in expansion of macro '__min'
>      __min(typeof(x), typeof(y),   \
>      ^~~~~
>    drivers/fpga/cyclone-ps-spi.c:101:19: note: in expansion of macro 'min'
>       size_t stride = min(fw_data_end - fw_data, SZ_4K);
>                       ^~~
>    drivers/fpga/cyclone-ps-spi.c:103:11: warning: passing argument 1 of 'rev_buf' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
>       rev_buf(fw_data, stride);
>               ^~~~~~~
>    drivers/fpga/cyclone-ps-spi.c:81:13: note: expected 'char *' but argument is of type 'const char *'
>     static void rev_buf(char *buf, size_t len)
>                 ^~~~~~~
>
> vim +86 drivers/fpga/cyclone-ps-spi.c
>
>     70		gpiod_set_value(conf->config, 0);
>     71		for (i = 0; i < (FPGA_MAX_DELAY / FPGA_MIN_DELAY); i++) {
>     72			usleep_range(FPGA_MIN_DELAY, FPGA_MIN_DELAY + 20);
>     73			if (!gpiod_get_value(conf->status))
>     74				return 0;
>     75		}
>     76	
>     77		dev_err(&mgr->dev, "Status pin not ready.\n");
>     78		return -EIO;
>     79	}
>     80	
>     81	static void rev_buf(char *buf, size_t len)
>     82	{
>     83		const u8 *fw_end = (buf + len);
Bah!
u8 * should be char *
>     84	
>     85		/* set buffer to lsb first */
>   > 86		while (buf < fw_end) {
>     87			*buf = bitrev8(*buf);
>     88			buf++;
>     89		}
>     90	}
>     91	
>     92	static int cyclonespi_write(struct fpga_manager *mgr, const char *buf,
>     93				    size_t count)
>     94	{
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Guess I had better add sparse to my pre send regimen.
v8 posted shortly.
~Joshua

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web