linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v18 0/6] Device Tree support for FPGA Programming
@ 2016-07-12 19:36 Alan Tull
  2016-07-12 19:36 ` [PATCH v18 1/6] fpga: add bindings document for fpga region Alan Tull
                   ` (6 more replies)
  0 siblings, 7 replies; 19+ messages in thread
From: Alan Tull @ 2016-07-12 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

v18 has very minimal changes to address comments about the device
tree bindings and device tree examples in the bindings document.

The diffstat from v17 is:
  4 files changed, 11 insertions(+), 18 deletions(-)
If there are more changes, it would be easier to
send these upstream and just start adding small
patches to fix whatever else.

Alan Tull (6):
  fpga: add bindings document for fpga region
  ARM: socfpga: add bindings document for fpga bridge drivers
  add sysfs document for fpga bridge class
  fpga: add fpga bridge framework
  fpga: fpga-region: device tree control for FPGA
  ARM: socfpga: fpga bridge driver support

 Documentation/ABI/testing/sysfs-class-fpga-bridge  |  11 +
 .../bindings/fpga/altera-fpga2sdram-bridge.txt     |  16 +
 .../bindings/fpga/altera-hps2fpga-bridge.txt       |  39 ++
 .../devicetree/bindings/fpga/fpga-region.txt       | 491 ++++++++++++++++++
 drivers/fpga/Kconfig                               |  21 +
 drivers/fpga/Makefile                              |   7 +
 drivers/fpga/altera-fpga2sdram.c                   | 174 +++++++
 drivers/fpga/altera-hps2fpga.c                     | 213 ++++++++
 drivers/fpga/fpga-bridge.c                         | 388 ++++++++++++++
 drivers/fpga/fpga-region.c                         | 555 +++++++++++++++++++++
 include/linux/fpga/fpga-bridge.h                   |  55 ++
 include/linux/fpga/fpga-mgr.h                      |   2 +
 12 files changed, 1972 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-region.txt
 create mode 100644 drivers/fpga/altera-fpga2sdram.c
 create mode 100644 drivers/fpga/altera-hps2fpga.c
 create mode 100644 drivers/fpga/fpga-bridge.c
 create mode 100644 drivers/fpga/fpga-region.c
 create mode 100644 include/linux/fpga/fpga-bridge.h

-- 
2.9.1

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

* [PATCH v18 1/6] fpga: add bindings document for fpga region
  2016-07-12 19:36 [PATCH v18 0/6] Device Tree support for FPGA Programming Alan Tull
