mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* (no subject)
@ 2013-11-12 14:31 Sascha Hauer
  2013-11-12 14:31 ` [PATCH 1/4] Add a Firmware programming framework Sascha Hauer
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Sascha Hauer @ 2013-11-12 14:31 UTC (permalink / raw)
  To: barebox; +Cc: jbe

v2 of the firmware programming framework.

Changes since v1:

- Create a device file under /dev/ and let the firmwareload command
  use it. This way the user has a choice whether to cp directly to
  the device or to use the provided command
- Rename everything from 'fpga' to 'firmware' since the stuff is useful
  for DSPs and other devices needing firmware aswell.
- Add a SoCFPGA FPGA firmware driver as second user

Sascha

----------------------------------------------------------------
Juergen Beisert (2):
      Add a Firmware programming framework
      Firmware: provide a handler to program Altera FPGAs

Sascha Hauer (2):
      DT: Add binding for Altera FPGAs in passive-serial mode
      Firmware: socfpga: Add SoCFPGA FPGA program support

 .../bindings/firmware/altr,passive-serial.txt      |  13 +
 arch/arm/dts/socfpga_cyclone5.dtsi                 |   5 +
 arch/arm/mach-socfpga/Makefile                     |   1 +
 arch/arm/mach-socfpga/include/mach/socfpga-regs.h  |   2 +
 commands/Kconfig                                   |   8 +
 commands/Makefile                                  |   1 +
 commands/firmwareload.c                            |  67 ++++
 common/Kconfig                                     |   3 +
 common/Makefile                                    |   1 +
 common/firmware.c                                  | 207 ++++++++++
 drivers/Kconfig                                    |   1 +
 drivers/Makefile                                   |   1 +
 drivers/firmware/Kconfig                           |  14 +
 drivers/firmware/Makefile                          |   2 +
 drivers/firmware/altera_serial.c                   | 307 +++++++++++++++
 drivers/firmware/socfpga.c                         | 437 +++++++++++++++++++++
 include/firmware.h                                 |  42 ++
 17 files changed, 1112 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
 create mode 100644 commands/firmwareload.c
 create mode 100644 common/firmware.c
 create mode 100644 drivers/firmware/Kconfig
 create mode 100644 drivers/firmware/Makefile
 create mode 100644 drivers/firmware/altera_serial.c
 create mode 100644 drivers/firmware/socfpga.c
 create mode 100644 include/firmware.h

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/4] Add a Firmware programming framework
  2013-11-12 14:31 Sascha Hauer
@ 2013-11-12 14:31 ` Sascha Hauer
  2013-11-12 14:31 ` [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs Sascha Hauer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 12+ messages in thread
From: Sascha Hauer @ 2013-11-12 14:31 UTC (permalink / raw)
  To: barebox; +Cc: Juergen Beisert

From: Juergen Beisert <jbe@pengutronix.de>

This framework handles a list of registered Firmware programming handlers
to unify a firmware programming interface by hiding the details how
to program a specific Firmware in its handler. This is created with FPGAs
in mind but should be usable for other devices aswell.
A user has two possibilities to load a firmware. A device file is create
under /dev/ which can be used to copy a firmware to. Additionally a
firmwareload command is introduced which can list the registered firmware
handlers and also to upload a firmware.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/Kconfig        |   8 ++
 commands/Makefile       |   1 +
 commands/firmwareload.c |  67 ++++++++++++++++
 common/Kconfig          |   3 +
 common/Makefile         |   1 +
 common/firmware.c       | 207 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/firmware.h      |  42 ++++++++++
 7 files changed, 329 insertions(+)
 create mode 100644 commands/firmwareload.c
 create mode 100644 common/firmware.c
 create mode 100644 include/firmware.h

diff --git a/commands/Kconfig b/commands/Kconfig
index 9738ec4..3d2c198 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -605,6 +605,14 @@ config CMD_BAREBOX_UPDATE
 	select BAREBOX_UPDATE
 	prompt "barebox-update"
 
+config CMD_FIRMWARELOAD
+	bool
+	select FIRMWARE
+	prompt "firmwareload"
+	help
+	  Provides the "firmwareload" command which deals with devices which need
+	  firmware to work. It is also used to upload firmware to FPGA devices.
+
 config CMD_TIMEOUT
 	tristate
 	prompt "timeout"
diff --git a/commands/Makefile b/commands/Makefile
index 58d27fa..6130c8f 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -93,3 +93,4 @@ obj-$(CONFIG_CMD_MIITOOL)	+= miitool.o
 obj-$(CONFIG_CMD_DETECT)	+= detect.o
 obj-$(CONFIG_CMD_BOOT)		+= boot.o
 obj-$(CONFIG_CMD_DEVINFO)	+= devinfo.o
+obj-$(CONFIG_CMD_FIRMWARELOAD)	+= firmwareload.o
diff --git a/commands/firmwareload.c b/commands/firmwareload.c
new file mode 100644
index 0000000..16326f4
--- /dev/null
+++ b/commands/firmwareload.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013 Juergen Beisert <kernel@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <getopt.h>
+#include <firmware.h>
+
+static int do_firmwareload(int argc, char *argv[])
+{
+	int ret, opt;
+	const char *name = NULL, *firmware;
+	struct firmware_mgr *mgr;
+
+	while ((opt = getopt(argc, argv, "t:l")) > 0) {
+		switch (opt) {
+		case 't':
+			name = optarg;
+			break;
+		case 'l':
+			firmwaremgr_list_handlers();
+			return 0;
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+	}
+
+	if (!(argc - optind))
+		return COMMAND_ERROR_USAGE;
+
+	firmware = argv[optind];
+
+	mgr = firmwaremgr_find(name);
+
+	if (!mgr) {
+		printf("No such programming handler found: %s\n",
+				name ? name : "default");
+		return 1;
+	}
+
+	ret = firmwaremgr_load_file(mgr, firmware);
+
+	return ret;
+}
+
+BAREBOX_CMD_HELP_START(firmwareload)
+BAREBOX_CMD_HELP_USAGE("firmwareload [OPTIONS] <firmware>\n")
+BAREBOX_CMD_HELP_SHORT("Program a firmware file into a device\n")
+BAREBOX_CMD_HELP_OPT("-t <target>", "define the firmware handler by name\n")
+BAREBOX_CMD_HELP_OPT("-l\t", "list devices capable of firmware loading\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(firmwareload)
+	.cmd = do_firmwareload,
+	.usage = "program a firmware",
+	BAREBOX_CMD_HELP(cmd_firmwareload_help)
+BAREBOX_CMD_END
diff --git a/common/Kconfig b/common/Kconfig
index ccfbc80..375b979 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -297,6 +297,9 @@ config MAXARGS
 	prompt "max. Number of arguments accepted for monitor commands"
 	default 16
 
+config FIRMWARE
+	bool
+
 choice
 	prompt "Select your shell"
 
diff --git a/common/Makefile b/common/Makefile
index 6f6e360..76d24db 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -48,6 +48,7 @@ obj-y += bootsource.o
 obj-$(CONFIG_BOOTM) += bootm.o
 extra-$(CONFIG_MODULES) += module.lds
 extra-y += barebox_default_env barebox_default_env.h
+obj-$(CONFIG_FIRMWARE) += firmware.o
 
 ifdef CONFIG_DEFAULT_ENVIRONMENT
 $(obj)/startup.o: $(obj)/barebox_default_env.h
diff --git a/common/firmware.c b/common/firmware.c
new file mode 100644
index 0000000..7cb1e83
--- /dev/null
+++ b/common/firmware.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2013 Juergen Beisert <kernel@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <firmware.h>
+#include <common.h>
+#include <malloc.h>
+#include <xfuncs.h>
+#include <fcntl.h>
+#include <libbb.h>
+#include <fs.h>
+#include <linux/list.h>
+#include <linux/stat.h>
+#include <linux/err.h>
+
+#define BUFSIZ 4096
+
+struct firmware_mgr {
+	struct list_head list;
+	struct firmware_handler *handler; /* the program handler */
+	struct cdev cdev;
+	u8 buf[BUFSIZ];
+	int ofs;
+};
+
+static LIST_HEAD(firmwaremgr_list);
+
+/*
+ * firmwaremgr_find - find a firmware device handler
+ *
+ * Find a firmware device handler based on the unique id. If @id is
+ * NULL this returns the single firmware device handler if only one
+ * is registered. If multiple handlers are registered @id is mandatory
+ *
+ */
+struct firmware_mgr *firmwaremgr_find(const char *id)
+{
+	struct firmware_mgr *mgr;
+
+	if (!id) {
+		if (list_is_singular(&firmwaremgr_list))
+			return list_first_entry(&firmwaremgr_list,
+					struct firmware_mgr, list);
+		else
+			return NULL;
+	}
+
+	list_for_each_entry(mgr, &firmwaremgr_list, list)
+		if (!strcmp(mgr->handler->id, id))
+			return mgr;
+
+	return NULL;
+}
+
+/*
+ * firmwaremgr_list_handlers - list registered firmware device handlers
+ *                             in pretty format
+ */
+void firmwaremgr_list_handlers(void)
+{
+	struct firmware_mgr *mgr;
+
+	printf("firmware programming handlers:\n\n");
+
+	if (list_empty(&firmwaremgr_list)) {
+		printf("(none)\n");
+		return;
+	}
+
+	printf("%-11s%-11s\n", "name:", "model:");
+
+	list_for_each_entry(mgr, &firmwaremgr_list, list) {
+		printf("%-11s", mgr->handler->id);
+		if (mgr->handler->model)
+			printf("%-11s", mgr->handler->model);
+		printf("\n");
+	}
+}
+
+static int firmware_open(struct cdev *cdev, unsigned long flags)
+{
+	struct firmware_mgr *mgr = cdev->priv;
+	int ret;
+
+	mgr->ofs = 0;
+
+	ret = mgr->handler->open(mgr->handler);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static ssize_t firmware_write(struct cdev *cdev, const void *buf, size_t insize,
+		loff_t offset, ulong flags)
+{
+	struct firmware_mgr *mgr = cdev->priv;
+	int ret;
+	size_t count = insize;
+
+	/*
+	 * We guarantee the write handler of the firmware device that only the
+	 * last write is a short write. All others are 4k in size.
+	 */
+
+	while (count) {
+		size_t space = BUFSIZ - mgr->ofs;
+		size_t now = min(count, space);
+
+		memcpy(mgr->buf + mgr->ofs, buf, now);
+
+		buf += now;
+		mgr->ofs += now;
+		count -= now;
+
+		if (mgr->ofs == BUFSIZ) {
+			ret = mgr->handler->write(mgr->handler, mgr->buf, BUFSIZ);
+			if (ret < 0)
+				return ret;
+
+			mgr->ofs = 0;
+		}
+	}
+
+	return insize;
+}
+
+static int firmware_close(struct cdev *cdev)
+{
+	struct firmware_mgr *mgr = cdev->priv;
+	int ret;
+
+	if (mgr->ofs) {
+		ret = mgr->handler->write(mgr->handler, mgr->buf, mgr->ofs);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static struct file_operations firmware_ops = {
+	.open = firmware_open,
+	.write = firmware_write,
+	.close = firmware_close,
+};
+
+/*
+ * firmwaremgr_register - register a device which needs firmware
+ */
+int firmwaremgr_register(struct firmware_handler *fh)
+{
+	struct firmware_mgr *mgr;
+	int ret;
+	struct cdev *cdev;
+
+	if (firmwaremgr_find(fh->id))
+		return -EBUSY;
+
+	mgr = xzalloc(sizeof(struct firmware_mgr));
+	mgr->handler = fh;
+
+	cdev = &mgr->cdev;
+
+	cdev->name = xstrdup(fh->id);
+	cdev->size = FILE_SIZE_STREAM;
+	cdev->ops = &firmware_ops;
+	cdev->priv = mgr;
+	cdev->dev = fh->dev;
+
+	ret = devfs_create(cdev);
+	if (ret)
+		goto out;
+
+	list_add_tail(&mgr->list, &firmwaremgr_list);
+
+	return 0;
+out:
+	free(cdev->name);
+	free(mgr);
+
+	return ret;
+}
+
+/*
+ * firmware_load_file - load a firmware to a device
+ */
+int firmwaremgr_load_file(struct firmware_mgr *mgr, const char *firmware)
+{
+	int ret;
+	char *name = asprintf("/dev/%s", mgr->handler->id);
+
+	ret = copy_file(firmware, name, 0);
+
+	free(name);
+
+	return ret;
+}
diff --git a/include/firmware.h b/include/firmware.h
new file mode 100644
index 0000000..f6f78c8
--- /dev/null
+++ b/include/firmware.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013 Juergen Beisert <kernel@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef FIRMWARE_H
+#define FIRMWARE_H
+
+#include <types.h>
+#include <driver.h>
+
+struct firmware_handler {
+	char *id; /* unique identifier for this firmware device */
+	char *model; /* description for this device */
+	struct device_d *dev;
+	/* called once to prepare the firmware's programming cycle */
+	int (*open)(struct firmware_handler*);
+	/* called multiple times to program the firmware with the given data */
+	int (*write)(struct firmware_handler*, const void*, size_t);
+	/* called once to finish programming cycle */
+	int (*close)(struct firmware_handler*);
+};
+
+struct firmware_mgr;
+
+int firmwaremgr_register(struct firmware_handler *);
+
+struct firmware_mgr *firmwaremgr_find(const char *);
+
+void firmwaremgr_list_handlers(void);
+
+int firmwaremgr_load_file(struct firmware_mgr *, const char *path);
+
+#endif /* FIRMWARE_H */
-- 
1.8.4.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs
  2013-11-12 14:31 Sascha Hauer
  2013-11-12 14:31 ` [PATCH 1/4] Add a Firmware programming framework Sascha Hauer
