108 lines
2.9 KiB
ReStructuredText
108 lines
2.9 KiB
ReStructuredText
|
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
|