@ 2016-07-12 19:36 ` Alan Tull
  2016-07-21 19:39   ` Rob Herring
  2016-07-12 19:36 ` [PATCH v18 2/6] ARM: socfpga: add bindings document for fpga bridge drivers Alan Tull
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Alan Tull @ 2016-07-12 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

New bindings document for FPGA Region to support programming
FPGA's under Device Tree control

Signed-off-by: Alan Tull <atull@opensource.altera.com>
Signed-off-by: Moritz Fischer <moritz.fischer@ettus.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 at 0xff20000 -> bridge at 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
v15: Cleanup as per Rob's comments
     Combine usage doc with bindings document
     Document as being Altera specific
     Additions and changes to add FPGA Bus
v16: Reworked to document FPGA Regions
     rename altera-fpga-bus-fpga-area.txt -> fpga-region.txt
     Remove references that made it sound exclusive to Altera
     Remove altr, prefix from fpga-bus and fpga-area compatible strings
     Added Moritz' usage example with Xilinx
     Cleaned up unit addresses
v17: Lots of rewrites to try to make things clearer
     Clarify that overlay can be rejected if FPGA isn't programmed
     Add external-fpga-config binding already used in u-boot
     Change partial-reconfig binding to partial-fpga-config to align
       with existing u-boot binding format *-fpga-config
     Add a document from Xilinx' website
v18: Fix node names underscores to be hyphens
     Fix copy/pasted duplicate nodes in diagram
---
 .../devicetree/bindings/fpga/fpga-region.txt       | 491 +++++++++++++++++++++
 1 file changed, 491 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/fpga/fpga-region.txt

diff --git a/Documentation/devicetree/bindings/fpga/fpga-region.txt b/Documentation/devicetree/bindings/fpga/fpga-region.txt
new file mode 100644
index 0000000..cfac8c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/fpga-region.txt
@@ -0,0 +1,491 @@
+FPGA Region Device Tree Binding
+
+Alan Tull 2016
+
+ CONTENTS
+ - Introduction
+ - Terminology
+ - Overview
+ - Constraints
+ - FPGA Region
+ - Supported Use Models
+ - Sequence
+ - Device Tree Examples
+
+
+Introduction
+============
+
+FPGA Regions are introduced as a way to solve the problem of how to program an
+FPGA under an operating system and have the new hardware show up in the device
+tree.  By adding these bindings to the Device Tree, a system can have the
+information needed to program the FPGA and add the desired hardware, and also
+the information about the devices to be added to the Device Tree once the
+programming has succeeded.
+
+This device tree binding document hits some of the high points of FPGA usage and
+attempts to include terminology used by both major FPGA manufacturers.  This
+document isn't a replacement for any manufacturers white papers and
+specifications for FPGA usage.
+
+
+Terminology
+===========
+
+Full Reconfiguration
+ * The entire FPGA is programmed.
+
+Partial Reconfiguration (PR)
+ * A section of the FPGA is reprogrammed while the rest of the FPGA is not
+   affected. Not all FPGA's support this.
+
+Partial Reconfiguration Region (PRR)
+ * Also called a "reconfigurable partition"
+ * A PRR is a specific section of a FPGA reserved for reconfiguration.
+ * A base (or static) FPGA image may create a set of PRR's that later may
+   be independently reprogrammed many times.
+ * The size and specific location of each PRR is fixed.
+ * The connections at the edge of each PRR are fixed.  The image that is loaded
+   into a PRR must fit and must use a subset of the region's connections.
+ * The busses within the FPGA are split such that each region gets its own
+   branch that may be gated independently.
+
+Persona
+ * Also called a "partial bit stream"
+ * An FPGA image that is designed to be loaded into a PRR.  There may be
+   any number of personas designed to fit into a PRR, but only one at at time
+   may be loaded.
+ * A persona may create more regions.
+
+FPGA Manager
+ * An FPGA Manager is a hardware block that programs an FPGA under the control
+   of a host processor.
+
+
+    ----------------       ------------------------------
+    |  Host CPU    |       |           FPGA             |
+    |              |       |                            |
+    |          ----|       |       -------    --------  |
+    |          | H |       |   |==>| FB0 |<==>| PRR0 |  |
+    |          | W |       |   |   -------    --------  |
+    |          |   |       |   |                        |
+    |          | B |<=====>|<==|   -------    --------  |
+    |          | R |       |   |==>| FB1 |<==>| PRR1 |  |
+    |          | I |       |   |   -------    --------  |
+    |          | D |       |   |                        |
+    |          | G |       |   |   -------    --------  |
+    |          | E |       |   |==>| FB2 |<==>| PRR2 |  |
+    |          ----|       |       -------    --------  |
+    |              |       |                            |
+    ----------------       ------------------------------
+
+Figure 1: An FPGA set up with a base image that created three regions.  Each
+region gets its own split of the busses that can be independently gated by an
+soft logic bridge in the FPGA.  The contents of each PRR can be reprogrammed
+independently while the rest of the system continues to function.
+
+FPGA Bridge
+ * FPGA Bridges gate bus signals between a host and FPGA.
+ * FPGA Bridges should be disabled while the FPGA is being programmed to
+   prevent spurious signals on the cpu bus.
+ * FPGA bridges may be actual hardware or soft logic on the FPGA.
+ * During Full Reconfiguration, hardware bridges between the host and FPGA
+   will be disabled to prevent spurious data on the bus.
+ * These hardware FPGA Bridges may not be needed in implementations where the
+   FPGA Manager transparantly handles gating the buses.
+ * A base FPGA image may create a set of reprogrammable regions, each having
+   its own split of the busses that is gated by its own bridge in the FPGA.
+ * During Partial Reconfiguration of a specific region, the region's bridge
+   will be used to gate the busses.  Traffic to other regions is not affected.
+
+Base Image
+ * Also called the "static image"
+ * An FPGA image that is designed to do full reconfiguration of the FPGA.
+ * A base image may set up a set of partial reconfiguration regions that may
+   later be reprogrammed.
+
+
+Overview
+========
+
+This binding introduces the FPGA Region which supports full or partial
+reconfiguration of a FPGA under device tree control.
+
+In the device tree, an FPGA Region brings together the devices (FPGA Managers
+and FPGA Bridges) needed to be able to program an FPGA device.  The FPGA Region
+also includes child nodes that are the devices that exist in the FPGA.
+
+The base FPGA Region in the device tree is required to include a phandle to an
+FPGA Manager.  This region also contains a list of phandles to the hardware FPGA
+Bridges, if any.  This base FPGA Region corresponds to the whole FPGA and is
+used for full reconfiguration.
+
+FPGA Regions that are children of the base FPGA region inherit the parent's FPGA
+Manager but specify their own bridges.  These child regions correspond to
+partial reconfiguration regions in the FPGA.  The bridges they specify will be
+FPGA Bridges within the static image of the FPGA.
+
+The intended use is that device tree overlays can be used to reprogram an FPGA
+while an operating system is running.  In that case, the live device tree will
+contain an FPGA Manager, FPGA Bridges, and the base FPGA Region.  The device
+tree overlays contain the name of the FPGA image file to be programmed and the
+child devices that will be contained in the FPGA after programming.
+
+When such a device tree overlay is applied, it is targeted to one of the
+existing FPGA regions.  A few things must happen in the OS's implementation
+before the overlay can be accepted into the live tree.  The OS will attempt to
+program the FPGA using the firmware that the overlay specifies.  That
+reprogramming sequence is detailed below (see the Sequence section).  If
+programming fails, the overlay is rejected.  If programming succeeds, the
+overlay is added into the live tree and correctly shows what firmware the FPGA
+has been programmed with.  Child nodes in the overlay are added and those
+devices are populated.
+
+The base FPGA Region supports full reconfiguration of the FPGA device.  If the
+FPGA image loaded contains the logic that creates a set of Partial
+Reconfiguration Regions, then the overlay that programs the FPGA should also add
+a set of FPGA Regions as children of the original FPGA Region.  The child FPGA
+Regions do not need to specify an FPGA Manager as they will use the ancestor
+region's FPGA Manager.
+
+
+Constraints
+===========
+
+It is beyond the scope of this document to fully describe all the FPGA design
+constraints required to make partial reconfiguration work[1] [2] [3], but a few
+deserve quick mention.
+
+A persona must have boundary connections that line up with those of the partion
+or region it is designed to go into.
+
+During programming, transactions through those connections must be stopped and
+the connections must be held at a fixed logic level.  This can be achieved by
+FPGA Bridges that exist on the FPGA fabric prior to the partial reconfiguration.
+
+FPGA Region
+===========
+
+An FPGA Region specifies the devices (FPGA Manager and FPGA Bridges ) needed to
+reconfigure a FPGA device.
+
+In the live Device Tree, an FPGA Region reflects the current configuration of
+the device.  If the live tree shows a "firmware-name" property under a FPGA
+Region, the FPGA already has been programmed with that firmware.
+
+A device tree overlay that targets a FPGA Region and adds the "firmware-name"
+property and child nodes is a request to reprogram the FPGA and, if successful,
+add the child nodes.  If reprogramming is not successful, the overlay must be
+rejected and not added to the live tree.
+
+Required properties:
+- compatible   : should contain "fpga-region"
+- fpga-mgr     : should contain a phandle to an FPGA Manager.  Child FPGA
+		 Regions inherit this property from the parent, so it
+		 should be left out for any child FPGA Regions.
+- fpga-bridges : should contain a list of phandles to FPGA Bridges.  This
+		 property is optional if the FPGA Manager controls the
+		 bridges during reprogramming.
+- #address-cells, #size-cells, ranges: must be present to handle address space
+  mapping for children.
+
+Properties added in an overlay:
+- firmware-name : should contain the name of an FPGA image file located on the
+  firmware search path.  If this property shows up in a live device tree it
+  can only mean that the FPGA has already been programmed with this image.
+- partial-fpga-config : boolean property should be defined if partial
+  reconfiguration of the FPGA is to be done, otherwise full reconfiguration
+  is done.
+- external-fpga-config : boolean property should be defined if the FPGA
+  has already been configured.  Then the FPGA Region can be used to add
+  child nodes for the devices that are in the FPGA.
+- child nodes : devices in the FPGA after programming.
+
+In the example below, when an overlay is applied targeting base_fpga_region,
+fpgamgr at ff706000 is used to program the FPGA and the bridge specified is
+controlled during the programming.  During programming, the bridges listed in
+that region are disabled, the firmware specified in the overlay is loaded to the
+FPGA using the FPGA manager specified in the region.  If FPGA programming
+succeeds, the bridges are reenabled and the overlay makes it into the live
+device tree.  The jtag_uart and led_pio child devices are then populated.  If
+FPGA programming fails, the bridges are left disabled and the overlay is
+rejected.
+
+Example:
+Base tree contains:
+
+	fpga_mgr0: fpgamgr at ff706000 {
+		compatible = "altr,socfpga-fpga-mgr";
+		reg = <0xff706000 0x1000
+		       0xffb90000 0x4>;
+		interrupts = <0 175 4>;
+	};
+
+	fpga_bridge0: fpga-bridge at ff400000 {
+		compatible = "altr,socfpga-lwhps2fpga-bridge";
+		reg = <0xff400000 0x100000>;
+		resets = <&rst LWHPS2FPGA_RESET>;
+		reset-names = "lwhps2fpga";
+		clocks = <&l4_main_clk>;
+	};
+
+	base_fpga_region {
+		compatible = "fpga-region";
+		fpga-mgr = <&fpga_mgr0>;
+		fpga-bridges = <&fpga_bridge0>;
+
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		ranges = <0 0xff200000 0x100000>;
+	};
+
+/dts-v1/ /plugin/;
+/ {
+	fragment at 0 {
+		target-path = "/soc/base_fpga_region";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		__overlay__ {
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			firmware-name = "soc_system.rbf";
+
+			jtag_uart: serial at 20000 {
+				compatible = "altr,juart-1.0";
+				reg = <0x20000 0x8>;
+				interrupt-parent = <&intc>;
+				interrupts = <0 42 4>;
+			};
+
+			led_pio: gpio at 10040 {
+				compatible = "altr,pio-1.0";
+				reg = <0x10040 0x20>;
+				altr,gpio-bank-width = <4>;
+				#gpio-cells = <2>;
+				gpio-controller;
+			};
+		};
+	};
+};
+
+Supported Use Models
+====================
+
+Here's a list of supported use models.  We may need to add more.  Some uses are
+specific to one FPGA device or another.
+
+In all cases the live DT must specify the FPGA Manager, FPGA Bridges (if any),
+and a FPGA Region.  The target of the Device Tree Overlay is the FPGA Region.
+
+ * No FPGA Bridges
+   In this case, the FPGA Manager which programs the FPGA also handles the
+   bridges.  No FPGA Bridge devices are needed for full reconfiguration.
+
+ * Full reconfiguration with bridges
+   In this case, there are hardware bridges between the processor and FPGA that
+   need to be disabled during full reconfiguration.  Before the overlay is
+   applied, the live DT must include the FPGA Manager, FPGA Bridges, and a
+   base FPGA Region which contains phandles to the FPGA Manager and Bridges.
+
+ * Partial reconfiguration with bridges in the FPGA
+   In this case, the FPGA will have more than one PRR that will be programmed
+   separately.  While one PRR is being programmed, other PRR's may be active
+   on the bus.  To manage this, FPGA Bridges need to exist in the FPGA
+   that can gate the buses going to one FPGA region while the buses are
+   enabled for other sections.  Before any partial reconfiguration can be
+   done, a base FPGA image must be loaded which includes PRR's with FPGA
+   bridges.  This can be done by doing full reconfiguration using an overlay
+   that contains the FPGA image that sets up the regions in the FPGA fabric.
+   The overlay would also contain FPGA Regions that will become children of
+   the original base FPGA Region.
+
+Sequence
+========
+
+When a DT overlay is loaded, the FPGA Region will be notified 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.
+
+When the overlay is removed, the FPGA Region will be notified and will disable
+the bridges and the child nodes will be removed.
+
+Device Tree Examples
+====================
+
+The intention of this section is to give some simple examples, focusing on
+the placement of the elements detailed above, especially:
+ * FPGA Manager
+ * FPGA Bridges
+ * FPGA Region
+ * ranges
+ * target-path or target
+
+For the purposes of this section, I'm dividing the Device Tree into two parts,
+each with its own requirements.  The two parts are:
+ * The live DT prior to the overlay being added
+ * The DT overlay
+
+The live Device Tree must contain an FPGA Region, an FPGA Manager, and any FPGA
+Bridges.  The FPGA Region's "fpga-mgr" property specifies the manager by phandle
+to handle programming the FPGA.  If the FPGA Region is the child of another FPGA
+Region, the parent's FPGA Manager is used.  If FPGA Bridges need to be involved,
+they are specified in the FPGA Region by the "fpga-bridges" property.  During
+FPGA programming, the FPGA Region will disable the bridges that are in its
+"fpga-bridges" list and will re-enable them after FPGA programming has
+succeeded.
+
+The Device Tree Overlay will contain:
+ * "target-path" or "target"
+   The insertion point where the the contents of the overlay will go into the
+   live tree.  target-path is a full path, while target is a phandle.
+ * "ranges"
+    The address space mapping from processor to FPGA bus(ses).
+ * "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-fpga-config"
+   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.
+
+Device Tree Example: Full Reconfiguration without Bridges
+=========================================================
+
+Live Device Tree contains:
+	fpga_mgr0: fpgamgr at f8007000 {
+		compatible = "xlnx,zynq-devcfg-1.0";
+		reg = <0xf8007000 0x100>;
+		interrupt-parent = <&intc>;
+		interrupts = <0 8 4>;
+		clocks = <&clkc 12>;
+		clock-names = "ref_clk";
+		syscon = <&slcr>;
+	};
+
+	base_fpga_region {
+		compatible = "fpga-region";
+		fpga-mgr = <&fpga_mgr0>;
+		#address-cells = <0x1>;
+		#size-cells = <0x1>;
+		ranges;
+	};
+
+DT Overlay contains:
+/dts-v1/ /plugin/;
+/ {
+fragment at 0 {
+	target = <&base_fpga_region>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+	__overlay__ {
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		firmware-name = "zynq-gpio.bin";
+
+		gpio1: gpio at 40000000 {
+			compatible = "xlnx,xps-gpio-1.00.a";
+			reg = <0x40000000 0x10000>;
+			gpio-controller;
+			#gpio-cells = <0x2>;
+			xlnx,gpio-width= <0x6>;
+		};
+	};
+};
+
+Device Tree Example: Full Reconfiguration to add PRR's
+======================================================
+
+The Base FPGA Region is specified similar to the first example above.
+
+This example programs the FPGA to have two regions that can later be partially
+configured.  Each region has its own bridge in the FPGA fabric.
+
+DT Overlay contains:
+/dts-v1/ /plugin/;
+/ {
+	fragment at 0 {
+		target-path = "/soc/base_fpga_region";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		__overlay__ {
+			#address-cells = <1>;
+		        #size-cells = <1>;
+
+			firmware-name = "base.rbf";
+
+			fpga_bridge1_0: fpga-bridge at 4400 {
+				compatible = "altr,freeze-bridge";
+				reg = <0x4400 0x10>;
+			};
+
+			fpga_bridge2_0: fpga-bridge at 4420 {
+				compatible = "altr,freeze-bridge";
+				reg = <0x4420 0x10>;
+			};
+
+			fpga_region1 {
+				compatible = "fpga-region";
+				fpga-bridges = <&fpga_bridge1_0>;
+				#address-cells = <0x1>;
+				#size-cells = <0x1>;
+				ranges;
+			};
+
+			fpga_region2 {
+				compatible = "fpga-region";
+				fpga-bridges = <&fpga_bridge2_0>;
+				#address-cells = <0x1>;
+				#size-cells = <0x1>;
+				ranges;
+			};
+		};
+	};
+};
+
+Device Tree Example: Partial Reconfiguration
+============================================
+
+This example reprograms one of the PRR's set up in the previous example.
+
+The sequence that occurs when this overlay is similar to the above, the only
+differences are that the FPGA is partially reconfigured due to the
+"partial-fpga-config" boolean and the only bridge that is controlled during
+programming is the FPGA based bridge of fpga_region1.
+
+/dts-v1/ /plugin/;
+/ {
+	fragment at 0 {
+		target-path = "/soc/base_fpga_region/fpga_region1";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		__overlay__ {
+			#address-cells = <1>;
+		        #size-cells = <1>;
+
+			firmware-name = "soc_image2.rbf";
+			partial-fpga-config;
+
+			gpio at 10040 {
+				compatible = "altr,pio-1.0";
+				reg = <0x10040 0x20>;
+				clocks = <0x2>;
+				altr,gpio-bank-width = <0x4>;
+				resetvalue = <0x0>;
+				#gpio-cells = <0x2>;
+				gpio-controller;
+			};
+		};
+	};
+};
+
+
+--
+[1] www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/ug/ug_partrecon.pdf
+[2] tspace.library.utoronto.ca/bitstream/1807/67932/1/Byma_Stuart_A_201411_MAS_thesis.pdf
+[3] http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_1/ug702.pdf
-- 
2.9.1

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

* [PATCH v18 2/6] ARM: socfpga: add bindings document for fpga bridge drivers
  2016-07-12 19:36 [PATCH v18 0/6] Device Tree support for FPGA Programming Alan Tull
  2016-07-12 19:36 ` [PATCH v18 1/6] fpga: add bindings document for fpga region Alan Tull
