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