@ 2013-11-12 14:31 ` Sascha Hauer
  2013-11-12 14:46   ` Jürgen Beisert
  2013-11-12 16:03   ` Jean-Christophe PLAGNIOL-VILLARD
  2013-11-12 14:31 ` [PATCH 3/4] DT: Add binding for Altera FPGAs in passive-serial mode Sascha Hauer
  2013-11-12 14:31 ` [PATCH 4/4] Firmware: socfpga: Add SoCFPGA FPGA program support Sascha Hauer
  3 siblings, 2 replies; 12+ messages in thread
From: Sascha Hauer @ 2013-11-12 14:31 UTC (permalink / raw)
  To: barebox; +Cc: Juergen Beisert

From: Juergen Beisert <jbe@pengutronix.de>

This handler uses a regular SPI master and a few GPIOs to program an
Altera FPGA in serial mode.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/Kconfig                  |   1 +
 drivers/Makefile                 |   1 +
 drivers/firmware/Kconfig         |  11 ++
 drivers/firmware/Makefile        |   1 +
 drivers/firmware/altera_serial.c | 307 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 321 insertions(+)
 create mode 100644 drivers/firmware/Kconfig
 create mode 100644 drivers/firmware/Makefile
 create mode 100644 drivers/firmware/altera_serial.c

diff --git a/drivers/Kconfig b/drivers/Kconfig
index d34d2c7..71d840c 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -25,5 +25,6 @@ source "drivers/gpio/Kconfig"
 source "drivers/w1/Kconfig"
 source "drivers/pinctrl/Kconfig"
 source "drivers/bus/Kconfig"
+source "drivers/firmware/Kconfig"
 
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index ba1dc6d..bf03d54 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_OFTREE) += of/
 obj-$(CONFIG_W1) += w1/
 obj-y += pinctrl/
 obj-y += bus/
+obj-y += firmware/
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
new file mode 100644
index 0000000..28a173b
--- /dev/null
+++ b/drivers/firmware/Kconfig
@@ -0,0 +1,11 @@
+menu "Firmware Drivers"
+
+config FIRMWARE_ALTERA_SERIAL
+	bool "Altera SPI programming"
+	depends on OFDEVICE
+	select FIRMWARE
+	help
+	  Programming an Altera FPGA via a few GPIOs for the control lines and
+	  MOSI, MISO and clock from an SPI interface for the data lines
+
+endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
new file mode 100644
index 0000000..ec6a5a1
--- /dev/null
+++ b/drivers/firmware/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
diff --git a/drivers/firmware/altera_serial.c b/drivers/firmware/altera_serial.c
new file mode 100644
index 0000000..047b6bd
--- /dev/null
+++ b/drivers/firmware/altera_serial.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2013 Juergen Beisert <kernel@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <firmware.h>
+#include <of_gpio.h>
+#include <xfuncs.h>
+#include <malloc.h>
+#include <gpio.h>
+#include <clock.h>
+#include <spi/spi.h>
+
+#include <fcntl.h>
+#include <fs.h>
+
+/*
+ * Physical requirements:
+ * - three free GPIOs for the signals nCONFIG, CONFIGURE_DONE, nSTATUS
+ * - 32 bit per word, LSB first capable SPI master (MOSI + clock)
+ *
+ * Example how to configure this driver via device tree
+ *
+ *	fpga@0 {
+ *		compatible = "altera_serial";
+ *		nstat-gpio = <&gpio4 18 0>;
+ *		confd-gpio = <&gpio4 19 0>;
+ *		nconfig-gpio = <&gpio4 20 0>;
+ *		spi-max-frequency = <10000000>;
+ *		reg = <0>;
+ *	};
+ */
+
+struct fpga_spi {
+	struct firmware_handler fh;
+	int nstat_gpio; /* input GPIO to read the status line */
+	int confd_gpio; /* input GPIO to read the config done line */
+	int nconfig_gpio; /* output GPIO to start the FPGA's config */
+	struct device_d *dev;
+	struct spi_device *spi;
+	bool padding_done;
+};
+
+static int altera_spi_open(struct firmware_handler *fh)
+{
+	struct fpga_spi *this = container_of(fh, struct fpga_spi, fh);
+	struct device_d *dev = this->dev;
+	int ret;
+
+	dev_dbg(dev, "Initiating programming\n");
+
+	/* initiate an FPGA programming */
+	gpio_set_value(this->nconfig_gpio, 0);
+
+	/*
+	 * after about 2 µs the FPGA must acknowledge with
+	 * STATUS and CONFIG DONE lines at low level
+	 */
+	ret = wait_on_timeout(2 * 1000,
+				(gpio_get_value(this->nstat_gpio) == 0) &&
+				(gpio_get_value(this->confd_gpio) == 0));
+
+	if (ret != 0) {
+		dev_err(dev, "FPGA does not acknowledge the programming initiation\n");
+		if (gpio_get_value(this->nstat_gpio))
+			dev_err(dev, "STATUS is still high!\n");
+		if (gpio_get_value(this->confd_gpio))
+			dev_err(dev, "CONFIG DONE is still high!\n");
+		return ret;
+	}
+
+	/* arm the FPGA to await its new firmware */
+	gpio_set_value(this->nconfig_gpio, 1);
+
+	/* once again, we might need padding the data */
+	this->padding_done = false;
+
+	/*
+	 * after about 1506 µs the FPGA must acknowledge this step
+	 * with the STATUS line at high level
+	 */
+	ret = wait_on_timeout(1600 * 1000,
+				gpio_get_value(this->nstat_gpio) == 1);
+	if (ret != 0) {
+		dev_err(dev, "FPGA does not acknowledge the programming start\n");
+		return ret;
+	}
+
+	dev_dbg(dev, "Initiating passed\n");
+	/* at the end, wait at least 2 µs prior beginning writing data */
+	ndelay(2 * 1000);
+
+	return 0;
+}
+
+static int altera_spi_write(struct firmware_handler *fh, const void *buf, size_t sz)
+{
+	struct fpga_spi *this = container_of(fh, struct fpga_spi, fh);
+	struct device_d *dev = this->dev;
+	struct spi_transfer t[2];
+	struct spi_message m;
+	u32 dummy;
+	int ret;
+
+	printf("%s: %d\n", __func__, sz);
+
+	spi_message_init(&m);
+
+	if (sz < sizeof(u32)) {
+		/* simple padding */
+		dummy = 0;
+		memcpy(&dummy, buf, sz);
+		buf = &dummy;
+		sz = sizeof(u32);
+		this->padding_done = true;
+	}
+
+	t[0].tx_buf = buf;
+	t[0].rx_buf = NULL;
+	t[0].len = sz;
+	spi_message_add_tail(&t[0], &m);
+
+	if (sz & 0x3) { /* padding required? */
+		u32 *word_buf = (u32 *)buf;
+		dummy = 0;
+		memcpy(&dummy, &word_buf[sz >> 2], sz & 0x3);
+		t[0].len &= ~0x03;
+		t[1].tx_buf = &dummy;
+		t[1].rx_buf = NULL;
+		t[1].len = sizeof(u32);
+		spi_message_add_tail(&t[1], &m);
+		this->padding_done = true;
+	}
+
+	ret = spi_sync(this->spi, &m);
+	if (ret != 0)
+		dev_err(dev, "programming failure\n");
+
+	return ret;
+}
+
+static int altera_spi_close(struct firmware_handler *fh)
+{
+	struct fpga_spi *this = container_of(fh, struct fpga_spi, fh);
+	struct device_d *dev = this->dev;
+	struct spi_transfer t;
+	struct spi_message m;
+	u32 dummy = 0;
+	int ret;
+
+	dev_dbg(dev, "Finalize programming\n");
+
+	if (this->padding_done == false) {
+		spi_message_init(&m);
+		t.tx_buf = &dummy;
+		t.rx_buf = NULL;
+		t.len = sizeof(dummy);
+		spi_message_add_tail(&t, &m);
+
+		ret = spi_sync(this->spi, &m);
+		if (ret != 0)
+			dev_err(dev, "programming failure\n");
+	}
+
+	/*
+	 * when programming was successfully,
+	 * both status lines should be at high level
+	 */
+	ret = wait_on_timeout(10 * 1000,
+				(gpio_get_value(this->nstat_gpio) == 1) &&
+				(gpio_get_value(this->confd_gpio) == 1));
+	if (ret == 0) {
+		dev_dbg(dev, "Programming successfull\n");
+		return ret;
+	}
+
+	dev_err(dev, "Programming failed due to time out\n");
+	if (gpio_get_value(this->nstat_gpio) == 0)
+		dev_err(dev, "STATUS is still low!\n");
+	if (gpio_get_value(this->confd_gpio) == 0)
+		dev_err(dev, "CONFIG DONE is still low!\n");
+
+	return -EIO;
+}
+
+static int altera_spi_of(struct device_d *dev, struct fpga_spi *this)
+{
+	struct device_node *n = dev->device_node;
+	const char *name;
+	int ret;
+
+	name = "nstat-gpio";
+	this->nstat_gpio = of_get_named_gpio(n, name, 0);
+	if (this->nstat_gpio < 0) {
+		ret = this->nstat_gpio;
+		goto out;
+	}
+
+	name = "confd-gpio";
+	this->confd_gpio = of_get_named_gpio(n, name, 0);
+	if (this->confd_gpio < 0) {
+		ret = this->confd_gpio;
+		goto out;
+	}
+
+	name = "nconfig-gpio";
+	this->nconfig_gpio = of_get_named_gpio(n, name, 0);
+	if (this->nconfig_gpio < 0) {
+		ret = this->nconfig_gpio;
+		goto out;
+	}
+
+	/* init to passive and sane values */
+	gpio_direction_output(this->nconfig_gpio, 1);
+	gpio_direction_input(this->nstat_gpio);
+	gpio_direction_input(this->confd_gpio);
+
+	return 0;
+
+out:
+	dev_err(dev, "Cannot request \"%s\" gpio: %s\n", name, strerror(-ret));
+
+	return ret;
+}
+
+static void altera_spi_init_mode(struct spi_device *spi)
+{
+	spi->bits_per_word = 32;
+	/*
+	 * CPHA = CPOL = 0
+	 * the FPGA expects its firmware data with LSB first
+	 */
+	spi->mode = SPI_MODE_0 | SPI_LSB_FIRST;
+}
+
+static int altera_spi_probe(struct device_d *dev)
+{
+	int rc;
+	struct fpga_spi *this;
+	struct firmware_handler *fh;
+	const char *alias = of_alias_get(dev->device_node);
+	const char *model = NULL;
+
+	dev_dbg(dev, "Probing FPGA firmware programmer\n");
+
+	this = xzalloc(sizeof(*this));
+	fh = &this->fh;
+
+	rc = altera_spi_of(dev, this);
+	if (rc != 0)
+		goto out;
+
+	if (alias)
+		fh->id = xstrdup(alias);
+	else
+		fh->id = xstrdup("altera-fpga");
+
+	fh->open = altera_spi_open;
+	fh->write = altera_spi_write;
+	fh->close = altera_spi_close;
+	of_property_read_string(dev->device_node, "compatible", &model);
+	if (model)
+		fh->model = xstrdup(model);
+	fh->dev = dev;
+
+	this->spi = (struct spi_device *)dev->type_data;
+	altera_spi_init_mode(this->spi);
+	this->dev = dev;
+
+	dev_dbg(dev, "Registering FPGA firmware programmer\n");
+	rc = firmwaremgr_register(fh);
+	if (rc != 0) {
+		free(this);
+		goto out;
+	}
+
+	return 0;
+out:
+	free(fh->id);
+	free(this);
+
+	return rc;
+}
+
+static struct of_device_id altera_spi_id_table[] = {
+	{
+		.compatible = "altr,passive-serial",
+	},
+};
+
+static struct driver_d altera_spi_driver = {
+	.name = "altera-fpga",
+	.of_compatible = DRV_OF_COMPAT(altera_spi_id_table),
+	.probe = altera_spi_probe,
+};
+device_spi_driver(altera_spi_driver);
-- 
1.8.4.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/4] DT: Add binding for Altera FPGAs in passive-serial mode
  2013-11-12 14:31 Sascha Hauer
  2013-11-12 14:31 ` [PATCH 1/4] Add a Firmware programming framework Sascha Hauer
  2013-11-12 14:31 ` [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs Sascha Hauer
@ 2013-11-12 14:31 ` Sascha Hauer
  2013-11-12 14:51   ` Jürgen Beisert
  2013-11-12 16:21   ` Kumar Gala
  2013-11-12 14:31 ` [PATCH 4/4] Firmware: socfpga: Add SoCFPGA FPGA program support Sascha Hauer
  3 siblings, 2 replies; 12+ messages in thread
From: Sascha Hauer @ 2013-11-12 14:31 UTC (permalink / raw)
  To: barebox; +Cc: devicetree, jbe

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: devicetree@vger.kernel.org
---
 .../devicetree/bindings/firmware/altr,passive-serial.txt    | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/altr,passive-serial.txt

diff --git a/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt b/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
new file mode 100644
index 0000000..6d40c91
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
@@ -0,0 +1,13 @@
+Altera FPGAs in passive serial mode
+-----------------------------------
+
+This binding defines the control interface to Altera FPGAs in
+passive serial mode. This is used to upload the firmware and
+to start the FPGA.
+
+Required properties:
+- compatible: shall be "altr,passive-serial"
+- reg: SPI chip select
+- nstat-gpio: Specify GPIO for controlling the nstat pin
+- confd-gpio: Specify GPIO for controlling the confd pin
+- nconfig-gpio: Specify GPIO for controlling the nconfig pin
-- 
1.8.4.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4/4] Firmware: socfpga: Add SoCFPGA FPGA program support
  2013-11-12 14:31 Sascha Hauer
                   ` (2 preceding siblings ...)
  2013-11-12 14:31 ` [PATCH 3/4] DT: Add binding for Altera FPGAs in passive-serial mode Sascha Hauer
@ 2013-11-12 14:31 ` Sascha Hauer
  3 siblings, 0 replies; 12+ messages in thread