@ 2016-07-12 19:36 ` Alan Tull
  2016-08-01 16:18   ` Rob Herring
  2016-07-12 19:36 ` [PATCH v18 3/6] add sysfs document for fpga bridge class Alan Tull
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Alan Tull @ 2016-07-12 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

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
v15: No change in this patch for v15 of this patch set
v16: Added regs property, cleaned up unit addresses
v17: No change to this patch in v17 of patch set
v18: Changed to not need reset-names property
     node names as fpga-bridge at ...
     labels as fpga_bridge
     Add address of fpgaportrst to give and address for f2s bridge
---
 .../bindings/fpga/altera-fpga2sdram-bridge.txt     | 16 +++++++++
 .../bindings/fpga/altera-hps2fpga-bridge.txt       | 39 ++++++++++++++++++++++
 2 files changed, 55 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..817a8d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
@@ -0,0 +1,16 @@
+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:
+	fpga_bridge3: fpga-bridge at ffc25080 {
+		compatible = "altr,socfpga-fpga2sdram-bridge";
+		reg = <0xffc25080 0x4>;
+		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..6406f93
--- /dev/null
+++ b/Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
@@ -0,0 +1,39 @@
+Altera FPGA/HPS Bridge Driver
+
+Required properties:
+- regs		: base address and size for AXI bridge module
+- compatible	: Should contain one of:
+		  "altr,socfpga-lwhps2fpga-bridge",
+		  "altr,socfpga-hps2fpga-bridge", or
+		  "altr,socfpga-fpga2hps-bridge"
+- resets	: Phandle and reset specifier for this bridge's reset
+- 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:
+	fpga_bridge0: fpga-bridge at ff400000 {
+		compatible = "altr,socfpga-lwhps2fpga-bridge";
+		reg = <0xff400000 0x100000>;
+		resets = <&rst LWHPS2FPGA_RESET>;
+		clocks = <&l4_main_clk>;
+		bridge-enable = <0>;
+	};
+
+	fpga_bridge1: fpga-bridge at ff500000 {
+		compatible = "altr,socfpga-hps2fpga-bridge";
+		reg = <0xff500000 0x10000>;
+		resets = <&rst HPS2FPGA_RESET>;
+		clocks = <&l4_main_clk>;
+		bridge-enable = <1>;
+	};
+
+	fpga_bridge2: fpga-bridge at ff600000 {
+		compatible = "altr,socfpga-fpga2hps-bridge";
+		reg = <0xff600000 0x100000>;
+		resets = <&rst FPGA2HPS_RESET>;
+		clocks = <&l4_main_clk>;
+	};
-- 
2.9.1

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

* [PATCH v18 3/6] add sysfs document for fpga bridge class
  2016-07-12 19:36 [PATCH v18 0/6] Device Tree support for FPGA Programming Alan Tull
  2016-07-12 19:36 ` [PATCH v18 1/6] fpga: add bindings document for fpga region Alan Tull
  2016-07-12 19:36 ` [PATCH v18 2/6] ARM: socfpga: add bindings document for fpga bridge drivers Alan Tull
@ 2016-07-12 19:36 ` Alan Tull
  2016-07-12 19:36 ` [PATCH v18 4/6] fpga: add fpga bridge framework Alan Tull
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Alan Tull @ 2016-07-12 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Alan Tull <atull@opensource.altera.com>
--
v15: Document added in v15 of patch set
v16: No change to this patch in v16 of patch set
v17: No change to this patch in v17 of patch set
v18: No change to this patch in v18 of patch set
---
 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..312ae2c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-fpga-bridge
@@ -0,0 +1,11 @@
+What:		/sys/class/fpga_bridge/<bridge>/name
+Date:		January 2016
+KernelVersion:	4.5
+Contact:	Alan Tull <atull@opensource.altera.com>
+Description:	Name of low level FPGA bridge driver.
+
+What:		/sys/class/fpga_bridge/<bridge>/state
+Date:		January 2016
+KernelVersion:	4.5
+Contact:	Alan Tull <atull@opensource.altera.com>
+Description:	Show bridge state as "enabled" or "disabled"
-- 
2.9.1

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

* [PATCH v18 4/6] fpga: add fpga bridge framework
  2016-07-12 19:36 [PATCH v18 0/6] Device Tree support for FPGA Programming Alan Tull
                   ` (2 preceding siblings ...)
  2016-07-12 19:36 ` [PATCH v18 3/6] add sysfs document for fpga bridge class Alan Tull
@ 2016-07-12 19:36 ` Alan Tull
  2016-07-14 20:54   ` Paul Gortmaker
  2016-07-12 19:36 ` [PATCH v18 5/6] fpga: fpga-region: device tree control for FPGA Alan Tull
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Alan Tull @ 2016-07-12 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

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
v15: No change in this patch for v15 of this patch set
v16: Remove of_get_fpga_bus function
v17: No change to this patch in v17 of patch set
v18: No change to this patch in v18 of patch set
---
 drivers/fpga/Kconfig             |   7 +
 drivers/fpga/Makefile            |   3 +
 drivers/fpga/fpga-bridge.c       | 388 +++++++++++++++++++++++++++++++++++++++
 include/linux/fpga/fpga-bridge.h |  55 ++++++
 4 files changed, 453 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 d614102..46e20af 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -25,6 +25,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..1a96934
--- /dev/null
+++ b/include/linux/fpga/fpga-bridge.h
@@ -0,0 +1,55 @@
+#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_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 */
-- 
2.9.1

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

* [PATCH v18 5/6] fpga: fpga-region: device tree control for FPGA
  2016-07-12 19:36 [PATCH v18 0/6] Device Tree support for FPGA Programming Alan Tull
                   ` (3 preceding siblings ...)
  2016-07-12 19:36 ` [PATCH v18 4/6] fpga: add fpga bridge framework Alan Tull
