xref: /OK3568_Linux_fs/kernel/Documentation/driver-api/fpga/fpga-programming.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunIn-kernel API for FPGA Programming
2*4882a593Smuzhiyun==================================
3*4882a593Smuzhiyun
4*4882a593SmuzhiyunOverview
5*4882a593Smuzhiyun--------
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunThe in-kernel API for FPGA programming is a combination of APIs from
8*4882a593SmuzhiyunFPGA manager, bridge, and regions.  The actual function used to
9*4882a593Smuzhiyuntrigger FPGA programming is fpga_region_program_fpga().
10*4882a593Smuzhiyun
11*4882a593Smuzhiyunfpga_region_program_fpga() uses functionality supplied by
12*4882a593Smuzhiyunthe FPGA manager and bridges.  It will:
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun * lock the region's mutex
15*4882a593Smuzhiyun * lock the mutex of the region's FPGA manager
16*4882a593Smuzhiyun * build a list of FPGA bridges if a method has been specified to do so
17*4882a593Smuzhiyun * disable the bridges
18*4882a593Smuzhiyun * program the FPGA using info passed in :c:expr:`fpga_region->info`.
19*4882a593Smuzhiyun * re-enable the bridges
20*4882a593Smuzhiyun * release the locks
21*4882a593Smuzhiyun
22*4882a593SmuzhiyunThe struct fpga_image_info specifies what FPGA image to program.  It is
23*4882a593Smuzhiyunallocated/freed by fpga_image_info_alloc() and freed with
24*4882a593Smuzhiyunfpga_image_info_free()
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunHow to program an FPGA using a region
27*4882a593Smuzhiyun-------------------------------------
28*4882a593Smuzhiyun
29*4882a593SmuzhiyunWhen the FPGA region driver probed, it was given a pointer to an FPGA manager
30*4882a593Smuzhiyundriver so it knows which manager to use.  The region also either has a list of
31*4882a593Smuzhiyunbridges to control during programming or it has a pointer to a function that
32*4882a593Smuzhiyunwill generate that list.  Here's some sample code of what to do next::
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun	#include <linux/fpga/fpga-mgr.h>
35*4882a593Smuzhiyun	#include <linux/fpga/fpga-region.h>
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun	struct fpga_image_info *info;
38*4882a593Smuzhiyun	int ret;
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun	/*
41*4882a593Smuzhiyun	 * First, alloc the struct with information about the FPGA image to
42*4882a593Smuzhiyun	 * program.
43*4882a593Smuzhiyun	 */
44*4882a593Smuzhiyun	info = fpga_image_info_alloc(dev);
45*4882a593Smuzhiyun	if (!info)
46*4882a593Smuzhiyun		return -ENOMEM;
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun	/* Set flags as needed, such as: */
49*4882a593Smuzhiyun	info->flags = FPGA_MGR_PARTIAL_RECONFIG;
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun	/*
52*4882a593Smuzhiyun	 * Indicate where the FPGA image is. This is pseudo-code; you're
53*4882a593Smuzhiyun	 * going to use one of these three.
54*4882a593Smuzhiyun	 */
55*4882a593Smuzhiyun	if (image is in a scatter gather table) {
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun		info->sgt = [your scatter gather table]
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun	} else if (image is in a buffer) {
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun		info->buf = [your image buffer]
62*4882a593Smuzhiyun		info->count = [image buffer size]
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun	} else if (image is in a firmware file) {
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun		info->firmware_name = devm_kstrdup(dev, firmware_name,
67*4882a593Smuzhiyun						   GFP_KERNEL);
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun	}
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun	/* Add info to region and do the programming */
72*4882a593Smuzhiyun	region->info = info;
73*4882a593Smuzhiyun	ret = fpga_region_program_fpga(region);
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun	/* Deallocate the image info if you're done with it */
76*4882a593Smuzhiyun	region->info = NULL;
77*4882a593Smuzhiyun	fpga_image_info_free(info);
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun	if (ret)
80*4882a593Smuzhiyun		return ret;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun	/* Now enumerate whatever hardware has appeared in the FPGA. */
83*4882a593Smuzhiyun
84*4882a593SmuzhiyunAPI for programming an FPGA
85*4882a593Smuzhiyun---------------------------
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun* fpga_region_program_fpga() —  Program an FPGA
88*4882a593Smuzhiyun* fpga_image_info() —  Specifies what FPGA image to program
89*4882a593Smuzhiyun* fpga_image_info_alloc() —  Allocate an FPGA image info struct
90*4882a593Smuzhiyun* fpga_image_info_free() —  Free an FPGA image info struct
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun.. kernel-doc:: drivers/fpga/fpga-region.c
93*4882a593Smuzhiyun   :functions: fpga_region_program_fpga
94*4882a593Smuzhiyun
95*4882a593SmuzhiyunFPGA Manager flags
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun.. kernel-doc:: include/linux/fpga/fpga-mgr.h
98*4882a593Smuzhiyun   :doc: FPGA Manager flags
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun.. kernel-doc:: include/linux/fpga/fpga-mgr.h
101*4882a593Smuzhiyun   :functions: fpga_image_info
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun.. kernel-doc:: drivers/fpga/fpga-mgr.c
104*4882a593Smuzhiyun   :functions: fpga_image_info_alloc
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun.. kernel-doc:: drivers/fpga/fpga-mgr.c
107*4882a593Smuzhiyun   :functions: fpga_image_info_free
108