From: Sascha Hauer @ 2013-11-12 14:31 UTC (permalink / raw)
  To: barebox; +Cc: jbe

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/dts/socfpga_cyclone5.dtsi                |   5 +
 arch/arm/mach-socfpga/Makefile                    |   1 +
 arch/arm/mach-socfpga/include/mach/socfpga-regs.h |   2 +
 drivers/firmware/Kconfig                          |   3 +
 drivers/firmware/Makefile                         |   1 +
 drivers/firmware/socfpga.c                        | 437 ++++++++++++++++++++++
 6 files changed, 449 insertions(+)
 create mode 100644 drivers/firmware/socfpga.c

diff --git a/arch/arm/dts/socfpga_cyclone5.dtsi b/arch/arm/dts/socfpga_cyclone5.dtsi
index ee2ec6c..188b91b 100644
--- a/arch/arm/dts/socfpga_cyclone5.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5.dtsi
@@ -47,6 +47,11 @@
 			};
 		};
 
+		fpgamgr@ff706000 {
+			compatible = "altr,fpga-mgr";
+			reg = <0xff706000 0x1000 0xffb90000 0x1000>;
+		};
+
 		timer@ffc08000 {
 			clock-frequency = <100000000>;
 		};
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index d8bf067..12585c5 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -2,3 +2,4 @@ obj-y += generic.o nic301.o bootsource.o reset-manager.o
 pbl-y += init.o freeze-controller.o scan-manager.o system-manager.o
 pbl-y += clock-manager.o iocsr-config-cyclone5.o
 obj-$(CONFIG_ARCH_SOCFPGA_XLOAD) += xload.o
