diff options
Diffstat (limited to 'Documentation/fpga/fpga-mgr.txt')
-rw-r--r-- | Documentation/fpga/fpga-mgr.txt | 199 |
1 files changed, 0 insertions, 199 deletions
diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt deleted file mode 100644 index cc6413ed6fc9..000000000000 --- a/Documentation/fpga/fpga-mgr.txt +++ /dev/null | |||
@@ -1,199 +0,0 @@ | |||
1 | FPGA Manager Core | ||
2 | |||
3 | Alan Tull 2015 | ||
4 | |||
5 | Overview | ||
6 | ======== | ||
7 | |||
8 | The FPGA manager core exports a set of functions for programming an FPGA with | ||
9 | an image. The API is manufacturer agnostic. All manufacturer specifics are | ||
10 | hidden away in a low level driver which registers a set of ops with the core. | ||
11 | The FPGA image data itself is very manufacturer specific, but for our purposes | ||
12 | it's just binary data. The FPGA manager core won't parse it. | ||
13 | |||
14 | The FPGA image to be programmed can be in a scatter gather list, a single | ||
15 | contiguous buffer, or a firmware file. Because allocating contiguous kernel | ||
16 | memory for the buffer should be avoided, users are encouraged to use a scatter | ||
17 | gather list instead if possible. | ||
18 | |||
19 | The particulars for programming the image are presented in a structure (struct | ||
20 | fpga_image_info). This struct contains parameters such as pointers to the | ||
21 | FPGA image as well as image-specific particulars such as whether the image was | ||
22 | built for full or partial reconfiguration. | ||
23 | |||
24 | API Functions: | ||
25 | ============== | ||
26 | |||
27 | To program the FPGA: | ||
28 | -------------------- | ||
29 | |||
30 | int fpga_mgr_load(struct fpga_manager *mgr, | ||
31 | struct fpga_image_info *info); | ||
32 | |||
33 | Load the FPGA from an image which is indicated in the info. If successful, | ||
34 | the FPGA ends up in operating mode. Return 0 on success or a negative error | ||
35 | code. | ||
36 | |||
37 | To allocate or free a struct fpga_image_info: | ||
38 | --------------------------------------------- | ||
39 | |||
40 | struct fpga_image_info *fpga_image_info_alloc(struct device *dev); | ||
41 | |||
42 | void fpga_image_info_free(struct fpga_image_info *info); | ||
43 | |||
44 | To get/put a reference to a FPGA manager: | ||
45 | ----------------------------------------- | ||
46 | |||
47 | struct fpga_manager *of_fpga_mgr_get(struct device_node *node); | ||
48 | struct fpga_manager *fpga_mgr_get(struct device *dev); | ||
49 | void fpga_mgr_put(struct fpga_manager *mgr); | ||
50 | |||
51 | Given a DT node or device, get a reference to a FPGA manager. This pointer | ||
52 | can be saved until you are ready to program the FPGA. fpga_mgr_put releases | ||
53 | the reference. | ||
54 | |||
55 | |||
56 | To get exclusive control of a FPGA manager: | ||
57 | ------------------------------------------- | ||
58 | |||
59 | int fpga_mgr_lock(struct fpga_manager *mgr); | ||
60 | void fpga_mgr_unlock(struct fpga_manager *mgr); | ||
61 | |||
62 | The user should call fpga_mgr_lock and verify that it returns 0 before | ||
63 | attempting to program the FPGA. Likewise, the user should call | ||
64 | fpga_mgr_unlock when done programming the FPGA. | ||
65 | |||
66 | |||
67 | To register or unregister the low level FPGA-specific driver: | ||
68 | ------------------------------------------------------------- | ||
69 | |||
70 | int fpga_mgr_register(struct device *dev, const char *name, | ||
71 | const struct fpga_manager_ops *mops, | ||
72 | void *priv); | ||
73 | |||
74 | void fpga_mgr_unregister(struct device *dev); | ||
75 | |||
76 | Use of these two functions is described below in "How To Support a new FPGA | ||
77 | device." | ||
78 | |||
79 | |||
80 | How to write an image buffer to a supported FPGA | ||
81 | ================================================ | ||
82 | #include <linux/fpga/fpga-mgr.h> | ||
83 | |||
84 | struct fpga_manager *mgr; | ||
85 | struct fpga_image_info *info; | ||
86 | int ret; | ||
87 | |||
88 | /* | ||
89 | * Get a reference to FPGA manager. The manager is not locked, so you can | ||
90 | * hold onto this reference without it preventing programming. | ||
91 | * | ||
92 | * This example uses the device node of the manager. Alternatively, use | ||
93 | * fpga_mgr_get(dev) instead if you have the device. | ||
94 | */ | ||
95 | mgr = of_fpga_mgr_get(mgr_node); | ||
96 | |||
97 | /* struct with information about the FPGA image to program. */ | ||
98 | info = fpga_image_info_alloc(dev); | ||
99 | |||
100 | /* flags indicates whether to do full or partial reconfiguration */ | ||
101 | info->flags = FPGA_MGR_PARTIAL_RECONFIG; | ||
102 | |||
103 | /* | ||
104 | * At this point, indicate where the image is. This is pseudo-code; you're | ||
105 | * going to use one of these three. | ||
106 | */ | ||
107 | if (image is in a scatter gather table) { | ||
108 | |||
109 | info->sgt = [your scatter gather table] | ||
110 | |||
111 | } else if (image is in a buffer) { | ||
112 | |||
113 | info->buf = [your image buffer] | ||
114 | info->count = [image buffer size] | ||
115 | |||
116 | } else if (image is in a firmware file) { | ||
117 | |||
118 | info->firmware_name = devm_kstrdup(dev, firmware_name, GFP_KERNEL); | ||
119 | |||
120 | } | ||
121 | |||
122 | /* Get exclusive control of FPGA manager */ | ||
123 | ret = fpga_mgr_lock(mgr); | ||
124 | |||
125 | /* Load the buffer to the FPGA */ | ||
126 | ret = fpga_mgr_buf_load(mgr, &info, buf, count); | ||
127 | |||
128 | /* Release the FPGA manager */ | ||
129 | fpga_mgr_unlock(mgr); | ||
130 | fpga_mgr_put(mgr); | ||
131 | |||
132 | /* Deallocate the image info if you're done with it */ | ||
133 | fpga_image_info_free(info); | ||
134 | |||
135 | How to support a new FPGA device | ||
136 | ================================ | ||
137 | To add another FPGA manager, write a driver that implements a set of ops. The | ||
138 | probe function calls fpga_mgr_register(), such as: | ||
139 | |||
140 | static const struct fpga_manager_ops socfpga_fpga_ops = { | ||
141 | .write_init = socfpga_fpga_ops_configure_init, | ||
142 | .write = socfpga_fpga_ops_configure_write, | ||
143 | .write_complete = socfpga_fpga_ops_configure_complete, | ||
144 | .state = socfpga_fpga_ops_state, | ||
145 | }; | ||
146 | |||
147 | static int socfpga_fpga_probe(struct platform_device *pdev) | ||
148 | { | ||
149 | struct device *dev = &pdev->dev; | ||
150 | struct socfpga_fpga_priv *priv; | ||
151 | int ret; | ||
152 | |||
153 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
154 | if (!priv) | ||
155 | return -ENOMEM; | ||
156 | |||
157 | /* ... do ioremaps, get interrupts, etc. and save | ||
158 | them in priv... */ | ||
159 | |||
160 | return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager", | ||
161 | &socfpga_fpga_ops, priv); | ||
162 | } | ||
163 | |||
164 | static int socfpga_fpga_remove(struct platform_device *pdev) | ||
165 | { | ||
166 | fpga_mgr_unregister(&pdev->dev); | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | |||
172 | The ops will implement whatever device specific register writes are needed to | ||
173 | do the programming sequence for this particular FPGA. These ops return 0 for | ||
174 | success or negative error codes otherwise. | ||
175 | |||
176 | The programming sequence is: | ||
177 | 1. .write_init | ||
178 | 2. .write or .write_sg (may be called once or multiple times) | ||
179 | 3. .write_complete | ||
180 | |||
181 | The .write_init function will prepare the FPGA to receive the image data. The | ||
182 | buffer passed into .write_init will be atmost .initial_header_size bytes long, | ||
183 | if the whole bitstream is not immediately available then the core code will | ||
184 | buffer up at least this much before starting. | ||
185 | |||
186 | The .write function writes a buffer to the FPGA. The buffer may be contain the | ||
187 | whole FPGA image or may be a smaller chunk of an FPGA image. In the latter | ||
188 | case, this function is called multiple times for successive chunks. This interface | ||
189 | is suitable for drivers which use PIO. | ||
190 | |||
191 | The .write_sg version behaves the same as .write except the input is a sg_table | ||
192 | scatter list. This interface is suitable for drivers which use DMA. | ||
193 | |||
194 | The .write_complete function is called after all the image has been written | ||
195 | to put the FPGA into operating mode. | ||
196 | |||
197 | The ops include a .state function which will read the hardware FPGA manager and | ||
198 | return a code of type enum fpga_mgr_states. It doesn't result in a change in | ||
199 | hardware state. | ||