@ 2016-07-12 19:36 ` Alan Tull
  2016-07-12 19:36 ` [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support Alan Tull
  2016-07-12 19:43 ` [PATCH v18 0/6] Device Tree support for FPGA Programming atull
  6 siblings, 0 replies; 19+ messages in thread
From: Alan Tull @ 2016-07-12 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

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

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
v15: Add altr,fpga-bus implementation
     Change compatible string "fpga-area" -> "altr,fpga-area"
v16: Much changes as FPGA Areas and Busses become FPGA Regions
     Add reconfig notifier, don't rely on simple-bus
v17: Use new overlay notifier instead of reconfig notifier
     Add external_fpga_config property used in u-boot
     Change partial-reconfig binding to partial-fpga-config to be
       similar to *-fpga-config bindings used in u-boot
v18: No change to this patch in v18 of patch set
---
 drivers/fpga/Kconfig          |   7 +
 drivers/fpga/Makefile         |   3 +
 drivers/fpga/fpga-region.c    | 555 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/fpga/fpga-mgr.h |   2 +
 4 files changed, 567 insertions(+)
 create mode 100644 drivers/fpga/fpga-region.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 46e20af..ec81e21 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -13,6 +13,13 @@ config FPGA
 
 if FPGA
 
+config FPGA_REGION
+       bool "FPGA Region"
+       depends on OF
+       help
+	 FPGA Regions allow loading FPGA images under control of
+	 the Device Tree.
+
 config FPGA_MGR_SOCFPGA
 	tristate "Altera SOCFPGA FPGA Manager"
 	depends on ARCH_SOCFPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 4baef00..8d746c3 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_REGION)		+= fpga-region.o
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
new file mode 100644
index 0000000..62b1799
--- /dev/null
+++ b/drivers/fpga/fpga-region.c
@@ -0,0 +1,555 @@
+/*
+ * FPGA Region - Device Tree support for FPGA programming under Linux
+ *
+ *  Copyright (C) 2013-2016 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/idr.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/**
+ * struct fpga_region - FPGA Region structure
+ * @dev: FPGA Region device
+ * @mutex: enforces exclusive reference to region
+ * @bridge_list: list of FPGA bridges specified in region
+ */
+struct fpga_region {
+	struct device dev;
+	struct mutex mutex; /* for exclusive reference to region */
+	struct list_head bridge_list;
+};
+
+#define to_fpga_region(d) container_of(d, struct fpga_region, dev)
+
+static DEFINE_IDA(fpga_region_ida);
+static struct class *fpga_region_class;
+
+static const struct of_device_id fpga_region_of_match[] = {
+	{ .compatible = "fpga-region", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, fpga_region_of_match);
+
+static int fpga_region_of_node_match(struct device *dev, const void *data)
+{
+	return dev->of_node == data;
+}
+
+/**
+ * fpga_region_find - find FPGA region
+ * @np: device node of FPGA Region
+ * Caller will need to put_device(&region->dev) when done.
+ * Returns FPGA Region struct or NULL
+ */
+static struct fpga_region *fpga_region_find(struct device_node *np)
+{
+	struct device *dev;
+
+	dev = class_find_device(fpga_region_class, NULL, np,
+				fpga_region_of_node_match);
+	if (!dev) {
+		pr_err("%s did not find FPGA Region in class: %s\n", __func__,
+		       np->full_name);
+		return NULL;
+	}
+
+	return to_fpga_region(dev);
+}
+
+/**
+ * fpga_region_get - get an exclusive reference to a fpga region
+ * @region: FPGA Region struct
+ *
+ * Caller should call fpga_region_put() when done with region.
+ *
+ * Return fpga_region struct if successful.
+ * Return -EBUSY if someone already has a reference to the region.
+ * Return -ENODEV if @np is not a FPGA Region.
+ */
+static struct fpga_region *fpga_region_get(struct fpga_region *region)
+{
+	struct device *dev = &region->dev;
+
+	if (!mutex_trylock(&region->mutex)) {
+		dev_dbg(dev, "%s: FPGA Region already in use\n", __func__);
+		return ERR_PTR(-EBUSY);
+	}
+
+	get_device(dev);
+	of_node_get(dev->of_node);
+	if (!try_module_get(dev->parent->driver->owner)) {
+		of_node_put(dev->of_node);
+		put_device(dev);
+		mutex_unlock(&region->mutex);
+		return ERR_PTR(-ENODEV);
+	}
+
+	dev_dbg(&region->dev, "get\n");
+
+	return region;
+}
+
+/**
+ * fpga_region_put - release a reference to a region
+ *
+ * @region: FPGA region
+ */
+static void fpga_region_put(struct fpga_region *region)
+{
+	struct device *dev = &region->dev;
+
+	dev_dbg(&region->dev, "put\n");
+
+	module_put(dev->parent->driver->owner);
+	of_node_put(dev->of_node);
+	put_device(dev);
+	mutex_unlock(&region->mutex);
+}
+
+/**
+ * fpga_region_get_manager - get exclusive reference for FPGA manager
+ * @region: FPGA region
+ *
+ * Get FPGA Manager from "fpga-mgr" property or from ancestor region.
+ *
+ * Caller should call fpga_mgr_put() when done with manager.
+ *
+ * Return: fpga manager struct or IS_ERR() condition containing error code.
+ */
+static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region)
+{
+	struct device *dev = &region->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node  *mgr_node;
+	struct fpga_manager *mgr;
+
+	of_node_get(np);
+	while (np) {
+		if (of_device_is_compatible(np, "fpga-region")) {
+			mgr_node = of_parse_phandle(np, "fpga-mgr", 0);
+			if (mgr_node) {
+				mgr = of_fpga_mgr_get(mgr_node);
+				of_node_put(np);
+				return mgr;
+			}
+		}
+		np = of_get_next_parent(np);
+	}
+	of_node_put(np);
+
+	return ERR_PTR(-EINVAL);
+}
+
+/**
+ * fpga_region_get_bridges - create a list of bridges
+ * @region: FPGA region
+ *
+ * Create a list of bridges specified by "fpga-bridges" property.
+ * If no bridges are specified, list will be empty.  Note that the
+ * fpga_bridges_enable/disable/put functions are all fine with an empty list.
+ *
+ * Caller should call fpga_bridges_put(&region->bridge_list) when
+ * done with the bridges.
+ *
+ * Return 0 for success (even if there are no bridges specified)
+ * or -EBUSY if any of the bridges are in use.
+ */
+static int fpga_region_get_bridges(struct fpga_region *region)
+{
+	struct device *dev = &region->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *br_node;
+	int i, ret;
+
+	for (i = 0; ; i++) {
+		br_node = of_parse_phandle(np, "fpga-bridges", i);
+		if (!br_node)
+			break;
+
+		/* If node is a bridge, get it and add to list */
+		ret = fpga_bridge_get_to_list(br_node, &region->bridge_list);
+
+		/* If any of the bridges are in use, give up */
+		if (ret == -EBUSY) {
+			fpga_bridges_put(&region->bridge_list);
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * fpga_region_program_fpga - program FPGA
+ * @region: FPGA region
+ * @firmware_name: name of FPGA image firmware file
+ * @flags: flags for FPGA programming mode
+ * Program an FPGA using information in the device tree.
+ * Function assumes that there is a firmware-name property.
+ * Return 0 for success or negative error code.
+ */
+static int fpga_region_program_fpga(struct fpga_region *region,
+				    const char *firmware_name,
+				    unsigned long flags)
+{
+	struct fpga_manager *mgr;
+	int ret;
+
+	region = fpga_region_get(region);
+	if (IS_ERR(region))
+		return PTR_ERR(region);
+
+	mgr = fpga_region_get_manager(region);
+	if (IS_ERR(mgr))
+		return PTR_ERR(mgr);
+
+	ret = fpga_region_get_bridges(region);
+	if (ret)
+		goto err_put_mgr;
+
+	ret = fpga_bridges_disable(&region->bridge_list);
+	if (ret)
+		goto err_put_br;
+
+	ret = fpga_mgr_firmware_load(mgr, flags, firmware_name);
+	if (ret)
+		goto err_put_br;
+
+	ret = fpga_bridges_enable(&region->bridge_list);
+	if (ret)
+		goto err_put_br;
+
+	fpga_mgr_put(mgr);
+	fpga_region_put(region);
+
+	return 0;
+
+err_put_br:
+	fpga_bridges_put(&region->bridge_list);
+err_put_mgr:
+	fpga_mgr_put(mgr);
+	fpga_region_put(region);
+
+	return ret;
+}
+
+/**
+ * child_regions_with_firmware
+ * @overlay: device node of the overlay
+ *
+ * If the overlay adds child FPGA regions, they are not allowed to have
+ * firmware-name property.
+ *
+ * Return 0 for OK or -EINVAL if child FPGA region adds firmware-name.
+ */
+static int child_regions_with_firmware(struct device_node *overlay)
+{
+	struct device_node *child_region;
+	const char *child_firmware_name;
+	int ret = 0;
+
+	of_node_get(overlay);
+
+	child_region = of_find_matching_node(overlay, fpga_region_of_match);
+	while (child_region) {
+		if (!of_property_read_string(child_region, "firmware-name",
+					     &child_firmware_name)) {
+			ret = -EINVAL;
+			break;
+		}
+		child_region = of_find_matching_node(child_region,
+						     fpga_region_of_match);
+	}
+
+	of_node_put(child_region);
+
+	if (ret)
+		pr_err("firmware-name not allowed in child FPGA region: %s",
+		       child_region->full_name);
+
+	return ret;
+}
+
+/**
+ * fpga_region_notify_pre_apply - pre-apply overlay notification
+ *
+ * @region: FPGA region that the overlay was applied to
+ * @nd: overlay notification data
+ *
+ * Called after when an overlay targeted to a FPGA Region is about to be
+ * applied.  Function will check the properties that will be added to the FPGA
+ * region.  If the checks pass, it will program the FPGA.
+ *
+ * The checks are:
+ * The overlay must add either firmware-name or external-fpga-config property
+ * to the FPGA Region.
+ *
+ *   firmware-name        : program the FPGA
+ *   external-fpga-config : FPGA is already programmed
+ *
+ * The overlay can add other FPGA regions, but child FPGA regions cannot have a
+ * firmware-name property since those regions don't exist yet.
+ *
+ * If the overlay that breaks the rules, notifier returns an error and the
+ * overlay is rejected before it goes into the main tree.
+ *
+ * Returns 0 for success or negative error code for failure.
+ */
+static int fpga_region_notify_pre_apply(struct fpga_region *region,
+					struct of_overlay_notify_data *nd)
+{
+	const char *firmware_name = NULL;
+	unsigned long flags = 0;
+	int ret;
+
+	/* Reject overlay if child FPGA Regions have firmware-name property */
+	ret = child_regions_with_firmware(nd->overlay);
+	if (ret)
+		return ret;
+
+	/* Read FPGA region properties from the overlay */
+	if (of_property_read_bool(nd->overlay, "partial-fpga-config"))
+		flags |= FPGA_MGR_PARTIAL_RECONFIG;
+
+	if (of_property_read_bool(nd->overlay, "external-fpga-config"))
+		flags |= FPGA_MGR_EXTERNAL_CONFIG;
+
+	of_property_read_string(nd->overlay, "firmware-name", &firmware_name);
+
+	/* If FPGA was externally programmed, don't specify firmware */
+	if ((flags & FPGA_MGR_EXTERNAL_CONFIG) && firmware_name) {
+		pr_err("error: specified firmware and external-fpga-config");
+		return -EINVAL;
+	}
+
+	/* FPGA is already configured externally.  We're done. */
+	if (flags & FPGA_MGR_EXTERNAL_CONFIG)
+		return 0;
+
+	/* If we got this far, we should be programming the FPGA */
+	if (!firmware_name) {
+		pr_err("should specify firmware-name or external-fpga-config\n");
+		return -EINVAL;
+	}
+
+	return fpga_region_program_fpga(region, firmware_name, flags);
+}
+
+/**
+ * fpga_region_notify_post_remove - post-remove overlay notification
+ *
+ * @region: FPGA region that was targeted by the overlay that was removed
+ * @nd: overlay notification data
+ *
+ * Called after an overlay has been removed if the overlay's target was a
+ * FPGA region.
+ */
+static void fpga_region_notify_post_remove(struct fpga_region *region,
+					   struct of_overlay_notify_data *nd)
+{
+	fpga_bridges_disable(&region->bridge_list);
+	fpga_bridges_put(&region->bridge_list);
+}
+
+/**
+ * of_fpga_region_notify - reconfig notifier for dynamic DT changes
+ * @nb:		notifier block
+ * @action:	notifier action
+ * @arg:	reconfig data
+ *
+ * This notifier handles programming a FPGA when a "firmware-name" property is
+ * added to a fpga-region.
+ *
+ * Returns NOTIFY_OK or error if FPGA programming fails.
+ */
+static int of_fpga_region_notify(struct notifier_block *nb,
+				 unsigned long action, void *arg)
+{
+	struct of_overlay_notify_data *nd = arg;
+	struct fpga_region *region;
+	int ret;
+
+	switch (action) {
+	case OF_OVERLAY_PRE_APPLY:
+		pr_debug("%s OF_OVERLAY_PRE_APPLY\n", __func__);
+		break;
+	case OF_OVERLAY_POST_APPLY:
+		pr_debug("%s OF_OVERLAY_POST_APPLY\n", __func__);
+		return NOTIFY_OK;       /* not for us */
+	case OF_OVERLAY_PRE_REMOVE:
+		pr_debug("%s OF_OVERLAY_PRE_REMOVE\n", __func__);
+		return NOTIFY_OK;       /* not for us */
+	case OF_OVERLAY_POST_REMOVE:
+		pr_debug("%s OF_OVERLAY_POST_REMOVE\n", __func__);
+		break;
+	default:			/* should not happen */
+		return NOTIFY_OK;
+	}
+
+	region = fpga_region_find(nd->target);
+	if (!region)
+		return NOTIFY_OK;
+
+	ret = 0;
+	switch (action) {
+	case OF_OVERLAY_PRE_APPLY:
+		ret = fpga_region_notify_pre_apply(region, nd);
+		break;
+
+	case OF_OVERLAY_POST_REMOVE:
+		fpga_region_notify_post_remove(region, nd);
+		break;
+	}
+
+	put_device(&region->dev);
+
+	if (ret)
+		return notifier_from_errno(ret);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block fpga_region_of_nb = {
+	.notifier_call = of_fpga_region_notify,
+};
+
+static int fpga_region_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct fpga_region *region;
+	int id, ret = 0;
+
+	region = kzalloc(sizeof(*region), GFP_KERNEL);
+	if (!region)
+		return -ENOMEM;
+
+	id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
+	if (id < 0) {
+		ret = id;
+		goto err_kfree;
+	}
+
+	mutex_init(&region->mutex);
+	INIT_LIST_HEAD(&region->bridge_list);
+
+	device_initialize(&region->dev);
+	region->dev.class = fpga_region_class;
+	region->dev.parent = dev;
+	region->dev.of_node = np;
+	region->dev.id = id;
+	dev_set_drvdata(dev, region);
+
+	ret = dev_set_name(&region->dev, "region%d", id);
+	if (ret)
+		goto err_remove;
+
+	ret = device_add(&region->dev);
+	if (ret)
+		goto err_remove;
+
+	of_platform_populate(np, fpga_region_of_match, NULL, &region->dev);
+
+	dev_info(dev, "FPGA Region probed\n");
+
+	return 0;
+
+err_remove:
+	ida_simple_remove(&fpga_region_ida, id);
+err_kfree:
+	kfree(region);
+
+	return ret;
+}
+
+static int fpga_region_remove(struct platform_device *pdev)
+{
+	struct fpga_region *region = platform_get_drvdata(pdev);
+
+	device_unregister(&region->dev);
+
+	return 0;
+}
+
+static struct platform_driver fpga_region_driver = {
+	.probe = fpga_region_probe,
+	.remove = fpga_region_remove,
+	.driver = {
+		.name	= "fpga-region",
+		.of_match_table = of_match_ptr(fpga_region_of_match),
+	},
+};
+
+static void fpga_region_dev_release(struct device *dev)
+{
+	struct fpga_region *region = to_fpga_region(dev);
+
+	ida_simple_remove(&fpga_region_ida, region->dev.id);
+	kfree(region);
+}
+
+/**
+ * fpga_region_init - init function for fpga_region class
+ * Creates the fpga_region class and registers a reconfig notifier.
+ */
+static int __init fpga_region_init(void)
+{
+	int ret;
+
+	fpga_region_class = class_create(THIS_MODULE, "fpga_region");
+	if (IS_ERR(fpga_region_class))
+		return PTR_ERR(fpga_region_class);
+
+	fpga_region_class->dev_release = fpga_region_dev_release;
+
+	ret = of_overlay_notifier_register(&fpga_region_of_nb);
+	if (ret)
+		goto err_class;
+
+	ret = platform_driver_register(&fpga_region_driver);
+	if (ret)
+		goto err_plat;
+
+	return 0;
+
+err_plat:
+	of_overlay_notifier_unregister(&fpga_region_of_nb);
+err_class:
+	class_destroy(fpga_region_class);
+	ida_destroy(&fpga_region_ida);
+	return ret;
+}
+
+static void __exit fpga_region_exit(void)
+{
+	platform_driver_unregister(&fpga_region_driver);
+	of_overlay_notifier_unregister(&fpga_region_of_nb);
+	class_destroy(fpga_region_class);
+	ida_destroy(&fpga_region_ida);
+}
+
+module_init(fpga_region_init);
+module_exit(fpga_region_exit);
+
+MODULE_DESCRIPTION("FPGA Region");
+MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
index 0940bf4..36107c0 100644
--- a/include/linux/fpga/fpga-mgr.h
+++ b/include/linux/fpga/fpga-mgr.h
@@ -65,8 +65,10 @@ enum fpga_mgr_states {
 /*
  * FPGA Manager flags
  * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
+ * FPGA_MGR_EXTERNAL_CONFIG: FPGA has been configured prior to Linux booting
  */
 #define FPGA_MGR_PARTIAL_RECONFIG	BIT(0)
+#define FPGA_MGR_EXTERNAL_CONFIG	BIT(1)
 
 /**
  * struct fpga_manager_ops - ops for low level fpga manager drivers
-- 
2.9.1

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

* [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support
  2016-07-12 19:36 [PATCH v18 0/6] Device Tree support for FPGA Programming Alan Tull
                   ` (4 preceding siblings ...)
  2016-07-12 19:36 ` [PATCH v18 5/6] fpga: fpga-region: device tree control for FPGA Alan Tull
@ 2016-07-12 19:36 ` Alan Tull
  2016-07-14 20:47   ` Paul Gortmaker
  2016-09-23 14:13   ` Steffen Trumtrar
  2016-07-12 19:43 ` [PATCH v18 0/6] Device Tree support for FPGA Programming atull
  6 siblings, 2 replies; 19+ messages in thread
From: Alan Tull @ 2016-07-12 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

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
v15: No change in this patch for v15 of this patch set
v16: No change in this patch for v16 of this patch set
v17: No change to this patch for v17 of this patch set
v18: Eliminate need to specify reset names since only one reset
---
 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 ec81e21..b346166 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -39,6 +39,13 @@ config FPGA_BRIDGE
          Say Y here if you want to support bridges connected between host
 	 processors and FPGAs or between FPGAs.
 
+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 8d746c3..e658436 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_REGION)		+= fpga-region.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..4466022
--- /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 = of_reset_control_get_by_index(dev->of_node, 0);
+	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");
-- 
2.9.1

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

* [PATCH v18 0/6] Device Tree support for FPGA Programming
  2016-07-12 19:36 [PATCH v18 0/6] Device Tree support for FPGA Programming Alan Tull
                   ` (5 preceding siblings ...)
  2016-07-12 19:36 ` [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support Alan Tull
@ 2016-07-12 19:43 ` atull
  6 siblings, 0 replies; 19+ messages in thread
From: atull @ 2016-07-12 19:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 12 Jul 2016, Alan Tull wrote:

> v18 has very minimal changes to address comments about the device
> tree bindings and device tree examples in the bindings document.
> 
> The diffstat from v17 is:
>   4 files changed, 11 insertions(+), 18 deletions(-)
> If there are more changes, it would be easier to
> send these upstream and just start adding small
> patches to fix whatever else.

As with v17, this patchset needs the "of overlay notifications"
patch, which has been approved.

  https://lkml.org/lkml/2016/4/19/704

> 
> Alan Tull (6):
>   fpga: add bindings document for fpga region
>   ARM: socfpga: add bindings document for fpga bridge drivers
>   add sysfs document for fpga bridge class
>   fpga: add fpga bridge framework
>   fpga: fpga-region: device tree control for FPGA
>   ARM: socfpga: fpga bridge driver support
> 
>  Documentation/ABI/testing/sysfs-class-fpga-bridge  |  11 +
>  .../bindings/fpga/altera-fpga2sdram-bridge.txt     |  16 +
>  .../bindings/fpga/altera-hps2fpga-bridge.txt       |  39 ++
>  .../devicetree/bindings/fpga/fpga-region.txt       | 491 ++++++++++++++++++
>  drivers/fpga/Kconfig                               |  21 +
>  drivers/fpga/Makefile                              |   7 +
>  drivers/fpga/altera-fpga2sdram.c                   | 174 +++++++
>  drivers/fpga/altera-hps2fpga.c                     | 213 ++++++++
>  drivers/fpga/fpga-bridge.c                         | 388 ++++++++++++++
>  drivers/fpga/fpga-region.c                         | 555 +++++++++++++++++++++
>  include/linux/fpga/fpga-bridge.h                   |  55 ++
>  include/linux/fpga/fpga-mgr.h                      |   2 +
>  12 files changed, 1972 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-region.txt
>  create mode 100644 drivers/fpga/altera-fpga2sdram.c
>  create mode 100644 drivers/fpga/altera-hps2fpga.c
>  create mode 100644 drivers/fpga/fpga-bridge.c
>  create mode 100644 drivers/fpga/fpga-region.c
>  create mode 100644 include/linux/fpga/fpga-bridge.h
> 
> -- 
> 2.9.1
> 
> 

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

* [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support
  2016-07-12 19:36 ` [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support Alan Tull
@ 2016-07-14 20:47   ` Paul Gortmaker
  2016-08-08 19:18     ` atull
  2016-09-23 14:13   ` Steffen Trumtrar
  1 sibling, 1 reply; 19+ messages in thread
From: Paul Gortmaker @ 2016-07-14 20:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 12, 2016 at 3:36 PM, Alan Tull <atull@opensource.altera.com> wrote:
> 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
> v15: No change in this patch for v15 of this patch set
> v16: No change in this patch for v16 of this patch set
> v17: No change to this patch for v17 of this patch set
> v18: Eliminate need to specify reset names since only one reset
> ---
>  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 ec81e21..b346166 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -39,6 +39,13 @@ config FPGA_BRIDGE
>           Say Y here if you want to support bridges connected between host
>          processors and FPGAs or between FPGAs.
>
> +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 8d746c3..e658436 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_REGION)              += fpga-region.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

Please don't use module.h in drivers controlled by a bool
Kconfig setting.

THanks,
Paul.

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

* [PATCH v18 4/6] fpga: add fpga bridge framework
  2016-07-12 19:36 ` [PATCH v18 4/6] fpga: add fpga bridge framework Alan Tull
@ 2016-07-14 20:54   ` Paul Gortmaker
  2016-07-15 16:58     ` Alan Tull
  0 siblings, 1 reply; 19+ messages in thread
From: Paul Gortmaker @ 2016-07-14 20:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 12, 2016 at 3:36 PM, Alan Tull <atull@opensource.altera.com> wrote:
> 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
> v15: No change in this patch for v15 of this patch set
> v16: Remove of_get_fpga_bus function
> v17: No change to this patch in v17 of patch set
> v18: No change to this patch in v18 of patch set
> ---
>  drivers/fpga/Kconfig             |   7 +
>  drivers/fpga/Makefile            |   3 +
>  drivers/fpga/fpga-bridge.c       | 388 +++++++++++++++++++++++++++++++++++++++
>  include/linux/fpga/fpga-bridge.h |  55 ++++++
>  4 files changed, 453 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 d614102..46e20af 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -25,6 +25,13 @@ config FPGA_MGR_ZYNQ_FPGA
>         help
>           FPGA manager driver support for Xilinx Zynq FPGAs.
>
> +config FPGA_BRIDGE
> +       bool "FPGA Bridge Framework"

Same here. A bool Kconfig but module.h etc. used in the driver.

Either make the code modular with a tristate if there is a valid
use case for that, or get rid of the modular references.

Thanks,
Paul.
--

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

* [PATCH v18 4/6] fpga: add fpga bridge framework
  2016-07-14 20:54   ` Paul Gortmaker
@ 2016-07-15 16:58     ` Alan Tull
  0 siblings, 0 replies; 19+ messages in thread
From: Alan Tull @ 2016-07-15 16:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jul 14, 2016 at 3:54 PM, Paul Gortmaker
<paul.gortmaker@windriver.com> wrote:
> On Tue, Jul 12, 2016 at 3:36 PM, Alan Tull <atull@opensource.altera.com> wrote:
>> 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
>> v15: No change in this patch for v15 of this patch set
>> v16: Remove of_get_fpga_bus function
>> v17: No change to this patch in v17 of patch set
>> v18: No change to this patch in v18 of patch set
>> ---
>>  drivers/fpga/Kconfig             |   7 +
>>  drivers/fpga/Makefile            |   3 +
>>  drivers/fpga/fpga-bridge.c       | 388 +++++++++++++++++++++++++++++++++++++++
>>  include/linux/fpga/fpga-bridge.h |  55 ++++++
>>  4 files changed, 453 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 d614102..46e20af 100644
>> --- a/drivers/fpga/Kconfig
>> +++ b/drivers/fpga/Kconfig
>> @@ -25,6 +25,13 @@ config FPGA_MGR_ZYNQ_FPGA
>>         help
>>           FPGA manager driver support for Xilinx Zynq FPGAs.
>>
>> +config FPGA_BRIDGE
>> +       bool "FPGA Bridge Framework"
>
> Same here. A bool Kconfig but module.h etc. used in the driver.
>
> Either make the code modular with a tristate if there is a valid
> use case for that, or get rid of the modular references.

Yes, of course.  Thanks!

Alan Tull

>
> Thanks,
> Paul.
> --

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

* [PATCH v18 1/6] fpga: add bindings document for fpga region
  2016-07-12 19:36 ` [PATCH v18 1/6] fpga: add bindings document for fpga region Alan Tull
@ 2016-07-21 19:39   ` Rob Herring
  0 siblings, 0 replies; 19+ messages in thread
From: Rob Herring @ 2016-07-21 19:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 12, 2016 at 02:36:40PM -0500, Alan Tull wrote:
> New bindings document for FPGA Region to support programming
> FPGA's under Device Tree control
> 
> Signed-off-by: Alan Tull <atull@opensource.altera.com>
> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.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 at 0xff20000 -> bridge at 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
> v15: Cleanup as per Rob's comments
>      Combine usage doc with bindings document
>      Document as being Altera specific
>      Additions and changes to add FPGA Bus
> v16: Reworked to document FPGA Regions
>      rename altera-fpga-bus-fpga-area.txt -> fpga-region.txt
>      Remove references that made it sound exclusive to Altera
>      Remove altr, prefix from fpga-bus and fpga-area compatible strings
>      Added Moritz' usage example with Xilinx
>      Cleaned up unit addresses
> v17: Lots of rewrites to try to make things clearer
>      Clarify that overlay can be rejected if FPGA isn't programmed
>      Add external-fpga-config binding already used in u-boot
>      Change partial-reconfig binding to partial-fpga-config to align
>        with existing u-boot binding format *-fpga-config
>      Add a document from Xilinx' website
> v18: Fix node names underscores to be hyphens

You missed some...

>      Fix copy/pasted duplicate nodes in diagram
> ---
>  .../devicetree/bindings/fpga/fpga-region.txt       | 491 +++++++++++++++++++++
>  1 file changed, 491 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/fpga/fpga-region.txt
> 
> diff --git a/Documentation/devicetree/bindings/fpga/fpga-region.txt b/Documentation/devicetree/bindings/fpga/fpga-region.txt
> new file mode 100644
> index 0000000..cfac8c2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/fpga/fpga-region.txt
> @@ -0,0 +1,491 @@
> +FPGA Region Device Tree Binding
> +
> +Alan Tull 2016
> +
> + CONTENTS
> + - Introduction
> + - Terminology
> + - Overview
> + - Constraints
> + - FPGA Region
> + - Supported Use Models
> + - Sequence
> + - Device Tree Examples
> +
> +
> +Introduction
> +============
> +
> +FPGA Regions are introduced as a way to solve the problem of how to program an
> +FPGA under an operating system and have the new hardware show up in the device
> +tree.  By adding these bindings to the Device Tree, a system can have the
> +information needed to program the FPGA and add the desired hardware, and also
> +the information about the devices to be added to the Device Tree once the
> +programming has succeeded.
> +
> +This device tree binding document hits some of the high points of FPGA usage and
> +attempts to include terminology used by both major FPGA manufacturers.  This
> +document isn't a replacement for any manufacturers white papers and
> +specifications for FPGA usage.
> +
> +
> +Terminology
> +===========
> +
> +Full Reconfiguration
> + * The entire FPGA is programmed.
> +
> +Partial Reconfiguration (PR)
> + * A section of the FPGA is reprogrammed while the rest of the FPGA is not
> +   affected. Not all FPGA's support this.
> +
> +Partial Reconfiguration Region (PRR)
> + * Also called a "reconfigurable partition"
> + * A PRR is a specific section of a FPGA reserved for reconfiguration.
> + * A base (or static) FPGA image may create a set of PRR's that later may
> +   be independently reprogrammed many times.
> + * The size and specific location of each PRR is fixed.
> + * The connections at the edge of each PRR are fixed.  The image that is loaded
> +   into a PRR must fit and must use a subset of the region's connections.
> + * The busses within the FPGA are split such that each region gets its own
> +   branch that may be gated independently.
> +
> +Persona
> + * Also called a "partial bit stream"
> + * An FPGA image that is designed to be loaded into a PRR.  There may be
> +   any number of personas designed to fit into a PRR, but only one at at time
> +   may be loaded.
> + * A persona may create more regions.
> +
> +FPGA Manager
> + * An FPGA Manager is a hardware block that programs an FPGA under the control
> +   of a host processor.
> +
> +
> +    ----------------       ------------------------------
> +    |  Host CPU    |       |           FPGA             |
> +    |              |       |                            |
> +    |          ----|       |       -------    --------  |
> +    |          | H |       |   |==>| FB0 |<==>| PRR0 |  |
> +    |          | W |       |   |   -------    --------  |
> +    |          |   |       |   |                        |
> +    |          | B |<=====>|<==|   -------    --------  |
> +    |          | R |       |   |==>| FB1 |<==>| PRR1 |  |
> +    |          | I |       |   |   -------    --------  |
> +    |          | D |       |   |                        |
> +    |          | G |       |   |   -------    --------  |
> +    |          | E |       |   |==>| FB2 |<==>| PRR2 |  |
> +    |          ----|       |       -------    --------  |
> +    |              |       |                            |
> +    ----------------       ------------------------------
> +
> +Figure 1: An FPGA set up with a base image that created three regions.  Each
> +region gets its own split of the busses that can be independently gated by an
> +soft logic bridge in the FPGA.  The contents of each PRR can be reprogrammed
> +independently while the rest of the system continues to function.
> +
> +FPGA Bridge
> + * FPGA Bridges gate bus signals between a host and FPGA.
> + * FPGA Bridges should be disabled while the FPGA is being programmed to
> +   prevent spurious signals on the cpu bus.
> + * FPGA bridges may be actual hardware or soft logic on the FPGA.
> + * During Full Reconfiguration, hardware bridges between the host and FPGA
> +   will be disabled to prevent spurious data on the bus.
> + * These hardware FPGA Bridges may not be needed in implementations where the
> +   FPGA Manager transparantly handles gating the buses.
> + * A base FPGA image may create a set of reprogrammable regions, each having
> +   its own split of the busses that is gated by its own bridge in the FPGA.
> + * During Partial Reconfiguration of a specific region, the region's bridge
> +   will be used to gate the busses.  Traffic to other regions is not affected.
> +
> +Base Image
> + * Also called the "static image"
> + * An FPGA image that is designed to do full reconfiguration of the FPGA.
> + * A base image may set up a set of partial reconfiguration regions that may
> +   later be reprogrammed.
> +
> +
> +Overview
> +========
> +
> +This binding introduces the FPGA Region which supports full or partial
> +reconfiguration of a FPGA under device tree control.
> +
> +In the device tree, an FPGA Region brings together the devices (FPGA Managers
> +and FPGA Bridges) needed to be able to program an FPGA device.  The FPGA Region
> +also includes child nodes that are the devices that exist in the FPGA.
> +
> +The base FPGA Region in the device tree is required to include a phandle to an
> +FPGA Manager.  This region also contains a list of phandles to the hardware FPGA
> +Bridges, if any.  This base FPGA Region corresponds to the whole FPGA and is
> +used for full reconfiguration.
> +
> +FPGA Regions that are children of the base FPGA region inherit the parent's FPGA
> +Manager but specify their own bridges.  These child regions correspond to
> +partial reconfiguration regions in the FPGA.  The bridges they specify will be
> +FPGA Bridges within the static image of the FPGA.
> +
> +The intended use is that device tree overlays can be used to reprogram an FPGA
> +while an operating system is running.  In that case, the live device tree will
> +contain an FPGA Manager, FPGA Bridges, and the base FPGA Region.  The device
> +tree overlays contain the name of the FPGA image file to be programmed and the
> +child devices that will be contained in the FPGA after programming.
> +
> +When such a device tree overlay is applied, it is targeted to one of the
> +existing FPGA regions.  A few things must happen in the OS's implementation
> +before the overlay can be accepted into the live tree.  The OS will attempt to
> +program the FPGA using the firmware that the overlay specifies.  That
> +reprogramming sequence is detailed below (see the Sequence section).  If
> +programming fails, the overlay is rejected.  If programming succeeds, the
> +overlay is added into the live tree and correctly shows what firmware the FPGA
> +has been programmed with.  Child nodes in the overlay are added and those
> +devices are populated.
> +
> +The base FPGA Region supports full reconfiguration of the FPGA device.  If the
> +FPGA image loaded contains the logic that creates a set of Partial
> +Reconfiguration Regions, then the overlay that programs the FPGA should also add
> +a set of FPGA Regions as children of the original FPGA Region.  The child FPGA
> +Regions do not need to specify an FPGA Manager as they will use the ancestor
> +region's FPGA Manager.
> +
> +
> +Constraints
> +===========
> +
> +It is beyond the scope of this document to fully describe all the FPGA design
> +constraints required to make partial reconfiguration work[1] [2] [3], but a few
> +deserve quick mention.
> +
> +A persona must have boundary connections that line up with those of the partion
> +or region it is designed to go into.
> +
> +During programming, transactions through those connections must be stopped and
> +the connections must be held at a fixed logic level.  This can be achieved by
> +FPGA Bridges that exist on the FPGA fabric prior to the partial reconfiguration.
> +
> +FPGA Region
> +===========
> +
> +An FPGA Region specifies the devices (FPGA Manager and FPGA Bridges ) needed to
> +reconfigure a FPGA device.
> +
> +In the live Device Tree, an FPGA Region reflects the current configuration of
> +the device.  If the live tree shows a "firmware-name" property under a FPGA
> +Region, the FPGA already has been programmed with that firmware.
> +
> +A device tree overlay that targets a FPGA Region and adds the "firmware-name"
> +property and child nodes is a request to reprogram the FPGA and, if successful,
> +add the child nodes.  If reprogramming is not successful, the overlay must be
> +rejected and not added to the live tree.
> +
> +Required properties:
> +- compatible   : should contain "fpga-region"
> +- fpga-mgr     : should contain a phandle to an FPGA Manager.  Child FPGA
> +		 Regions inherit this property from the parent, so it
> +		 should be left out for any child FPGA Regions.
> +- fpga-bridges : should contain a list of phandles to FPGA Bridges.  This
> +		 property is optional if the FPGA Manager controls the
> +		 bridges during reprogramming.
> +- #address-cells, #size-cells, ranges: must be present to handle address space
> +  mapping for children.
> +
> +Properties added in an overlay:
> +- firmware-name : should contain the name of an FPGA image file located on the
> +  firmware search path.  If this property shows up in a live device tree it
> +  can only mean that the FPGA has already been programmed with this image.
> +- partial-fpga-config : boolean property should be defined if partial
> +  reconfiguration of the FPGA is to be done, otherwise full reconfiguration
> +  is done.
> +- external-fpga-config : boolean property should be defined if the FPGA
> +  has already been configured.  Then the FPGA Region can be used to add
> +  child nodes for the devices that are in the FPGA.
> +- child nodes : devices in the FPGA after programming.
> +
> +In the example below, when an overlay is applied targeting base_fpga_region,
> +fpgamgr at ff706000 is used to program the FPGA and the bridge specified is
> +controlled during the programming.  During programming, the bridges listed in
> +that region are disabled, the firmware specified in the overlay is loaded to the
> +FPGA using the FPGA manager specified in the region.  If FPGA programming
> +succeeds, the bridges are reenabled and the overlay makes it into the live
> +device tree.  The jtag_uart and led_pio child devices are then populated.  If
> +FPGA programming fails, the bridges are left disabled and the overlay is
> +rejected.
> +
> +Example:
> +Base tree contains:
> +
> +	fpga_mgr0: fpgamgr at ff706000 {
> +		compatible = "altr,socfpga-fpga-mgr";
> +		reg = <0xff706000 0x1000
> +		       0xffb90000 0x4>;
> +		interrupts = <0 175 4>;
> +	};
> +
> +	fpga_bridge0: fpga-bridge at ff400000 {
> +		compatible = "altr,socfpga-lwhps2fpga-bridge";
> +		reg = <0xff400000 0x100000>;
> +		resets = <&rst LWHPS2FPGA_RESET>;
> +		reset-names = "lwhps2fpga";
> +		clocks = <&l4_main_clk>;
> +	};
> +
> +	base_fpga_region {

Sigh, don't use '_'. Just use "fpga-region".

Also, I think in this case, this node should be under fpga_bridge0. Or 
was there some reason not to do that?

> +		compatible = "fpga-region";
> +		fpga-mgr = <&fpga_mgr0>;
> +		fpga-bridges = <&fpga_bridge0>;
> +
> +		#address-cells = <0x1>;
> +		#size-cells = <0x1>;
> +		ranges = <0 0xff200000 0x100000>;
> +	};
> +
> +/dts-v1/ /plugin/;
> +/ {
> +	fragment at 0 {
> +		target-path = "/soc/base_fpga_region";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			firmware-name = "soc_system.rbf";
> +
> +			jtag_uart: serial at 20000 {
> +				compatible = "altr,juart-1.0";
> +				reg = <0x20000 0x8>;
> +				interrupt-parent = <&intc>;
> +				interrupts = <0 42 4>;
> +			};
> +
> +			led_pio: gpio at 10040 {
> +				compatible = "altr,pio-1.0";
> +				reg = <0x10040 0x20>;
> +				altr,gpio-bank-width = <4>;
> +				#gpio-cells = <2>;
> +				gpio-controller;
> +			};
> +		};
> +	};
> +};
> +
> +Supported Use Models
> +====================
> +
> +Here's a list of supported use models.  We may need to add more.  Some uses are
> +specific to one FPGA device or another.
> +
> +In all cases the live DT must specify the FPGA Manager, FPGA Bridges (if any),
> +and a FPGA Region.  The target of the Device Tree Overlay is the FPGA Region.
> +
> + * No FPGA Bridges
> +   In this case, the FPGA Manager which programs the FPGA also handles the
> +   bridges.  No FPGA Bridge devices are needed for full reconfiguration.
> +
> + * Full reconfiguration with bridges
> +   In this case, there are hardware bridges between the processor and FPGA that
> +   need to be disabled during full reconfiguration.  Before the overlay is
> +   applied, the live DT must include the FPGA Manager, FPGA Bridges, and a
> +   base FPGA Region which contains phandles to the FPGA Manager and Bridges.
> +
> + * Partial reconfiguration with bridges in the FPGA
> +   In this case, the FPGA will have more than one PRR that will be programmed
> +   separately.  While one PRR is being programmed, other PRR's may be active
> +   on the bus.  To manage this, FPGA Bridges need to exist in the FPGA
> +   that can gate the buses going to one FPGA region while the buses are
> +   enabled for other sections.  Before any partial reconfiguration can be
> +   done, a base FPGA image must be loaded which includes PRR's with FPGA
> +   bridges.  This can be done by doing full reconfiguration using an overlay
> +   that contains the FPGA image that sets up the regions in the FPGA fabric.
> +   The overlay would also contain FPGA Regions that will become children of
> +   the original base FPGA Region.
> +
> +Sequence
> +========
> +
> +When a DT overlay is loaded, the FPGA Region will be notified 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.
> +
> +When the overlay is removed, the FPGA Region will be notified and will disable
> +the bridges and the child nodes will be removed.
> +
> +Device Tree Examples
> +====================
> +
> +The intention of this section is to give some simple examples, focusing on
> +the placement of the elements detailed above, especially:
> + * FPGA Manager
> + * FPGA Bridges
> + * FPGA Region
> + * ranges
> + * target-path or target
> +
> +For the purposes of this section, I'm dividing the Device Tree into two parts,
> +each with its own requirements.  The two parts are:
> + * The live DT prior to the overlay being added
> + * The DT overlay
> +
> +The live Device Tree must contain an FPGA Region, an FPGA Manager, and any FPGA
> +Bridges.  The FPGA Region's "fpga-mgr" property specifies the manager by phandle
> +to handle programming the FPGA.  If the FPGA Region is the child of another FPGA
> +Region, the parent's FPGA Manager is used.  If FPGA Bridges need to be involved,
> +they are specified in the FPGA Region by the "fpga-bridges" property.  During
> +FPGA programming, the FPGA Region will disable the bridges that are in its
> +"fpga-bridges" list and will re-enable them after FPGA programming has
> +succeeded.
> +
> +The Device Tree Overlay will contain:
> + * "target-path" or "target"
> +   The insertion point where the the contents of the overlay will go into the
> +   live tree.  target-path is a full path, while target is a phandle.
> + * "ranges"
> +    The address space mapping from processor to FPGA bus(ses).
> + * "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-fpga-config"
> +   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.
> +
> +Device Tree Example: Full Reconfiguration without Bridges
> +=========================================================
> +
> +Live Device Tree contains:
> +	fpga_mgr0: fpgamgr at f8007000 {
> +		compatible = "xlnx,zynq-devcfg-1.0";
> +		reg = <0xf8007000 0x100>;
> +		interrupt-parent = <&intc>;
> +		interrupts = <0 8 4>;
> +		clocks = <&clkc 12>;
> +		clock-names = "ref_clk";
> +		syscon = <&slcr>;
> +	};
> +
> +	base_fpga_region {
> +		compatible = "fpga-region";
> +		fpga-mgr = <&fpga_mgr0>;
> +		#address-cells = <0x1>;
> +		#size-cells = <0x1>;
> +		ranges;
> +	};
> +
> +DT Overlay contains:
> +/dts-v1/ /plugin/;
> +/ {
> +fragment at 0 {
> +	target = <&base_fpga_region>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	__overlay__ {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		firmware-name = "zynq-gpio.bin";
> +
> +		gpio1: gpio at 40000000 {
> +			compatible = "xlnx,xps-gpio-1.00.a";
> +			reg = <0x40000000 0x10000>;
> +			gpio-controller;
> +			#gpio-cells = <0x2>;
> +			xlnx,gpio-width= <0x6>;
> +		};
> +	};
> +};
> +
> +Device Tree Example: Full Reconfiguration to add PRR's
> +======================================================
> +
> +The Base FPGA Region is specified similar to the first example above.
> +
> +This example programs the FPGA to have two regions that can later be partially
> +configured.  Each region has its own bridge in the FPGA fabric.
> +
> +DT Overlay contains:
> +/dts-v1/ /plugin/;
> +/ {
> +	fragment at 0 {
> +		target-path = "/soc/base_fpga_region";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		__overlay__ {
> +			#address-cells = <1>;
> +		        #size-cells = <1>;
> +
> +			firmware-name = "base.rbf";
> +
> +			fpga_bridge1_0: fpga-bridge at 4400 {
> +				compatible = "altr,freeze-bridge";
> +				reg = <0x4400 0x10>;
> +			};
> +
> +			fpga_bridge2_0: fpga-bridge at 4420 {
> +				compatible = "altr,freeze-bridge";
> +				reg = <0x4420 0x10>;
> +			};
> +
> +			fpga_region1 {

Likewise, put this under fpga_bridge1_0.

> +				compatible = "fpga-region";
> +				fpga-bridges = <&fpga_bridge1_0>;
> +				#address-cells = <0x1>;
> +				#size-cells = <0x1>;
> +				ranges;
> +			};

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

* [PATCH v18 2/6] ARM: socfpga: add bindings document for fpga bridge drivers
  2016-07-12 19:36 ` [PATCH v18 2/6] ARM: socfpga: add bindings document for fpga bridge drivers Alan Tull
@ 2016-08-01 16:18   ` Rob Herring
  2016-08-03 18:44     ` atull
  0 siblings, 1 reply; 19+ messages in thread
From: Rob Herring @ 2016-08-01 16:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 12, 2016 at 02:36:41PM -0500, Alan Tull wrote:
> 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
> v15: No change in this patch for v15 of this patch set
> v16: Added regs property, cleaned up unit addresses
> v17: No change to this patch in v17 of patch set
> v18: Changed to not need reset-names property
>      node names as fpga-bridge at ...
>      labels as fpga_bridge
>      Add address of fpgaportrst to give and address for f2s bridge
> ---
>  .../bindings/fpga/altera-fpga2sdram-bridge.txt     | 16 +++++++++
>  .../bindings/fpga/altera-hps2fpga-bridge.txt       | 39 ++++++++++++++++++++++
>  2 files changed, 55 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
>  create mode 100644 Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt

Acked-by: Rob Herring <robh@kernel.org>

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

* [PATCH v18 2/6] ARM: socfpga: add bindings document for fpga bridge drivers
  2016-08-01 16:18   ` Rob Herring
@ 2016-08-03 18:44     ` atull
  0 siblings, 0 replies; 19+ messages in thread
From: atull @ 2016-08-03 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 1 Aug 2016, Rob Herring wrote:

> On Tue, Jul 12, 2016 at 02:36:41PM -0500, Alan Tull wrote:
> > 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
> > v15: No change in this patch for v15 of this patch set
> > v16: Added regs property, cleaned up unit addresses
> > v17: No change to this patch in v17 of patch set
> > v18: Changed to not need reset-names property
> >      node names as fpga-bridge at ...
> >      labels as fpga_bridge
> >      Add address of fpgaportrst to give and address for f2s bridge
> > ---
> >  .../bindings/fpga/altera-fpga2sdram-bridge.txt     | 16 +++++++++
> >  .../bindings/fpga/altera-hps2fpga-bridge.txt       | 39 ++++++++++++++++++++++
> >  2 files changed, 55 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/fpga/altera-fpga2sdram-bridge.txt
> >  create mode 100644 Documentation/devicetree/bindings/fpga/altera-hps2fpga-bridge.txt
> 
> Acked-by: Rob Herring <robh@kernel.org>
> 

Thanks!

Alan

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

* [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support
  2016-07-14 20:47   ` Paul Gortmaker
@ 2016-08-08 19:18     ` atull
  2016-08-08 20:44       ` Moritz Fischer
  0 siblings, 1 reply; 19+ messages in thread
From: atull @ 2016-08-08 19:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 14 Jul 2016, Paul Gortmaker wrote:

> On Tue, Jul 12, 2016 at 3:36 PM, Alan Tull <atull@opensource.altera.com> wrote:
> > 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
> > v15: No change in this patch for v15 of this patch set
> > v16: No change in this patch for v16 of this patch set
> > v17: No change to this patch for v17 of this patch set
> > v18: Eliminate need to specify reset names since only one reset
> > ---
> >  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 ec81e21..b346166 100644
> > --- a/drivers/fpga/Kconfig
> > +++ b/drivers/fpga/Kconfig
> > @@ -39,6 +39,13 @@ config FPGA_BRIDGE
> >           Say Y here if you want to support bridges connected between host
> >          processors and FPGAs or between FPGAs.
> >
> > +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 8d746c3..e658436 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_REGION)              += fpga-region.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
> 
> Please don't use module.h in drivers controlled by a bool
> Kconfig setting.
> 
> THanks,
> Paul.
> 

Thanks for the feedback.  Can you provide an example of what you
would consider to be proper usage in the kernel?

Alan

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

* [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support
  2016-08-08 19:18     ` atull
@ 2016-08-08 20:44       ` Moritz Fischer
  2016-08-09 16:00         ` Paul Gortmaker
  0 siblings, 1 reply; 19+ messages in thread
From: Moritz Fischer @ 2016-08-08 20:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Alan,

On Mon, Aug 8, 2016 at 12:18 PM, atull <atull@opensource.altera.com> wrote:

>> Please don't use module.h in drivers controlled by a bool
>> Kconfig setting.
>>
>> THanks,
>> Paul.
>>
>
> Thanks for the feedback.  Can you provide an example of what you
> would consider to be proper usage in the kernel?


I think Paul is suggesting to use

static int __init alt_fpga_bridge_init(void)
{
        platform_driver_register(&alt_fpga_bridge_driver);
}

device_initcall(alt_fpga_bridge_init);

or better:

builtin_platform_driver(&alt_fpga_bridge_driver);

Like for example in: drivers/cpuidle/cpuidle-mvebu-v7.c

Cheers,

Moritz

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

* [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support
  2016-08-08 20:44       ` Moritz Fischer
@ 2016-08-09 16:00         ` Paul Gortmaker
  2016-09-22 19:53           ` atull
  0 siblings, 1 reply; 19+ messages in thread
From: Paul Gortmaker @ 2016-08-09 16:00 UTC (permalink / raw)
  To: linux-arm-kernel

[Re: [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support] On 08/08/2016 (Mon 13:44) Moritz Fischer wrote:

> Hi Alan,
> 
> On Mon, Aug 8, 2016 at 12:18 PM, atull <atull@opensource.altera.com> wrote:
> 
> >> Please don't use module.h in drivers controlled by a bool
> >> Kconfig setting.
> >>
> >> THanks,
> >> Paul.
> >>
> >
> > Thanks for the feedback.  Can you provide an example of what you
> > would consider to be proper usage in the kernel?
> 
> 
> I think Paul is suggesting to use
> 
> static int __init alt_fpga_bridge_init(void)
> {
>         platform_driver_register(&alt_fpga_bridge_driver);
> }
> 
> device_initcall(alt_fpga_bridge_init);
> 
> or better:
> 
> builtin_platform_driver(&alt_fpga_bridge_driver);
> 
> Like for example in: drivers/cpuidle/cpuidle-mvebu-v7.c

Yes, pretty much that -- if you have a bool Kconfig, you should be using
builtin registration functions, and have no need for module.h or
anything MODULE_<xyz> or any module_init/module_exit calls.

An empty file containing nothing but #include <linux/module.h> will
cause cpp to emit about 750k of goop, so we really should only be using
it for drivers that are genuinely modular; i.e. tristate Kconfig.

Thanks,
Paul.
--

> 
> Cheers,
> 
> Moritz

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

* [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support
  2016-08-09 16:00         ` Paul Gortmaker
@ 2016-09-22 19:53           ` atull
  0 siblings, 0 replies; 19+ messages in thread
From: atull @ 2016-09-22 19:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 9 Aug 2016, Paul Gortmaker wrote:

> [Re: [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support] On 08/08/2016 (Mon 13:44) Moritz Fischer wrote:
> 
> > Hi Alan,
> > 
> > On Mon, Aug 8, 2016 at 12:18 PM, atull <atull@opensource.altera.com> wrote:
> > 
> > >> Please don't use module.h in drivers controlled by a bool
> > >> Kconfig setting.
> > >>
> > >> THanks,
> > >> Paul.
> > >>
> > >
> > > Thanks for the feedback.  Can you provide an example of what you
> > > would consider to be proper usage in the kernel?
> > 
> > 
> > I think Paul is suggesting to use
> > 
> > static int __init alt_fpga_bridge_init(void)
> > {
> >         platform_driver_register(&alt_fpga_bridge_driver);
> > }
> > 
> > device_initcall(alt_fpga_bridge_init);
> > 
> > or better:
> > 
> > builtin_platform_driver(&alt_fpga_bridge_driver);
> > 
> > Like for example in: drivers/cpuidle/cpuidle-mvebu-v7.c
> 
> Yes, pretty much that -- if you have a bool Kconfig, you should be using
> builtin registration functions, and have no need for module.h or
> anything MODULE_<xyz> or any module_init/module_exit calls.
> 
> An empty file containing nothing but #include <linux/module.h> will
> cause cpp to emit about 750k of goop, so we really should only be using
> it for drivers that are genuinely modular; i.e. tristate Kconfig.
> 
> Thanks,
> Paul.
> --
> 
> > 
> > Cheers,
> > 
> > Moritz
> 

Thanks for the feedback and explanations!

I've retested my stuff with it all built as modules (mgr, bridged,
and fpga-region) and it all works that way as well as built in.
So I'll fix up the Kconfig as tristates for everybody.  Also
I'll add some dependencies as FPGA_REGION should be dependent
on FPGA_BRIDGE.

Alan

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

* [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support
  2016-07-12 19:36 ` [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support Alan Tull
  2016-07-14 20:47   ` Paul Gortmaker
@ 2016-09-23 14:13   ` Steffen Trumtrar
  1 sibling, 0 replies; 19+ messages in thread
From: Steffen Trumtrar @ 2016-09-23 14:13 UTC (permalink / raw)
  To: linux-arm-kernel


Hi!

Alan Tull writes:

> 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>

(...)

> +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);
> +}

(...)

> +	/* Get f2s bridge configuration saved in handoff register */
> +	regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask);
> +

Could you maybe add some documentation about this implicit information
shared between a bootloader and this driver?
I understand why you do this, but there must be a better way than
depending on something some bootloader wrote in some undocumented
register, no?
The documentation just says:

"These registers are used to store handoff infomation between the
preloader and the OS. These 8 registers can be used to store any
information. The contents of these registers have no impact on the
state of the HPS hardware"

If it is already agreed upon, that a bridge-enable property is okay,
why not add a port-enable property, too?

Regards,
Steffen Trumtrar

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

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

end of thread, other threads:[~2016-09-23 14:13 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-12 19:36 [PATCH v18 0/6] Device Tree support for FPGA Programming Alan Tull
2016-07-12 19:36 ` [PATCH v18 1/6] fpga: add bindings document for fpga region Alan Tull
2016-07-21 19:39   ` Rob Herring
2016-07-12 19:36 ` [PATCH v18 2/6] ARM: socfpga: add bindings document for fpga bridge drivers Alan Tull
2016-08-01 16:18   ` Rob Herring
2016-08-03 18:44     ` atull
2016-07-12 19:36 ` [PATCH v18 3/6] add sysfs document for fpga bridge class Alan Tull
2016-07-12 19:36 ` [PATCH v18 4/6] fpga: add fpga bridge framework Alan Tull
2016-07-14 20:54   ` Paul Gortmaker
2016-07-15 16:58     ` Alan Tull
2016-07-12 19:36 ` [PATCH v18 5/6] fpga: fpga-region: device tree control for FPGA Alan Tull
2016-07-12 19:36 ` [PATCH v18 6/6] ARM: socfpga: fpga bridge driver support Alan Tull
2016-07-14 20:47   ` Paul Gortmaker
2016-08-08 19:18     ` atull
2016-08-08 20:44       ` Moritz Fischer
2016-08-09 16:00         ` Paul Gortmaker
2016-09-22 19:53           ` atull
2016-09-23 14:13   ` Steffen Trumtrar
2016-07-12 19:43 ` [PATCH v18 0/6] Device Tree support for FPGA Programming atull

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).