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