All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v14 0/7] fpga area and fpga bridge framework
@ 2015-12-10 23:37 ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

For v14 I'm dropping the concept of "simple-fpga-bus" for "fpga-area"
with reworked bindings.

An FPGA Area describes a section of an FPGA including the FPGA image needed to
program it and the hardware contained once it is programmed.  The intent is
to support Device Tree controlled programming of FPGA's.

Alan Tull (7):
  fpga: add usage documentation for fpga area
  fpga: add bindings document for fpga area
  add sysfs document for fpga bridge class
  ARM: socfpga: add bindings document for fpga bridge drivers
  fpga: add fpga bridge framework
  fpga: fpga-area: support device tree control for FPGA programming
  ARM: socfpga: fpga bridge driver support

 Documentation/ABI/testing/sysfs-class-fpga-bridge  |   11 +
 .../bindings/fpga/altera-fpga2sdram-bridge.txt     |   15 +
 .../bindings/fpga/altera-hps2fpga-bridge.txt       |   43 +++
 .../devicetree/bindings/fpga/fpga-area.txt         |   70 ++++
 Documentation/fpga/fpga-area.txt                   |  299 +++++++++++++++
 drivers/fpga/Kconfig                               |   21 ++
 drivers/fpga/Makefile                              |    7 +
 drivers/fpga/altera-fpga2sdram.c                   |  174 +++++++++
 drivers/fpga/altera-hps2fpga.c                     |  213 +++++++++++
 drivers/fpga/fpga-area.c                           |  313 ++++++++++++++++
 drivers/fpga/fpga-bridge.c                         |  388 ++++++++++++++++++++
 include/linux/fpga/fpga-bridge.h                   |   56 +++
 12 files changed, 1610 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-bridge
 create mode 100644 Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
 create mode 100644 Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
 create mode 100644 Documentation/devicetree/bindings/fpga/fpga-area.txt
 create mode 100644 Documentation/fpga/fpga-area.txt
 create mode 100644 drivers/fpga/altera-fpga2sdram.c
 create mode 100644 drivers/fpga/altera-hps2fpga.c
 create mode 100644 drivers/fpga/fpga-area.c
 create mode 100644 drivers/fpga/fpga-bridge.c
 create mode 100644 include/linux/fpga/fpga-bridge.h

-- 
1.7.9.5


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

* [PATCH v14 0/7] fpga area and fpga bridge framework
@ 2015-12-10 23:37 ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

For v14 I'm dropping the concept of "simple-fpga-bus" for "fpga-area"
with reworked bindings.

An FPGA Area describes a section of an FPGA including the FPGA image needed to
program it and the hardware contained once it is programmed.  The intent is
to support Device Tree controlled programming of FPGA's.

Alan Tull (7):
  fpga: add usage documentation for fpga area
  fpga: add bindings document for fpga area
  add sysfs document for fpga bridge class
  ARM: socfpga: add bindings document for fpga bridge drivers
  fpga: add fpga bridge framework
  fpga: fpga-area: support device tree control for FPGA programming
  ARM: socfpga: fpga bridge driver support

 Documentation/ABI/testing/sysfs-class-fpga-bridge  |   11 +
 .../bindings/fpga/altera-fpga2sdram-bridge.txt     |   15 +
 .../bindings/fpga/altera-hps2fpga-bridge.txt       |   43 +++
 .../devicetree/bindings/fpga/fpga-area.txt         |   70 ++++
 Documentation/fpga/fpga-area.txt                   |  299 +++++++++++++++
 drivers/fpga/Kconfig                               |   21 ++
 drivers/fpga/Makefile                              |    7 +
 drivers/fpga/altera-fpga2sdram.c                   |  174 +++++++++
 drivers/fpga/altera-hps2fpga.c                     |  213 +++++++++++
 drivers/fpga/fpga-area.c                           |  313 ++++++++++++++++
 drivers/fpga/fpga-bridge.c                         |  388 ++++++++++++++++++++
 include/linux/fpga/fpga-bridge.h                   |   56 +++
 12 files changed, 1610 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-bridge
 create mode 100644 Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
 create mode 100644 Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
 create mode 100644 Documentation/devicetree/bindings/fpga/fpga-area.txt
 create mode 100644 Documentation/fpga/fpga-area.txt
 create mode 100644 drivers/fpga/altera-fpga2sdram.c
 create mode 100644 drivers/fpga/altera-hps2fpga.c
 create mode 100644 drivers/fpga/fpga-area.c
 create mode 100644 drivers/fpga/fpga-bridge.c
 create mode 100644 include/linux/fpga/fpga-bridge.h

-- 
1.7.9.5

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

* [PATCH v14 1/7] fpga: add usage documentation for fpga area
  2015-12-10 23:37 ` atull
@ 2015-12-10 23:37   ` atull
  -1 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

Add a document spelling out usage of the FPGA Area for
reprogramming FPGA's under Device Tree control.

Signed-off-by: Alan Tull <atull@opensource.altera.com>

---
v9:  Initial version of this patch in patchset
v10: s/fpga/FPGA/g
     improve formatting
     some rewriting
     move to staging/simple-fpga-bus
v11: No change in this patch for v11 of the patch set
v12: Moved out of staging
     Small changes due to using FPGA bridge framework and not
     representing the bridges as resets.
v13: Fix some nits
v14: fpga-area instead of simple-fpga-bus
---
 Documentation/fpga/fpga-area.txt |  299 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 299 insertions(+)
 create mode 100644 Documentation/fpga/fpga-area.txt

