Re: [PATCH v12 3/6] fpga manager: Add altera-ps-spi driver for Altera FPGAs

2017-06-05 Thread Alan Tull
On Fri, Jun 2, 2017 at 3:30 PM, Joshua Clayton  wrote:
> altera-ps-spi loads FPGA firmware over SPI, using the "passive serial"
> interface on Altera Arria 10, Cyclone V or Stratix V 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 
> Signed-off-by: Anatolij Gustschin 

Signed-off-by: Alan Tull 

> ---
>  drivers/fpga/Kconfig |   7 +
>  drivers/fpga/Makefile|   1 +
>  drivers/fpga/altera-ps-spi.c | 297 
> +++
>  3 files changed, 305 insertions(+)
>  create mode 100644 drivers/fpga/altera-ps-spi.c
>
> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
> index 161ba9dccede..00e4cae7b79e 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -26,6 +26,13 @@ config FPGA_MGR_ICE40_SPI
> help
>   FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
>
> +config FPGA_MGR_ALTERA_PS_SPI
> +   tristate "Altera FPGA Passive Serial over SPI"
> +   depends on SPI || COMPILE_TEST
> +   help
> + FPGA manager driver support for Altera Arria/Cyclone/Stratix
> + 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 2a4f0218145c..e75d3570e26a 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_ALTERA_PS_SPI)   += altera-ps-spi.o
>  obj-$(CONFIG_FPGA_MGR_ICE40_SPI)   += ice40-spi.o
>  obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
>  obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
> diff --git a/drivers/fpga/altera-ps-spi.c b/drivers/fpga/altera-ps-spi.c
> new file mode 100644
> index ..0db8def668ed
> --- /dev/null
> +++ b/drivers/fpga/altera-ps-spi.c
> @@ -0,0 +1,297 @@
> +/*
> + * Altera Passive Serial SPI Driver
> + *
> + *  Copyright (c) 2017 United Western Technologies, Corporation
> + *
> + *  Joshua Clayton 
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * Manage Altera FPGA firmware that is loaded over SPI using the passive
> + * serial configuration method.
> + * Firmware must be in binary "rbf" format.
> + * Works on Arria 10, Cyclone V and Stratix V. Should work on Cyclone series.
> + * May work on other Altera FPGAs.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +enum altera_ps_devtype {
> +   CYCLONE5,
> +   ARRIA10,
> +};
> +
> +struct altera_ps_data {
> +   enum altera_ps_devtype devtype;
> +   int status_wait_min_us;
> +   int status_wait_max_us;
> +   int t_cfg_us;
> +   int t_st2ck_us;
> +};
> +
> +struct altera_ps_conf {
> +   struct gpio_desc *config;
> +   struct gpio_desc *confd;
> +   struct gpio_desc *status;
> +   struct spi_device *spi;
> +   const struct altera_ps_data *data;
> +   u32 info_flags;
> +   char mgr_name[64];
> +};
> +
> +/*  |   Arria 10  |   Cyclone5  |   Stratix5  |
> + * t_CF2ST0 | [; 600] | [; 600] | [; 600] |ns
> + * t_CFG|[2;] |[2;] |[2;] |µs
> + * t_STATUS | [268; 3000] | [268; 1506] | [268; 1506] |µs
> + * t_CF2ST1 |[; 3000] |[; 1506] |[; 1506] |µs
> + * t_CF2CK  | [3010;] | [1506;] | [1506;] |µs
> + * t_ST2CK  |   [10;] |[2;] |[2;] |µs
> + * t_CD2UM  |  [175; 830] |  [175; 437] |  [175; 437] |µs
> + */
> +static struct altera_ps_data c5_data = {
> +   /* these values for Cyclone5 are compatible with Stratix5 */
> +   .devtype = CYCLONE5,
> +   .status_wait_min_us = 268,
> +   .status_wait_max_us = 1506,
> +   .t_cfg_us = 2,
> +   .t_st2ck_us = 2,
> +};
> +
> +static struct altera_ps_data a10_data = {
> +   .devtype = ARRIA10,
> +   .status_wait_min_us = 268,  /* min(t_STATUS) */
> +   .status_wait_max_us = 3000, /* max(t_CF2ST1) */
> +   .t_cfg_us = 2,/* max { min(t_CFG), max(tCF2ST0) } */
> +   .t_st2ck_us = 10, /* min(t_ST2CK) */
> +};
> +
> +static const struct of_device_id of_ef_match[] = {
> +   { .compatible = "altr,fpga-passive-serial", .data = &c5_data },
> +   { .compatible = "altr,fpga-arria10-passive-serial", .data = &a10_data 
> },
> +   {}
> +};
> +MODULE_DEVICE_TABLE(of, of_ef_match);
> +
> +static enum fpga_mgr_states altera_ps_state(struct fpga_manager *mgr)
> +{
> +   struct altera_ps_conf *conf = mgr->priv;
> +
> +   if (gpiod_get_value_cansleep(conf->status))
> + 

[PATCH v12 3/6] fpga manager: Add altera-ps-spi driver for Altera FPGAs

2017-06-02 Thread Joshua Clayton
altera-ps-spi loads FPGA firmware over SPI, using the "passive serial"
interface on Altera Arria 10, Cyclone V or Stratix V 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 
Signed-off-by: Anatolij Gustschin 
---
 drivers/fpga/Kconfig |   7 +
 drivers/fpga/Makefile|   1 +
 drivers/fpga/altera-ps-spi.c | 297 +++
 3 files changed, 305 insertions(+)
 create mode 100644 drivers/fpga/altera-ps-spi.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 161ba9dccede..00e4cae7b79e 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -26,6 +26,13 @@ config FPGA_MGR_ICE40_SPI
help
  FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
 
+config FPGA_MGR_ALTERA_PS_SPI
+   tristate "Altera FPGA Passive Serial over SPI"
+   depends on SPI || COMPILE_TEST
+   help
+ FPGA manager driver support for Altera Arria/Cyclone/Stratix
+ 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 2a4f0218145c..e75d3570e26a 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_ALTERA_PS_SPI)   += altera-ps-spi.o
 obj-$(CONFIG_FPGA_MGR_ICE40_SPI)   += ice40-spi.o
 obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
 obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
