|
@@ -11,61 +11,53 @@ hidden away in a low level driver which registers a set of ops with the core.
|
|
|
The FPGA image data itself is very manufacturer specific, but for our purposes
|
|
|
it's just binary data. The FPGA manager core won't parse it.
|
|
|
|
|
|
+The FPGA image to be programmed can be in a scatter gather list, a single
|
|
|
+contiguous buffer, or a firmware file. Because allocating contiguous kernel
|
|
|
+memory for the buffer should be avoided, users are encouraged to use a scatter
|
|
|
+gather list instead if possible.
|
|
|
+
|
|
|
+The particulars for programming the image are presented in a structure (struct
|
|
|
+fpga_image_info). This struct contains parameters such as pointers to the
|
|
|
+FPGA image as well as image-specific particulars such as whether the image was
|
|
|
+built for full or partial reconfiguration.
|
|
|
|
|
|
API Functions:
|
|
|
==============
|
|
|
|
|
|
-To program the FPGA from a file or from a buffer:
|
|
|
--------------------------------------------------
|
|
|
-
|
|
|
- int fpga_mgr_buf_load(struct fpga_manager *mgr,
|
|
|
- struct fpga_image_info *info,
|
|
|
- const char *buf, size_t count);
|
|
|
-
|
|
|
-Load the FPGA from an image which exists as a contiguous buffer in
|
|
|
-memory. Allocating contiguous kernel memory for the buffer should be avoided,
|
|
|
-users are encouraged to use the _sg interface instead of this.
|
|
|
-
|
|
|
- int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,
|
|
|
- struct fpga_image_info *info,
|
|
|
- struct sg_table *sgt);
|
|
|
+To program the FPGA:
|
|
|
+--------------------
|
|
|
|
|
|
-Load the FPGA from an image from non-contiguous in memory. Callers can
|
|
|
-construct a sg_table using alloc_page backed memory.
|
|
|
+ int fpga_mgr_load(struct fpga_manager *mgr,
|
|
|
+ struct fpga_image_info *info);
|
|
|
|
|
|
- int fpga_mgr_firmware_load(struct fpga_manager *mgr,
|
|
|
- struct fpga_image_info *info,
|
|
|
- const char *image_name);
|
|
|
-
|
|
|
-Load the FPGA from an image which exists as a file. The image file must be on
|
|
|
-the firmware search path (see the firmware class documentation). If successful,
|
|
|
+Load the FPGA from an image which is indicated in the info. If successful,
|
|
|
the FPGA ends up in operating mode. Return 0 on success or a negative error
|
|
|
code.
|
|
|
|
|
|
-A FPGA design contained in a FPGA image file will likely have particulars that
|
|
|
-affect how the image is programmed to the FPGA. These are contained in struct
|
|
|
-fpga_image_info. Currently the only such particular is a single flag bit
|
|
|
-indicating whether the image is for full or partial reconfiguration.
|
|
|
+To allocate or free a struct fpga_image_info:
|
|
|
+---------------------------------------------
|
|
|
+
|
|
|
+ struct fpga_image_info *fpga_image_info_alloc(struct device *dev);
|
|
|
+
|
|
|
+ void fpga_image_info_free(struct fpga_image_info *info);
|
|
|
|
|
|
To get/put a reference to a FPGA manager:
|
|
|
-----------------------------------------
|
|
|
|
|
|
struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
|
|
|
struct fpga_manager *fpga_mgr_get(struct device *dev);
|
|
|
-
|
|
|
-Given a DT node or device, get an exclusive reference to a FPGA manager.
|
|
|
-
|
|
|
void fpga_mgr_put(struct fpga_manager *mgr);
|
|
|
|
|
|
-Release the reference.
|
|
|
+Given a DT node or device, get an exclusive reference to a FPGA manager.
|
|
|
+fpga_mgr_put releases the reference.
|
|
|
|
|
|
|
|
|
To register or unregister the low level FPGA-specific driver:
|
|
|
-------------------------------------------------------------
|
|
|
|
|
|
int fpga_mgr_register(struct device *dev, const char *name,
|
|
|
- const struct fpga_manager_ops *mops,
|
|
|
- void *priv);
|
|
|
+ const struct fpga_manager_ops *mops,
|
|
|
+ void *priv);
|
|
|
|
|
|
void fpga_mgr_unregister(struct device *dev);
|
|
|
|
|
@@ -78,59 +70,50 @@ How to write an image buffer to a supported FPGA
|
|
|
/* Include to get the API */
|
|
|
#include <linux/fpga/fpga-mgr.h>
|
|
|
|
|
|
-/* device node that specifies the FPGA manager to use */
|
|
|
-struct device_node *mgr_node = ...
|
|
|
-
|
|
|
-/* FPGA image is in this buffer. count is size of the buffer. */
|
|
|
-char *buf = ...
|
|
|
-int count = ...
|
|
|
+struct fpga_manager *mgr;
|
|
|
+struct fpga_image_info *info;
|
|
|
+int ret;
|
|
|
|
|
|
/* struct with information about the FPGA image to program. */
|
|
|
-struct fpga_image_info info;
|
|
|
+info = fpga_image_info_alloc(dev);
|
|
|
|
|
|
/* flags indicates whether to do full or partial reconfiguration */
|
|
|
-info.flags = 0;
|
|
|
-
|
|
|
-int ret;
|
|
|
+info->flags = FPGA_MGR_PARTIAL_RECONFIG;
|
|
|
|
|
|
-/* Get exclusive control of FPGA manager */
|
|
|
-struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node);
|
|
|
+/*
|
|
|
+ * At this point, indicate where the image is. This is pseudo-code; you're
|
|
|
+ * going to use one of these three.
|
|
|
+ */
|
|
|
+if (image is in a scatter gather table) {
|
|
|
|
|
|
-/* Load the buffer to the FPGA */
|
|
|
-ret = fpga_mgr_buf_load(mgr, &info, buf, count);
|
|
|
-
|
|
|
-/* Release the FPGA manager */
|
|
|
-fpga_mgr_put(mgr);
|
|
|
+ info->sgt = [your scatter gather table]
|
|
|
|
|
|
+} else if (image is in a buffer) {
|
|
|
|
|
|
-How to write an image file to a supported FPGA
|
|
|
-==============================================
|
|
|
-/* Include to get the API */
|
|
|
-#include <linux/fpga/fpga-mgr.h>
|
|
|
+ info->buf = [your image buffer]
|
|
|
+ info->count = [image buffer size]
|
|
|
|
|
|
-/* device node that specifies the FPGA manager to use */
|
|
|
-struct device_node *mgr_node = ...
|
|
|
+} else if (image is in a firmware file) {
|
|
|
|
|
|
-/* FPGA image is in this file which is in the firmware search path */
|
|
|
-const char *path = "fpga-image-9.rbf"
|
|
|
+ info->firmware_name = devm_kstrdup(dev, firmware_name, GFP_KERNEL);
|
|
|
|
|
|
-/* struct with information about the FPGA image to program. */
|
|
|
-struct fpga_image_info info;
|
|
|
-
|
|
|
-/* flags indicates whether to do full or partial reconfiguration */
|
|
|
-info.flags = 0;
|
|
|
-
|
|
|
-int ret;
|
|
|
+}
|
|
|
|
|
|
-/* Get exclusive control of FPGA manager */
|
|
|
-struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node);
|
|
|
+/*
|
|
|
+ * Get a reference to FPGA manager. This example uses the device node of the
|
|
|
+ * manager. You could use fpga_mgr_get() instead if you have the device instead
|
|
|
+ * of the device node.
|
|
|
+ */
|
|
|
+mgr = of_fpga_mgr_get(mgr_node);
|
|
|
|
|
|
-/* Get the firmware image (path) and load it to the FPGA */
|
|
|
-ret = fpga_mgr_firmware_load(mgr, &info, path);
|
|
|
+/* Load the buffer to the FPGA */
|
|
|
+ret = fpga_mgr_buf_load(mgr, &info, buf, count);
|
|
|
|
|
|
/* Release the FPGA manager */
|
|
|
fpga_mgr_put(mgr);
|
|
|
|
|
|
+/* Deallocate the image info if you're done with it */
|
|
|
+fpga_image_info_free(info);
|
|
|
|
|
|
How to support a new FPGA device
|
|
|
================================
|