+obj-$(CONFIG_ARCH_SOCFPGA_FPGA) += fpga.o
diff --git a/arch/arm/mach-socfpga/include/mach/socfpga-regs.h b/arch/arm/mach-socfpga/include/mach/socfpga-regs.h
index 9d1e677..b124ed6 100644
--- a/arch/arm/mach-socfpga/include/mach/socfpga-regs.h
+++ b/arch/arm/mach-socfpga/include/mach/socfpga-regs.h
@@ -2,10 +2,12 @@
 #define __MACH_SOCFPGA_REGS_H
 
 #define CYCLONE5_SDMMC_ADDRESS		0xff704000
+#define CYCLONE5_FPGAMGRREGS_ADDRESS	0xff706000
 #define CYCLONE5_GPIO0_BASE		0xff708000
 #define CYCLONE5_GPIO1_BASE		0xff709000
 #define CYCLONE5_GPIO2_BASE		0xff70A000
 #define CYCLONE5_L3REGS_ADDRESS		0xff800000
+#define CYCLONE5_FPGAMGRDATA_ADDRESS	0xffb90000
 #define CYCLONE5_UART0_ADDRESS		0xffc02000
 #define CYCLONE5_UART1_ADDRESS		0xffc03000
 #define CYCLONE5_SDR_ADDRESS		0xffc20000
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 28a173b..5866063 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -8,4 +8,7 @@ config FIRMWARE_ALTERA_SERIAL
 	  Programming an Altera FPGA via a few GPIOs for the control lines and
 	  MOSI, MISO and clock from an SPI interface for the data lines
 
+config FIRMWARE_ALTERA_SOCFPGA
+	bool "Altera SoCFPGA fpga loader"
+
 endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index ec6a5a1..c3a3c34 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