diff --git a/Documentation/fpga/fpga-area.txt b/Documentation/fpga/fpga-area.txt
new file mode 100644
index 0000000..f031522
--- /dev/null
+++ b/Documentation/fpga/fpga-area.txt
@@ -0,0 +1,299 @@
+FPGA Area
+
+Alan Tull 2015
+
+Overview
+========
+
+An FPGA Area details information about a section of an FPGA including the FPGA
+image needed to program it and the hardware contained once it is programmed.
+
+Loading a Device Tree overlay which contains an FPGA Area will cause the
+FPGA to be programmed and the children of the FPGA Area will get probed.
+
+There may be FPGA Bridges involved to prevent spurious data from going out onto
+the processor bus during FPGA programming.  If so, the FPGA Area will need to
+disable and enable bridges that will only affect the child devices that are
+below the FPGA Area.  In the case of partial reconfiguration, bridges will
+be required within the FPGA design such that the active sections of the
+FPGA are on the bus while sections that are not programmed or being
+reprogrammed at the moment are isolated.
+
+Removing the overlay will result in the child devices getting removed and the
+bridges disabled.  Note that in the case of partial reconfiguration the rest of
+the FPGA continues to function as normal while this is happening.
+
+Below are more details on the structuring of the Device Tree for this.
+
+Terminology
+===========
+
+Full Reconfiguration
+ * The entire FPGA is reprogrammed.
+
+Partial Reconfiguration (PR)
+ * Part of the FPGA is reprogrammed while the rest of the FPGA is live and
+   active.  Not all FPGA's support this.
+
+Associated Blocks
+=================
+
+FPGA Manager Framework
+ * An FPGA Manager is a hardware block that programs an FPGA under the control
+   of a host processor.
+ * The FPGA Manager Framework provides drivers and functions to program an
+   FPGA.
+
+FPGA Bridge Framework
+ * Provides drivers and functions to control bridges that enable/disable
+   data to the FPGA.
+ * FPGA bridges should be disabled while the FPGA is being programmed to
+   prevent spurious data on the bus.
+ * FPGA bridges are not needed in implementations where the FPGA Manager
+   handles this.
+
+Device Tree
+===========
+
+For the purposes of this document, I'm dividing the Device Tree (DT) into two parts,
+each with its own requirements.  The two parts are:
+ * The live DT prior to the overlay being added
+ * The overlay containing an FPGA Area
+
+The live DT will contain:
+ * FPGA Manager
+ * FPGA Bridges as children of the FPGA Manager (optional, architecture specific)
+
+The live Device Tree must contain an FPGA Manager to handle programming the FPGA.
+If FPGA Bridges need to be involved, they show up in the DT as direct children
+of the FPGA Manager.  During full reconfiguration, the FPGA Area will disable
+any bridges that are direct children of the manager during full reconfiguration
+and will re-enable them afterwards.
+
+The insertion point in the live tree will also need the "simple-bus"
+compatibility string to enable populating the child nodes for the overlay.
+That includes the nodes for the FPGA Manager and controlling FPGA Bridges
+as explained below.
+
+The Device Tree Overlay will contain:
+ * "target-path"
+   The insertion point where the the contents of the overlay will go into the
+   live tree.
+ * "ranges"
+ * "firmware-name"
+   Specifies the name of the FPGA image file on the firmware search
+   path.  The search path is described in the firmware class documentation.
+ * "partial-reconfig"
+   This binding is a boolean and should be present if partial reconfiguration
+   is to be done.
+ * child nodes corresponding to hardware that will be loaded in this
+   region of the FPGA.
+
+Supported use models
+====================
+
+Here's a list of the superset of supported use models.  We may need to add
+more.  Some uses are specific to one FPGA or another.
+
+ * No FPGA Bridges
+   In this case, the FPGA Manager which programs the FPGA also handles the
+   bridges and no FPGA Bridge devices are needed for full reconfiguration.
+
+   The DT overlay will specify the FPGA Manager as the overlay target.
+
+ * Full reconfiguration with bridges
+   In the case, there are several bridges between the processor and FPGA,
+   that need to be disabled during full reconfiguration.
+   The DT before the overlay is applied will have an FPGA Manager.  The
+   immediate children of the manager will be the FPGA Bridges that need to be
+   disabled during FPGA programming.
+
+   The DT overlay will specify one of those bridges as the overlay target,
+   typically the bridge that allows memory mapped register access ("the
+   controlling bridge").
+
+ * Partial reconfiguration with bridges in the FPGA
+   In this case, the FPGA can have more than one section that will be
+   reprogrammed separately.  Other sections may be active on the bus while FPGA
+   is being programmed.  To manage this, FPGA Bridges need to exist on the FPGA
+   that can freeze all the buses going to one FPGA area while the buses are
+   enabled for other sections.
+
+Controlling Bridge
+==================
+
+It is possible that there are multiple FPGA Bridges connecting the processor
+and FPGA.  In a text based hierarchy, it is difficult to show this properly
+so what we do is consider the bridge that handles register access to be
+the controlling bridge.  The overlay is targeted to be inserted under the
+controlling bridge.  Other bridges are on the same level of the device tree
+as the controlling bridge, i.e. all are children of the FPGA Manager.  The
+ranges property handles mapping memory ranges through multiple bridges.
+
+Sequence
+========
+
+Load the DT overlay.  One way to do that from user space is to use Pantelis
+Antoniou's DT-Overlay configfs interface.  In that case the sequence from
+userspace is:
+
+ $ mkdir /config/device-tree/overlays/1
+ $ echo "some_overlay.dtb.o" > /config/device-tree/overlays/1/path
+
+This causes the FPGA Area to be probed and will do the following:
+ 1. Disable the FPGA bridges.
+ 2. Use the the FPGA manager core to program the FPGA.
+ 3. Enable the FPGA bridges.
+ 4. Call of_platform_populate resulting in device drivers getting probed.
+
+Removing the overlay is done by:
+
+ $ rmdir /config/device-tree/overlays/1
+
+This causes the child nodes to be removed and then the bridges are disabled.
+
+Device Tree Examples
+====================
+
+The intention of this section is to give some simple examples, focusing on
+the placement of the elements detailed above in, especially:
+ * FPGA Managers
+ * FPGA Bridges in some cases
+ * FPGA Areas and associated properties
+ * simple-bus
+ * ranges
+ * target-path
+
+Please note the "simple-bus" compatible string added for FPGA Managers and for
+FPGA Bridges where the overlay is targeted for insertion.  This is required for
+populating the child nodes.
+
+Device Tree Example: Partial Reconfiguration with no Bridges
+============================================================
+
+Live Device Tree contains:
+	fpgamgr@0 {
+		compatible = "altr,socfpga-a10-fpga-mgr", "simple-bus";
+		clocks = <&l4_mp_clk>;
+		resets = <&rst FPGAMGR_RESET>;
+		reset-names = "fpgamgr";
+		reg = <0xffd03000 0x1000
+		       0xffcfe400 0x1000>;
+
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		ranges;
+	};
+
+DT Overlay contains:
+/dts-v1/;
+/plugin/;
+/ {
+	fragment@0 {
+		target-path="/soc/fpgamgr@0";  /* targeted to the manager */
+		__overlay__ {
+			#address-cells = <1>;
+	                #size-cells = <1>;
+
+			area@0 {
+				compatible = "fpga-area";
+
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x10010 0xff210010 0x10>;
+
+				firmware-name = "fit_pr_v1.rbf";
+				partial-reconfig;
+
+				gpio@0x100010010 {
+					compatible = "altr,pio-1.0";
+					reg = <0x10010 0x10>;
+					altr,ngpio = <4>;
+					#gpio-cells = <0x2>;
+					gpio-controller;
+				};
+			};
+		};
+	};
+};
+
+
+Device Tree Example: Full Reconfiguration with Bridges
+======================================================
+
+Live Device Tree contains:
+	fpgamgr@0 {
+		compatible = "altr,socfpga-fpga-mgr", "simple-bus";
+		reg = <0xFF706000 0x1000
+		       0xFFB90000 0x1000>;
+		interrupts = <0 175 4>;
+
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		ranges;
+
+		bridge@0 {
+			/* both the manager and the controlling bridge have
+			 * the added simple-bus compatible to allow child
+			 * devices to be populated. */
+			compatible = "altr,socfpga-lwhps2fpga-bridge",
+				     "simple-bus";
+			resets = <&rst LWHPS2FPGA_RESET>;
+			reset-names = "lwhps2fpga";
+			clocks = <&l4_main_clk>;
+			#address-cells = <0x1>;
+			#size-cells = <0x1>;
+			ranges;
+		};
+
+		bridge@1 {
+			/* In the case of full reconfiguration, both bridge@0
+			 * and bridge@1 will be disabled during FPGA
+			 * programming and enabled afterwards. */
+			compatible = "altr,socfpga-hps2fpga-bridge";
+			resets = <&rst HPS2FPGA_RESET>;
+			reset-names = "hps2fpga";
+			clocks = <&l4_main_clk>;
+		};
+	};
+
+DT Overlay contains:
+/dts-v1/;
+/plugin/;
+/ {
+	fragment@0 {
+		target-path="/soc/fpgamgr@0/bridge@0"; /* controlling bridge */
+		__overlay__ {
+			#address-cells = <1>;
+	                #size-cells = <1>;
+
+			area@0 {
+				compatible = "fpga-area";
+
+				#address-cells = <2>;
+				#size-cells = <1>;
+				/* Note that two ranges are mapped due to the
+				 * two bridges. */
+				ranges = <0 0x00000000 0xc0000000 0x00010000>,
+					 <1 0x00020000 0xff220000 0x00000008>;
+
+				firmware-name = "soc_system.rbf";
+
+				onchip_memory2_0: memory@000000000 {
+					device_type = "memory";
+					compatible = "altr,onchipmem-15.1";
+					reg = <0 0x00000000 0x00010000>;
+				};
+
+				jtag_uart: serial@0x100020000 {
+					compatible = "altr,juart-1.0";
+					reg = <1 0x00020000 0x00000008>;
+					interrupt-parent = <&intc>;
+					interrupts = <0 42 4>;
+					clocks = <&osc2>;
+				};
+			};
+		};
+	};
+};
+
-- 
1.7.9.5


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

* [PATCH v14 1/7] fpga: add usage documentation for fpga area
@ 2015-12-10 23:37   ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

Add a document spelling out usage of the FPGA Area for
reprogramming FPGA's under Device Tree control.

Signed-off-by: Alan Tull <atull@opensource.altera.com>

---
v9:  Initial version of this patch in patchset
v10: s/fpga/FPGA/g
     improve formatting
     some rewriting
     move to staging/simple-fpga-bus
v11: No change in this patch for v11 of the patch set
v12: Moved out of staging
     Small changes due to using FPGA bridge framework and not
     representing the bridges as resets.
v13: Fix some nits
v14: fpga-area instead of simple-fpga-bus
---
 Documentation/fpga/fpga-area.txt |  299 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 299 insertions(+)
 create mode 100644 Documentation/fpga/fpga-area.txt

diff --git a/Documentation/fpga/fpga-area.txt b/Documentation/fpga/fpga-area.txt
new file mode 100644
index 0000000..f031522
--- /dev/null
+++ b/Documentation/fpga/fpga-area.txt
@@ -0,0 +1,299 @@
+FPGA Area
+
+Alan Tull 2015
+
+Overview
+========
+
+An FPGA Area details information about a section of an FPGA including the FPGA
+image needed to program it and the hardware contained once it is programmed.
+
+Loading a Device Tree overlay which contains an FPGA Area will cause the
+FPGA to be programmed and the children of the FPGA Area will get probed.
+
+There may be FPGA Bridges involved to prevent spurious data from going out onto
+the processor bus during FPGA programming.  If so, the FPGA Area will need to
+disable and enable bridges that will only affect the child devices that are
+below the FPGA Area.  In the case of partial reconfiguration, bridges will
+be required within the FPGA design such that the active sections of the
+FPGA are on the bus while sections that are not programmed or being
+reprogrammed at the moment are isolated.
+
+Removing the overlay will result in the child devices getting removed and the
+bridges disabled.  Note that in the case of partial reconfiguration the rest of
+the FPGA continues to function as normal while this is happening.
+
+Below are more details on the structuring of the Device Tree for this.
+
+Terminology
+===========
+
+Full Reconfiguration
+ * The entire FPGA is reprogrammed.
+
+Partial Reconfiguration (PR)
+ * Part of the FPGA is reprogrammed while the rest of the FPGA is live and
+   active.  Not all FPGA's support this.
+
+Associated Blocks
+=================
+
+FPGA Manager Framework
+ * An FPGA Manager is a hardware block that programs an FPGA under the control
+   of a host processor.
+ * The FPGA Manager Framework provides drivers and functions to program an
+   FPGA.
+
+FPGA Bridge Framework
+ * Provides drivers and functions to control bridges that enable/disable
+   data to the FPGA.
+ * FPGA bridges should be disabled while the FPGA is being programmed to
+   prevent spurious data on the bus.
+ * FPGA bridges are not needed in implementations where the FPGA Manager
+   handles this.
+
+Device Tree
+===========
+
+For the purposes of this document, I'm dividing the Device Tree (DT) into two parts,
+each with its own requirements.  The two parts are:
+ * The live DT prior to the overlay being added
+ * The overlay containing an FPGA Area
+
+The live DT will contain:
+ * FPGA Manager
+ * FPGA Bridges as children of the FPGA Manager (optional, architecture specific)
+
+The live Device Tree must contain an FPGA Manager to handle programming the FPGA.
+If FPGA Bridges need to be involved, they show up in the DT as direct children
+of the FPGA Manager.  During full reconfiguration, the FPGA Area will disable
+any bridges that are direct children of the manager during full reconfiguration
+and will re-enable them afterwards.
+
+The insertion point in the live tree will also need the "simple-bus"
+compatibility string to enable populating the child nodes for the overlay.
+That includes the nodes for the FPGA Manager and controlling FPGA Bridges
+as explained below.
+
+The Device Tree Overlay will contain:
+ * "target-path"
+   The insertion point where the the contents of the overlay will go into the
+   live tree.
+ * "ranges"
+ * "firmware-name"
+   Specifies the name of the FPGA image file on the firmware search
+   path.  The search path is described in the firmware class documentation.
+ * "partial-reconfig"
+   This binding is a boolean and should be present if partial reconfiguration
+   is to be done.
+ * child nodes corresponding to hardware that will be loaded in this
+   region of the FPGA.
+
+Supported use models
+====================
+
+Here's a list of the superset of supported use models.  We may need to add
+more.  Some uses are specific to one FPGA or another.
+
+ * No FPGA Bridges
+   In this case, the FPGA Manager which programs the FPGA also handles the
+   bridges and no FPGA Bridge devices are needed for full reconfiguration.
+
+   The DT overlay will specify the FPGA Manager as the overlay target.
+
+ * Full reconfiguration with bridges
+   In the case, there are several bridges between the processor and FPGA,
+   that need to be disabled during full reconfiguration.
+   The DT before the overlay is applied will have an FPGA Manager.  The
+   immediate children of the manager will be the FPGA Bridges that need to be
+   disabled during FPGA programming.
+
+   The DT overlay will specify one of those bridges as the overlay target,
+   typically the bridge that allows memory mapped register access ("the
+   controlling bridge").
+
+ * Partial reconfiguration with bridges in the FPGA
+   In this case, the FPGA can have more than one section that will be
+   reprogrammed separately.  Other sections may be active on the bus while FPGA
+   is being programmed.  To manage this, FPGA Bridges need to exist on the FPGA
+   that can freeze all the buses going to one FPGA area while the buses are
+   enabled for other sections.
+
+Controlling Bridge
+==================
+
+It is possible that there are multiple FPGA Bridges connecting the processor
+and FPGA.  In a text based hierarchy, it is difficult to show this properly
+so what we do is consider the bridge that handles register access to be
+the controlling bridge.  The overlay is targeted to be inserted under the
+controlling bridge.  Other bridges are on the same level of the device tree
+as the controlling bridge, i.e. all are children of the FPGA Manager.  The
+ranges property handles mapping memory ranges through multiple bridges.
+
+Sequence
+========
+
+Load the DT overlay.  One way to do that from user space is to use Pantelis
+Antoniou's DT-Overlay configfs interface.  In that case the sequence from
+userspace is:
+
+ $ mkdir /config/device-tree/overlays/1
+ $ echo "some_overlay.dtb.o" > /config/device-tree/overlays/1/path
+
+This causes the FPGA Area to be probed and will do the following:
+ 1. Disable the FPGA bridges.
+ 2. Use the the FPGA manager core to program the FPGA.
+ 3. Enable the FPGA bridges.
+ 4. Call of_platform_populate resulting in device drivers getting probed.
+
+Removing the overlay is done by:
+
+ $ rmdir /config/device-tree/overlays/1
+
+This causes the child nodes to be removed and then the bridges are disabled.
+
+Device Tree Examples
+====================
+
+The intention of this section is to give some simple examples, focusing on
+the placement of the elements detailed above in, especially:
+ * FPGA Managers
+ * FPGA Bridges in some cases
+ * FPGA Areas and associated properties
+ * simple-bus
+ * ranges
+ * target-path
+
+Please note the "simple-bus" compatible string added for FPGA Managers and for
+FPGA Bridges where the overlay is targeted for insertion.  This is required for
+populating the child nodes.
+
+Device Tree Example: Partial Reconfiguration with no Bridges
+============================================================
+
+Live Device Tree contains:
+	fpgamgr@0 {
+		compatible = "altr,socfpga-a10-fpga-mgr", "simple-bus";
+		clocks = <&l4_mp_clk>;
+		resets = <&rst FPGAMGR_RESET>;
+		reset-names = "fpgamgr";
+		reg = <0xffd03000 0x1000
+		       0xffcfe400 0x1000>;
+
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		ranges;
+	};
+
+DT Overlay contains:
+/dts-v1/;
+/plugin/;
+/ {
+	fragment@0 {
+		target-path="/soc/fpgamgr@0";  /* targeted to the manager */
+		__overlay__ {
+			#address-cells = <1>;
+	                #size-cells = <1>;
+
+			area@0 {
+				compatible = "fpga-area";
+
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0x10010 0xff210010 0x10>;
+
+				firmware-name = "fit_pr_v1.rbf";
+				partial-reconfig;
+
+				gpio@0x100010010 {
+					compatible = "altr,pio-1.0";
+					reg = <0x10010 0x10>;
+					altr,ngpio = <4>;
+					#gpio-cells = <0x2>;
+					gpio-controller;
+				};
+			};
+		};
+	};
+};
+
+
+Device Tree Example: Full Reconfiguration with Bridges
+======================================================
+
+Live Device Tree contains:
+	fpgamgr@0 {
+		compatible = "altr,socfpga-fpga-mgr", "simple-bus";
+		reg = <0xFF706000 0x1000
+		       0xFFB90000 0x1000>;
+		interrupts = <0 175 4>;
+
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		ranges;
+
+		bridge@0 {
+			/* both the manager and the controlling bridge have
+			 * the added simple-bus compatible to allow child
+			 * devices to be populated. */
+			compatible = "altr,socfpga-lwhps2fpga-bridge",
+				     "simple-bus";
+			resets = <&rst LWHPS2FPGA_RESET>;
+			reset-names = "lwhps2fpga";
+			clocks = <&l4_main_clk>;
+			#address-cells = <0x1>;
+			#size-cells = <0x1>;
+			ranges;
+		};
+
+		bridge@1 {
+			/* In the case of full reconfiguration, both bridge@0
+			 * and bridge@1 will be disabled during FPGA
+			 * programming and enabled afterwards. */
+			compatible = "altr,socfpga-hps2fpga-bridge";
+			resets = <&rst HPS2FPGA_RESET>;
+			reset-names = "hps2fpga";
+			clocks = <&l4_main_clk>;
+		};
+	};
+
+DT Overlay contains:
+/dts-v1/;
+/plugin/;
+/ {
+	fragment@0 {
+		target-path="/soc/fpgamgr@0/bridge@0"; /* controlling bridge */
+		__overlay__ {
+			#address-cells = <1>;
+	                #size-cells = <1>;
+
+			area@0 {
+				compatible = "fpga-area";
+
+				#address-cells = <2>;
+				#size-cells = <1>;
+				/* Note that two ranges are mapped due to the
+				 * two bridges. */
+				ranges = <0 0x00000000 0xc0000000 0x00010000>,
+					 <1 0x00020000 0xff220000 0x00000008>;
+
+				firmware-name = "soc_system.rbf";
+
+				onchip_memory2_0: memory@000000000 {
+					device_type = "memory";
+					compatible = "altr,onchipmem-15.1";
+					reg = <0 0x00000000 0x00010000>;
+				};
+
+				jtag_uart: serial@0x100020000 {
+					compatible = "altr,juart-1.0";
+					reg = <1 0x00020000 0x00000008>;
+					interrupt-parent = <&intc>;
+					interrupts = <0 42 4>;
+					clocks = <&osc2>;
+				};
+			};
+		};
+	};
+};
+
-- 
1.7.9.5

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

* [PATCH v14 2/7] fpga: add bindings document for fpga area
  2015-12-10 23:37 ` atull
@ 2015-12-10 23:37   ` atull
  -1 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

New bindings document for FPGA Area for reprogramming
FPGA's under Device Tree control

Signed-off-by: Alan Tull <atull@opensource.altera.com>
---
v9:  initial version added to this patchset
v10: s/fpga/FPGA/g
     replace DT overlay example with slightly more complicated example
     move to staging/simple-fpga-bus
v11: No change in this patch for v11 of the patch set
v12: Moved out of staging.
     Changed to use FPGA bridges framework instead of resets
     for bridges.
v13: bridge@0xff20000 -> bridge@ff200000, etc
     Leave out directly talking about overlays
     Remove regs and clocks directly under simple-fpga-bus in example
     Use common "firmware-name" binding instead of "fpga-firmware"
v14: Use firmware-name in bindings description
     Call it FPGA Area
     Remove bindings that specify FPGA Manager and FPGA Bridges
---
 .../devicetree/bindings/fpga/fpga-area.txt         |   70 ++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fpga/fpga-area.txt

diff --git a/Documentation/devicetree/bindings/fpga/fpga-area.txt b/Documentation/devicetree/bindings/fpga/fpga-area.txt
new file mode 100644
index 0000000..d656e35
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/fpga-area.txt
@@ -0,0 +1,70 @@
+FPGA Area
+=========
+
+A FPGA Area details information about a section of an FPGA including the FPGA
+image needed to program it and the hardware contained in this section of the
+FPGA once it is programmed.
+
+A FPGA Area corresponds to the whole FPGA in the case of full reconfiguration
+or a section of a FPGA in the case of partial reconfiguration.
+
+Required properties:
+- compatible : should contain "fpga-area"
+- #address-cells, #size-cells, ranges: must be present to handle address space
+  mapping for children.
+
+Optional properties:
+- firmware-name : should contain the name of a FPGA image file located on the
+  firmware search path.
+- partial-reconfig : boolean property should be defined if partial
+  reconfiguration of the FPGA is to be done, otherwise full reconfiguration
+  is done.
+
+Example:
+
+/dts-v1/;
+/plugin/;
+/ {
+	fragment@0 {
+		target-path="/soc/fpgamgr@0/bridge@0";
+		__overlay__ {
+			#address-cells = <1>;
+	                #size-cells = <1>;
+
+			bridge@ff200000 {
+				compatible = "fpga-area";
+
+				#address-cells = <2>;
+				#size-cells = <1>;
+
+				ranges = <0 0x00000000 0xc0000000 0x00010000>,
+					 <1 0x00020000 0xff220000 0x00000008>,
+					 <1 0x00010040 0xff210040 0x00000020>;
+
+				firmware-name = "soc_system.rbf";
+
+				onchip_memory2_0: memory@000000000 {
+					device_type = "memory";
+					compatible = "altr,onchipmem-15.1";
+					reg = <0 0x00000000 0x00010000>;
+				};
+
+				jtag_uart: serial@100020000 {
+					compatible = "altr,juart-1.0";
+					reg = <1 0x00020000 0x00000008>;
+					interrupt-parent = <&intc>;
+					interrupts = <0 42 4>;
+				};
+
+				led_pio: gpio@100010040 {
+					compatible = "altr,pio-1.0";
+					reg = <1 0x00010040 0x00000020>;
+					altr,gpio-bank-width = <4>;
+					#gpio-cells = <2>;
+					gpio-controller;
+				};
+			};
+		};
+	};
+};
+
-- 
1.7.9.5


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

* [PATCH v14 2/7] fpga: add bindings document for fpga area
@ 2015-12-10 23:37   ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

New bindings document for FPGA Area for reprogramming
FPGA's under Device Tree control

Signed-off-by: Alan Tull <atull@opensource.altera.com>
---
v9:  initial version added to this patchset
v10: s/fpga/FPGA/g
     replace DT overlay example with slightly more complicated example
     move to staging/simple-fpga-bus
v11: No change in this patch for v11 of the patch set
v12: Moved out of staging.
     Changed to use FPGA bridges framework instead of resets
     for bridges.
v13: bridge@0xff20000 -> bridge@ff200000, etc
     Leave out directly talking about overlays
     Remove regs and clocks directly under simple-fpga-bus in example
     Use common "firmware-name" binding instead of "fpga-firmware"
v14: Use firmware-name in bindings description
     Call it FPGA Area
     Remove bindings that specify FPGA Manager and FPGA Bridges
---
 .../devicetree/bindings/fpga/fpga-area.txt         |   70 ++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fpga/fpga-area.txt

diff --git a/Documentation/devicetree/bindings/fpga/fpga-area.txt b/Documentation/devicetree/bindings/fpga/fpga-area.txt
new file mode 100644
index 0000000..d656e35
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/fpga-area.txt
@@ -0,0 +1,70 @@
+FPGA Area
+=========
+
+A FPGA Area details information about a section of an FPGA including the FPGA
+image needed to program it and the hardware contained in this section of the
+FPGA once it is programmed.
+
+A FPGA Area corresponds to the whole FPGA in the case of full reconfiguration
+or a section of a FPGA in the case of partial reconfiguration.
+
+Required properties:
+- compatible : should contain "fpga-area"
+- #address-cells, #size-cells, ranges: must be present to handle address space
+  mapping for children.
+
+Optional properties:
+- firmware-name : should contain the name of a FPGA image file located on the
+  firmware search path.
+- partial-reconfig : boolean property should be defined if partial
+  reconfiguration of the FPGA is to be done, otherwise full reconfiguration
+  is done.
+
+Example:
+
+/dts-v1/;
+/plugin/;
+/ {
+	fragment@0 {
+		target-path="/soc/fpgamgr@0/bridge@0";
+		__overlay__ {
+			#address-cells = <1>;
+	                #size-cells = <1>;
+
+			bridge@ff200000 {
+				compatible = "fpga-area";
+
+				#address-cells = <2>;
+				#size-cells = <1>;
+
+				ranges = <0 0x00000000 0xc0000000 0x00010000>,
+					 <1 0x00020000 0xff220000 0x00000008>,
+					 <1 0x00010040 0xff210040 0x00000020>;
+
+				firmware-name = "soc_system.rbf";
+
+				onchip_memory2_0: memory@000000000 {
+					device_type = "memory";
+					compatible = "altr,onchipmem-15.1";
+					reg = <0 0x00000000 0x00010000>;
+				};
+
+				jtag_uart: serial@100020000 {
+					compatible = "altr,juart-1.0";
+					reg = <1 0x00020000 0x00000008>;
+					interrupt-parent = <&intc>;
+					interrupts = <0 42 4>;
+				};
+
+				led_pio: gpio@100010040 {
+					compatible = "altr,pio-1.0";
+					reg = <1 0x00010040 0x00000020>;
+					altr,gpio-bank-width = <4>;
+					#gpio-cells = <2>;
+					gpio-controller;
+				};
+			};
+		};
+	};
+};
+
-- 
1.7.9.5

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

* [PATCH v14 3/7] add sysfs document for fpga bridge class
  2015-12-10 23:37 ` atull
@ 2015-12-10 23:37   ` atull
  -1 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

Add documentation for new FPGA bridge class's sysfs interface.

Signed-off-by: Alan Tull <atull@opensource.altera.com>
---
 Documentation/ABI/testing/sysfs-class-fpga-bridge |   11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-bridge

diff --git a/Documentation/ABI/testing/sysfs-class-fpga-bridge b/Documentation/ABI/testing/sysfs-class-fpga-bridge
new file mode 100644
index 0000000..e45d952
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-fpga-bridge
@@ -0,0 +1,11 @@
+What:		/sys/class/fpga_bridge/<bridge>/name
+Date:		December 2015
+KernelVersion:	4.4
+Contact:	Alan Tull <atull@opensource.altera.com>
+Description:	Name of low level FPGA bridge driver.
+
+What:		/sys/class/fpga_bridge/<bridge>/state
+Date:		December 2015
+KernelVersion:	4.4
+Contact:	Alan Tull <atull@opensource.altera.com>
+Description:	Show bridge state as "enabled" or "disabled"
-- 
1.7.9.5


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

* [PATCH v14 3/7] add sysfs document for fpga bridge class
@ 2015-12-10 23:37   ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

Add documentation for new FPGA bridge class's sysfs interface.

Signed-off-by: Alan Tull <atull@opensource.altera.com>
---
 Documentation/ABI/testing/sysfs-class-fpga-bridge |   11 +++++++++++
 1 file changed, 11 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-bridge

diff --git a/Documentation/ABI/testing/sysfs-class-fpga-bridge b/Documentation/ABI/testing/sysfs-class-fpga-bridge
new file mode 100644
index 0000000..e45d952
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-fpga-bridge
@@ -0,0 +1,11 @@
+What:		/sys/class/fpga_bridge/<bridge>/name
+Date:		December 2015
+KernelVersion:	4.4
+Contact:	Alan Tull <atull@opensource.altera.com>
+Description:	Name of low level FPGA bridge driver.
+
+What:		/sys/class/fpga_bridge/<bridge>/state
+Date:		December 2015
+KernelVersion:	4.4
+Contact:	Alan Tull <atull@opensource.altera.com>
+Description:	Show bridge state as "enabled" or "disabled"
-- 
1.7.9.5

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

* [PATCH v14 4/7] ARM: socfpga: add bindings document for fpga bridge drivers
  2015-12-10 23:37 ` atull
@ 2015-12-10 23:37   ` atull
  -1 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull,
	Matthew Gerlach

From: Alan Tull <atull@opensource.altera.com>

Add bindings documentation for Altera SOCFPGA bridges:
 * fpga2sdram
 * fpga2hps
 * hps2fpga
 * lwhps2fpga

Signed-off-by: Alan Tull <atull@opensource.altera.com>
Signed-off-by: Matthew Gerlach <mgerlach@altera.com>
Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
---
v2:  separate into 2 documents for the 2 drivers
v12: bump version to line up with simple-fpga-bus version
     remove Linux specific notes such as references to sysfs
     move non-DT specific documentation elsewhere
     remove bindings that would have been used to pass configuration
     clean up formatting
v13: Remove 'label' property
     Change property from init-val to bridge-enable
     Fix email address
v14: Add resets
     Change order of bridges to put lw bridge (controlling bridge) first
---
 .../bindings/fpga/altera-fpga2sdram-bridge.txt     |   15 +++++++
 .../bindings/fpga/altera-hps2fpga-bridge.txt       |   43 ++++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
 create mode 100644 Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt

diff --git a/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
new file mode 100644
index 0000000..81e2f06
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
@@ -0,0 +1,15 @@
+Altera FPGA To SDRAM Bridge Driver
+
+Required properties:
+- compatible		: Should contain "altr,socfpga-fpga2sdram-bridge"
+
+Optional properties:
+- bridge-enable		: 0 if driver should disable bridge at startup
+			  1 if driver should enable bridge at startup
+			  Default is to leave bridge in current state.
+
+Example:
+	fpga2sdram_br: fpgabridge@3 {
+		compatible = "altr,socfpga-fpga2sdram-bridge";
+		bridge-enable = <0>;
+	};
diff --git a/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
new file mode 100644
index 0000000..16db3b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
@@ -0,0 +1,43 @@
+Altera FPGA/HPS Bridge Driver
+
+Required properties:
+- compatible	: Should contain one of:
+		  "altr,socfpga-lwhps2fpga-bridge",
+		  "altr,socfpga-hps2fpga-bridge", or
+		  "altr,socfpga-fpga2hps-bridge"
+- reset-names	: Should contain one of:
+		  "lwhps2fpga",
+		  "hps2fpga", or
+		  "fpga2hps"
+- resets	: Phandle and reset specifier for the reset listed in
+		  reset-names
+- clocks	: Clocks used by this module.
+
+Optional properties:
+- bridge-enable	: 0 if driver should disable bridge at startup.
+		  1 if driver should enable bridge at startup.
+		  Default is to leave bridge in its current state.
+
+Example:
+	hps_fpgabridge0: fpgabridge@0 {
+		compatible = "altr,socfpga-lwhps2fpga-bridge";
+		resets = <&rst LWHPS2FPGA_RESET>;
+		reset-names = "lwhps2fpga";
+		clocks = <&l4_main_clk>;
+		bridge-enable = <0>;
+	};
+
+	hps_fpgabridge1: fpgabridge@1 {
+		compatible = "altr,socfpga-hps2fpga-bridge";
+		resets = <&rst HPS2FPGA_RESET>;
+		reset-names = "hps2fpga";
+		clocks = <&l4_main_clk>;
+		bridge-enable = <1>;
+	};
+
+	hps_fpgabridge2: fpgabridge@2 {
+		compatible = "altr,socfpga-fpga2hps-bridge";
+		resets = <&rst FPGA2HPS_RESET>;
+		reset-names = "fpga2hps";
+		clocks = <&l4_main_clk>;
+	};
-- 
1.7.9.5


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

* [PATCH v14 4/7] ARM: socfpga: add bindings document for fpga bridge drivers
@ 2015-12-10 23:37   ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull,
	Matthew Gerlach

From: Alan Tull <atull@opensource.altera.com>

Add bindings documentation for Altera SOCFPGA bridges:
 * fpga2sdram
 * fpga2hps
 * hps2fpga
 * lwhps2fpga

Signed-off-by: Alan Tull <atull@opensource.altera.com>
Signed-off-by: Matthew Gerlach <mgerlach@altera.com>
Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
---
v2:  separate into 2 documents for the 2 drivers
v12: bump version to line up with simple-fpga-bus version
     remove Linux specific notes such as references to sysfs
     move non-DT specific documentation elsewhere
     remove bindings that would have been used to pass configuration
     clean up formatting
v13: Remove 'label' property
     Change property from init-val to bridge-enable
     Fix email address
v14: Add resets
     Change order of bridges to put lw bridge (controlling bridge) first
---
 .../bindings/fpga/altera-fpga2sdram-bridge.txt     |   15 +++++++
 .../bindings/fpga/altera-hps2fpga-bridge.txt       |   43 ++++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
 create mode 100644 Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt

diff --git a/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
new file mode 100644
index 0000000..81e2f06
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
@@ -0,0 +1,15 @@
+Altera FPGA To SDRAM Bridge Driver
+
+Required properties:
+- compatible		: Should contain "altr,socfpga-fpga2sdram-bridge"
+
+Optional properties:
+- bridge-enable		: 0 if driver should disable bridge at startup
+			  1 if driver should enable bridge at startup
+			  Default is to leave bridge in current state.
+
+Example:
+	fpga2sdram_br: fpgabridge@3 {
+		compatible = "altr,socfpga-fpga2sdram-bridge";
+		bridge-enable = <0>;
+	};
diff --git a/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
new file mode 100644
index 0000000..16db3b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
@@ -0,0 +1,43 @@
+Altera FPGA/HPS Bridge Driver
+
+Required properties:
+- compatible	: Should contain one of:
+		  "altr,socfpga-lwhps2fpga-bridge",
+		  "altr,socfpga-hps2fpga-bridge", or
+		  "altr,socfpga-fpga2hps-bridge"
+- reset-names	: Should contain one of:
+		  "lwhps2fpga",
+		  "hps2fpga", or
+		  "fpga2hps"
+- resets	: Phandle and reset specifier for the reset listed in
+		  reset-names
+- clocks	: Clocks used by this module.
+
+Optional properties:
+- bridge-enable	: 0 if driver should disable bridge at startup.
+		  1 if driver should enable bridge at startup.
+		  Default is to leave bridge in its current state.
+
+Example:
+	hps_fpgabridge0: fpgabridge@0 {
+		compatible = "altr,socfpga-lwhps2fpga-bridge";
+		resets = <&rst LWHPS2FPGA_RESET>;
+		reset-names = "lwhps2fpga";
+		clocks = <&l4_main_clk>;
+		bridge-enable = <0>;
+	};
+
+	hps_fpgabridge1: fpgabridge@1 {
+		compatible = "altr,socfpga-hps2fpga-bridge";
+		resets = <&rst HPS2FPGA_RESET>;
+		reset-names = "hps2fpga";
+		clocks = <&l4_main_clk>;
+		bridge-enable = <1>;
+	};
+
+	hps_fpgabridge2: fpgabridge@2 {
+		compatible = "altr,socfpga-fpga2hps-bridge";
+		resets = <&rst FPGA2HPS_RESET>;
+		reset-names = "fpga2hps";
+		clocks = <&l4_main_clk>;
+	};
-- 
1.7.9.5

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

* [PATCH v14 5/7] fpga: add fpga bridge framework
  2015-12-10 23:37 ` atull
@ 2015-12-10 23:37   ` atull
  -1 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

This framework adds API functions for enabling/
disabling FPGA bridges under kernel control.

This allows the Linux kernel to disable FPGA bridges
during FPGA reprogramming and to enable FPGA bridges
when FPGA reprogramming is done.  This framework is
be manufacturer-agnostic, allowing it to be used in
interfaces that use the FPGA Manager Framework to
reprogram FPGA's.

The functions are:
* of_fpga_bridge_get
* fpga_bridge_put
   Get/put an exclusive reference to a FPGA bridge.

* fpga_bridge_enable
* fpga_bridge_disable
   Enable/Disable traffic through a bridge.

* fpga_bridge_register
* fpga_bridge_unregister
   Register/unregister a device-specific low level FPGA
   Bridge driver.

Get an exclusive reference to a bridge and add it to a list:
* fpga_bridge_get_to_list

To enable/disable/put a set of bridges that are on a list:
* fpga_bridges_enable
* fpga_bridges_disable
* fpga_bridges_put

Signed-off-by: Alan Tull <atull@opensource.altera.com>
---
v2:  Minor cleanup
v12: Bump version to line up with simple fpga bus
     Remove sysfs
     Improve get/put functions, get the low level driver too.
     Clean up class implementation
     Add kernel doc documentation
     Rename (un)register_fpga_bridge -> fpga_bridge_(un)register
v13: Add inlined empty functions for if not CONFIG_FPGA_BRIDGE
     Clean up debugging
     Remove unneeded #include in .h
     Remove unnecessary prints
     Remove 'label' DT binding.
     Document the mutex
v14: Allow bridges with no ops
     *const* struct fpga_bridge_ops
     Add functions to git/put/enable/disable list of bridges
     Add list node to struct fpga_bridge
     Do of_node_get/put in of_fpga_bridge_get()
     Add r/o attributes: name and state
---
 drivers/fpga/Kconfig             |    7 +
 drivers/fpga/Makefile            |    3 +
 drivers/fpga/fpga-bridge.c       |  388 ++++++++++++++++++++++++++++++++++++++
 include/linux/fpga/fpga-bridge.h |   56 ++++++
 4 files changed, 454 insertions(+)
 create mode 100644 drivers/fpga/fpga-bridge.c
 create mode 100644 include/linux/fpga/fpga-bridge.h

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index c9b9fdf..b6cfd89 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -24,6 +24,13 @@ config FPGA_MGR_ZYNQ_FPGA
 	help
 	  FPGA manager driver support for Xilinx Zynq FPGAs.
 
+config FPGA_BRIDGE
+       bool "FPGA Bridge Framework"
+       depends on OF
+       help
+         Say Y here if you want to support bridges connected between host
+	 processors and FPGAs or between FPGAs.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8d83fc6..4baef00 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -8,3 +8,6 @@ obj-$(CONFIG_FPGA)			+= fpga-mgr.o
 # FPGA Manager Drivers
 obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
 obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
+
+# FPGA Bridge Drivers
+obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
new file mode 100644
index 0000000..5119d8e
--- /dev/null
+++ b/drivers/fpga/fpga-bridge.c
@@ -0,0 +1,388 @@
+/*
+ * FPGA Bridge Framework Driver
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation, All Rights Reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/fpga/fpga-bridge.h>
+#include <linux/idr.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+static DEFINE_IDA(fpga_bridge_ida);
+static struct class *fpga_bridge_class;
+
+/* Lock for adding/removing bridges to linked lists*/
+spinlock_t bridge_list_lock;
+
+static int fpga_bridge_of_node_match(struct device *dev, const void *data)
+{
+	return dev->of_node == data;
+}
+
+/**
+ * fpga_bridge_enable - Enable transactions on the bridge
+ *
+ * @bridge: FPGA bridge
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_enable(struct fpga_bridge *bridge)
+{
+	dev_dbg(&bridge->dev, "enable\n");
+
+	if (bridge->br_ops && bridge->br_ops->enable_set)
+		return bridge->br_ops->enable_set(bridge, 1);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_enable);
+
+/**
+ * fpga_bridge_disable - Disable transactions on the bridge
+ *
+ * @bridge: FPGA bridge
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_disable(struct fpga_bridge *bridge)
+{
+	dev_dbg(&bridge->dev, "disable\n");
+
+	if (bridge->br_ops && bridge->br_ops->enable_set)
+		return bridge->br_ops->enable_set(bridge, 0);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_disable);
+
+/**
+ * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
+ *
+ * @np: node pointer of a FPGA bridge
+ *
+ * Return fpga_bridge struct if successful.
+ * Return -EBUSY if someone already has a reference to the bridge.
+ * Return -ENODEV if @np is not a FPGA Bridge.
+ */
+struct fpga_bridge *of_fpga_bridge_get(struct device_node *np)
+{
+	struct device *dev;
+	struct fpga_bridge *bridge;
+	int ret = -ENODEV;
+
+	of_node_get(np);
+
+	dev = class_find_device(fpga_bridge_class, NULL, np,
+				fpga_bridge_of_node_match);
+	if (!dev)
+		goto err_dev;
+
+	bridge = to_fpga_bridge(dev);
+	if (!bridge)
+		goto err_dev;
+
+	if (!mutex_trylock(&bridge->mutex)) {
+		ret = -EBUSY;
+		goto err_dev;
+	}
+
+	if (!try_module_get(dev->parent->driver->owner))
+		goto err_ll_mod;
+
+	dev_dbg(&bridge->dev, "get\n");
+
+	return bridge;
+
+err_ll_mod:
+	mutex_unlock(&bridge->mutex);
+err_dev:
+	put_device(dev);
+	of_node_put(np);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
+
+/**
+ * fpga_bridge_put - release a reference to a bridge
+ *
+ * @bridge: FPGA bridge
+ */
+void fpga_bridge_put(struct fpga_bridge *bridge)
+{
+	dev_dbg(&bridge->dev, "put\n");
+
+	module_put(bridge->dev.parent->driver->owner);
+	mutex_unlock(&bridge->mutex);
+	put_device(&bridge->dev);
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_put);
+
+/**
+ * fpga_bridges_enable - enable bridges in a list
+ * @bridge_list: list of FPGA bridges
+ *
+ * Enable each bridge in the list.  If list is empty, do nothing.
+ *
+ * Return 0 for success or empty bridge list; return error code otherwise.
+ */
+int fpga_bridges_enable(struct list_head *bridge_list)
+{
+	struct fpga_bridge *bridge;
+	struct list_head *node;
+	int ret;
+
+	list_for_each(node, bridge_list) {
+		bridge = list_entry(node, struct fpga_bridge, node);
+		ret = fpga_bridge_enable(bridge);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridges_enable);
+
+/**
+ * fpga_bridges_disable - disable bridges in a list
+ *
+ * @bridge_list: list of FPGA bridges
+ *
+ * Disable each bridge in the list.  If list is empty, do nothing.
+ *
+ * Return 0 for success or empty bridge list; return error code otherwise.
+ */
+int fpga_bridges_disable(struct list_head *bridge_list)
+{
+	struct fpga_bridge *bridge;
+	struct list_head *node;
+	int ret;
+
+	list_for_each(node, bridge_list) {
+		bridge = list_entry(node, struct fpga_bridge, node);
+		ret = fpga_bridge_disable(bridge);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridges_disable);
+
+/**
+ * fpga_bridges_put - put bridges
+ *
+ * @bridge_list: list of FPGA bridges
+ *
+ * For each bridge in the list, put the bridge and remove it from the list.
+ * If list is empty, do nothing.
+ */
+void fpga_bridges_put(struct list_head *bridge_list)
+{
+	struct fpga_bridge *bridge;
+	struct list_head *node, *next;
+	unsigned long flags;
+
+	list_for_each_safe(node, next, bridge_list) {
+		bridge = list_entry(node, struct fpga_bridge, node);
+
+		fpga_bridge_put(bridge);
+
+		spin_lock_irqsave(&bridge_list_lock, flags);
+		list_del(&bridge->node);
+		spin_unlock_irqrestore(&bridge_list_lock, flags);
+	}
+}
+EXPORT_SYMBOL_GPL(fpga_bridges_put);
+
+/**
+ * fpga_bridges_get_to_list - get a bridge, add it to a list
+ *
+ * @np: node pointer of a FPGA bridge
+ * @bridge_list: list of FPGA bridges
+ *
+ * Get an exclusive reference to the bridge and and it to the list.
+ *
+ * Return 0 for success, error code from of_fpga_bridge_get() othewise.
+ */
+int fpga_bridge_get_to_list(struct device_node *np,
+			    struct list_head *bridge_list)
+{
+	struct fpga_bridge *bridge;
+	unsigned long flags;
+
+	bridge = of_fpga_bridge_get(np);
+	if (IS_ERR(bridge))
+		return PTR_ERR(bridge);
+
+	spin_lock_irqsave(&bridge_list_lock, flags);
+	list_add(&bridge->node, bridge_list);
+	spin_unlock_irqrestore(&bridge_list_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
+
+static ssize_t name_show(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	struct fpga_bridge *bridge = to_fpga_bridge(dev);
+
+	return sprintf(buf, "%s\n", bridge->name);
+}
+
+static ssize_t state_show(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	struct fpga_bridge *bridge = to_fpga_bridge(dev);
+	int enable = 1;
+
+	if (bridge->br_ops && bridge->br_ops->enable_show)
+		enable = bridge->br_ops->enable_show(bridge);
+
+	return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
+}
+
+static DEVICE_ATTR_RO(name);
+static DEVICE_ATTR_RO(state);
+
+static struct attribute *fpga_bridge_attrs[] = {
+	&dev_attr_name.attr,
+	&dev_attr_state.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(fpga_bridge);
+
+/**
+ * fpga_bridge_register - register a fpga bridge driver
+ * @dev:	FPGA bridge device from pdev
+ * @name:	FPGA bridge name
+ * @br_ops:	pointer to structure of fpga bridge ops
+ * @priv:	FPGA bridge private data
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_register(struct device *dev, const char *name,
+			 const struct fpga_bridge_ops *br_ops, void *priv)
+{
+	struct fpga_bridge *bridge;
+	int id, ret = 0;
+
+	if (!name || !strlen(name)) {
+		dev_err(dev, "Attempt to register with no name!\n");
+		return -EINVAL;
+	}
+
+	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
+	if (!bridge)
+		return -ENOMEM;
+
+	id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
+	if (id < 0) {
+		ret = id;
+		goto error_kfree;
+	}
+
+	mutex_init(&bridge->mutex);
+	INIT_LIST_HEAD(&bridge->node);
+
+	bridge->name = name;
+	bridge->br_ops = br_ops;
+	bridge->priv = priv;
+
+	device_initialize(&bridge->dev);
+	bridge->dev.class = fpga_bridge_class;
+	bridge->dev.parent = dev;
+	bridge->dev.of_node = dev->of_node;
+	bridge->dev.id = id;
+	dev_set_drvdata(dev, bridge);
+
+	ret = dev_set_name(&bridge->dev, "br%d", id);
+	if (ret)
+		goto error_device;
+
+	ret = device_add(&bridge->dev);
+	if (ret)
+		goto error_device;
+
+	dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
+		 bridge->name);
+
+	return 0;
+
+error_device:
+	ida_simple_remove(&fpga_bridge_ida, id);
+error_kfree:
+	kfree(bridge);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_register);
+
+/**
+ * fpga_bridge_unregister - unregister a fpga bridge driver
+ * @dev: FPGA bridge device from pdev
+ */
+void fpga_bridge_unregister(struct device *dev)
+{
+	struct fpga_bridge *bridge = dev_get_drvdata(dev);
+
+	/*
+	 * If the low level driver provides a method for putting bridge into
+	 * a desired state upon unregister, do it.
+	 */
+	if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
+		bridge->br_ops->fpga_bridge_remove(bridge);
+
+	device_unregister(&bridge->dev);
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
+
+static void fpga_bridge_dev_release(struct device *dev)
+{
+	struct fpga_bridge *bridge = to_fpga_bridge(dev);
+
+	ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
+	kfree(bridge);
+}
+
+static int __init fpga_bridge_dev_init(void)
+{
+	spin_lock_init(&bridge_list_lock);
+
+	fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
+	if (IS_ERR(fpga_bridge_class))
+		return PTR_ERR(fpga_bridge_class);
+
+	fpga_bridge_class->dev_groups = fpga_bridge_groups;
+	fpga_bridge_class->dev_release = fpga_bridge_dev_release;
+
+	return 0;
+}
+
+static void __exit fpga_bridge_dev_exit(void)
+{
+	class_destroy(fpga_bridge_class);
+	ida_destroy(&fpga_bridge_ida);
+}
+
+MODULE_DESCRIPTION("FPGA Bridge Driver");
+MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
+MODULE_LICENSE("GPL v2");
+
+subsys_initcall(fpga_bridge_dev_init);
+module_exit(fpga_bridge_dev_exit);
diff --git a/include/linux/fpga/fpga-bridge.h b/include/linux/fpga/fpga-bridge.h
new file mode 100644
index 0000000..ad8471c
--- /dev/null
+++ b/include/linux/fpga/fpga-bridge.h
@@ -0,0 +1,56 @@
+#include <linux/device.h>
+
+#ifndef _LINUX_FPGA_BRIDGE_H
+#define _LINUX_FPGA_BRIDGE_H
+
+struct fpga_bridge;
+
+/**
+ * struct fpga_bridge_ops - ops for low level FPGA bridge drivers
+ * @enable_show: returns the FPGA bridge's status
+ * @enable_set: set a FPGA bridge as enabled or disabled
+ * @fpga_bridge_remove: set FPGA into a specific state during driver remove
+ */
+struct fpga_bridge_ops {
+	int (*enable_show)(struct fpga_bridge *bridge);
+	int (*enable_set)(struct fpga_bridge *bridge, bool enable);
+	void (*fpga_bridge_remove)(struct fpga_bridge *bridge);
+};
+
+/**
+ * struct fpga_bridge - FPGA bridge structure
+ * @name: name of low level FPGA bridge
+ * @dev: FPGA bridge device
+ * @mutex: enforces exclusive reference to bridge
+ * @br_ops: pointer to struct of FPGA bridge ops
+ * @node: FPGA bridge list node
+ * @priv: low level driver private date
+ */
+struct fpga_bridge {
+	const char *name;
+	struct device dev;
+	struct mutex mutex; /* for exclusive reference to bridge */
+	const struct fpga_bridge_ops *br_ops;
+	struct list_head node;
+	void *priv;
+};
+
+#define to_fpga_bridge(d) container_of(d, struct fpga_bridge, dev)
+
+struct fpga_bridge *of_get_fpga_bus(struct device_node *np);
+struct fpga_bridge *of_fpga_bridge_get(struct device_node *node);
+void fpga_bridge_put(struct fpga_bridge *bridge);
+int fpga_bridge_enable(struct fpga_bridge *bridge);
+int fpga_bridge_disable(struct fpga_bridge *bridge);
+
+int fpga_bridges_enable(struct list_head *bridge_list);
+int fpga_bridges_disable(struct list_head *bridge_list);
+void fpga_bridges_put(struct list_head *bridge_list);
+int fpga_bridge_get_to_list(struct device_node *np,
+			    struct list_head *bridge_list);
+
+int fpga_bridge_register(struct device *dev, const char *name,
+			 const struct fpga_bridge_ops *br_ops, void *priv);
+void fpga_bridge_unregister(struct device *dev);
+
+#endif /* _LINUX_FPGA_BRIDGE_H */
-- 
1.7.9.5


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

* [PATCH v14 5/7] fpga: add fpga bridge framework
@ 2015-12-10 23:37   ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

This framework adds API functions for enabling/
disabling FPGA bridges under kernel control.

This allows the Linux kernel to disable FPGA bridges
during FPGA reprogramming and to enable FPGA bridges
when FPGA reprogramming is done.  This framework is
be manufacturer-agnostic, allowing it to be used in
interfaces that use the FPGA Manager Framework to
reprogram FPGA's.

The functions are:
* of_fpga_bridge_get
* fpga_bridge_put
   Get/put an exclusive reference to a FPGA bridge.

* fpga_bridge_enable
* fpga_bridge_disable
   Enable/Disable traffic through a bridge.

* fpga_bridge_register
* fpga_bridge_unregister
   Register/unregister a device-specific low level FPGA
   Bridge driver.

Get an exclusive reference to a bridge and add it to a list:
* fpga_bridge_get_to_list

To enable/disable/put a set of bridges that are on a list:
* fpga_bridges_enable
* fpga_bridges_disable
* fpga_bridges_put

Signed-off-by: Alan Tull <atull@opensource.altera.com>
---
v2:  Minor cleanup
v12: Bump version to line up with simple fpga bus
     Remove sysfs
     Improve get/put functions, get the low level driver too.
     Clean up class implementation
     Add kernel doc documentation
     Rename (un)register_fpga_bridge -> fpga_bridge_(un)register
v13: Add inlined empty functions for if not CONFIG_FPGA_BRIDGE
     Clean up debugging
     Remove unneeded #include in .h
     Remove unnecessary prints
     Remove 'label' DT binding.
     Document the mutex
v14: Allow bridges with no ops
     *const* struct fpga_bridge_ops
     Add functions to git/put/enable/disable list of bridges
     Add list node to struct fpga_bridge
     Do of_node_get/put in of_fpga_bridge_get()
     Add r/o attributes: name and state
---
 drivers/fpga/Kconfig             |    7 +
 drivers/fpga/Makefile            |    3 +
 drivers/fpga/fpga-bridge.c       |  388 ++++++++++++++++++++++++++++++++++++++
 include/linux/fpga/fpga-bridge.h |   56 ++++++
 4 files changed, 454 insertions(+)
 create mode 100644 drivers/fpga/fpga-bridge.c
 create mode 100644 include/linux/fpga/fpga-bridge.h

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index c9b9fdf..b6cfd89 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -24,6 +24,13 @@ config FPGA_MGR_ZYNQ_FPGA
 	help
 	  FPGA manager driver support for Xilinx Zynq FPGAs.
 
+config FPGA_BRIDGE
+       bool "FPGA Bridge Framework"
+       depends on OF
+       help
+         Say Y here if you want to support bridges connected between host
+	 processors and FPGAs or between FPGAs.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 8d83fc6..4baef00 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -8,3 +8,6 @@ obj-$(CONFIG_FPGA)			+= fpga-mgr.o
 # FPGA Manager Drivers
 obj-$(CONFIG_FPGA_MGR_SOCFPGA)		+= socfpga.o
 obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
+
+# FPGA Bridge Drivers
+obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
new file mode 100644
index 0000000..5119d8e
--- /dev/null
+++ b/drivers/fpga/fpga-bridge.c
@@ -0,0 +1,388 @@
+/*
+ * FPGA Bridge Framework Driver
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation, All Rights Reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/fpga/fpga-bridge.h>
+#include <linux/idr.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+static DEFINE_IDA(fpga_bridge_ida);
+static struct class *fpga_bridge_class;
+
+/* Lock for adding/removing bridges to linked lists*/
+spinlock_t bridge_list_lock;
+
+static int fpga_bridge_of_node_match(struct device *dev, const void *data)
+{
+	return dev->of_node == data;
+}
+
+/**
+ * fpga_bridge_enable - Enable transactions on the bridge
+ *
+ * @bridge: FPGA bridge
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_enable(struct fpga_bridge *bridge)
+{
+	dev_dbg(&bridge->dev, "enable\n");
+
+	if (bridge->br_ops && bridge->br_ops->enable_set)
+		return bridge->br_ops->enable_set(bridge, 1);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_enable);
+
+/**
+ * fpga_bridge_disable - Disable transactions on the bridge
+ *
+ * @bridge: FPGA bridge
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_disable(struct fpga_bridge *bridge)
+{
+	dev_dbg(&bridge->dev, "disable\n");
+
+	if (bridge->br_ops && bridge->br_ops->enable_set)
+		return bridge->br_ops->enable_set(bridge, 0);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_disable);
+
+/**
+ * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
+ *
+ * @np: node pointer of a FPGA bridge
+ *
+ * Return fpga_bridge struct if successful.
+ * Return -EBUSY if someone already has a reference to the bridge.
+ * Return -ENODEV if @np is not a FPGA Bridge.
+ */
+struct fpga_bridge *of_fpga_bridge_get(struct device_node *np)
+{
+	struct device *dev;
+	struct fpga_bridge *bridge;
+	int ret = -ENODEV;
+
+	of_node_get(np);
+
+	dev = class_find_device(fpga_bridge_class, NULL, np,
+				fpga_bridge_of_node_match);
+	if (!dev)
+		goto err_dev;
+
+	bridge = to_fpga_bridge(dev);
+	if (!bridge)
+		goto err_dev;
+
+	if (!mutex_trylock(&bridge->mutex)) {
+		ret = -EBUSY;
+		goto err_dev;
+	}
+
+	if (!try_module_get(dev->parent->driver->owner))
+		goto err_ll_mod;
+
+	dev_dbg(&bridge->dev, "get\n");
+
+	return bridge;
+
+err_ll_mod:
+	mutex_unlock(&bridge->mutex);
+err_dev:
+	put_device(dev);
+	of_node_put(np);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
+
+/**
+ * fpga_bridge_put - release a reference to a bridge
+ *
+ * @bridge: FPGA bridge
+ */
+void fpga_bridge_put(struct fpga_bridge *bridge)
+{
+	dev_dbg(&bridge->dev, "put\n");
+
+	module_put(bridge->dev.parent->driver->owner);
+	mutex_unlock(&bridge->mutex);
+	put_device(&bridge->dev);
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_put);
+
+/**
+ * fpga_bridges_enable - enable bridges in a list
+ * @bridge_list: list of FPGA bridges
+ *
+ * Enable each bridge in the list.  If list is empty, do nothing.
+ *
+ * Return 0 for success or empty bridge list; return error code otherwise.
+ */
+int fpga_bridges_enable(struct list_head *bridge_list)
+{
+	struct fpga_bridge *bridge;
+	struct list_head *node;
+	int ret;
+
+	list_for_each(node, bridge_list) {
+		bridge = list_entry(node, struct fpga_bridge, node);
+		ret = fpga_bridge_enable(bridge);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridges_enable);
+
+/**
+ * fpga_bridges_disable - disable bridges in a list
+ *
+ * @bridge_list: list of FPGA bridges
+ *
+ * Disable each bridge in the list.  If list is empty, do nothing.
+ *
+ * Return 0 for success or empty bridge list; return error code otherwise.
+ */
+int fpga_bridges_disable(struct list_head *bridge_list)
+{
+	struct fpga_bridge *bridge;
+	struct list_head *node;
+	int ret;
+
+	list_for_each(node, bridge_list) {
+		bridge = list_entry(node, struct fpga_bridge, node);
+		ret = fpga_bridge_disable(bridge);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridges_disable);
+
+/**
+ * fpga_bridges_put - put bridges
+ *
+ * @bridge_list: list of FPGA bridges
+ *
+ * For each bridge in the list, put the bridge and remove it from the list.
+ * If list is empty, do nothing.
+ */
+void fpga_bridges_put(struct list_head *bridge_list)
+{
+	struct fpga_bridge *bridge;
+	struct list_head *node, *next;
+	unsigned long flags;
+
+	list_for_each_safe(node, next, bridge_list) {
+		bridge = list_entry(node, struct fpga_bridge, node);
+
+		fpga_bridge_put(bridge);
+
+		spin_lock_irqsave(&bridge_list_lock, flags);
+		list_del(&bridge->node);
+		spin_unlock_irqrestore(&bridge_list_lock, flags);
+	}
+}
+EXPORT_SYMBOL_GPL(fpga_bridges_put);
+
+/**
+ * fpga_bridges_get_to_list - get a bridge, add it to a list
+ *
+ * @np: node pointer of a FPGA bridge
+ * @bridge_list: list of FPGA bridges
+ *
+ * Get an exclusive reference to the bridge and and it to the list.
+ *
+ * Return 0 for success, error code from of_fpga_bridge_get() othewise.
+ */
+int fpga_bridge_get_to_list(struct device_node *np,
+			    struct list_head *bridge_list)
+{
+	struct fpga_bridge *bridge;
+	unsigned long flags;
+
+	bridge = of_fpga_bridge_get(np);
+	if (IS_ERR(bridge))
+		return PTR_ERR(bridge);
+
+	spin_lock_irqsave(&bridge_list_lock, flags);
+	list_add(&bridge->node, bridge_list);
+	spin_unlock_irqrestore(&bridge_list_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
+
+static ssize_t name_show(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	struct fpga_bridge *bridge = to_fpga_bridge(dev);
+
+	return sprintf(buf, "%s\n", bridge->name);
+}
+
+static ssize_t state_show(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	struct fpga_bridge *bridge = to_fpga_bridge(dev);
+	int enable = 1;
+
+	if (bridge->br_ops && bridge->br_ops->enable_show)
+		enable = bridge->br_ops->enable_show(bridge);
+
+	return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
+}
+
+static DEVICE_ATTR_RO(name);
+static DEVICE_ATTR_RO(state);
+
+static struct attribute *fpga_bridge_attrs[] = {
+	&dev_attr_name.attr,
+	&dev_attr_state.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(fpga_bridge);
+
+/**
+ * fpga_bridge_register - register a fpga bridge driver
+ * @dev:	FPGA bridge device from pdev
+ * @name:	FPGA bridge name
+ * @br_ops:	pointer to structure of fpga bridge ops
+ * @priv:	FPGA bridge private data
+ *
+ * Return: 0 for success, error code otherwise.
+ */
+int fpga_bridge_register(struct device *dev, const char *name,
+			 const struct fpga_bridge_ops *br_ops, void *priv)
+{
+	struct fpga_bridge *bridge;
+	int id, ret = 0;
+
+	if (!name || !strlen(name)) {
+		dev_err(dev, "Attempt to register with no name!\n");
+		return -EINVAL;
+	}
+
+	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
+	if (!bridge)
+		return -ENOMEM;
+
+	id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
+	if (id < 0) {
+		ret = id;
+		goto error_kfree;
+	}
+
+	mutex_init(&bridge->mutex);
+	INIT_LIST_HEAD(&bridge->node);
+
+	bridge->name = name;
+	bridge->br_ops = br_ops;
+	bridge->priv = priv;
+
+	device_initialize(&bridge->dev);
+	bridge->dev.class = fpga_bridge_class;
+	bridge->dev.parent = dev;
+	bridge->dev.of_node = dev->of_node;
+	bridge->dev.id = id;
+	dev_set_drvdata(dev, bridge);
+
+	ret = dev_set_name(&bridge->dev, "br%d", id);
+	if (ret)
+		goto error_device;
+
+	ret = device_add(&bridge->dev);
+	if (ret)
+		goto error_device;
+
+	dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
+		 bridge->name);
+
+	return 0;
+
+error_device:
+	ida_simple_remove(&fpga_bridge_ida, id);
+error_kfree:
+	kfree(bridge);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_register);
+
+/**
+ * fpga_bridge_unregister - unregister a fpga bridge driver
+ * @dev: FPGA bridge device from pdev
+ */
+void fpga_bridge_unregister(struct device *dev)
+{
+	struct fpga_bridge *bridge = dev_get_drvdata(dev);
+
+	/*
+	 * If the low level driver provides a method for putting bridge into
+	 * a desired state upon unregister, do it.
+	 */
+	if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
+		bridge->br_ops->fpga_bridge_remove(bridge);
+
+	device_unregister(&bridge->dev);
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
+
+static void fpga_bridge_dev_release(struct device *dev)
+{
+	struct fpga_bridge *bridge = to_fpga_bridge(dev);
+
+	ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
+	kfree(bridge);
+}
+
+static int __init fpga_bridge_dev_init(void)
+{
+	spin_lock_init(&bridge_list_lock);
+
+	fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
+	if (IS_ERR(fpga_bridge_class))
+		return PTR_ERR(fpga_bridge_class);
+
+	fpga_bridge_class->dev_groups = fpga_bridge_groups;
+	fpga_bridge_class->dev_release = fpga_bridge_dev_release;
+
+	return 0;
+}
+
+static void __exit fpga_bridge_dev_exit(void)
+{
+	class_destroy(fpga_bridge_class);
+	ida_destroy(&fpga_bridge_ida);
+}
+
+MODULE_DESCRIPTION("FPGA Bridge Driver");
+MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
+MODULE_LICENSE("GPL v2");
+
+subsys_initcall(fpga_bridge_dev_init);
+module_exit(fpga_bridge_dev_exit);
diff --git a/include/linux/fpga/fpga-bridge.h b/include/linux/fpga/fpga-bridge.h
new file mode 100644
index 0000000..ad8471c
--- /dev/null
+++ b/include/linux/fpga/fpga-bridge.h
@@ -0,0 +1,56 @@
+#include <linux/device.h>
+
+#ifndef _LINUX_FPGA_BRIDGE_H
+#define _LINUX_FPGA_BRIDGE_H
+
+struct fpga_bridge;
+
+/**
+ * struct fpga_bridge_ops - ops for low level FPGA bridge drivers
+ * @enable_show: returns the FPGA bridge's status
+ * @enable_set: set a FPGA bridge as enabled or disabled
+ * @fpga_bridge_remove: set FPGA into a specific state during driver remove
+ */
+struct fpga_bridge_ops {
+	int (*enable_show)(struct fpga_bridge *bridge);
+	int (*enable_set)(struct fpga_bridge *bridge, bool enable);
+	void (*fpga_bridge_remove)(struct fpga_bridge *bridge);
+};
+
+/**
+ * struct fpga_bridge - FPGA bridge structure
+ * @name: name of low level FPGA bridge
+ * @dev: FPGA bridge device
+ * @mutex: enforces exclusive reference to bridge
+ * @br_ops: pointer to struct of FPGA bridge ops
+ * @node: FPGA bridge list node
+ * @priv: low level driver private date
+ */
+struct fpga_bridge {
+	const char *name;
+	struct device dev;
+	struct mutex mutex; /* for exclusive reference to bridge */
+	const struct fpga_bridge_ops *br_ops;
+	struct list_head node;
+	void *priv;
+};
+
+#define to_fpga_bridge(d) container_of(d, struct fpga_bridge, dev)
+
+struct fpga_bridge *of_get_fpga_bus(struct device_node *np);
+struct fpga_bridge *of_fpga_bridge_get(struct device_node *node);
+void fpga_bridge_put(struct fpga_bridge *bridge);
+int fpga_bridge_enable(struct fpga_bridge *bridge);
+int fpga_bridge_disable(struct fpga_bridge *bridge);
+
+int fpga_bridges_enable(struct list_head *bridge_list);
+int fpga_bridges_disable(struct list_head *bridge_list);
+void fpga_bridges_put(struct list_head *bridge_list);
+int fpga_bridge_get_to_list(struct device_node *np,
+			    struct list_head *bridge_list);
+
+int fpga_bridge_register(struct device *dev, const char *name,
+			 const struct fpga_bridge_ops *br_ops, void *priv);
+void fpga_bridge_unregister(struct device *dev);
+
+#endif /* _LINUX_FPGA_BRIDGE_H */
-- 
1.7.9.5

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

* [PATCH v14 6/7] fpga: fpga-area: support device tree control for FPGA programming
  2015-12-10 23:37 ` atull
@ 2015-12-10 23:37   ` atull
  -1 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

FPGA Areas support programming FPGA under control of the
Device Tree.

When a Device Tree Overlay containing a FPGA Area is
applied, the FPGA Area will be probed and will:
 * check to see if there is an image to program to a FPGA
 * get references to the FPGA manager and bridges if any
 * disable FPGA bridges to prevent spurious data on busses
 * reprogram the FPGA
 * enable the specified FPGA bridges
 * populate the child devices

The use case where FPGA Bridges are not needed is supported.

Removing the Device Tree Overlay is also supported.

This supports fpga use where hardware blocks on a fpga will
need drivers.

Signed-off-by: Alan Tull <atull@opensource.altera.com>
---
v9:  initial version (this patch added during rest of patchset's v9)
v10: request deferral if fpga mgr or bridges not available yet
     cleanup as fpga manager core goes into the real kernel
     Don't assume bridges are disabled before programming FPGA
     Don't hang onto reference for fpga manager
     Move to staging/simple-fpga-bus
v11: No change in this patch for v11 of the patch set
v12: Moved out of staging.
     Use fpga bridges framework.
v13: If no bridges are specified, assume we don't need any.
     Clean up debug messages
     Some dev_info -> dev_dbg
     Remove unneeded #include
     Fix size of array of pointers
     Don't need to specify .owner
     Use common binding: firmware-name
v14: OK it's not a simple bus.  Call it "FPGA Area"
     Remove bindings that specify FPGA manager and FPGA bridges
     Use parent FPGA bridge and bridges that are its peers
     Use ancestor FPGA Manager
---
 drivers/fpga/Kconfig     |    7 ++
 drivers/fpga/Makefile    |    3 +
 drivers/fpga/fpga-area.c |  313 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 323 insertions(+)
 create mode 100644 drivers/fpga/fpga-area.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index b6cfd89..6ac916b 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -31,6 +31,13 @@ config FPGA_BRIDGE
          Say Y here if you want to support bridges connected between host
 	 processors and FPGAs or between FPGAs.
 
+config FPGA_AREA
+       bool "Device Tree Based FPGA Reprogramming"
+       depends on FPGA_BRIDGE
+       help
+         Enable FPGA Area which supports programming FPGAs under control of
+	 Device Tree.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 4baef00..4f7e49f 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -11,3 +11,6 @@ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
 
 # FPGA Bridge Drivers
 obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
+
+# High Level Interfaces
+obj-$(CONFIG_FPGA_AREA)			+= fpga-area.o
diff --git a/drivers/fpga/fpga-area.c b/drivers/fpga/fpga-area.c
new file mode 100644
index 0000000..d01dc14
--- /dev/null
+++ b/drivers/fpga/fpga-area.c
@@ -0,0 +1,313 @@
+/*
+ * FPGA Tree Area Support for Device Tree controlled FPGA reprogramming
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation
+ *
+ * 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.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/fpga/fpga-bridge.h>
+#include <linux/fpga/fpga-mgr.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+
+/*
+ * In the case of a FPGA doing full reconfiguration, the area == the whole
+ * FPGA.  In the case of partial reconfiguration, several areas can be
+ * reconfigured separately.
+ */
+
+/**
+ * struct fpga_area
+ * @mgr:	FPGA Manager that is the ancestor of the area
+ * @flags:	Flags for reconfiguration
+ * @firmware_name: Name of FPGA image file
+ * @bridge_list: Linked list of FPGA bridges controlled by area
+ * @br:		FPGA Bridge corresponding to area
+ */
+struct fpga_area {
+	struct fpga_manager *mgr;
+	u32 flags;
+	const char *firmware_name;
+	struct list_head bridge_list;
+	struct fpga_bridge *br;
+};
+
+/**
+ * fpga_area_get_parent_peer_bridges - get bridges that are peers of parent
+ * @area: FPGA Area struct
+ *
+ * Intended to support case where multiple bridges need to be disabled
+ * during FPGA reprogramming.
+ *
+ * Finds the FPGA bridge that is the parent of @area in the device tree.
+ * Creates a linked list of FPGA bridges that includes the parent bridge and
+ * its peers.  Gets an exclusive reference to each of these bridges as they
+ * are added to the list.  The list of bridges is saved in @area's
+ * fpga_bridge struct.
+ *
+ * These bridges must be disabled while the FPGA is being reprogrammed to
+ * support the children of the @area bridge and enabled after FPGA
+ * programming is finished.
+ *
+ * For the use case where no FPGA bridges are required, the parent node should
+ * be a FPGA Manager.  In this case, the bridge list will end up empty.
+ *
+ * Returns error code or 0 for success.  Returns 0 if the parent is a FPGA
+ * manager.
+ */
+static int fpga_area_get_parent_peer_bridges(struct fpga_area *area)
+{
+	struct device_node *parent, *child;
+	struct fpga_bridge *bridge;
+	int ret;
+
+	/* Create a list of bridges that are peers of area's parent */
+	parent = of_get_parent(area->br->dev.of_node);
+	parent = of_get_next_parent(parent);
+
+	for_each_child_of_node(parent, child) {
+		/* If node is a bridge, get it and add to list */
+		ret = fpga_bridge_get_to_list(child, &area->bridge_list);
+
+		/* if any of the bridges are in use, give up */
+		if (ret == -EBUSY) {
+			fpga_bridges_put(&area->bridge_list);
+			of_node_put(parent);
+			return PTR_ERR(bridge);
+		}
+	}
+	of_node_put(parent);
+
+	return 0;
+}
+
+/**
+ * fpga_area_get_bridges - create list of exclusive references to fpga bridges
+ * @area: FPGA Area struct
+ *
+ * Get exclusive references to a FPGA bridge or bridges.
+ * In the case of full reconfiguration build a list of bridges that are the
+ * parent of @area and its peers.  We are reprogramming the full FPGA and
+ * need to have no communication on the processor/FPGA bridges while that
+ * is happening
+ * In the case of partial reconfiguration, only add the parent of @area to
+ * the list.  This one bridge is a freeze block which is in the FPGA itself
+ * and is downstream from its parent bridge and the parent's peers.
+ *
+ * Return 0 for success. Return -ENODEV is there are no bridges.
+ * Pass other error codes ultimately from of_fpga_bridge_get() such as:
+ * Return -EBUSY if any of the bridges were already gotten.
+ */
+static int fpga_area_get_bridges(struct fpga_area *area)
+{
+	struct device_node *parent;
+	int ret = 0;
+
+	/* If parent is FPGA Manager, no bridges to get */
+	parent = of_get_parent(area->br->dev.of_node);
+	if (parent == area->mgr->dev.of_node) {
+		of_node_put(parent);
+		return -ENODEV;
+	}
+
+	if (area->flags & FPGA_MGR_PARTIAL_RECONFIG)
+		ret = fpga_bridge_get_to_list(parent, &area->bridge_list);
+	else
+		ret = fpga_area_get_parent_peer_bridges(area);
+
+	of_node_put(parent);
+
+	return ret;
+}
+
+/**
+ * fpga_area_load - program the FPGA based on info in area
+ * @area: FPGA Area struct
+ *
+ * Program the FPGA that the area has a reference to.
+ *
+ * Returns 0 for success or error codes passed down from
+ * fpga_mgr_firmware_load()
+ */
+static int fpga_area_load(struct fpga_area *area)
+{
+	return fpga_mgr_firmware_load(area->mgr,
+				      area->flags,
+				      area->firmware_name);
+}
+
+/**
+ * fpga_area_get_manager - get exclusive reference for FPGA manager
+ * @area: FPGA Area struct
+ *
+ * One of the ancestor nodes of the FPGA Area should be an FPGA Manager.
+ * This function goes up the tree to find it, gets exclusive reference,
+ * and saves it in the area struct.
+ *
+ * Return: 0 for success or IS_ERR() condition containing error code.
+ */
+static int fpga_area_get_manager(struct fpga_area *area)
+{
+	struct device_node *np = area->br->dev.of_node;
+	struct fpga_manager *mgr;
+	int ret = -EINVAL;
+
+	of_node_get(np);
+
+	while (np) {
+		mgr = of_fpga_mgr_get(np);
+		if (!IS_ERR(mgr)) {
+			area->mgr = mgr;
+			ret = 0;
+			break;
+		}
+		np = of_get_next_parent(np);
+	}
+
+	of_node_put(np);
+
+	return ret;
+}
+
+/**
+ * fpga_area_put_manager - put exclusive reference to FPGA manager
+ * @area: FPGA Area struct
+ */
+static void fpga_area_put_manager(struct fpga_area *area)
+{
+	fpga_mgr_put(area->mgr);
+	area->mgr = NULL;
+}
+
+/**
+ * fpga_area_probe - probe function for FPGA area
+ * @pdev: platform device
+ *
+ * If there is an image to program to a FPGA, get the FPGA manager and bridges,
+ * reprogram the FPGA, and  populate the child devices.
+ *
+ * If there are FPGA Bridges, this function will hold the references to the
+ * bridges; they are released in fpga_area_remove().
+ *
+ * Return:  0 for success, -EBUSY if someone already got the bridges or manager.
+ */
+static int fpga_area_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct fpga_area *area;
+	int ret;
+
+	area = devm_kzalloc(dev, sizeof(*area), GFP_KERNEL);
+	if (!area)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&area->bridge_list);
+
+	ret = fpga_bridge_register(dev, "FPGA Area", NULL, area);
+	if (ret)
+		return ret;
+	area->br = dev_get_drvdata(dev);
+
+	if (of_property_read_string(np, "firmware-name",
+				    &area->firmware_name)) {
+		of_platform_populate(np, of_default_bus_match_table, NULL, dev);
+		return 0;
+	}
+
+	if (of_property_read_bool(np, "partial-reconfig"))
+		area->flags |= FPGA_MGR_PARTIAL_RECONFIG;
+
+	ret = fpga_area_get_manager(area);
+	if (ret) {
+		dev_dbg(dev, "Should be child of a FPGA Manager");
+		goto err_unreg;
+	}
+
+	/* Give up if there is an error other than no bridges. */
+	ret = fpga_area_get_bridges(area);
+	if (ret && ret != -ENODEV)
+		goto err_release;
+
+	ret = fpga_bridges_disable(&area->bridge_list);
+	if (ret)
+		goto err_release;
+
+	ret = fpga_area_load(area);
+	if (ret)
+		goto err_release;
+
+	ret = fpga_bridges_enable(&area->bridge_list);
+	if (ret)
+		goto err_release;
+
+	/* If successful, put the mgr, but keep the bridges */
+	fpga_area_put_manager(area);
+
+	of_platform_populate(np, of_default_bus_match_table, NULL, dev);
+
+	return 0;
+
+err_release:
+	fpga_bridges_put(&area->bridge_list);
+	fpga_area_put_manager(area);
+err_unreg:
+	fpga_bridge_unregister(dev);
+
+	return ret;
+}
+
+/**
+ * fpga_area_remove - remove a FPGA area
+ *
+ * Called when an FPGA Area is removed.  If there are any FPGA Bridges in the
+ * area's bridge list, disable them and put them.
+ *
+ * Return: 0
+ */
+static int fpga_area_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct fpga_bridge *bridge = dev_get_drvdata(dev);
+	struct fpga_area *area = bridge->priv;
+
+	fpga_bridges_disable(&area->bridge_list);
+	fpga_bridges_put(&area->bridge_list);
+
+	fpga_bridge_unregister(dev);
+
+	return 0;
+}
+
+static const struct of_device_id fpga_area_of_match[] = {
+	{ .compatible = "fpga-area", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, fpga_area_of_match);
+
+static struct platform_driver fpga_area_driver = {
+	.probe = fpga_area_probe,
+	.remove = fpga_area_remove,
+	.driver = {
+		.name	= "FPGA Area",
+		.of_match_table = of_match_ptr(fpga_area_of_match),
+	},
+};
+
+module_platform_driver(fpga_area_driver);
+
+MODULE_DESCRIPTION("Altera FPGA Bus");
+MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5


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

* [PATCH v14 6/7] fpga: fpga-area: support device tree control for FPGA programming
@ 2015-12-10 23:37   ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull

From: Alan Tull <atull@opensource.altera.com>

FPGA Areas support programming FPGA under control of the
Device Tree.

When a Device Tree Overlay containing a FPGA Area is
applied, the FPGA Area will be probed and will:
 * check to see if there is an image to program to a FPGA
 * get references to the FPGA manager and bridges if any
 * disable FPGA bridges to prevent spurious data on busses
 * reprogram the FPGA
 * enable the specified FPGA bridges
 * populate the child devices

The use case where FPGA Bridges are not needed is supported.

Removing the Device Tree Overlay is also supported.

This supports fpga use where hardware blocks on a fpga will
need drivers.

Signed-off-by: Alan Tull <atull@opensource.altera.com>
---
v9:  initial version (this patch added during rest of patchset's v9)
v10: request deferral if fpga mgr or bridges not available yet
     cleanup as fpga manager core goes into the real kernel
     Don't assume bridges are disabled before programming FPGA
     Don't hang onto reference for fpga manager
     Move to staging/simple-fpga-bus
v11: No change in this patch for v11 of the patch set
v12: Moved out of staging.
     Use fpga bridges framework.
v13: If no bridges are specified, assume we don't need any.
     Clean up debug messages
     Some dev_info -> dev_dbg
     Remove unneeded #include
     Fix size of array of pointers
     Don't need to specify .owner
     Use common binding: firmware-name
v14: OK it's not a simple bus.  Call it "FPGA Area"
     Remove bindings that specify FPGA manager and FPGA bridges
     Use parent FPGA bridge and bridges that are its peers
     Use ancestor FPGA Manager
---
 drivers/fpga/Kconfig     |    7 ++
 drivers/fpga/Makefile    |    3 +
 drivers/fpga/fpga-area.c |  313 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 323 insertions(+)
 create mode 100644 drivers/fpga/fpga-area.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index b6cfd89..6ac916b 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -31,6 +31,13 @@ config FPGA_BRIDGE
          Say Y here if you want to support bridges connected between host
 	 processors and FPGAs or between FPGAs.
 
+config FPGA_AREA
+       bool "Device Tree Based FPGA Reprogramming"
+       depends on FPGA_BRIDGE
+       help
+         Enable FPGA Area which supports programming FPGAs under control of
+	 Device Tree.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 4baef00..4f7e49f 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -11,3 +11,6 @@ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
 
 # FPGA Bridge Drivers
 obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
+
+# High Level Interfaces
+obj-$(CONFIG_FPGA_AREA)			+= fpga-area.o
diff --git a/drivers/fpga/fpga-area.c b/drivers/fpga/fpga-area.c
new file mode 100644
index 0000000..d01dc14
--- /dev/null
+++ b/drivers/fpga/fpga-area.c
@@ -0,0 +1,313 @@
+/*
+ * FPGA Tree Area Support for Device Tree controlled FPGA reprogramming
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation
+ *
+ * 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.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/fpga/fpga-bridge.h>
+#include <linux/fpga/fpga-mgr.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+
+/*
+ * In the case of a FPGA doing full reconfiguration, the area == the whole
+ * FPGA.  In the case of partial reconfiguration, several areas can be
+ * reconfigured separately.
+ */
+
+/**
+ * struct fpga_area
+ * @mgr:	FPGA Manager that is the ancestor of the area
+ * @flags:	Flags for reconfiguration
+ * @firmware_name: Name of FPGA image file
+ * @bridge_list: Linked list of FPGA bridges controlled by area
+ * @br:		FPGA Bridge corresponding to area
+ */
+struct fpga_area {
+	struct fpga_manager *mgr;
+	u32 flags;
+	const char *firmware_name;
+	struct list_head bridge_list;
+	struct fpga_bridge *br;
+};
+
+/**
+ * fpga_area_get_parent_peer_bridges - get bridges that are peers of parent
+ * @area: FPGA Area struct
+ *
+ * Intended to support case where multiple bridges need to be disabled
+ * during FPGA reprogramming.
+ *
+ * Finds the FPGA bridge that is the parent of @area in the device tree.
+ * Creates a linked list of FPGA bridges that includes the parent bridge and
+ * its peers.  Gets an exclusive reference to each of these bridges as they
+ * are added to the list.  The list of bridges is saved in @area's
+ * fpga_bridge struct.
+ *
+ * These bridges must be disabled while the FPGA is being reprogrammed to
+ * support the children of the @area bridge and enabled after FPGA
+ * programming is finished.
+ *
+ * For the use case where no FPGA bridges are required, the parent node should
+ * be a FPGA Manager.  In this case, the bridge list will end up empty.
+ *
+ * Returns error code or 0 for success.  Returns 0 if the parent is a FPGA
+ * manager.
+ */
+static int fpga_area_get_parent_peer_bridges(struct fpga_area *area)
+{
+	struct device_node *parent, *child;
+	struct fpga_bridge *bridge;
+	int ret;
+
+	/* Create a list of bridges that are peers of area's parent */
+	parent = of_get_parent(area->br->dev.of_node);
+	parent = of_get_next_parent(parent);
+
+	for_each_child_of_node(parent, child) {
+		/* If node is a bridge, get it and add to list */
+		ret = fpga_bridge_get_to_list(child, &area->bridge_list);
+
+		/* if any of the bridges are in use, give up */
+		if (ret == -EBUSY) {
+			fpga_bridges_put(&area->bridge_list);
+			of_node_put(parent);
+			return PTR_ERR(bridge);
+		}
+	}
+	of_node_put(parent);
+
+	return 0;
+}
+
+/**
+ * fpga_area_get_bridges - create list of exclusive references to fpga bridges
+ * @area: FPGA Area struct
+ *
+ * Get exclusive references to a FPGA bridge or bridges.
+ * In the case of full reconfiguration build a list of bridges that are the
+ * parent of @area and its peers.  We are reprogramming the full FPGA and
+ * need to have no communication on the processor/FPGA bridges while that
+ * is happening
+ * In the case of partial reconfiguration, only add the parent of @area to
+ * the list.  This one bridge is a freeze block which is in the FPGA itself
+ * and is downstream from its parent bridge and the parent's peers.
+ *
+ * Return 0 for success. Return -ENODEV is there are no bridges.
+ * Pass other error codes ultimately from of_fpga_bridge_get() such as:
+ * Return -EBUSY if any of the bridges were already gotten.
+ */
+static int fpga_area_get_bridges(struct fpga_area *area)
+{
+	struct device_node *parent;
+	int ret = 0;
+
+	/* If parent is FPGA Manager, no bridges to get */
+	parent = of_get_parent(area->br->dev.of_node);
+	if (parent == area->mgr->dev.of_node) {
+		of_node_put(parent);
+		return -ENODEV;
+	}
+
+	if (area->flags & FPGA_MGR_PARTIAL_RECONFIG)
+		ret = fpga_bridge_get_to_list(parent, &area->bridge_list);
+	else
+		ret = fpga_area_get_parent_peer_bridges(area);
+
+	of_node_put(parent);
+
+	return ret;
+}
+
+/**
+ * fpga_area_load - program the FPGA based on info in area
+ * @area: FPGA Area struct
+ *
+ * Program the FPGA that the area has a reference to.
+ *
+ * Returns 0 for success or error codes passed down from
+ * fpga_mgr_firmware_load()
+ */
+static int fpga_area_load(struct fpga_area *area)
+{
+	return fpga_mgr_firmware_load(area->mgr,
+				      area->flags,
+				      area->firmware_name);
+}
+
+/**
+ * fpga_area_get_manager - get exclusive reference for FPGA manager
+ * @area: FPGA Area struct
+ *
+ * One of the ancestor nodes of the FPGA Area should be an FPGA Manager.
+ * This function goes up the tree to find it, gets exclusive reference,
+ * and saves it in the area struct.
+ *
+ * Return: 0 for success or IS_ERR() condition containing error code.
+ */
+static int fpga_area_get_manager(struct fpga_area *area)
+{
+	struct device_node *np = area->br->dev.of_node;
+	struct fpga_manager *mgr;
+	int ret = -EINVAL;
+
+	of_node_get(np);
+
+	while (np) {
+		mgr = of_fpga_mgr_get(np);
+		if (!IS_ERR(mgr)) {
+			area->mgr = mgr;
+			ret = 0;
+			break;
+		}
+		np = of_get_next_parent(np);
+	}
+
+	of_node_put(np);
+
+	return ret;
+}
+
+/**
+ * fpga_area_put_manager - put exclusive reference to FPGA manager
+ * @area: FPGA Area struct
+ */
+static void fpga_area_put_manager(struct fpga_area *area)
+{
+	fpga_mgr_put(area->mgr);
+	area->mgr = NULL;
+}
+
+/**
+ * fpga_area_probe - probe function for FPGA area
+ * @pdev: platform device
+ *
+ * If there is an image to program to a FPGA, get the FPGA manager and bridges,
+ * reprogram the FPGA, and  populate the child devices.
+ *
+ * If there are FPGA Bridges, this function will hold the references to the
+ * bridges; they are released in fpga_area_remove().
+ *
+ * Return:  0 for success, -EBUSY if someone already got the bridges or manager.
+ */
+static int fpga_area_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct fpga_area *area;
+	int ret;
+
+	area = devm_kzalloc(dev, sizeof(*area), GFP_KERNEL);
+	if (!area)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&area->bridge_list);
+
+	ret = fpga_bridge_register(dev, "FPGA Area", NULL, area);
+	if (ret)
+		return ret;
+	area->br = dev_get_drvdata(dev);
+
+	if (of_property_read_string(np, "firmware-name",
+				    &area->firmware_name)) {
+		of_platform_populate(np, of_default_bus_match_table, NULL, dev);
+		return 0;
+	}
+
+	if (of_property_read_bool(np, "partial-reconfig"))
+		area->flags |= FPGA_MGR_PARTIAL_RECONFIG;
+
+	ret = fpga_area_get_manager(area);
+	if (ret) {
+		dev_dbg(dev, "Should be child of a FPGA Manager");
+		goto err_unreg;
+	}
+
+	/* Give up if there is an error other than no bridges. */
+	ret = fpga_area_get_bridges(area);
+	if (ret && ret != -ENODEV)
+		goto err_release;
+
+	ret = fpga_bridges_disable(&area->bridge_list);
+	if (ret)
+		goto err_release;
+
+	ret = fpga_area_load(area);
+	if (ret)
+		goto err_release;
+
+	ret = fpga_bridges_enable(&area->bridge_list);
+	if (ret)
+		goto err_release;
+
+	/* If successful, put the mgr, but keep the bridges */
+	fpga_area_put_manager(area);
+
+	of_platform_populate(np, of_default_bus_match_table, NULL, dev);
+
+	return 0;
+
+err_release:
+	fpga_bridges_put(&area->bridge_list);
+	fpga_area_put_manager(area);
+err_unreg:
+	fpga_bridge_unregister(dev);
+
+	return ret;
+}
+
+/**
+ * fpga_area_remove - remove a FPGA area
+ *
+ * Called when an FPGA Area is removed.  If there are any FPGA Bridges in the
+ * area's bridge list, disable them and put them.
+ *
+ * Return: 0
+ */
+static int fpga_area_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct fpga_bridge *bridge = dev_get_drvdata(dev);
+	struct fpga_area *area = bridge->priv;
+
+	fpga_bridges_disable(&area->bridge_list);
+	fpga_bridges_put(&area->bridge_list);
+
+	fpga_bridge_unregister(dev);
+
+	return 0;
+}
+
+static const struct of_device_id fpga_area_of_match[] = {
+	{ .compatible = "fpga-area", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, fpga_area_of_match);
+
+static struct platform_driver fpga_area_driver = {
+	.probe = fpga_area_probe,
+	.remove = fpga_area_remove,
+	.driver = {
+		.name	= "FPGA Area",
+		.of_match_table = of_match_ptr(fpga_area_of_match),
+	},
+};
+
+module_platform_driver(fpga_area_driver);
+
+MODULE_DESCRIPTION("Altera FPGA Bus");
+MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5

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

* [PATCH v14 7/7] ARM: socfpga: fpga bridge driver support
  2015-12-10 23:37 ` atull
@ 2015-12-10 23:37   ` atull
  -1 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull,
	Matthew Gerlach

From: Alan Tull <atull@opensource.altera.com>

Supports Altera SOCFPGA bridges:
 * fpga2sdram
 * fpga2hps
 * hps2fpga
 * lwhps2fpga

Allows enabling/disabling the bridges through the FPGA
Bridge Framework API functions.

The fpga2sdram driver only supports enabling and disabling
of the ports that been configured early on.  This is due to
a hardware limitation where the read, write, and command
ports on the fpga2sdram bridge can only be reconfigured
while there are no transactions to the sdram, i.e. when
running out of OCRAM before the kernel boots.

Device tree property 'init-val' configures the driver to
enable or disable the bridge during probe.  If the property
does not exist, the driver will leave the bridge in its
current state.

Signed-off-by: Alan Tull <atull@opensource.altera.com>
Signed-off-by: Matthew Gerlach <mgerlach@altera.com>
Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
---
v2:  Use resets instead of directly writing reset registers
v12: Bump version to align with simple-fpga-bus version
     Get rid of the sysfs interface
     fpga2sdram: get configuration stored in handoff register
v13: Remove unneeded WARN_ON
     Change property from init-val to bridge-enable
     Checkpatch cleanup
     Fix email address
v14: use module_platform_driver
     remove unused struct field and some #defines
     don't really need exclamation points on error msgs
     *const* struct fpga_bridge_ops
---
 drivers/fpga/Kconfig             |    7 ++
 drivers/fpga/Makefile            |    1 +
 drivers/fpga/altera-fpga2sdram.c |  174 +++++++++++++++++++++++++++++++
 drivers/fpga/altera-hps2fpga.c   |  213 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 395 insertions(+)
 create mode 100644 drivers/fpga/altera-fpga2sdram.c
 create mode 100644 drivers/fpga/altera-hps2fpga.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 6ac916b..30ebe42 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -38,6 +38,13 @@ config FPGA_AREA
          Enable FPGA Area which supports programming FPGAs under control of
 	 Device Tree.
 
+config SOCFPGA_FPGA_BRIDGE
+	bool "Altera SoCFPGA FPGA Bridges"
+	depends on ARCH_SOCFPGA && FPGA_BRIDGE
+	help
+	  Say Y to enable drivers for FPGA bridges for Altera SOCFPGA
+	  devices.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 4f7e49f..3efc132 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
 
 # FPGA Bridge Drivers
 obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
+obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)	+= altera-hps2fpga.o altera-fpga2sdram.o
 
 # High Level Interfaces
 obj-$(CONFIG_FPGA_AREA)			+= fpga-area.o
diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c
new file mode 100644
index 0000000..91f4a40
--- /dev/null
+++ b/drivers/fpga/altera-fpga2sdram.c
@@ -0,0 +1,174 @@
+/*
+ * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation, All Rights Reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This driver manages a bridge between an FPGA and the SDRAM used by the ARM
+ * host processor system (HPS).
+ *
+ * The bridge contains 4 read ports, 4 write ports, and 6 command ports.
+ * Reconfiguring these ports requires that no SDRAM transactions occur during
+ * reconfiguration.  The code reconfiguring the ports cannot run out of SDRAM
+ * nor can the FPGA access the SDRAM during reconfiguration.  This driver does
+ * not support reconfiguring the ports.  The ports are configured by code
+ * running out of on chip ram before Linux is started and the configuration
+ * is passed in a handoff register in the system manager.
+ *
+ * This driver supports enabling and disabling of the configured ports, which
+ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
+ * uses the same port configuration.  Bridges must be disabled before
+ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
+ */
+
+#include <linux/fpga/fpga-bridge.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+
+#define ALT_SDR_CTL_FPGAPORTRST_OFST		0x80
+#define ALT_SDR_CTL_FPGAPORTRST_PORTRSTN_MSK	0x00003fff
+#define ALT_SDR_CTL_FPGAPORTRST_RD_SHIFT	0
+#define ALT_SDR_CTL_FPGAPORTRST_WR_SHIFT	4
+#define ALT_SDR_CTL_FPGAPORTRST_CTRL_SHIFT	8
+
+#define SYSMGR_ISWGRP_HANDOFF3          (0x8C)
+#define ISWGRP_HANDOFF_FPGA2SDR         SYSMGR_ISWGRP_HANDOFF3
+
+#define F2S_BRIDGE_NAME "fpga2sdram"
+
+struct alt_fpga2sdram_data {
+	struct device *dev;
+	struct regmap *sdrctl;
+	int mask;
+};
+
+static int alt_fpga2sdram_enable_show(struct fpga_bridge *bridge)
+{
+	struct alt_fpga2sdram_data *priv = bridge->priv;
+	int value;
+
+	regmap_read(priv->sdrctl, ALT_SDR_CTL_FPGAPORTRST_OFST, &value);
+
+	return (value & priv->mask) == priv->mask;
+}
+
+static inline int _alt_fpga2sdram_enable_set(struct alt_fpga2sdram_data *priv,
+					     bool enable)
+{
+	return regmap_update_bits(priv->sdrctl, ALT_SDR_CTL_FPGAPORTRST_OFST,
+				  priv->mask, enable ? priv->mask : 0);
+}
+
+static int alt_fpga2sdram_enable_set(struct fpga_bridge *bridge, bool enable)
+{
+	return _alt_fpga2sdram_enable_set(bridge->priv, enable);
+}
+
+struct prop_map {
+	char *prop_name;
+	u32 *prop_value;
+	u32 prop_max;
+};
+
+static const struct fpga_bridge_ops altera_fpga2sdram_br_ops = {
+	.enable_set = alt_fpga2sdram_enable_set,
+	.enable_show = alt_fpga2sdram_enable_show,
+};
+
+static const struct of_device_id altera_fpga_of_match[] = {
+	{ .compatible = "altr,socfpga-fpga2sdram-bridge" },
+	{},
+};
+
+static int alt_fpga_bridge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct alt_fpga2sdram_data *priv;
+	u32 enable;
+	struct regmap *sysmgr;
+	int ret = 0;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = dev;
+
+	priv->sdrctl = syscon_regmap_lookup_by_compatible("altr,sdr-ctl");
+	if (IS_ERR(priv->sdrctl)) {
+		dev_err(dev, "regmap for altr,sdr-ctl lookup failed.\n");
+		return PTR_ERR(priv->sdrctl);
+	}
+
+	sysmgr = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
+	if (IS_ERR(priv->sdrctl)) {
+		dev_err(dev, "regmap for altr,sys-mgr lookup failed.\n");
+		return PTR_ERR(sysmgr);
+	}
+
+	/* Get f2s bridge configuration saved in handoff register */
+	regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask);
+
+	ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME,
+				   &altera_fpga2sdram_br_ops, priv);
+	if (ret)
+		return ret;
+
+	dev_info(dev, "driver initialized with handoff %08x\n", priv->mask);
+
+	if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) {
+		if (enable > 1) {
+			dev_warn(dev, "invalid bridge-enable %u > 1\n", enable);
+		} else {
+			dev_info(dev, "%s bridge\n",
+				 (enable ? "enabling" : "disabling"));
+			ret = _alt_fpga2sdram_enable_set(priv, enable);
+			if (ret) {
+				fpga_bridge_unregister(&pdev->dev);
+				return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int alt_fpga_bridge_remove(struct platform_device *pdev)
+{
+	fpga_bridge_unregister(&pdev->dev);
+
+	return 0;
+}
+
+MODULE_DEVICE_TABLE(of, altera_fpga_of_match);
+
+static struct platform_driver altera_fpga_driver = {
+	.probe = alt_fpga_bridge_probe,
+	.remove = alt_fpga_bridge_remove,
+	.driver = {
+		.name	= "altera_fpga2sdram_bridge",
+		.of_match_table = of_match_ptr(altera_fpga_of_match),
+	},
+};
+
+module_platform_driver(altera_fpga_driver);
+
+MODULE_DESCRIPTION("Altera SoCFPGA FPGA to SDRAM Bridge");
+MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/altera-hps2fpga.c b/drivers/fpga/altera-hps2fpga.c
new file mode 100644
index 0000000..c15df47
--- /dev/null
+++ b/drivers/fpga/altera-hps2fpga.c
@@ -0,0 +1,213 @@
+/*
+ * FPGA to/from HPS Bridge Driver for Altera SoCFPGA Devices
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation, All Rights Reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This driver manages bridges on a Altera SOCFPGA between the ARM host
+ * processor system (HPS) and the embedded FPGA.
+ *
+ * This driver supports enabling and disabling of the configured ports, which
+ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
+ * uses the same port configuration.  Bridges must be disabled before
+ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
+ */
+
+#include <linux/clk.h>
+#include <linux/fpga/fpga-bridge.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define ALT_L3_REMAP_OFST			0x0
+#define ALT_L3_REMAP_MPUZERO_MSK		0x00000001
+#define ALT_L3_REMAP_H2F_MSK			0x00000008
+#define ALT_L3_REMAP_LWH2F_MSK			0x00000010
+
+#define HPS2FPGA_BRIDGE_NAME			"hps2fpga"
+#define LWHPS2FPGA_BRIDGE_NAME			"lwhps2fpga"
+#define FPGA2HPS_BRIDGE_NAME			"fpga2hps"
+
+struct altera_hps2fpga_data {
+	const char *name;
+	struct reset_control *bridge_reset;
+	struct regmap *l3reg;
+	/* The L3 REMAP register is write only, so keep a cached value. */
+	unsigned int l3_remap_value;
+	unsigned int remap_mask;
+	struct clk *clk;
+};
+
+static int alt_hps2fpga_enable_show(struct fpga_bridge *bridge)
+{
+	struct altera_hps2fpga_data *priv = bridge->priv;
+
+	return reset_control_status(priv->bridge_reset);
+}
+
+static int _alt_hps2fpga_enable_set(struct altera_hps2fpga_data *priv,
+				    bool enable)
+{
+	int ret;
+
+	/* bring bridge out of reset */
+	if (enable)
+		ret = reset_control_deassert(priv->bridge_reset);
+	else
+		ret = reset_control_assert(priv->bridge_reset);
+	if (ret)
+		return ret;
+
+	/* Allow bridge to be visible to L3 masters or not */
+	if (priv->remap_mask) {
+		priv->l3_remap_value |= ALT_L3_REMAP_MPUZERO_MSK;
+
+		if (enable)
+			priv->l3_remap_value |= priv->remap_mask;
+		else
+			priv->l3_remap_value &= ~priv->remap_mask;
+
+		ret = regmap_write(priv->l3reg, ALT_L3_REMAP_OFST,
+				   priv->l3_remap_value);
+	}
+
+	return ret;
+}
+
+static int alt_hps2fpga_enable_set(struct fpga_bridge *bridge, bool enable)
+{
+	return _alt_hps2fpga_enable_set(bridge->priv, enable);
+}
+
+static const struct fpga_bridge_ops altera_hps2fpga_br_ops = {
+	.enable_set = alt_hps2fpga_enable_set,
+	.enable_show = alt_hps2fpga_enable_show,
+};
+
+static struct altera_hps2fpga_data hps2fpga_data  = {
+	.name = HPS2FPGA_BRIDGE_NAME,
+	.remap_mask = ALT_L3_REMAP_H2F_MSK,
+};
+
+static struct altera_hps2fpga_data lwhps2fpga_data  = {
+	.name = LWHPS2FPGA_BRIDGE_NAME,
+	.remap_mask = ALT_L3_REMAP_LWH2F_MSK,
+};
+
+static struct altera_hps2fpga_data fpga2hps_data  = {
+	.name = FPGA2HPS_BRIDGE_NAME,
+};
+
+static const struct of_device_id altera_fpga_of_match[] = {
+	{ .compatible = "altr,socfpga-hps2fpga-bridge",
+	  .data = &hps2fpga_data },
+	{ .compatible = "altr,socfpga-lwhps2fpga-bridge",
+	  .data = &lwhps2fpga_data },
+	{ .compatible = "altr,socfpga-fpga2hps-bridge",
+	  .data = &fpga2hps_data },
+	{},
+};
+
+static int alt_fpga_bridge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct altera_hps2fpga_data *priv;
+	const struct of_device_id *of_id;
+	u32 enable;
+	int ret;
+
+	of_id = of_match_device(altera_fpga_of_match, dev);
+	priv = (struct altera_hps2fpga_data *)of_id->data;
+
+	priv->bridge_reset = devm_reset_control_get(dev, priv->name);
+	if (IS_ERR(priv->bridge_reset)) {
+		dev_err(dev, "Could not get %s reset control\n", priv->name);
+		return PTR_ERR(priv->bridge_reset);
+	}
+
+	priv->l3reg = syscon_regmap_lookup_by_compatible("altr,l3regs");
+	if (IS_ERR(priv->l3reg)) {
+		dev_err(dev, "regmap for altr,l3regs lookup failed\n");
+		return PTR_ERR(priv->l3reg);
+	}
+
+	priv->clk = of_clk_get(dev->of_node, 0);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "no clock specified\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(dev, "could not enable clock\n");
+		return -EBUSY;
+	}
+
+	ret = fpga_bridge_register(dev, priv->name, &altera_hps2fpga_br_ops,
+				   priv);
+	if (ret)
+		return ret;
+
+	if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) {
+		if (enable > 1) {
+			dev_warn(dev, "invalid bridge-enable %u > 1\n", enable);
+		} else {
+			dev_info(dev, "%s bridge\n",
+				 (enable ? "enabling" : "disabling"));
+
+			ret = _alt_hps2fpga_enable_set(priv, enable);
+			if (ret) {
+				fpga_bridge_unregister(&pdev->dev);
+				return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int alt_fpga_bridge_remove(struct platform_device *pdev)
+{
+	struct fpga_bridge *bridge = platform_get_drvdata(pdev);
+	struct altera_hps2fpga_data *priv = bridge->priv;
+
+	fpga_bridge_unregister(&pdev->dev);
+
+	clk_disable_unprepare(priv->clk);
+	clk_put(priv->clk);
+
+	return 0;
+}
+
+MODULE_DEVICE_TABLE(of, altera_fpga_of_match);
+
+static struct platform_driver alt_fpga_bridge_driver = {
+	.probe = alt_fpga_bridge_probe,
+	.remove = alt_fpga_bridge_remove,
+	.driver = {
+		.name	= "altera_hps2fpga_bridge",
+		.of_match_table = of_match_ptr(altera_fpga_of_match),
+	},
+};
+
+module_platform_driver(alt_fpga_bridge_driver);
+
+MODULE_DESCRIPTION("Altera SoCFPGA HPS to FPGA Bridge");
+MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5


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

* [PATCH v14 7/7] ARM: socfpga: fpga bridge driver support
@ 2015-12-10 23:37   ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-10 23:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen, Alan Tull,
	Matthew Gerlach

From: Alan Tull <atull@opensource.altera.com>

Supports Altera SOCFPGA bridges:
 * fpga2sdram
 * fpga2hps
 * hps2fpga
 * lwhps2fpga

Allows enabling/disabling the bridges through the FPGA
Bridge Framework API functions.

The fpga2sdram driver only supports enabling and disabling
of the ports that been configured early on.  This is due to
a hardware limitation where the read, write, and command
ports on the fpga2sdram bridge can only be reconfigured
while there are no transactions to the sdram, i.e. when
running out of OCRAM before the kernel boots.

Device tree property 'init-val' configures the driver to
enable or disable the bridge during probe.  If the property
does not exist, the driver will leave the bridge in its
current state.

Signed-off-by: Alan Tull <atull@opensource.altera.com>
Signed-off-by: Matthew Gerlach <mgerlach@altera.com>
Signed-off-by: Dinh Nguyen <dinguyen@opensource.altera.com>
---
v2:  Use resets instead of directly writing reset registers
v12: Bump version to align with simple-fpga-bus version
     Get rid of the sysfs interface
     fpga2sdram: get configuration stored in handoff register
v13: Remove unneeded WARN_ON
     Change property from init-val to bridge-enable
     Checkpatch cleanup
     Fix email address
v14: use module_platform_driver
     remove unused struct field and some #defines
     don't really need exclamation points on error msgs
     *const* struct fpga_bridge_ops
---
 drivers/fpga/Kconfig             |    7 ++
 drivers/fpga/Makefile            |    1 +
 drivers/fpga/altera-fpga2sdram.c |  174 +++++++++++++++++++++++++++++++
 drivers/fpga/altera-hps2fpga.c   |  213 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 395 insertions(+)
 create mode 100644 drivers/fpga/altera-fpga2sdram.c
 create mode 100644 drivers/fpga/altera-hps2fpga.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 6ac916b..30ebe42 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -38,6 +38,13 @@ config FPGA_AREA
          Enable FPGA Area which supports programming FPGAs under control of
 	 Device Tree.
 
+config SOCFPGA_FPGA_BRIDGE
+	bool "Altera SoCFPGA FPGA Bridges"
+	depends on ARCH_SOCFPGA && FPGA_BRIDGE
+	help
+	  Say Y to enable drivers for FPGA bridges for Altera SOCFPGA
+	  devices.
+
 endif # FPGA
 
 endmenu
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 4f7e49f..3efc132 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_FPGA_MGR_ZYNQ_FPGA)	+= zynq-fpga.o
 
 # FPGA Bridge Drivers
 obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
+obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)	+= altera-hps2fpga.o altera-fpga2sdram.o
 
 # High Level Interfaces
 obj-$(CONFIG_FPGA_AREA)			+= fpga-area.o
diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c
new file mode 100644
index 0000000..91f4a40
--- /dev/null
+++ b/drivers/fpga/altera-fpga2sdram.c
@@ -0,0 +1,174 @@
+/*
+ * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation, All Rights Reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This driver manages a bridge between an FPGA and the SDRAM used by the ARM
+ * host processor system (HPS).
+ *
+ * The bridge contains 4 read ports, 4 write ports, and 6 command ports.
+ * Reconfiguring these ports requires that no SDRAM transactions occur during
+ * reconfiguration.  The code reconfiguring the ports cannot run out of SDRAM
+ * nor can the FPGA access the SDRAM during reconfiguration.  This driver does
+ * not support reconfiguring the ports.  The ports are configured by code
+ * running out of on chip ram before Linux is started and the configuration
+ * is passed in a handoff register in the system manager.
+ *
+ * This driver supports enabling and disabling of the configured ports, which
+ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
+ * uses the same port configuration.  Bridges must be disabled before
+ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
+ */
+
+#include <linux/fpga/fpga-bridge.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+
+#define ALT_SDR_CTL_FPGAPORTRST_OFST		0x80
+#define ALT_SDR_CTL_FPGAPORTRST_PORTRSTN_MSK	0x00003fff
+#define ALT_SDR_CTL_FPGAPORTRST_RD_SHIFT	0
+#define ALT_SDR_CTL_FPGAPORTRST_WR_SHIFT	4
+#define ALT_SDR_CTL_FPGAPORTRST_CTRL_SHIFT	8
+
+#define SYSMGR_ISWGRP_HANDOFF3          (0x8C)
+#define ISWGRP_HANDOFF_FPGA2SDR         SYSMGR_ISWGRP_HANDOFF3
+
+#define F2S_BRIDGE_NAME "fpga2sdram"
+
+struct alt_fpga2sdram_data {
+	struct device *dev;
+	struct regmap *sdrctl;
+	int mask;
+};
+
+static int alt_fpga2sdram_enable_show(struct fpga_bridge *bridge)
+{
+	struct alt_fpga2sdram_data *priv = bridge->priv;
+	int value;
+
+	regmap_read(priv->sdrctl, ALT_SDR_CTL_FPGAPORTRST_OFST, &value);
+
+	return (value & priv->mask) == priv->mask;
+}
+
+static inline int _alt_fpga2sdram_enable_set(struct alt_fpga2sdram_data *priv,
+					     bool enable)
+{
+	return regmap_update_bits(priv->sdrctl, ALT_SDR_CTL_FPGAPORTRST_OFST,
+				  priv->mask, enable ? priv->mask : 0);
+}
+
+static int alt_fpga2sdram_enable_set(struct fpga_bridge *bridge, bool enable)
+{
+	return _alt_fpga2sdram_enable_set(bridge->priv, enable);
+}
+
+struct prop_map {
+	char *prop_name;
+	u32 *prop_value;
+	u32 prop_max;
+};
+
+static const struct fpga_bridge_ops altera_fpga2sdram_br_ops = {
+	.enable_set = alt_fpga2sdram_enable_set,
+	.enable_show = alt_fpga2sdram_enable_show,
+};
+
+static const struct of_device_id altera_fpga_of_match[] = {
+	{ .compatible = "altr,socfpga-fpga2sdram-bridge" },
+	{},
+};
+
+static int alt_fpga_bridge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct alt_fpga2sdram_data *priv;
+	u32 enable;
+	struct regmap *sysmgr;
+	int ret = 0;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = dev;
+
+	priv->sdrctl = syscon_regmap_lookup_by_compatible("altr,sdr-ctl");
+	if (IS_ERR(priv->sdrctl)) {
+		dev_err(dev, "regmap for altr,sdr-ctl lookup failed.\n");
+		return PTR_ERR(priv->sdrctl);
+	}
+
+	sysmgr = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
+	if (IS_ERR(priv->sdrctl)) {
+		dev_err(dev, "regmap for altr,sys-mgr lookup failed.\n");
+		return PTR_ERR(sysmgr);
+	}
+
+	/* Get f2s bridge configuration saved in handoff register */
+	regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask);
+
+	ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME,
+				   &altera_fpga2sdram_br_ops, priv);
+	if (ret)
+		return ret;
+
+	dev_info(dev, "driver initialized with handoff %08x\n", priv->mask);
+
+	if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) {
+		if (enable > 1) {
+			dev_warn(dev, "invalid bridge-enable %u > 1\n", enable);
+		} else {
+			dev_info(dev, "%s bridge\n",
+				 (enable ? "enabling" : "disabling"));
+			ret = _alt_fpga2sdram_enable_set(priv, enable);
+			if (ret) {
+				fpga_bridge_unregister(&pdev->dev);
+				return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int alt_fpga_bridge_remove(struct platform_device *pdev)
+{
+	fpga_bridge_unregister(&pdev->dev);
+
+	return 0;
+}
+
+MODULE_DEVICE_TABLE(of, altera_fpga_of_match);
+
+static struct platform_driver altera_fpga_driver = {
+	.probe = alt_fpga_bridge_probe,
+	.remove = alt_fpga_bridge_remove,
+	.driver = {
+		.name	= "altera_fpga2sdram_bridge",
+		.of_match_table = of_match_ptr(altera_fpga_of_match),
+	},
+};
+
+module_platform_driver(altera_fpga_driver);
+
+MODULE_DESCRIPTION("Altera SoCFPGA FPGA to SDRAM Bridge");
+MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/altera-hps2fpga.c b/drivers/fpga/altera-hps2fpga.c
new file mode 100644
index 0000000..c15df47
--- /dev/null
+++ b/drivers/fpga/altera-hps2fpga.c
@@ -0,0 +1,213 @@
+/*
+ * FPGA to/from HPS Bridge Driver for Altera SoCFPGA Devices
+ *
+ *  Copyright (C) 2013-2015 Altera Corporation, All Rights Reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This driver manages bridges on a Altera SOCFPGA between the ARM host
+ * processor system (HPS) and the embedded FPGA.
+ *
+ * This driver supports enabling and disabling of the configured ports, which
+ * allows for safe reprogramming of the FPGA, assuming that the new FPGA image
+ * uses the same port configuration.  Bridges must be disabled before
+ * reprogramming the FPGA and re-enabled after the FPGA has been programmed.
+ */
+
+#include <linux/clk.h>
+#include <linux/fpga/fpga-bridge.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#define ALT_L3_REMAP_OFST			0x0
+#define ALT_L3_REMAP_MPUZERO_MSK		0x00000001
+#define ALT_L3_REMAP_H2F_MSK			0x00000008
+#define ALT_L3_REMAP_LWH2F_MSK			0x00000010
+
+#define HPS2FPGA_BRIDGE_NAME			"hps2fpga"
+#define LWHPS2FPGA_BRIDGE_NAME			"lwhps2fpga"
+#define FPGA2HPS_BRIDGE_NAME			"fpga2hps"
+
+struct altera_hps2fpga_data {
+	const char *name;
+	struct reset_control *bridge_reset;
+	struct regmap *l3reg;
+	/* The L3 REMAP register is write only, so keep a cached value. */
+	unsigned int l3_remap_value;
+	unsigned int remap_mask;
+	struct clk *clk;
+};
+
+static int alt_hps2fpga_enable_show(struct fpga_bridge *bridge)
+{
+	struct altera_hps2fpga_data *priv = bridge->priv;
+
+	return reset_control_status(priv->bridge_reset);
+}
+
+static int _alt_hps2fpga_enable_set(struct altera_hps2fpga_data *priv,
+				    bool enable)
+{
+	int ret;
+
+	/* bring bridge out of reset */
+	if (enable)
+		ret = reset_control_deassert(priv->bridge_reset);
+	else
+		ret = reset_control_assert(priv->bridge_reset);
+	if (ret)
+		return ret;
+
+	/* Allow bridge to be visible to L3 masters or not */
+	if (priv->remap_mask) {
+		priv->l3_remap_value |= ALT_L3_REMAP_MPUZERO_MSK;
+
+		if (enable)
+			priv->l3_remap_value |= priv->remap_mask;
+		else
+			priv->l3_remap_value &= ~priv->remap_mask;
+
+		ret = regmap_write(priv->l3reg, ALT_L3_REMAP_OFST,
+				   priv->l3_remap_value);
+	}
+
+	return ret;
+}
+
+static int alt_hps2fpga_enable_set(struct fpga_bridge *bridge, bool enable)
+{
+	return _alt_hps2fpga_enable_set(bridge->priv, enable);
+}
+
+static const struct fpga_bridge_ops altera_hps2fpga_br_ops = {
+	.enable_set = alt_hps2fpga_enable_set,
+	.enable_show = alt_hps2fpga_enable_show,
+};
+
+static struct altera_hps2fpga_data hps2fpga_data  = {
+	.name = HPS2FPGA_BRIDGE_NAME,
+	.remap_mask = ALT_L3_REMAP_H2F_MSK,
+};
+
+static struct altera_hps2fpga_data lwhps2fpga_data  = {
+	.name = LWHPS2FPGA_BRIDGE_NAME,
+	.remap_mask = ALT_L3_REMAP_LWH2F_MSK,
+};
+
+static struct altera_hps2fpga_data fpga2hps_data  = {
+	.name = FPGA2HPS_BRIDGE_NAME,
+};
+
+static const struct of_device_id altera_fpga_of_match[] = {
+	{ .compatible = "altr,socfpga-hps2fpga-bridge",
+	  .data = &hps2fpga_data },
+	{ .compatible = "altr,socfpga-lwhps2fpga-bridge",
+	  .data = &lwhps2fpga_data },
+	{ .compatible = "altr,socfpga-fpga2hps-bridge",
+	  .data = &fpga2hps_data },
+	{},
+};
+
+static int alt_fpga_bridge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct altera_hps2fpga_data *priv;
+	const struct of_device_id *of_id;
+	u32 enable;
+	int ret;
+
+	of_id = of_match_device(altera_fpga_of_match, dev);
+	priv = (struct altera_hps2fpga_data *)of_id->data;
+
+	priv->bridge_reset = devm_reset_control_get(dev, priv->name);
+	if (IS_ERR(priv->bridge_reset)) {
+		dev_err(dev, "Could not get %s reset control\n", priv->name);
+		return PTR_ERR(priv->bridge_reset);
+	}
+
+	priv->l3reg = syscon_regmap_lookup_by_compatible("altr,l3regs");
+	if (IS_ERR(priv->l3reg)) {
+		dev_err(dev, "regmap for altr,l3regs lookup failed\n");
+		return PTR_ERR(priv->l3reg);
+	}
+
+	priv->clk = of_clk_get(dev->of_node, 0);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "no clock specified\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(dev, "could not enable clock\n");
+		return -EBUSY;
+	}
+
+	ret = fpga_bridge_register(dev, priv->name, &altera_hps2fpga_br_ops,
+				   priv);
+	if (ret)
+		return ret;
+
+	if (!of_property_read_u32(dev->of_node, "bridge-enable", &enable)) {
+		if (enable > 1) {
+			dev_warn(dev, "invalid bridge-enable %u > 1\n", enable);
+		} else {
+			dev_info(dev, "%s bridge\n",
+				 (enable ? "enabling" : "disabling"));
+
+			ret = _alt_hps2fpga_enable_set(priv, enable);
+			if (ret) {
+				fpga_bridge_unregister(&pdev->dev);
+				return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int alt_fpga_bridge_remove(struct platform_device *pdev)
+{
+	struct fpga_bridge *bridge = platform_get_drvdata(pdev);
+	struct altera_hps2fpga_data *priv = bridge->priv;
+
+	fpga_bridge_unregister(&pdev->dev);
+
+	clk_disable_unprepare(priv->clk);
+	clk_put(priv->clk);
+
+	return 0;
+}
+
+MODULE_DEVICE_TABLE(of, altera_fpga_of_match);
+
+static struct platform_driver alt_fpga_bridge_driver = {
+	.probe = alt_fpga_bridge_probe,
+	.remove = alt_fpga_bridge_remove,
+	.driver = {
+		.name	= "altera_hps2fpga_bridge",
+		.of_match_table = of_match_ptr(altera_fpga_of_match),
+	},
+};
+
+module_platform_driver(alt_fpga_bridge_driver);
+
+MODULE_DESCRIPTION("Altera SoCFPGA HPS to FPGA Bridge");
+MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5

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

* Re: [PATCH v14 2/7] fpga: add bindings document for fpga area
  2015-12-10 23:37   ` atull
  (?)
@ 2015-12-11 14:34   ` Rob Herring
  -1 siblings, 0 replies; 24+ messages in thread
From: Rob Herring @ 2015-12-11 14:34 UTC (permalink / raw)
  To: atull
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen

On Thu, Dec 10, 2015 at 05:37:04PM -0600, atull@opensource.altera.com wrote:
> From: Alan Tull <atull@opensource.altera.com>
> 
> New bindings document for FPGA Area for reprogramming
> FPGA's under Device Tree control
> 
> Signed-off-by: Alan Tull <atull@opensource.altera.com>
> ---
> v9:  initial version added to this patchset
> v10: s/fpga/FPGA/g
>      replace DT overlay example with slightly more complicated example
>      move to staging/simple-fpga-bus
> v11: No change in this patch for v11 of the patch set
> v12: Moved out of staging.
>      Changed to use FPGA bridges framework instead of resets
>      for bridges.
> v13: bridge@0xff20000 -> bridge@ff200000, etc
>      Leave out directly talking about overlays
>      Remove regs and clocks directly under simple-fpga-bus in example
>      Use common "firmware-name" binding instead of "fpga-firmware"
> v14: Use firmware-name in bindings description
>      Call it FPGA Area
>      Remove bindings that specify FPGA Manager and FPGA Bridges
> ---
>  .../devicetree/bindings/fpga/fpga-area.txt         |   70 ++++++++++++++++++++
>  1 file changed, 70 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/fpga/fpga-area.txt
> 
> diff --git a/Documentation/devicetree/bindings/fpga/fpga-area.txt b/Documentation/devicetree/bindings/fpga/fpga-area.txt
> new file mode 100644
> index 0000000..d656e35
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/fpga/fpga-area.txt
> @@ -0,0 +1,70 @@
> +FPGA Area
> +=========
> +
> +A FPGA Area details information about a section of an FPGA including the FPGA
> +image needed to program it and the hardware contained in this section of the
> +FPGA once it is programmed.
> +
> +A FPGA Area corresponds to the whole FPGA in the case of full reconfiguration
> +or a section of a FPGA in the case of partial reconfiguration.
> +
> +Required properties:
> +- compatible : should contain "fpga-area"

I'm not too sure about this. I think this needs to be FPGA specfic.

> +- #address-cells, #size-cells, ranges: must be present to handle address space
> +  mapping for children.
> +
> +Optional properties:
> +- firmware-name : should contain the name of a FPGA image file located on the
> +  firmware search path.
> +- partial-reconfig : boolean property should be defined if partial
> +  reconfiguration of the FPGA is to be done, otherwise full reconfiguration
> +  is done.
> +
> +Example:
> +
> +/dts-v1/;
> +/plugin/;
> +/ {
> +	fragment@0 {
> +		target-path="/soc/fpgamgr@0/bridge@0";

Does the bus really go thru the fpgamgr and then the bridge as this 
implies? Or fpgamgr is a sideband controller? For example purposes, it 
would be better to show this not as an overlay so I get the complete 
picture.

Unit addresses of 0 look a bit questionable as I'd expect these to be 
addresses.

> +		__overlay__ {
> +			#address-cells = <1>;
> +	                #size-cells = <1>;
> +
> +			bridge@ff200000 {

2 levels of bridge devices/buses?

There is nothing programmable for this bridge? clocks, resets, etc.?

> +				compatible = "fpga-area";
> +
> +				#address-cells = <2>;
> +				#size-cells = <1>;
> +
> +				ranges = <0 0x00000000 0xc0000000 0x00010000>,
> +					 <1 0x00020000 0xff220000 0x00000008>,
> +					 <1 0x00010040 0xff210040 0x00000020>;
> +
> +				firmware-name = "soc_system.rbf";
> +
> +				onchip_memory2_0: memory@000000000 {
> +					device_type = "memory";
> +					compatible = "altr,onchipmem-15.1";
> +					reg = <0 0x00000000 0x00010000>;
> +				};
> +
> +				jtag_uart: serial@100020000 {
> +					compatible = "altr,juart-1.0";
> +					reg = <1 0x00020000 0x00000008>;
> +					interrupt-parent = <&intc>;
> +					interrupts = <0 42 4>;
> +				};
> +
> +				led_pio: gpio@100010040 {
> +					compatible = "altr,pio-1.0";
> +					reg = <1 0x00010040 0x00000020>;
> +					altr,gpio-bank-width = <4>;
> +					#gpio-cells = <2>;
> +					gpio-controller;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> -- 
> 1.7.9.5
> 
> --
> 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

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

* Re: [PATCH v14 1/7] fpga: add usage documentation for fpga area
  2015-12-10 23:37   ` atull
  (?)
@ 2015-12-11 15:05   ` Rob Herring
  2015-12-11 18:33       ` atull
  -1 siblings, 1 reply; 24+ messages in thread
From: Rob Herring @ 2015-12-11 15:05 UTC (permalink / raw)
  To: atull
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen

On Thu, Dec 10, 2015 at 05:37:03PM -0600, atull@opensource.altera.com wrote:
> From: Alan Tull <atull@opensource.altera.com>
> 
> Add a document spelling out usage of the FPGA Area for
> reprogramming FPGA's under Device Tree control.
 
I'm not too sure about the split between this and the binding doc. This 
one clears up a bit after reading the binding doc first and most of this 
is about DT.

> Signed-off-by: Alan Tull <atull@opensource.altera.com>
> 
> ---
> v9:  Initial version of this patch in patchset
> v10: s/fpga/FPGA/g
>      improve formatting
>      some rewriting
>      move to staging/simple-fpga-bus
> v11: No change in this patch for v11 of the patch set
> v12: Moved out of staging
>      Small changes due to using FPGA bridge framework and not
>      representing the bridges as resets.
> v13: Fix some nits
> v14: fpga-area instead of simple-fpga-bus
> ---
>  Documentation/fpga/fpga-area.txt |  299 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 299 insertions(+)
>  create mode 100644 Documentation/fpga/fpga-area.txt
> 
> diff --git a/Documentation/fpga/fpga-area.txt b/Documentation/fpga/fpga-area.txt
> new file mode 100644
> index 0000000..f031522
> --- /dev/null
> +++ b/Documentation/fpga/fpga-area.txt
> @@ -0,0 +1,299 @@
> +FPGA Area
> +
> +Alan Tull 2015
> +
> +Overview
> +========
> +
> +An FPGA Area details information about a section of an FPGA including the FPGA
> +image needed to program it and the hardware contained once it is programmed.
> +
> +Loading a Device Tree overlay which contains an FPGA Area will cause the
> +FPGA to be programmed and the children of the FPGA Area will get probed.
> +
> +There may be FPGA Bridges involved to prevent spurious data from going out onto
> +the processor bus during FPGA programming.  If so, the FPGA Area will need to
> +disable and enable bridges that will only affect the child devices that are
> +below the FPGA Area.  In the case of partial reconfiguration, bridges will
> +be required within the FPGA design such that the active sections of the
> +FPGA are on the bus while sections that are not programmed or being
> +reprogrammed at the moment are isolated.
> +
> +Removing the overlay will result in the child devices getting removed and the
> +bridges disabled.  Note that in the case of partial reconfiguration the rest of
> +the FPGA continues to function as normal while this is happening.
> +
> +Below are more details on the structuring of the Device Tree for this.
> +
> +Terminology
> +===========
> +
> +Full Reconfiguration
> + * The entire FPGA is reprogrammed.
> +
> +Partial Reconfiguration (PR)
> + * Part of the FPGA is reprogrammed while the rest of the FPGA is live and
> +   active.  Not all FPGA's support this.
> +
> +Associated Blocks
> +=================
> +
> +FPGA Manager Framework
> + * An FPGA Manager is a hardware block that programs an FPGA under the control
> +   of a host processor.
> + * The FPGA Manager Framework provides drivers and functions to program an
> +   FPGA.
> +
> +FPGA Bridge Framework
> + * Provides drivers and functions to control bridges that enable/disable
> +   data to the FPGA.
> + * FPGA bridges should be disabled while the FPGA is being programmed to
> +   prevent spurious data on the bus.
> + * FPGA bridges are not needed in implementations where the FPGA Manager
> +   handles this.
> +
> +Device Tree
> +===========
> +
> +For the purposes of this document, I'm dividing the Device Tree (DT) into two parts,
> +each with its own requirements.  The two parts are:
> + * The live DT prior to the overlay being added
> + * The overlay containing an FPGA Area
> +
> +The live DT will contain:
> + * FPGA Manager
> + * FPGA Bridges as children of the FPGA Manager (optional, architecture specific)
> +
> +The live Device Tree must contain an FPGA Manager to handle programming the FPGA.
> +If FPGA Bridges need to be involved, they show up in the DT as direct children
> +of the FPGA Manager.  During full reconfiguration, the FPGA Area will disable
> +any bridges that are direct children of the manager during full reconfiguration
> +and will re-enable them afterwards.
> +
> +The insertion point in the live tree will also need the "simple-bus"
> +compatibility string to enable populating the child nodes for the overlay.
> +That includes the nodes for the FPGA Manager and controlling FPGA Bridges
> +as explained below.
> +
> +The Device Tree Overlay will contain:
> + * "target-path"
> +   The insertion point where the the contents of the overlay will go into the
> +   live tree.
> + * "ranges"
> + * "firmware-name"
> +   Specifies the name of the FPGA image file on the firmware search
> +   path.  The search path is described in the firmware class documentation.
> + * "partial-reconfig"
> +   This binding is a boolean and should be present if partial reconfiguration
> +   is to be done.
> + * child nodes corresponding to hardware that will be loaded in this
> +   region of the FPGA.
> +
> +Supported use models
> +====================
> +
> +Here's a list of the superset of supported use models.  We may need to add
> +more.  Some uses are specific to one FPGA or another.
> +
> + * No FPGA Bridges
> +   In this case, the FPGA Manager which programs the FPGA also handles the
> +   bridges and no FPGA Bridge devices are needed for full reconfiguration.
> +
> +   The DT overlay will specify the FPGA Manager as the overlay target.
> +
> + * Full reconfiguration with bridges
> +   In the case, there are several bridges between the processor and FPGA,
> +   that need to be disabled during full reconfiguration.
> +   The DT before the overlay is applied will have an FPGA Manager.  The
> +   immediate children of the manager will be the FPGA Bridges that need to be
> +   disabled during FPGA programming.
> +
> +   The DT overlay will specify one of those bridges as the overlay target,
> +   typically the bridge that allows memory mapped register access ("the
> +   controlling bridge").
> +
> + * Partial reconfiguration with bridges in the FPGA
> +   In this case, the FPGA can have more than one section that will be
> +   reprogrammed separately.  Other sections may be active on the bus while FPGA
> +   is being programmed.  To manage this, FPGA Bridges need to exist on the FPGA
> +   that can freeze all the buses going to one FPGA area while the buses are
> +   enabled for other sections.
> +
> +Controlling Bridge
> +==================
> +
> +It is possible that there are multiple FPGA Bridges connecting the processor
> +and FPGA.  In a text based hierarchy, it is difficult to show this properly
> +so what we do is consider the bridge that handles register access to be
> +the controlling bridge.  The overlay is targeted to be inserted under the
> +controlling bridge.  Other bridges are on the same level of the device tree
> +as the controlling bridge, i.e. all are children of the FPGA Manager.  The
> +ranges property handles mapping memory ranges through multiple bridges.
> +
> +Sequence
> +========
> +
> +Load the DT overlay.  One way to do that from user space is to use Pantelis
> +Antoniou's DT-Overlay configfs interface.  In that case the sequence from
> +userspace is:

It will be a problem merging this series if you document things that are 
not upstream yet.

> +
> + $ mkdir /config/device-tree/overlays/1
> + $ echo "some_overlay.dtb.o" > /config/device-tree/overlays/1/path
> +
> +This causes the FPGA Area to be probed and will do the following:
> + 1. Disable the FPGA bridges.
> + 2. Use the the FPGA manager core to program the FPGA.
> + 3. Enable the FPGA bridges.
> + 4. Call of_platform_populate resulting in device drivers getting probed.
> +
> +Removing the overlay is done by:
> +
> + $ rmdir /config/device-tree/overlays/1
> +
> +This causes the child nodes to be removed and then the bridges are disabled.
> +
> +Device Tree Examples
> +====================
> +
> +The intention of this section is to give some simple examples, focusing on
> +the placement of the elements detailed above in, especially:
> + * FPGA Managers
> + * FPGA Bridges in some cases
> + * FPGA Areas and associated properties
> + * simple-bus
> + * ranges
> + * target-path
> +
> +Please note the "simple-bus" compatible string added for FPGA Managers and for
> +FPGA Bridges where the overlay is targeted for insertion.  This is required for
> +populating the child nodes.
> +
> +Device Tree Example: Partial Reconfiguration with no Bridges
> +============================================================
> +
> +Live Device Tree contains:
> +	fpgamgr@0 {

Unit address should be ffd03000 here.

> +		compatible = "altr,socfpga-a10-fpga-mgr", "simple-bus";

This should not have simple-bus. This would be broken in the case of 
applying the overlay before booting the kernel. You don't want the 
devices probed before the fpgamgr has programmed them.

> +		clocks = <&l4_mp_clk>;
> +		resets = <&rst FPGAMGR_RESET>;
> +		reset-names = "fpgamgr";
> +		reg = <0xffd03000 0x1000
> +		       0xffcfe400 0x1000>;
> +
> +		#address-cells = <0x1>;
> +		#size-cells = <0x1>;
> +		ranges;
> +	};
> +
> +DT Overlay contains:
> +/dts-v1/;
> +/plugin/;
> +/ {
> +	fragment@0 {
> +		target-path="/soc/fpgamgr@0";  /* targeted to the manager */
> +		__overlay__ {
> +			#address-cells = <1>;
> +	                #size-cells = <1>;
> +
> +			area@0 {
> +				compatible = "fpga-area";
> +
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +				ranges = <0x10010 0xff210010 0x10>;
> +
> +				firmware-name = "fit_pr_v1.rbf";
> +				partial-reconfig;
> +
> +				gpio@0x100010010 {

Remove 0x

> +					compatible = "altr,pio-1.0";
> +					reg = <0x10010 0x10>;
> +					altr,ngpio = <4>;
> +					#gpio-cells = <0x2>;
> +					gpio-controller;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +
> +Device Tree Example: Full Reconfiguration with Bridges
> +======================================================
> +
> +Live Device Tree contains:
> +	fpgamgr@0 {

unit address

> +		compatible = "altr,socfpga-fpga-mgr", "simple-bus";
> +		reg = <0xFF706000 0x1000
> +		       0xFFB90000 0x1000>;

lower case

> +		interrupts = <0 175 4>;
> +
> +		#address-cells = <0x1>;
> +		#size-cells = <0x1>;
> +		ranges;
> +
> +		bridge@0 {

Don't the outbound bridges have an address range associated with them? 
Possibly, they should not be children of the fpgamgr unless the fpgamgr 
itself is a bridge.

> +			/* both the manager and the controlling bridge have
> +			 * the added simple-bus compatible to allow child
> +			 * devices to be populated. */

Why? Once you have initialized the bridge, you call of_platform_populate 
with this node as the starting point. The root does not need any 
matching string.

> +			compatible = "altr,socfpga-lwhps2fpga-bridge",
> +				     "simple-bus";
> +			resets = <&rst LWHPS2FPGA_RESET>;
> +			reset-names = "lwhps2fpga";
> +			clocks = <&l4_main_clk>;
> +			#address-cells = <0x1>;
> +			#size-cells = <0x1>;
> +			ranges;
> +		};
> +
> +		bridge@1 {
> +			/* In the case of full reconfiguration, both bridge@0
> +			 * and bridge@1 will be disabled during FPGA
> +			 * programming and enabled afterwards. */
> +			compatible = "altr,socfpga-hps2fpga-bridge";
> +			resets = <&rst HPS2FPGA_RESET>;
> +			reset-names = "hps2fpga";
> +			clocks = <&l4_main_clk>;
> +		};
> +	};
> +
> +DT Overlay contains:
> +/dts-v1/;
> +/plugin/;
> +/ {
> +	fragment@0 {
> +		target-path="/soc/fpgamgr@0/bridge@0"; /* controlling bridge */
> +		__overlay__ {
> +			#address-cells = <1>;
> +	                #size-cells = <1>;
> +
> +			area@0 {
> +				compatible = "fpga-area";
> +
> +				#address-cells = <2>;
> +				#size-cells = <1>;
> +				/* Note that two ranges are mapped due to the
> +				 * two bridges. */
> +				ranges = <0 0x00000000 0xc0000000 0x00010000>,
> +					 <1 0x00020000 0xff220000 0x00000008>;

0 and 1 are address bits or mean something else (chip select # is common 
example)?

> +
> +				firmware-name = "soc_system.rbf";
> +
> +				onchip_memory2_0: memory@000000000 {

Drop leading zeros (i.e. memory@0).

> +					device_type = "memory";
> +					compatible = "altr,onchipmem-15.1";
> +					reg = <0 0x00000000 0x00010000>;
> +				};
> +
> +				jtag_uart: serial@0x100020000 {

Drop '0x'

> +					compatible = "altr,juart-1.0";
> +					reg = <1 0x00020000 0x00000008>;
> +					interrupt-parent = <&intc>;
> +					interrupts = <0 42 4>;
> +					clocks = <&osc2>;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> -- 
> 1.7.9.5
> 

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

* Re: [PATCH v14 1/7] fpga: add usage documentation for fpga area
  2015-12-11 15:05   ` Rob Herring
@ 2015-12-11 18:33       ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-11 18:33 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen

On Fri, 11 Dec 2015, Rob Herring wrote:

Hi Rob,

> > +Device Tree Example: Partial Reconfiguration with no Bridges
> > +============================================================
> > +
> > +Live Device Tree contains:
> > +	fpgamgr@0 {
> 
> Unit address should be ffd03000 here.

I'll clean up the addresses (and add that to my checklist!).

> 
> > +		compatible = "altr,socfpga-a10-fpga-mgr", "simple-bus";
> 
> This should not have simple-bus. This would be broken in the case of 
> applying the overlay before booting the kernel. You don't want the 
> devices probed before the fpgamgr has programmed them.
> 

I debugged this and had to add the simple-bus's to see my child devices
probe.  Otherwise I can apply the overlay, but when I call
of_platform_populate, no child nodes get populated.
In drivers/of/platform.c's of_platform_notify(), the OF_POPULATED_BUS
flag has to be set for the parent (implying it was set for its parents
or it wouldn't be set).  The child nodes do not get populated unless
the insertion point and all the ancestors of the insertion point are
simple-bus's.  

So the issue of applying the overlay before booting the kernel:
if FPGA Area gets probed before its children get populated, then
I'm K since FPGA Area is responsible for programming the FPGA.

I can rework this to have a virtualized fpgabus that has the fpgamgr
and bridges as its children if that is more correct.  I actually
worked this up several different ways so I have the code.  I still
would like to keep the FPGA Area because that gives me a module that
gets probed that can be in charge of programming the FPGA.  If I were
to rid of FPGA Area and just have an overlay of "firmware-name" plus
child nodes, then I have to add a notifier to the fpgabus.  This I
can do (and have done and seen it work) so if that is preferable,
that's what v15 of this can easily be.

In that case, the target path for the overlay could be the fpgabus.
The fpgabus would need to also be a simple-bus but not the manager
or bridges.

So if I have a fpgabus, the live tree would be:
	fpgabus@0 {
		compatible = "altr,fpga-bus", "simple-bus";
		#address-cells = <0x1>;
		#size-cells = <0x1>;
		ranges;

		fpgamgr@ff706000 {
			compatible = "altr,socfpga-fpga-mgr";
			reg = <0xff706000 0x1000
			       0xffb90000 0x1000>;
			interrupts = <0 175 4>;
		};

		bridge@0 {
			compatible = "altr,socfpga-lwhps2fpga-bridge";
			resets = <&rst LWHPS2FPGA_RESET>;
			reset-names = "lwhps2fpga";
			clocks = <&l4_main_clk>;
			#address-cells = <0x1>;
			#size-cells = <0x1>;
			ranges;
		};

		bridge@1 {
			compatible = "altr,socfpga-hps2fpga-bridge";
			resets = <&rst HPS2FPGA_RESET>;
			reset-names = "hps2fpga";
			clocks = <&l4_main_clk>;
		};
	};

Alan

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

* Re: [PATCH v14 1/7] fpga: add usage documentation for fpga area
@ 2015-12-11 18:33       ` atull
  0 siblings, 0 replies; 24+ messages in thread
From: atull @ 2015-12-11 18:33 UTC (permalink / raw)
  To: Rob Herring
  Cc: Moritz Fischer, Josh Cartwright, gregkh, monstr, michal.simek,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, linux-kernel, devicetree, linux-doc,
	pantelis.antoniou, delicious.quinoa, dinguyen

On Fri, 11 Dec 2015, Rob Herring wrote:

Hi Rob,

> > +Device Tree Example: Partial Reconfiguration with no Bridges
> > +============================================================
> > +
> > +Live Device Tree contains:
> > +	fpgamgr@0 {
> 
> Unit address should be ffd03000 here.

I'll clean up the addresses (and add that to my checklist!).

> 
> > +		compatible = "altr,socfpga-a10-fpga-mgr", "simple-bus";
> 
> This should not have simple-bus. This would be broken in the case of 
> applying the overlay before booting the kernel. You don't want the 
> devices probed before the fpgamgr has programmed them.
> 

I debugged this and had to add the simple-bus's to see my child devices
probe.  Otherwise I can apply the overlay, but when I call
of_platform_populate, no child nodes get populated.
In drivers/of/platform.c's of_platform_notify(), the OF_POPULATED_BUS
flag has to be set for the parent (implying it was set for its parents
or it wouldn't be set).  The child nodes do not get populated unless
the insertion point and all the ancestors of the insertion point are
simple-bus's.  

So the issue of applying the overlay before booting the kernel:
if FPGA Area gets probed before its children get populated, then
I'm K since FPGA Area is responsible for programming the FPGA.

I can rework this to have a virtualized fpgabus that has the fpgamgr
and bridges as its children if that is more correct.  I actually
worked this up several different ways so I have the code.  I still
would like to keep the FPGA Area because that gives me a module that
gets probed that can be in charge of programming the FPGA.  If I were
to rid of FPGA Area and just have an overlay of "firmware-name" plus
child nodes, then I have to add a notifier to the fpgabus.  This I
can do (and have done and seen it work) so if that is preferable,
that's what v15 of this can easily be.

In that case, the target path for the overlay could be the fpgabus.
The fpgabus would need to also be a simple-bus but not the manager
or bridges.

So if I have a fpgabus, the live tree would be:
	fpgabus@0 {
		compatible = "altr,fpga-bus", "simple-bus";
		#address-cells = <0x1>;
		#size-cells = <0x1>;
		ranges;

		fpgamgr@ff706000 {
			compatible = "altr,socfpga-fpga-mgr";
			reg = <0xff706000 0x1000
			       0xffb90000 0x1000>;
			interrupts = <0 175 4>;
		};

		bridge@0 {
			compatible = "altr,socfpga-lwhps2fpga-bridge";
			resets = <&rst LWHPS2FPGA_RESET>;
			reset-names = "lwhps2fpga";
			clocks = <&l4_main_clk>;
			#address-cells = <0x1>;
			#size-cells = <0x1>;
			ranges;
		};

		bridge@1 {
			compatible = "altr,socfpga-hps2fpga-bridge";
			resets = <&rst HPS2FPGA_RESET>;
			reset-names = "hps2fpga";
			clocks = <&l4_main_clk>;
		};
	};

Alan

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

* Re: [PATCH v14 1/7] fpga: add usage documentation for fpga area
  2015-12-11 18:33       ` atull
  (?)
@ 2015-12-11 19:18       ` Rob Herring
  -1 siblings, 0 replies; 24+ messages in thread
From: Rob Herring @ 2015-12-11 19:18 UTC (permalink / raw)
  To: atull
  Cc: Moritz Fischer, Josh Cartwright, Greg Kroah-Hartman,
	Michal Simek, Michal Simek, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Jonathan Corbet, linux-kernel,
	devicetree, linux-doc, Pantelis Antoniou, Alan Tull, Dinh Nguyen

On Fri, Dec 11, 2015 at 12:33 PM, atull <atull@opensource.altera.com> wrote:
> On Fri, 11 Dec 2015, Rob Herring wrote:
>
> Hi Rob,
>
>> > +Device Tree Example: Partial Reconfiguration with no Bridges
>> > +============================================================
>> > +
>> > +Live Device Tree contains:
>> > +   fpgamgr@0 {
>>
>> Unit address should be ffd03000 here.
>
> I'll clean up the addresses (and add that to my checklist!).
>
>>
>> > +           compatible = "altr,socfpga-a10-fpga-mgr", "simple-bus";
>>
>> This should not have simple-bus. This would be broken in the case of
>> applying the overlay before booting the kernel. You don't want the
>> devices probed before the fpgamgr has programmed them.
>>
>
> I debugged this and had to add the simple-bus's to see my child devices
> probe.  Otherwise I can apply the overlay, but when I call
> of_platform_populate, no child nodes get populated.
> In drivers/of/platform.c's of_platform_notify(), the OF_POPULATED_BUS
> flag has to be set for the parent (implying it was set for its parents
> or it wouldn't be set).  The child nodes do not get populated unless
> the insertion point and all the ancestors of the insertion point are
> simple-bus's.

That's probably an oddity in how overlays are applied. We may not want the core to populate the devices, but require that the FPGA mgr does that.

> So the issue of applying the overlay before booting the kernel:
> if FPGA Area gets probed before its children get populated, then
> I'm K since FPGA Area is responsible for programming the FPGA.
>
> I can rework this to have a virtualized fpgabus that has the fpgamgr
> and bridges as its children if that is more correct.  I actually
> worked this up several different ways so I have the code.  I still
> would like to keep the FPGA Area because that gives me a module that
> gets probed that can be in charge of programming the FPGA.  If I were
> to rid of FPGA Area and just have an overlay of "firmware-name" plus
> child nodes, then I have to add a notifier to the fpgabus.  This I
> can do (and have done and seen it work) so if that is preferable,
> that's what v15 of this can easily be.
>
> In that case, the target path for the overlay could be the fpgabus.
> The fpgabus would need to also be a simple-bus but not the manager
> or bridges.
>
> So if I have a fpgabus, the live tree would be:
>         fpgabus@0 {
>                 compatible = "altr,fpga-bus", "simple-bus";
>                 #address-cells = <0x1>;
>                 #size-cells = <0x1>;
>                 ranges;
>
>                 fpgamgr@ff706000 {
>                         compatible = "altr,socfpga-fpga-mgr";
>                         reg = <0xff706000 0x1000
>                                0xffb90000 0x1000>;
>                         interrupts = <0 175 4>;
>                 };
>
>                 bridge@0 {
>                         compatible = "altr,socfpga-lwhps2fpga-bridge";
>                         resets = <&rst LWHPS2FPGA_RESET>;
>                         reset-names = "lwhps2fpga";
>                         clocks = <&l4_main_clk>;
>                         #address-cells = <0x1>;
>                         #size-cells = <0x1>;
>                         ranges;
>                 };
>
>                 bridge@1 {
>                         compatible = "altr,socfpga-hps2fpga-bridge";
>                         resets = <&rst HPS2FPGA_RESET>;
>                         reset-names = "hps2fpga";
>                         clocks = <&l4_main_clk>;
>                 };
>         };
>
> Alan
> --
> 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

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

* Re: [PATCH v14 0/7] fpga area and fpga bridge framework
  2015-12-10 23:37 ` atull
                   ` (7 preceding siblings ...)
  (?)
@ 2015-12-14 17:16 ` Moritz Fischer
  2015-12-15  1:56   ` Alan Tull
  -1 siblings, 1 reply; 24+ messages in thread
From: Moritz Fischer @ 2015-12-14 17:16 UTC (permalink / raw)
  To: Alan Tull
  Cc: Rob Herring, Josh Cartwright, Greg KH, Michal Simek,
	Michal Simek, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, Linux Kernel Mailing List, Devicetree List,
	linux-doc, Pantelis Antoniou, Alan Tull, dinguyen

Hi Alan,

On Thu, Dec 10, 2015 at 3:37 PM,  <atull@opensource.altera.com> wrote:
> From: Alan Tull <atull@opensource.altera.com>
>
> For v14 I'm dropping the concept of "simple-fpga-bus" for "fpga-area"
> with reworked bindings.

I had an offline discussion with Josh Cartwright about his concerns.
He brought up a good
point on w.r.t to the way FPGA Area (Bus) deals with things.

Currently we only support complete status = "okay" vs "disabled" kind
of overlays.

If now you have say a UART in the FPGA that you don't want to go away
and come back on reload,
we don't have a good way of expressing this. Is there a good way to
express non-mmio FPGA devices?

I've been toying around with hacking up struct device to include a
FPGA 'domain', and then, similar
to power domains allow devices to register suspend() / resume() style
callbacks (could call them pre_reload() or something like that ...)

I haven't gotten around to think it through. At this point it's just
an idea and I don't have real code to show.

I realize the issue with that is we'd have to make changes to struct device.

Cheers,

Moritz

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

* Re: [PATCH v14 0/7] fpga area and fpga bridge framework
  2015-12-14 17:16 ` [PATCH v14 0/7] fpga area and fpga bridge framework Moritz Fischer
@ 2015-12-15  1:56   ` Alan Tull
  2015-12-15 18:15     ` Moritz Fischer
  0 siblings, 1 reply; 24+ messages in thread
From: Alan Tull @ 2015-12-15  1:56 UTC (permalink / raw)
  To: Moritz Fischer
  Cc: Alan Tull, Rob Herring, Josh Cartwright, Greg KH, Michal Simek,
	Michal Simek, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, Linux Kernel Mailing List, Devicetree List,
	linux-doc, Pantelis Antoniou, dinguyen

On Mon, Dec 14, 2015 at 11:16 AM, Moritz Fischer
<moritz.fischer@ettus.com> wrote:
> Hi Alan,
>
> On Thu, Dec 10, 2015 at 3:37 PM,  <atull@opensource.altera.com> wrote:
>> From: Alan Tull <atull@opensource.altera.com>
>>
>> For v14 I'm dropping the concept of "simple-fpga-bus" for "fpga-area"
>> with reworked bindings.
>
> I had an offline discussion with Josh Cartwright about his concerns.
> He brought up a good
> point on w.r.t to the way FPGA Area (Bus) deals with things.
>
> Currently we only support complete status = "okay" vs "disabled" kind
> of overlays.
>
> If now you have say a UART in the FPGA that you don't want to go away
> and come back on reload,
> we don't have a good way of expressing this.

Maybe i don't understand what you are saying; could you write out a
sequence you want to be able to do?

If you want suspend/resume functionality that would reload the FPGA
after a suspend powers off the FPGA, that would be simple to add to
the FPGA area code and it wasn't a hack at all.

> Is there a good way to
> express non-mmio FPGA devices?

Is this a separate question/issue from the above?  Are you talking
about acceleration?

>
> I've been toying around with hacking up struct device to include a
> FPGA 'domain', and then, similar
> to power domains allow devices to register suspend() / resume() style
> callbacks (could call them pre_reload() or something like that ...)
>
> I haven't gotten around to think it through. At this point it's just
> an idea and I don't have real code to show.
>
> I realize the issue with that is we'd have to make changes to struct device.

That's interesting.  Usually a FPGA image has many devices in it, so
so way of making that dependency clear would be needed.  If any of the
devices involved are powered up, that FPGA image would need to be
loaded.

Currently I'm trying to get some bindings approved for doing device
tree control of loading the FPGA and probing the devices.  My idea is
that these bindings could be useful for some use cases where we are
loading hardware onto the FPGA that needs to show up in the device
tree. Some of Rob's feedback is that my proposal may be
Altera-specific. If the bindings that I am proposing are useful for at
least some uses with Xilinx parts, that would be valuable feedback at
this point.  If they are Altera-specific, then I may need to add
"altr," to some of the compatible strings like "altr,fpga-bus" and
"altr,fpga-area".  My original intent was to implement something that
you could use also, so I hope that's not the future here.

So my question for you is: is this stuff useful for you?

Alan Tull

>
> Cheers,
>
> Moritz

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

* Re: [PATCH v14 0/7] fpga area and fpga bridge framework
  2015-12-15  1:56   ` Alan Tull
@ 2015-12-15 18:15     ` Moritz Fischer
  0 siblings, 0 replies; 24+ messages in thread
From: Moritz Fischer @ 2015-12-15 18:15 UTC (permalink / raw)
  To: Alan Tull
  Cc: Alan Tull, Rob Herring, Josh Cartwright, Greg KH, Michal Simek,
	Michal Simek, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Corbet, Linux Kernel Mailing List, Devicetree List,
	linux-doc, Pantelis Antoniou, dinguyen

Hi Alan,

On Mon, Dec 14, 2015 at 5:56 PM, Alan Tull <delicious.quinoa@gmail.com> wrote:

>> I had an offline discussion with Josh Cartwright about his concerns.
>> He brought up a good
>> point on w.r.t to the way FPGA Area (Bus) deals with things.
>>
>> Currently we only support complete status = "okay" vs "disabled" kind
>> of overlays.

> Maybe i don't understand what you are saying; could you write out a
> sequence you want to be able to do?

Let's say you have a UART in the FPGA. You want to reprogram the FPGA
fabric that includes the UART (assuming proper resets etc happen)

1) Driver gets notified of impending doom, keeps hands off of FPGA
2) FPGA Manager reloads FPGA
3) FPGA Manager lets driver know FPGA is back
4) Driver can continue to function as always

It wouldn't even have to be a UART, on some boards simple SPI lines or UART
lines  go from the processor through the FPGA logic out to a pin.
When you reload the FPGA for a short moment of time that doesn't work,
while after the reload it works just fine. Maybe something like extcon could
be used for that?

> Is this a separate question/issue from the above?  Are you talking
> about acceleration?

I meant stuff like SPI that gets routed through the FPGA, sorry for
being unclear ;-)

>>
>> I've been toying around with hacking up struct device to include a
>> FPGA 'domain', and then, similar
>> to power domains allow devices to register suspend() / resume() style
>> callbacks (could call them pre_reload() or something like that ...)
>>
>> I haven't gotten around to think it through. At this point it's just
>> an idea and I don't have real code to show.
>>
>> I realize the issue with that is we'd have to make changes to struct device.
>
> That's interesting.  Usually a FPGA image has many devices in it, so
> so way of making that dependency clear would be needed.  If any of the
> devices involved are powered up, that FPGA image would need to be
> loaded.

Yeah. That's why I think the power domain model we have has a bunch of
similarities.

> Currently I'm trying to get some bindings approved for doing device
> tree control of loading the FPGA and probing the devices.  My idea is
> that these bindings could be useful for some use cases where we are
> loading hardware onto the FPGA that needs to show up in the device
> tree. Some of Rob's feedback is that my proposal may be
> Altera-specific. If the bindings that I am proposing are useful for at
> least some uses with Xilinx parts, that would be valuable feedback at
> this point.  If they are Altera-specific, then I may need to add
> "altr," to some of the compatible strings like "altr,fpga-bus" and
> "altr,fpga-area".  My original intent was to implement something that
> you could use also, so I hope that's not the future here.
>
> So my question for you is: is this stuff useful for you?

Definitely, I'm pretty happy with what you have so far!
I think the points I mentioned above apply to Altera devices, too.
Maybe we can solve this in two parts, and the first step is getting the
loading bindings accepted ;-)

Cheers,

Moritz

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

end of thread, other threads:[~2015-12-15 18:15 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-10 23:37 [PATCH v14 0/7] fpga area and fpga bridge framework atull
2015-12-10 23:37 ` atull
2015-12-10 23:37 ` [PATCH v14 1/7] fpga: add usage documentation for fpga area atull
2015-12-10 23:37   ` atull
2015-12-11 15:05   ` Rob Herring
2015-12-11 18:33     ` atull
2015-12-11 18:33       ` atull
2015-12-11 19:18       ` Rob Herring
2015-12-10 23:37 ` [PATCH v14 2/7] fpga: add bindings document " atull
2015-12-10 23:37   ` atull
2015-12-11 14:34   ` Rob Herring
2015-12-10 23:37 ` [PATCH v14 3/7] add sysfs document for fpga bridge class atull
2015-12-10 23:37   ` atull
2015-12-10 23:37 ` [PATCH v14 4/7] ARM: socfpga: add bindings document for fpga bridge drivers atull
2015-12-10 23:37   ` atull
2015-12-10 23:37 ` [PATCH v14 5/7] fpga: add fpga bridge framework atull
2015-12-10 23:37   ` atull
2015-12-10 23:37 ` [PATCH v14 6/7] fpga: fpga-area: support device tree control for FPGA programming atull
2015-12-10 23:37   ` atull
2015-12-10 23:37 ` [PATCH v14 7/7] ARM: socfpga: fpga bridge driver support atull
2015-12-10 23:37   ` atull
2015-12-14 17:16 ` [PATCH v14 0/7] fpga area and fpga bridge framework Moritz Fischer
2015-12-15  1:56   ` Alan Tull
2015-12-15 18:15     ` Moritz Fischer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.