mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
2.9 KiB
107 lines
2.9 KiB
In-kernel API for FPGA Programming |
|
================================== |
|
|
|
Overview |
|
-------- |
|
|
|
The in-kernel API for FPGA programming is a combination of APIs from |
|
FPGA manager, bridge, and regions. The actual function used to |
|
trigger FPGA programming is fpga_region_program_fpga(). |
|
|
|
fpga_region_program_fpga() uses functionality supplied by |
|
the FPGA manager and bridges. It will: |
|
|
|
* lock the region's mutex |
|
* lock the mutex of the region's FPGA manager |
|
* build a list of FPGA bridges if a method has been specified to do so |
|
* disable the bridges |
|
* program the FPGA using info passed in :c:expr:`fpga_region->info`. |
|
* re-enable the bridges |
|
* release the locks |
|
|
|
The struct fpga_image_info specifies what FPGA image to program. It is |
|
allocated/freed by fpga_image_info_alloc() and freed with |
|
fpga_image_info_free() |
|
|
|
How to program an FPGA using a region |
|
------------------------------------- |
|
|
|
When the FPGA region driver probed, it was given a pointer to an FPGA manager |
|
driver so it knows which manager to use. The region also either has a list of |
|
bridges to control during programming or it has a pointer to a function that |
|
will generate that list. Here's some sample code of what to do next:: |
|
|
|
#include <linux/fpga/fpga-mgr.h> |
|
#include <linux/fpga/fpga-region.h> |
|
|
|
struct fpga_image_info *info; |
|
int ret; |
|
|
|
/* |
|
* First, alloc the struct with information about the FPGA image to |
|
* program. |
|
*/ |
|
info = fpga_image_info_alloc(dev); |
|
if (!info) |
|
return -ENOMEM; |
|
|
|
/* Set flags as needed, such as: */ |
|
info->flags = FPGA_MGR_PARTIAL_RECONFIG; |
|
|
|
/* |
|
* Indicate where the FPGA image is. This is pseudo-code; you're |
|
* going to use one of these three. |
|
*/ |
|
if (image is in a scatter gather table) { |
|
|
|
info->sgt = [your scatter gather table] |
|
|
|
} else if (image is in a buffer) { |
|
|
|
info->buf = [your image buffer] |
|
info->count = [image buffer size] |
|
|
|
} else if (image is in a firmware file) { |
|
|
|
info->firmware_name = devm_kstrdup(dev, firmware_name, |
|
GFP_KERNEL); |
|
|
|
} |
|
|
|
/* Add info to region and do the programming */ |
|
region->info = info; |
|
ret = fpga_region_program_fpga(region); |
|
|
|
/* Deallocate the image info if you're done with it */ |
|
region->info = NULL; |
|
fpga_image_info_free(info); |
|
|
|
if (ret) |
|
return ret; |
|
|
|
/* Now enumerate whatever hardware has appeared in the FPGA. */ |
|
|
|
API for programming an FPGA |
|
--------------------------- |
|
|
|
* fpga_region_program_fpga() - Program an FPGA |
|
* fpga_image_info() - Specifies what FPGA image to program |
|
* fpga_image_info_alloc() - Allocate an FPGA image info struct |
|
* fpga_image_info_free() - Free an FPGA image info struct |
|
|
|
.. kernel-doc:: drivers/fpga/fpga-region.c |
|
:functions: fpga_region_program_fpga |
|
|
|
FPGA Manager flags |
|
|
|
.. kernel-doc:: include/linux/fpga/fpga-mgr.h |
|
:doc: FPGA Manager flags |
|
|
|
.. kernel-doc:: include/linux/fpga/fpga-mgr.h |
|
:functions: fpga_image_info |
|
|
|
.. kernel-doc:: drivers/fpga/fpga-mgr.c |
|
:functions: fpga_image_info_alloc |
|
|
|
.. kernel-doc:: drivers/fpga/fpga-mgr.c |
|
:functions: fpga_image_info_free
|
|
|