+obj-$(CONFIG_FIRMWARE_ALTERA_SOCFPGA) += socfpga.o
diff --git a/drivers/firmware/socfpga.c b/drivers/firmware/socfpga.c
new file mode 100644
index 0000000..7d8f888
--- /dev/null
+++ b/drivers/firmware/socfpga.c
@@ -0,0 +1,437 @@
+/*
+ *
+ * Copyright (C) 2012 Altera Corporation <www.altera.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *  - Neither the name of the Altera Corporation nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <firmware.h>
+#include <command.h>
+#include <common.h>
+#include <malloc.h>
+#include <clock.h>
+#include <fcntl.h>
+#include <init.h>
+#include <io.h>
+#include <mach/system-manager.h>
+#include <mach/reset-manager.h>
+#include <mach/socfpga-regs.h>
+#include <mach/sdram.h>
+
+#define FPGAMGRREGS_STAT			0x0
+#define FPGAMGRREGS_CTRL			0x4
+#define FPGAMGRREGS_DCLKCNT			0x8
+#define FPGAMGRREGS_DCLKSTAT			0xc
+
+#define FPGAMGRREGS_MON_GPIO_PORTA_EOI_ADDRESS	0x84c
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_ADDRESS	0x850
+
+#define FPGAMGRREGS_CTRL_CFGWDTH_MASK		0x200
+#define FPGAMGRREGS_CTRL_AXICFGEN_MASK		0x100
+#define FPGAMGRREGS_CTRL_NCONFIGPULL_MASK	0x4
+#define FPGAMGRREGS_CTRL_NCE_MASK		0x2
+#define FPGAMGRREGS_CTRL_EN_MASK		0x1
+#define FPGAMGRREGS_CTRL_CDRATIO_LSB		6
+
+#define FPGAMGRREGS_STAT_MODE_MASK		0x7
+#define FPGAMGRREGS_STAT_MSEL_MASK		0xf8
+#define FPGAMGRREGS_STAT_MSEL_LSB		3
+
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CRC_MASK	0x8
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_ID_MASK	0x4
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK	0x2
+#define FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK	0x1
+
+/* FPGA Mode */
+#define FPGAMGRREGS_MODE_FPGAOFF	0x0
+#define FPGAMGRREGS_MODE_RESETPHASE	0x1
+#define FPGAMGRREGS_MODE_CFGPHASE	0x2
+#define FPGAMGRREGS_MODE_INITPHASE	0x3
+#define FPGAMGRREGS_MODE_USERMODE	0x4
+#define FPGAMGRREGS_MODE_UNKNOWN	0x5
+
+/* FPGA CD Ratio Value */
+#define CDRATIO_x1	0x0
+#define CDRATIO_x2	0x1
+#define CDRATIO_x4	0x2
+#define CDRATIO_x8	0x3
+
+struct fpgamgr {
+	struct firmware_handler fh;
+	struct device_d *dev;
+	void __iomem *regs;
+	void __iomem *regs_data;
+};
+
+/* Get the FPGA mode */
+static uint32_t fpgamgr_get_mode(struct fpgamgr *mgr)
+{
+	return readl(mgr->regs + FPGAMGRREGS_STAT) & FPGAMGRREGS_STAT_MODE_MASK;
+}
+
+static int fpgamgr_dclkcnt_set(struct fpgamgr *mgr, unsigned long cnt)
+{
+	uint64_t start;
+
+	/* clear any existing done status */
+	if (readl(mgr->regs + FPGAMGRREGS_DCLKSTAT))
+		writel(0x1, mgr->regs + FPGAMGRREGS_DCLKSTAT);
+
+	writel(cnt, mgr->regs + FPGAMGRREGS_DCLKCNT);
+
+	/* wait till the dclkcnt done */
+	start = get_time_ns();
+	while (1) {
+		if (readl(mgr->regs + FPGAMGRREGS_DCLKSTAT)) {
+			writel(0x1, mgr->regs + FPGAMGRREGS_DCLKSTAT);
+			return 0;
+		}
+
+		if (is_timeout(start, 100 * MSECOND))
+			return -ETIMEDOUT;
+	}
+}
+
+/* Start the FPGA programming by initialize the FPGA Manager */
+static int fpgamgr_program_init(struct fpgamgr *mgr)
+{
+	unsigned long reg;
+	uint32_t ctrl = 0, ratio;
+	uint64_t start;
+
+	/* get the MSEL value */
+	reg = readl(mgr->regs + FPGAMGRREGS_STAT);
+	reg = ((reg & FPGAMGRREGS_STAT_MSEL_MASK) >> FPGAMGRREGS_STAT_MSEL_LSB);
+
+	if (reg & 0x8)
+		ctrl |= FPGAMGRREGS_CTRL_CFGWDTH_MASK;
+	else
+		ctrl &= ~FPGAMGRREGS_CTRL_CFGWDTH_MASK;
+
+	switch (reg & 0xb) {
+	case 0xa:
+		ratio = CDRATIO_x8;
+		break;
+	case 0x2:
+	case 0x9:
+		ratio = CDRATIO_x4;
+		break;
+	case 0x1:
+		ratio = CDRATIO_x2;
+		break;
+	case 0x8:
+	case 0xb:
+	default:
+		ratio = CDRATIO_x1;
+		break;
+	}
+
+	ctrl |= ratio << FPGAMGRREGS_CTRL_CDRATIO_LSB;
+
+	/* to enable FPGA Manager drive over configuration line */
+	ctrl |= FPGAMGRREGS_CTRL_EN_MASK;
+
+	/* put FPGA into reset phase */
+	ctrl |= FPGAMGRREGS_CTRL_NCONFIGPULL_MASK;
+
+	writel(ctrl, mgr->regs + FPGAMGRREGS_CTRL);
+
+	/* (1) wait until FPGA enter reset phase */
+	start = get_time_ns();
+	while (1) {
+		if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_RESETPHASE)
+			break;
+		if (is_timeout(start, 100 * MSECOND))
+			return -ETIMEDOUT;
+	}
+
+	/* release FPGA from reset phase */
+	ctrl = readl(mgr->regs + FPGAMGRREGS_CTRL);
+	ctrl &= ~FPGAMGRREGS_CTRL_NCONFIGPULL_MASK;
+	writel(ctrl, mgr->regs + FPGAMGRREGS_CTRL);
+
+	/* (2) wait until FPGA enter configuration phase */
+	start = get_time_ns();
+	while (1) {
+		if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_CFGPHASE)
+			break;
+		if (is_timeout(start, 100 * MSECOND))
+			return -ETIMEDOUT;
+	}
+
+	/* clear all interrupt in CB Monitor */
+	writel(0xFFF, (mgr->regs + FPGAMGRREGS_MON_GPIO_PORTA_EOI_ADDRESS));
+
+	/* enable AXI configuration */
+	ctrl = readl(mgr->regs + FPGAMGRREGS_CTRL);
+	ctrl |= FPGAMGRREGS_CTRL_AXICFGEN_MASK;
+	writel(ctrl, mgr->regs + FPGAMGRREGS_CTRL);
+
+	return 0;
+}
+
+/* Ensure the FPGA entering config done */
+static int fpgamgr_program_poll_cd(struct fpgamgr *mgr)
+{
+	unsigned long reg;
+	uint32_t val;
+	uint64_t start;
+
+	/* (3) wait until full config done */
+	start = get_time_ns();
+	while (1) {
+		reg = readl(mgr->regs + FPGAMGRREGS_MON_GPIO_EXT_PORTA_ADDRESS);
+
+		/* config error */
+		if (!(reg & FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK) &&
+			!(reg & FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK))
+			return -EIO;
+
+		/* config done without error */
+		if ((reg & FPGAMGRREGS_MON_GPIO_EXT_PORTA_NS_MASK) &&
+			(reg & FPGAMGRREGS_MON_GPIO_EXT_PORTA_CD_MASK))
+			break;
+
+		if (is_timeout(start, 100 * MSECOND))
+			return -ETIMEDOUT;
+	}
+
+	/* disable AXI configuration */
+	val = readl(mgr->regs + FPGAMGRREGS_CTRL);
+	val &= ~FPGAMGRREGS_CTRL_AXICFGEN_MASK;
+	writel(val, mgr->regs + FPGAMGRREGS_CTRL);
+
+	return 0;
+}
+
+/* Ensure the FPGA entering init phase */
+static int fpgamgr_program_poll_initphase(struct fpgamgr *mgr)
+{
+	uint64_t start;
+
+	/* additional clocks for the CB to enter initialization phase */
+	if (fpgamgr_dclkcnt_set(mgr, 0x4) != 0)
+		return -5;
+
+	/* (4) wait until FPGA enter init phase or user mode */
+	start = get_time_ns();
+	while (1) {
+		int mode = fpgamgr_get_mode(mgr);
+
+		if (mode == FPGAMGRREGS_MODE_INITPHASE ||
+				mode == FPGAMGRREGS_MODE_USERMODE)
+			break;
+
+		if (is_timeout(start, 100 * MSECOND))
+			return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+/* Ensure the FPGA entering user mode */
+static int fpgamgr_program_poll_usermode(struct fpgamgr *mgr)
+{
+	uint32_t val;
+	uint64_t start;
+
+	/* additional clocks for the CB to exit initialization phase */
+	if (fpgamgr_dclkcnt_set(mgr, 0x5000) != 0)
+		return -7;
+
+	/* (5) wait until FPGA enter user mode */
+	start = get_time_ns();
+	while (1) {
+		if (fpgamgr_get_mode(mgr) == FPGAMGRREGS_MODE_USERMODE)
+			break;
+		if (is_timeout(start, 100 * MSECOND))
+			return -ETIMEDOUT;
+	}
+
+	/* to release FPGA Manager drive over configuration line */
+	val = readl(mgr->regs + FPGAMGRREGS_CTRL);
+	val &= ~FPGAMGRREGS_CTRL_EN_MASK;
+	writel(val, mgr->regs + FPGAMGRREGS_CTRL);
+
+	return 0;
+}
+
+/*
+ * Using FPGA Manager to program the FPGA
+ * Return 0 for sucess
+ */
+static int fpgamgr_program_start(struct firmware_handler *fh)
+{
+	struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
+	int status;
+
+	/* prior programming the FPGA, all bridges need to be shut off */
+
+	/* disable all signals from hps peripheral controller to fpga */
+	writel(0, SYSMGR_FPGAINTF_MODULE);
+
+	/* disable all signals from fpga to hps sdram */
+	writel(0, (CYCLONE5_SDR_ADDRESS + SDR_CTRLGRP_FPGAPORTRST_ADDRESS));
+
+	/* disable all axi bridge (hps2fpga, lwhps2fpga & fpga2hps) */
+	writel(~0, CYCLONE5_RSTMGR_ADDRESS + RESET_MGR_BRG_MOD_RESET_OFS);
+
+	/* unmap the bridges from NIC-301 */
+	writel(0x1, CYCLONE5_L3REGS_ADDRESS);
+
+	dev_dbg(mgr->dev, "start programming...\n");
+
+	/* initialize the FPGA Manager */
+	status = fpgamgr_program_init(mgr);
+	if (status) {
+		dev_err(mgr->dev, "program init failed with: %s\n",
+				strerror(-status));
+		return status;
+	}
+
+	return 0;
+}
+
+/* Write the RBF data to FPGA Manager */
+static int fpgamgr_program_write_buf(struct firmware_handler *fh, const void *buf,
+		size_t size)
+{
+	struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
+	const uint32_t *buf32 = buf;
+
+	/* write to FPGA Manager AXI data */
+	while (size) {
+		writel(*buf32, mgr->regs_data);
+		readl(mgr->regs + FPGAMGRREGS_MON_GPIO_EXT_PORTA_ADDRESS);
+		buf32++;
+		size -= sizeof(uint32_t);
+	}
+
+	return 0;
+}
+
+static int fpgamgr_program_finish(struct firmware_handler *fh)
+{
+	struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh);
+	int status;
+
+	/* Ensure the FPGA entering config done */
+	status = fpgamgr_program_poll_cd(mgr);
+	if (status) {
+		dev_err(mgr->dev, "poll for config done failed with: %s\n",
+				strerror(-status));
+		return status;
+	}
+
+	dev_dbg(mgr->dev, "waiting for init phase...\n");
+
+	/* Ensure the FPGA entering init phase */
+	status = fpgamgr_program_poll_initphase(mgr);
+	if (status) {
+		dev_err(mgr->dev, "poll for init phase failed with: %s\n",
+				strerror(-status));
+		return status;
+	}
+
+	dev_dbg(mgr->dev, "waiting for user mode...\n");
+
+	/* Ensure the FPGA entering user mode */
+	status = fpgamgr_program_poll_usermode(mgr);
+	if (status) {
+		dev_err(mgr->dev, "poll for user mode with: %s\n",
+				strerror(-status));
+		return status;
+	}
+
+	return 0;
+}
+
+static int fpgamgr_probe(struct device_d *dev)
+{
+	struct fpgamgr *mgr;
+	struct firmware_handler *fh;
+	const char *alias = of_alias_get(dev->device_node);
+	const char *model = NULL;
+	int ret;
+
+	dev_dbg(dev, "Probing FPGA firmware programmer\n");
+
+	mgr = xzalloc(sizeof(*mgr));
+	fh = &mgr->fh;
+
+	mgr->regs = dev_request_mem_region(dev, 0);
+	if (!mgr->regs) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	mgr->regs_data = dev_request_mem_region(dev, 1);
+	if (!mgr->regs_data) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if (alias)
+		fh->id = xstrdup(alias);
+	else
+		fh->id = xstrdup("socfpga-fpga");
+
+	fh->open = fpgamgr_program_start;
+	fh->write = fpgamgr_program_write_buf;
+	fh->close = fpgamgr_program_finish;
+	of_property_read_string(dev->device_node, "compatible", &model);
+	if (model)
+		fh->model = xstrdup(model);
+	fh->dev = dev;
+
+	mgr->dev = dev;
+
+	dev_dbg(dev, "Registering FPGA firmware programmer\n");
+
+	ret = firmwaremgr_register(fh);
+	if (ret != 0) {
+		free(mgr);
+		goto out;
+	}
+
+	return 0;
+out:
+	free(fh->id);
+	free(mgr);
+
+	return ret;
+}
+
+static struct of_device_id fpgamgr_id_table[] = {
+	{
+		.compatible = "altr,fpga-mgr",
+	},
+};
+
+static struct driver_d fpgamgr_driver = {
+	.name = "socfpa-fpgamgr",
+	.of_compatible = DRV_OF_COMPAT(fpgamgr_id_table),
+	.probe = fpgamgr_probe,
+};
+device_platform_driver(fpgamgr_driver);
-- 
1.8.4.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs
  2013-11-12 14:31 ` [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs Sascha Hauer
@ 2013-11-12 14:46   ` Jürgen Beisert
  2013-11-12 16:03   ` Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 0 replies; 12+ messages in thread
From: Jürgen Beisert @ 2013-11-12 14:46 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

I know, documentation will never be read, but...

On Tuesday 12 November 2013 15:31:39 Sascha Hauer wrote:
> [...]
> +
> +/*
> + * Physical requirements:
> + * - three free GPIOs for the signals nCONFIG, CONFIGURE_DONE, nSTATUS
> + * - 32 bit per word, LSB first capable SPI master (MOSI + clock)
> + *
> + * Example how to configure this driver via device tree
> + *
> + *	fpga@0 {
> + *		compatible = "altera_serial";
> [...]

Then we also should should remove this sample or change it 
to "altr,passive-serial"

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | http://www.pengutronix.de/  |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] DT: Add binding for Altera FPGAs in passive-serial mode
  2013-11-12 14:31 ` [PATCH 3/4] DT: Add binding for Altera FPGAs in passive-serial mode Sascha Hauer
@ 2013-11-12 14:51   ` Jürgen Beisert
  2013-11-12 16:21   ` Kumar Gala
  1 sibling, 0 replies; 12+ messages in thread
From: Jürgen Beisert @ 2013-11-12 14:51 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, devicetree

On Tuesday 12 November 2013 15:31:40 Sascha Hauer wrote:
> [...]
> +Required properties:
> +- compatible: shall be "altr,passive-serial"
> +- reg: SPI chip select
> +- nstat-gpio: Specify GPIO for controlling the nstat pin
> +- confd-gpio: Specify GPIO for controlling the confd pin
> +- nconfig-gpio: Specify GPIO for controlling the nconfig pin

A suggestion was to use the genuine signal names at the FPGA side:

 "nstatus", "config-done" and "nconfig" (all with the trailing "-gpio")

jbe

-- 
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | http://www.pengutronix.de/  |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs
  2013-11-12 14:31 ` [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs Sascha Hauer
  2013-11-12 14:46   ` Jürgen Beisert
@ 2013-11-12 16:03   ` Jean-Christophe PLAGNIOL-VILLARD
  2013-11-13 10:23     ` Sascha Hauer
  1 sibling, 1 reply; 12+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-11-12 16:03 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Juergen Beisert

On 15:31 Tue 12 Nov     , Sascha Hauer wrote:
> From: Juergen Beisert <jbe@pengutronix.de>
> 
> This handler uses a regular SPI master and a few GPIOs to program an
> Altera FPGA in serial mode.
> 
> Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/Kconfig                  |   1 +
>  drivers/Makefile                 |   1 +
>  drivers/firmware/Kconfig         |  11 ++
>  drivers/firmware/Makefile        |   1 +
>  drivers/firmware/altera_serial.c | 307 +++++++++++++++++++++++++++++++++++++++
>  5 files changed, 321 insertions(+)
>  create mode 100644 drivers/firmware/Kconfig
>  create mode 100644 drivers/firmware/Makefile
>  create mode 100644 drivers/firmware/altera_serial.c
> 
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index d34d2c7..71d840c 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -25,5 +25,6 @@ source "drivers/gpio/Kconfig"
>  source "drivers/w1/Kconfig"
>  source "drivers/pinctrl/Kconfig"
>  source "drivers/bus/Kconfig"
> +source "drivers/firmware/Kconfig"
>  
>  endmenu
> diff --git a/drivers/Makefile b/drivers/Makefile
> index ba1dc6d..bf03d54 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -24,3 +24,4 @@ obj-$(CONFIG_OFTREE) += of/
>  obj-$(CONFIG_W1) += w1/
>  obj-y += pinctrl/
>  obj-y += bus/
> +obj-y += firmware/
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> new file mode 100644
> index 0000000..28a173b
> --- /dev/null
> +++ b/drivers/firmware/Kconfig
> @@ -0,0 +1,11 @@
> +menu "Firmware Drivers"
> +
> +config FIRMWARE_ALTERA_SERIAL
> +	bool "Altera SPI programming"
> +	depends on OFDEVICE
> +	select FIRMWARE
> +	help
> +	  Programming an Altera FPGA via a few GPIOs for the control lines and
> +	  MOSI, MISO and clock from an SPI interface for the data lines
> +
> +endmenu
> diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
> new file mode 100644
> index 0000000..ec6a5a1
> --- /dev/null
> +++ b/drivers/firmware/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_FIRMWARE_ALTERA_SERIAL) += altera_serial.o
> diff --git a/drivers/firmware/altera_serial.c b/drivers/firmware/altera_serial.c
> new file mode 100644
> index 0000000..047b6bd
> --- /dev/null
> +++ b/drivers/firmware/altera_serial.c
> @@ -0,0 +1,307 @@
> +/*
> + * Copyright (c) 2013 Juergen Beisert <kernel@pengutronix.de>, Pengutronix
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <driver.h>
> +#include <firmware.h>
> +#include <of_gpio.h>
> +#include <xfuncs.h>
> +#include <malloc.h>
> +#include <gpio.h>
> +#include <clock.h>
> +#include <spi/spi.h>
> +
> +#include <fcntl.h>
> +#include <fs.h>
> +
> +/*
> + * Physical requirements:
> + * - three free GPIOs for the signals nCONFIG, CONFIGURE_DONE, nSTATUS
> + * - 32 bit per word, LSB first capable SPI master (MOSI + clock)
> + *
> + * Example how to configure this driver via device tree
> + *
> + *	fpga@0 {
> + *		compatible = "altera_serial";
> + *		nstat-gpio = <&gpio4 18 0>;
> + *		confd-gpio = <&gpio4 19 0>;
> + *		nconfig-gpio = <&gpio4 20 0>;
you are missing on 's' to gpio mandatory for all the gpios binding

Best Regards,
J.
> + *		spi-max-frequency = <10000000>;
> + *		reg = <0>;
> + *	};
> + */
> +
> +struct fpga_spi {
> +	struct firmware_handler fh;
> +	int nstat_gpio; /* input GPIO to read the status line */
> +	int confd_gpio; /* input GPIO to read the config done line */
> +	int nconfig_gpio; /* output GPIO to start the FPGA's config */
> +	struct device_d *dev;
> +	struct spi_device *spi;
> +	bool padding_done;
> +};
> +
> +static int altera_spi_open(struct firmware_handler *fh)
> +{
> +	struct fpga_spi *this = container_of(fh, struct fpga_spi, fh);
> +	struct device_d *dev = this->dev;
> +	int ret;
> +
> +	dev_dbg(dev, "Initiating programming\n");
> +
> +	/* initiate an FPGA programming */
> +	gpio_set_value(this->nconfig_gpio, 0);
> +
> +	/*
> +	 * after about 2 µs the FPGA must acknowledge with
> +	 * STATUS and CONFIG DONE lines at low level
> +	 */
> +	ret = wait_on_timeout(2 * 1000,
> +				(gpio_get_value(this->nstat_gpio) == 0) &&
> +				(gpio_get_value(this->confd_gpio) == 0));
> +
> +	if (ret != 0) {
> +		dev_err(dev, "FPGA does not acknowledge the programming initiation\n");
> +		if (gpio_get_value(this->nstat_gpio))
> +			dev_err(dev, "STATUS is still high!\n");
> +		if (gpio_get_value(this->confd_gpio))
> +			dev_err(dev, "CONFIG DONE is still high!\n");
> +		return ret;
> +	}
> +
> +	/* arm the FPGA to await its new firmware */
> +	gpio_set_value(this->nconfig_gpio, 1);
no one check the return of gpio_set but we need to

on a i2c-gpio it might fail
> +
> +	/* once again, we might need padding the data */
> +	this->padding_done = false;
> +
> +	/*
> +	 * after about 1506 µs the FPGA must acknowledge this step
> +	 * with the STATUS line at high level
> +	 */
> +	ret = wait_on_timeout(1600 * 1000,
> +				gpio_get_value(this->nstat_gpio) == 1);
> +	if (ret != 0) {
> +		dev_err(dev, "FPGA does not acknowledge the programming start\n");
> +		return ret;
> +	}
> +
> +	dev_dbg(dev, "Initiating passed\n");
> +	/* at the end, wait at least 2 µs prior beginning writing data */
> +	ndelay(2 * 1000);
so udelay(2);
> +
> +	return 0;
> +}
> +
> +static int altera_spi_write(struct firmware_handler *fh, const void *buf, size_t sz)
> +{
> +	struct fpga_spi *this = container_of(fh, struct fpga_spi, fh);
> +	struct device_d *dev = this->dev;
> +	struct spi_transfer t[2];
> +	struct spi_message m;
> +	u32 dummy;
> +	int ret;
> +
> +	printf("%s: %d\n", __func__, sz);
> +
> +	spi_message_init(&m);
> +
> +	if (sz < sizeof(u32)) {
> +		/* simple padding */
> +		dummy = 0;
> +		memcpy(&dummy, buf, sz);
> +		buf = &dummy;
> +		sz = sizeof(u32);
> +		this->padding_done = true;
> +	}
> +
> +	t[0].tx_buf = buf;
> +	t[0].rx_buf = NULL;
> +	t[0].len = sz;
> +	spi_message_add_tail(&t[0], &m);
> +
> +	if (sz & 0x3) { /* padding required? */
> +		u32 *word_buf = (u32 *)buf;
> +		dummy = 0;
> +		memcpy(&dummy, &word_buf[sz >> 2], sz & 0x3);
> +		t[0].len &= ~0x03;
> +		t[1].tx_buf = &dummy;
> +		t[1].rx_buf = NULL;
> +		t[1].len = sizeof(u32);
> +		spi_message_add_tail(&t[1], &m);
> +		this->padding_done = true;
> +	}
> +
> +	ret = spi_sync(this->spi, &m);
> +	if (ret != 0)
> +		dev_err(dev, "programming failure\n");
> +
> +	return ret;
> +}
> +
> +static int altera_spi_close(struct firmware_handler *fh)
> +{
> +	struct fpga_spi *this = container_of(fh, struct fpga_spi, fh);
> +	struct device_d *dev = this->dev;
> +	struct spi_transfer t;
> +	struct spi_message m;
> +	u32 dummy = 0;
> +	int ret;
> +
> +	dev_dbg(dev, "Finalize programming\n");
> +
> +	if (this->padding_done == false) {
> +		spi_message_init(&m);
> +		t.tx_buf = &dummy;
> +		t.rx_buf = NULL;
> +		t.len = sizeof(dummy);
> +		spi_message_add_tail(&t, &m);
> +
> +		ret = spi_sync(this->spi, &m);
> +		if (ret != 0)
> +			dev_err(dev, "programming failure\n");
> +	}
> +
> +	/*
> +	 * when programming was successfully,
> +	 * both status lines should be at high level
> +	 */
> +	ret = wait_on_timeout(10 * 1000,
> +				(gpio_get_value(this->nstat_gpio) == 1) &&
> +				(gpio_get_value(this->confd_gpio) == 1));
> +	if (ret == 0) {
> +		dev_dbg(dev, "Programming successfull\n");
> +		return ret;
> +	}
> +
> +	dev_err(dev, "Programming failed due to time out\n");
> +	if (gpio_get_value(this->nstat_gpio) == 0)
> +		dev_err(dev, "STATUS is still low!\n");
> +	if (gpio_get_value(this->confd_gpio) == 0)
> +		dev_err(dev, "CONFIG DONE is still low!\n");
> +
> +	return -EIO;
> +}
> +
> +static int altera_spi_of(struct device_d *dev, struct fpga_spi *this)
> +{
> +	struct device_node *n = dev->device_node;
> +	const char *name;
> +	int ret;
> +
> +	name = "nstat-gpio";
> +	this->nstat_gpio = of_get_named_gpio(n, name, 0);
> +	if (this->nstat_gpio < 0) {
> +		ret = this->nstat_gpio;
> +		goto out;
> +	}
> +
> +	name = "confd-gpio";
> +	this->confd_gpio = of_get_named_gpio(n, name, 0);
> +	if (this->confd_gpio < 0) {
> +		ret = this->confd_gpio;
> +		goto out;
> +	}
> +
> +	name = "nconfig-gpio";
> +	this->nconfig_gpio = of_get_named_gpio(n, name, 0);
> +	if (this->nconfig_gpio < 0) {
> +		ret = this->nconfig_gpio;
> +		goto out;
> +	}
> +
> +	/* init to passive and sane values */
> +	gpio_direction_output(this->nconfig_gpio, 1);
> +	gpio_direction_input(this->nstat_gpio);
> +	gpio_direction_input(this->confd_gpio);
we need to check the return and request the gpio correctly
> +
> +	return 0;
> +
> +out:
> +	dev_err(dev, "Cannot request \"%s\" gpio: %s\n", name, strerror(-ret));
> +
> +	return ret;
> +}
> +
> +static void altera_spi_init_mode(struct spi_device *spi)
> +{
> +	spi->bits_per_word = 32;
> +	/*
> +	 * CPHA = CPOL = 0
> +	 * the FPGA expects its firmware data with LSB first
> +	 */
> +	spi->mode = SPI_MODE_0 | SPI_LSB_FIRST;
> +}
> +
> +static int altera_spi_probe(struct device_d *dev)
> +{
> +	int rc;
> +	struct fpga_spi *this;
> +	struct firmware_handler *fh;
> +	const char *alias = of_alias_get(dev->device_node);
> +	const char *model = NULL;
> +
> +	dev_dbg(dev, "Probing FPGA firmware programmer\n");
> +
> +	this = xzalloc(sizeof(*this));
> +	fh = &this->fh;
> +
> +	rc = altera_spi_of(dev, this);
> +	if (rc != 0)
> +		goto out;
> +
> +	if (alias)
> +		fh->id = xstrdup(alias);
> +	else
> +		fh->id = xstrdup("altera-fpga");
> +
> +	fh->open = altera_spi_open;
> +	fh->write = altera_spi_write;
> +	fh->close = altera_spi_close;
> +	of_property_read_string(dev->device_node, "compatible", &model);
> +	if (model)
> +		fh->model = xstrdup(model);
> +	fh->dev = dev;
> +
> +	this->spi = (struct spi_device *)dev->type_data;
> +	altera_spi_init_mode(this->spi);
> +	this->dev = dev;
> +
> +	dev_dbg(dev, "Registering FPGA firmware programmer\n");
> +	rc = firmwaremgr_register(fh);
> +	if (rc != 0) {
> +		free(this);
> +		goto out;
> +	}
> +
> +	return 0;
> +out:
> +	free(fh->id);
> +	free(this);
> +
> +	return rc;
> +}
> +
> +static struct of_device_id altera_spi_id_table[] = {
> +	{
> +		.compatible = "altr,passive-serial",
> +	},
> +};
> +
> +static struct driver_d altera_spi_driver = {
> +	.name = "altera-fpga",
> +	.of_compatible = DRV_OF_COMPAT(altera_spi_id_table),
> +	.probe = altera_spi_probe,
> +};
> +device_spi_driver(altera_spi_driver);
> -- 
> 1.8.4.2
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] DT: Add binding for Altera FPGAs in passive-serial mode
  2013-11-12 14:31 ` [PATCH 3/4] DT: Add binding for Altera FPGAs in passive-serial mode Sascha Hauer
  2013-11-12 14:51   ` Jürgen Beisert
