1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2002
4 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
5 */
6
7 /* Generic FPGA support */
8 #include <common.h> /* core U-Boot definitions */
9 #include <init.h>
10 #include <log.h>
11 #include <xilinx.h> /* xilinx specific definitions */
12 #include <altera.h> /* altera specific definitions */
13 #include <lattice.h>
14 #include <dm/device_compat.h>
15
16 /* Local static data */
17 static int next_desc = FPGA_INVALID_DEVICE;
18 static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES];
19
20 /*
21 * fpga_no_sup
22 * 'no support' message function
23 */
fpga_no_sup(char * fn,char * msg)24 static void fpga_no_sup(char *fn, char *msg)
25 {
26 if (fn && msg)
27 printf("%s: No support for %s.\n", fn, msg);
28 else if (msg)
29 printf("No support for %s.\n", msg);
30 else
31 printf("No FPGA support!\n");
32 }
33
34
35 /* fpga_get_desc
36 * map a device number to a descriptor
37 */
fpga_get_desc(int devnum)38 const fpga_desc *const fpga_get_desc(int devnum)
39 {
40 fpga_desc *desc = (fpga_desc *)NULL;
41
42 if ((devnum >= 0) && (devnum < next_desc)) {
43 desc = &desc_table[devnum];
44 debug("%s: found fpga descriptor #%d @ 0x%p\n",
45 __func__, devnum, desc);
46 }
47
48 return desc;
49 }
50
51 /*
52 * fpga_validate
53 * generic parameter checking code
54 */
fpga_validate(int devnum,const void * buf,size_t bsize,char * fn)55 const fpga_desc *const fpga_validate(int devnum, const void *buf,
56 size_t bsize, char *fn)
57 {
58 const fpga_desc *desc = fpga_get_desc(devnum);
59
60 if (!desc)
61 printf("%s: Invalid device number %d\n", fn, devnum);
62
63 if (!buf) {
64 printf("%s: Null buffer.\n", fn);
65 return (fpga_desc * const)NULL;
66 }
67 return desc;
68 }
69
70 /*
71 * fpga_dev_info
72 * generic multiplexing code
73 */
fpga_dev_info(int devnum)74 static int fpga_dev_info(int devnum)
75 {
76 int ret_val = FPGA_FAIL; /* assume failure */
77 const fpga_desc * const desc = fpga_get_desc(devnum);
78
79 if (desc) {
80 debug("%s: Device Descriptor @ 0x%p\n",
81 __func__, desc->devdesc);
82
83 switch (desc->devtype) {
84 case fpga_xilinx:
85 #if defined(CONFIG_FPGA_XILINX)
86 printf("Xilinx Device\nDescriptor @ 0x%p\n", desc);
87 ret_val = xilinx_info(desc->devdesc);
88 #else
89 fpga_no_sup((char *)__func__, "Xilinx devices");
90 #endif
91 break;
92 case fpga_altera:
93 #if defined(CONFIG_FPGA_ALTERA)
94 printf("Altera Device\nDescriptor @ 0x%p\n", desc);
95 ret_val = altera_info(desc->devdesc);
96 #else
97 fpga_no_sup((char *)__func__, "Altera devices");
98 #endif
99 break;
100 case fpga_lattice:
101 #if defined(CONFIG_FPGA_LATTICE)
102 printf("Lattice Device\nDescriptor @ 0x%p\n", desc);
103 ret_val = lattice_info(desc->devdesc);
104 #else
105 fpga_no_sup((char *)__func__, "Lattice devices");
106 #endif
107 break;
108 default:
109 printf("%s: Invalid or unsupported device type %d\n",
110 __func__, desc->devtype);
111 }
112 } else {
113 printf("%s: Invalid device number %d\n", __func__, devnum);
114 }
115
116 return ret_val;
117 }
118
119 /*
120 * fpga_init is usually called from misc_init_r() and MUST be called
121 * before any of the other fpga functions are used.
122 */
fpga_init(void)123 void fpga_init(void)
124 {
125 next_desc = 0;
126 memset(desc_table, 0, sizeof(desc_table));
127
128 debug("%s\n", __func__);
129 }
130
131 /*
132 * fpga_count
133 * Basic interface function to get the current number of devices available.
134 */
fpga_count(void)135 int fpga_count(void)
136 {
137 return next_desc;
138 }
139
140 /*
141 * fpga_add
142 * Add the device descriptor to the device table.
143 */
fpga_add(fpga_type devtype,void * desc)144 int fpga_add(fpga_type devtype, void *desc)
145 {
146 int devnum = FPGA_INVALID_DEVICE;
147
148 if (!desc) {
149 printf("%s: NULL device descriptor\n", __func__);
150 return devnum;
151 }
152
153 if (next_desc < 0) {
154 printf("%s: FPGA support not initialized!\n", __func__);
155 } else if ((devtype > fpga_min_type) && (devtype < fpga_undefined)) {
156 if (next_desc < CONFIG_MAX_FPGA_DEVICES) {
157 devnum = next_desc;
158 desc_table[next_desc].devtype = devtype;
159 desc_table[next_desc++].devdesc = desc;
160 } else {
161 printf("%s: Exceeded Max FPGA device count\n",
162 __func__);
163 }
164 } else {
165 printf("%s: Unsupported FPGA type %d\n", __func__, devtype);
166 }
167
168 return devnum;
169 }
170
171 /*
172 * Return 1 if the fpga data is partial.
173 * This is only required for fpga drivers that support bitstream_type.
174 */
fpga_is_partial_data(int devnum,size_t img_len)175 int __weak fpga_is_partial_data(int devnum, size_t img_len)
176 {
177 return 0;
178 }
179
180 /*
181 * Convert bitstream data and load into the fpga
182 */
fpga_loadbitstream(int devnum,char * fpgadata,size_t size,bitstream_type bstype)183 int __weak fpga_loadbitstream(int devnum, char *fpgadata, size_t size,
184 bitstream_type bstype)
185 {
186 printf("Bitstream support not implemented for this FPGA device\n");
187 return FPGA_FAIL;
188 }
189
190 #if defined(CONFIG_CMD_FPGA_LOADFS)
fpga_fsload(int devnum,const void * buf,size_t size,fpga_fs_info * fpga_fsinfo)191 int fpga_fsload(int devnum, const void *buf, size_t size,
192 fpga_fs_info *fpga_fsinfo)
193 {
194 int ret_val = FPGA_FAIL; /* assume failure */
195 const fpga_desc *desc = fpga_validate(devnum, buf, size,
196 (char *)__func__);
197
198 if (desc) {
199 switch (desc->devtype) {
200 case fpga_xilinx:
201 #if defined(CONFIG_FPGA_XILINX)
202 ret_val = xilinx_loadfs(desc->devdesc, buf, size,
203 fpga_fsinfo);
204 #else
205 fpga_no_sup((char *)__func__, "Xilinx devices");
206 #endif
207 break;
208 default:
209 printf("%s: Invalid or unsupported device type %d\n",
210 __func__, desc->devtype);
211 }
212 }
213
214 return ret_val;
215 }
216 #endif
217
218 #if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)
fpga_loads(int devnum,const void * buf,size_t size,struct fpga_secure_info * fpga_sec_info)219 int fpga_loads(int devnum, const void *buf, size_t size,
220 struct fpga_secure_info *fpga_sec_info)
221 {
222 int ret_val = FPGA_FAIL;
223
224 const fpga_desc *desc = fpga_validate(devnum, buf, size,
225 (char *)__func__);
226
227 if (desc) {
228 switch (desc->devtype) {
229 case fpga_xilinx:
230 #if defined(CONFIG_FPGA_XILINX)
231 ret_val = xilinx_loads(desc->devdesc, buf, size,
232 fpga_sec_info);
233 #else
234 fpga_no_sup((char *)__func__, "Xilinx devices");
235 #endif
236 break;
237 default:
238 printf("%s: Invalid or unsupported device type %d\n",
239 __func__, desc->devtype);
240 }
241 }
242
243 return ret_val;
244 }
245 #endif
246
247 /*
248 * Generic multiplexing code
249 */
fpga_load(int devnum,const void * buf,size_t bsize,bitstream_type bstype,int flags)250 int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype,
251 int flags)
252 {
253 int ret_val = FPGA_FAIL; /* assume failure */
254 const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
255 (char *)__func__);
256
257 if (desc) {
258 switch (desc->devtype) {
259 case fpga_xilinx:
260 #if defined(CONFIG_FPGA_XILINX)
261 ret_val = xilinx_load(desc->devdesc, buf, bsize,
262 bstype, flags);
263 #else
264 fpga_no_sup((char *)__func__, "Xilinx devices");
265 #endif
266 break;
267 case fpga_altera:
268 #if defined(CONFIG_FPGA_ALTERA)
269 ret_val = altera_load(desc->devdesc, buf, bsize);
270 #else
271 fpga_no_sup((char *)__func__, "Altera devices");
272 #endif
273 break;
274 case fpga_lattice:
275 #if defined(CONFIG_FPGA_LATTICE)
276 ret_val = lattice_load(desc->devdesc, buf, bsize);
277 #else
278 fpga_no_sup((char *)__func__, "Lattice devices");
279 #endif
280 break;
281 default:
282 printf("%s: Invalid or unsupported device type %d\n",
283 __func__, desc->devtype);
284 }
285 }
286
287 return ret_val;
288 }
289
290 /*
291 * fpga_dump
292 * generic multiplexing code
293 */
fpga_dump(int devnum,const void * buf,size_t bsize)294 int fpga_dump(int devnum, const void *buf, size_t bsize)
295 {
296 int ret_val = FPGA_FAIL; /* assume failure */
297 const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
298 (char *)__func__);
299
300 if (desc) {
301 switch (desc->devtype) {
302 case fpga_xilinx:
303 #if defined(CONFIG_FPGA_XILINX)
304 ret_val = xilinx_dump(desc->devdesc, buf, bsize);
305 #else
306 fpga_no_sup((char *)__func__, "Xilinx devices");
307 #endif
308 break;
309 case fpga_altera:
310 #if defined(CONFIG_FPGA_ALTERA)
311 ret_val = altera_dump(desc->devdesc, buf, bsize);
312 #else
313 fpga_no_sup((char *)__func__, "Altera devices");
314 #endif
315 break;
316 case fpga_lattice:
317 #if defined(CONFIG_FPGA_LATTICE)
318 ret_val = lattice_dump(desc->devdesc, buf, bsize);
319 #else
320 fpga_no_sup((char *)__func__, "Lattice devices");
321 #endif
322 break;
323 default:
324 printf("%s: Invalid or unsupported device type %d\n",
325 __func__, desc->devtype);
326 }
327 }
328
329 return ret_val;
330 }
331
332 /*
333 * fpga_info
334 * front end to fpga_dev_info. If devnum is invalid, report on all
335 * available devices.
336 */
fpga_info(int devnum)337 int fpga_info(int devnum)
338 {
339 if (devnum == FPGA_INVALID_DEVICE) {
340 if (next_desc > 0) {
341 int dev;
342
343 for (dev = 0; dev < next_desc; dev++)
344 fpga_dev_info(dev);
345
346 return FPGA_SUCCESS;
347 } else {
348 printf("%s: No FPGA devices available.\n", __func__);
349 return FPGA_FAIL;
350 }
351 }
352
353 return fpga_dev_info(devnum);
354 }
355
356 #if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)
fpga_compatible2flag(int devnum,const char * compatible)357 int fpga_compatible2flag(int devnum, const char *compatible)
358 {
359 const fpga_desc * const desc = fpga_get_desc(devnum);
360
361 if (!desc)
362 return 0;
363
364 switch (desc->devtype) {
365 #if defined(CONFIG_FPGA_XILINX)
366 case fpga_xilinx:
367 {
368 xilinx_desc *xdesc = (xilinx_desc *)desc->devdesc;
369
370 if (xdesc->operations && xdesc->operations->str2flag)
371 return xdesc->operations->str2flag(xdesc, compatible);
372 }
373 #endif
374 default:
375 break;
376 }
377
378 return 0;
379 }
380 #endif
381