diff --git a/drivers/fpga/altera-ps-spi.c b/drivers/fpga/altera-ps-spi.c
new file mode 100644
index ..0db8def668ed
--- /dev/null
+++ b/drivers/fpga/altera-ps-spi.c
@@ -0,0 +1,297 @@
+/*
+ * Altera Passive Serial SPI Driver
+ *
+ *  Copyright (c) 2017 United Western Technologies, Corporation
+ *
+ *  Joshua Clayton 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * Manage Altera FPGA firmware that is loaded over SPI using the passive
+ * serial configuration method.
+ * Firmware must be in binary "rbf" format.
+ * Works on Arria 10, Cyclone V and Stratix V. Should work on Cyclone series.
+ * May work on other Altera FPGAs.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum altera_ps_devtype {
+   CYCLONE5,
+   ARRIA10,
+};
+
+struct altera_ps_data {
+   enum altera_ps_devtype devtype;
+   int status_wait_min_us;
+   int status_wait_max_us;
+   int t_cfg_us;
+   int t_st2ck_us;
+};
+
+struct altera_ps_conf {
+   struct gpio_desc *config;
+   struct gpio_desc *confd;
+   struct gpio_desc *status;
+   struct spi_device *spi;
+   const struct altera_ps_data *data;
+   u32 info_flags;
+   char mgr_name[64];
+};
+
+/*  |   Arria 10  |   Cyclone5  |   Stratix5  |
+ * t_CF2ST0 | [; 600] | [; 600] | [; 600] |ns
+ * t_CFG|[2;] |[2;] |[2;] |µs
+ * t_STATUS | [268; 3000] | [268; 1506] | [268; 1506] |µs
+ * t_CF2ST1 |[; 3000] |[; 1506] |[; 1506] |µs
+ * t_CF2CK  | [3010;] | [1506;] | [1506;] |µs
+ * t_ST2CK  |   [10;] |[2;] |[2;] |µs
+ * t_CD2UM  |  [175; 830] |  [175; 437] |  [175; 437] |µs
+ */
+static struct altera_ps_data c5_data = {
+   /* these values for Cyclone5 are compatible with Stratix5 */
+   .devtype = CYCLONE5,
+   .status_wait_min_us = 268,
+   .status_wait_max_us = 1506,
+   .t_cfg_us = 2,
+   .t_st2ck_us = 2,
+};
+
+static struct altera_ps_data a10_data = {
+   .devtype = ARRIA10,
+   .status_wait_min_us = 268,  /* min(t_STATUS) */
+   .status_wait_max_us = 3000, /* max(t_CF2ST1) */
+   .t_cfg_us = 2,/* max { min(t_CFG), max(tCF2ST0) } */
+   .t_st2ck_us = 10, /* min(t_ST2CK) */
+};
+
+static const struct of_device_id of_ef_match[] = {
+   { .compatible = "altr,fpga-passive-serial", .data = &c5_data },
+   { .compatible = "altr,fpga-arria10-passive-serial", .data = &a10_data },
+   {}
+};
+MODULE_DEVICE_TABLE(of, of_ef_match);
+
+static enum fpga_mgr_states altera_ps_state(struct fpga_manager *mgr)
+{
+   struct altera_ps_conf *conf = mgr->priv;
+
+   if (gpiod_get_value_cansleep(conf->status))
+   return FPGA_MGR_STATE_RESET;
+
+   return FPGA_MGR_STATE_UNKNOWN;
+}
+
+static inline void altera_ps_delay(int delay_us)
+{
+   if (delay_us > 10)
+   usleep_range(delay_us, delay_us + 5);
+   else
+   udelay(delay_us);
+}
+
+static int altera_ps_write_init(struct fpga_manager *mgr,
+   struct fpg