@ 2013-11-12 16:21   ` Kumar Gala
  2013-11-12 22:02     ` Sascha Hauer
  1 sibling, 1 reply; 12+ messages in thread
From: Kumar Gala @ 2013-11-12 16:21 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, jbe, devicetree


On Nov 12, 2013, at 8:31 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:

> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: devicetree@vger.kernel.org
> ---
> .../devicetree/bindings/firmware/altr,passive-serial.txt    | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
> 
> diff --git a/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt b/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
> new file mode 100644
> index 0000000..6d40c91
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
> @@ -0,0 +1,13 @@
> +Altera FPGAs in passive serial mode
> +-----------------------------------
> +
> +This binding defines the control interface to Altera FPGAs in
> +passive serial mode. This is used to upload the firmware and
> +to start the FPGA.
> +
> +Required properties:
> +- compatible: shall be "altr,passive-serial”

This doesn’t seem quite descriptive enough, easy to confuse with a serial port.

> +- reg: SPI chip select

Is this a SPI device than?

> +- nstat-gpio: Specify GPIO for controlling the nstat pin
> +- confd-gpio: Specify GPIO for controlling the confd pin
> +- nconfig-gpio: Specify GPIO for controlling the nconfig pin
> -- 
> 1.8.4.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/4] DT: Add binding for Altera FPGAs in passive-serial mode
  2013-11-12 16:21   ` Kumar Gala
@ 2013-11-12 22:02     ` Sascha Hauer
  0 siblings, 0 replies; 12+ messages in thread
