hc
2024-05-09 b9d5c334faa47a75f1f28e72d203fc0334e8471d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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