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