From: Sascha Hauer @ 2013-11-12 22:02 UTC (permalink / raw)
  To: Kumar Gala; +Cc: barebox, jbe, devicetree

On Tue, Nov 12, 2013 at 10:21:02AM -0600, Kumar Gala wrote:
> 
> On Nov 12, 2013, at 8:31 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > Cc: devicetree@vger.kernel.org
> > ---
> > .../devicetree/bindings/firmware/altr,passive-serial.txt    | 13 +++++++++++++
> > 1 file changed, 13 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt b/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
> > new file mode 100644
> > index 0000000..6d40c91
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/firmware/altr,passive-serial.txt
> > @@ -0,0 +1,13 @@
> > +Altera FPGAs in passive serial mode
> > +-----------------------------------
> > +
> > +This binding defines the control interface to Altera FPGAs in
> > +passive serial mode. This is used to upload the firmware and
> > +to start the FPGA.
> > +
> > +Required properties:
> > +- compatible: shall be "altr,passive-serial”
> 
> This doesn’t seem quite descriptive enough, easy to confuse with a serial port.

How about altr,fpga-passive-serial? Other suggestions?

> 
> > +- reg: SPI chip select
> 
> Is this a SPI device than?

Yes, it is.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs
  2013-11-12 16:03   ` Jean-Christophe PLAGNIOL-VILLARD
@ 2013-11-13 10:23     ` Sascha Hauer
  2013-11-13 13:36       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 12+ messages in thread
From: Sascha Hauer @ 2013-11-13 10:23 UTC (permalink / raw)
  To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox, Juergen Beisert

On Tue, Nov 12, 2013 at 05:03:59PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > +	if (ret != 0) {
> > +		dev_err(dev, "FPGA does not acknowledge the programming initiation\n");
> > +		if (gpio_get_value(this->nstat_gpio))
> > +			dev_err(dev, "STATUS is still high!\n");
> > +		if (gpio_get_value(this->confd_gpio))
> > +			dev_err(dev, "CONFIG DONE is still high!\n");
> > +		return ret;
> > +	}
> > +
> > +	/* arm the FPGA to await its new firmware */
> > +	gpio_set_value(this->nconfig_gpio, 1);
> no one check the return of gpio_set but we need to
> 
> on a i2c-gpio it might fail

I don't think that's necessary here. If setting gpios fails the firmware
programming will fail later anyway.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs
  2013-11-13 10:23     ` Sascha Hauer
@ 2013-11-13 13:36       ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 0 replies; 12+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-11-13 13:36 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox, Juergen Beisert

On 11:23 Wed 13 Nov     , Sascha Hauer wrote:
> On Tue, Nov 12, 2013 at 05:03:59PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > > +	if (ret != 0) {
> > > +		dev_err(dev, "FPGA does not acknowledge the programming initiation\n");
> > > +		if (gpio_get_value(this->nstat_gpio))
> > > +			dev_err(dev, "STATUS is still high!\n");
> > > +		if (gpio_get_value(this->confd_gpio))
> > > +			dev_err(dev, "CONFIG DONE is still high!\n");
> > > +		return ret;
> > > +	}
> > > +
> > > +	/* arm the FPGA to await its new firmware */
> > > +	gpio_set_value(this->nconfig_gpio, 1);
> > no one check the return of gpio_set but we need to
> > 
> > on a i2c-gpio it might fail
> 
> I don't think that's necessary here. If setting gpios fails the firmware
> programming will fail later anyway.

except when you debug and want to known why and where it fail

Best Regards,
J.
> 
> Sascha
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-11-13 13:34 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-12 14:31 Sascha Hauer
2013-11-12 14:31 ` [PATCH 1/4] Add a Firmware programming framework Sascha Hauer
2013-11-12 14:31 ` [PATCH 2/4] Firmware: provide a handler to program Altera FPGAs Sascha Hauer
2013-11-12 14:46   ` Jürgen Beisert
2013-11-12 16:03   ` Jean-Christophe PLAGNIOL-VILLARD
2013-11-13 10:23     ` Sascha Hauer
2013-11-13 13:36       ` Jean-Christophe PLAGNIOL-VILLARD
2013-11-12 14:31 ` [PATCH 3/4] DT: Add binding for Altera FPGAs in passive-serial mode Sascha Hauer
2013-11-12 14:51   ` Jürgen Beisert
2013-11-12 16:21   ` Kumar Gala
2013-11-12 22:02     ` Sascha Hauer
2013-11-12 14:31 ` [PATCH 4/4] Firmware: socfpga: Add SoCFPGA FPGA program support Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox