blob: 38ba6c21ea2beeb733704196dfb56e6df9107b35 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
wdenke2211742002-11-02 23:30:20 +00002/*
3 * (C) Copyright 2002
4 * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
wdenke2211742002-11-02 23:30:20 +00005 */
6
Michal Simek5125ba12013-04-26 08:46:56 +02007/* Generic FPGA support */
Simon Glass97589732020-05-10 11:40:02 -06008#include <init.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
wdenke2211742002-11-02 23:30:20 +000010#include <xilinx.h> /* xilinx specific definitions */
11#include <altera.h> /* altera specific definitions */
Stefano Babicec65c592010-06-29 11:47:48 +020012#include <lattice.h>
Simon Glass9bc15642020-02-03 07:36:16 -070013#include <dm/device_compat.h>
wdenke2211742002-11-02 23:30:20 +000014
wdenke2211742002-11-02 23:30:20 +000015/* Local static data */
wdenke2211742002-11-02 23:30:20 +000016static int next_desc = FPGA_INVALID_DEVICE;
17static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES];
18
Michal Simek5125ba12013-04-26 08:46:56 +020019/*
20 * fpga_no_sup
wdenke2211742002-11-02 23:30:20 +000021 * 'no support' message function
22 */
Michal Simek5125ba12013-04-26 08:46:56 +020023static void fpga_no_sup(char *fn, char *msg)
wdenke2211742002-11-02 23:30:20 +000024{
Michal Simek5125ba12013-04-26 08:46:56 +020025 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
Robert P. J. Day8d56db92016-07-15 13:44:45 -040030 printf("No FPGA support!\n");
wdenke2211742002-11-02 23:30:20 +000031}
32
33
34/* fpga_get_desc
35 * map a device number to a descriptor
36 */
Michal Simekfbadb762015-01-13 16:09:53 +010037const fpga_desc *const fpga_get_desc(int devnum)
wdenke2211742002-11-02 23:30:20 +000038{
Michal Simek5125ba12013-04-26 08:46:56 +020039 fpga_desc *desc = (fpga_desc *)NULL;
wdenke2211742002-11-02 23:30:20 +000040
Michal Simek5125ba12013-04-26 08:46:56 +020041 if ((devnum >= 0) && (devnum < next_desc)) {
wdenke2211742002-11-02 23:30:20 +000042 desc = &desc_table[devnum];
Michal Simek5125ba12013-04-26 08:46:56 +020043 debug("%s: found fpga descriptor #%d @ 0x%p\n",
44 __func__, devnum, desc);
wdenke2211742002-11-02 23:30:20 +000045 }
46
47 return desc;
48}
49
Michal Simek5125ba12013-04-26 08:46:56 +020050/*
51 * fpga_validate
wdenke2211742002-11-02 23:30:20 +000052 * generic parameter checking code
53 */
Michal Simek6ff890d2013-04-26 15:04:48 +020054const fpga_desc *const fpga_validate(int devnum, const void *buf,
55 size_t bsize, char *fn)
wdenke2211742002-11-02 23:30:20 +000056{
Michal Simek5125ba12013-04-26 08:46:56 +020057 const fpga_desc *desc = fpga_get_desc(devnum);
wdenke2211742002-11-02 23:30:20 +000058
Michal Simek5125ba12013-04-26 08:46:56 +020059 if (!desc)
60 printf("%s: Invalid device number %d\n", fn, devnum);
wdenke2211742002-11-02 23:30:20 +000061
Michal Simek5125ba12013-04-26 08:46:56 +020062 if (!buf) {
63 printf("%s: Null buffer.\n", fn);
wdenke2211742002-11-02 23:30:20 +000064 return (fpga_desc * const)NULL;
65 }
wdenke2211742002-11-02 23:30:20 +000066 return desc;
67}
68
Michal Simek5125ba12013-04-26 08:46:56 +020069/*
70 * fpga_dev_info
wdenke2211742002-11-02 23:30:20 +000071 * generic multiplexing code
72 */
Michal Simek5125ba12013-04-26 08:46:56 +020073static int fpga_dev_info(int devnum)
wdenke2211742002-11-02 23:30:20 +000074{
Michal Simek5125ba12013-04-26 08:46:56 +020075 int ret_val = FPGA_FAIL; /* assume failure */
76 const fpga_desc * const desc = fpga_get_desc(devnum);
wdenke2211742002-11-02 23:30:20 +000077
Michal Simek5125ba12013-04-26 08:46:56 +020078 if (desc) {
79 debug("%s: Device Descriptor @ 0x%p\n",
80 __func__, desc->devdesc);
wdenke2211742002-11-02 23:30:20 +000081
Michal Simek5125ba12013-04-26 08:46:56 +020082 switch (desc->devtype) {
wdenke2211742002-11-02 23:30:20 +000083 case fpga_xilinx:
Matthias Fuchsa4400872007-12-27 17:12:34 +010084#if defined(CONFIG_FPGA_XILINX)
Michal Simek5125ba12013-04-26 08:46:56 +020085 printf("Xilinx Device\nDescriptor @ 0x%p\n", desc);
86 ret_val = xilinx_info(desc->devdesc);
wdenke2211742002-11-02 23:30:20 +000087#else
Michal Simek5125ba12013-04-26 08:46:56 +020088 fpga_no_sup((char *)__func__, "Xilinx devices");
wdenke2211742002-11-02 23:30:20 +000089#endif
90 break;
91 case fpga_altera:
Matthias Fuchsa4400872007-12-27 17:12:34 +010092#if defined(CONFIG_FPGA_ALTERA)
Michal Simek5125ba12013-04-26 08:46:56 +020093 printf("Altera Device\nDescriptor @ 0x%p\n", desc);
94 ret_val = altera_info(desc->devdesc);
wdenke2211742002-11-02 23:30:20 +000095#else
Michal Simek5125ba12013-04-26 08:46:56 +020096 fpga_no_sup((char *)__func__, "Altera devices");
wdenke2211742002-11-02 23:30:20 +000097#endif
98 break;
Stefano Babicec65c592010-06-29 11:47:48 +020099 case fpga_lattice:
Wolfgang Denkace143a2010-10-18 21:32:14 +0200100#if defined(CONFIG_FPGA_LATTICE)
Stefano Babicec65c592010-06-29 11:47:48 +0200101 printf("Lattice Device\nDescriptor @ 0x%p\n", desc);
102 ret_val = lattice_info(desc->devdesc);
Wolfgang Denkace143a2010-10-18 21:32:14 +0200103#else
Michal Simek5125ba12013-04-26 08:46:56 +0200104 fpga_no_sup((char *)__func__, "Lattice devices");
Wolfgang Denkace143a2010-10-18 21:32:14 +0200105#endif
Stefano Babicec65c592010-06-29 11:47:48 +0200106 break;
wdenke2211742002-11-02 23:30:20 +0000107 default:
Michal Simek5125ba12013-04-26 08:46:56 +0200108 printf("%s: Invalid or unsupported device type %d\n",
109 __func__, desc->devtype);
wdenke2211742002-11-02 23:30:20 +0000110 }
111 } else {
Michal Simek5125ba12013-04-26 08:46:56 +0200112 printf("%s: Invalid device number %d\n", __func__, devnum);
wdenke2211742002-11-02 23:30:20 +0000113 }
114
115 return ret_val;
116}
117
Michal Simek5125ba12013-04-26 08:46:56 +0200118/*
Michal Simekb563a6b2016-05-17 14:32:00 +0200119 * fpga_init is usually called from misc_init_r() and MUST be called
wdenke2211742002-11-02 23:30:20 +0000120 * before any of the other fpga functions are used.
121 */
Peter Tysercf8582c2009-09-21 11:20:32 -0500122void fpga_init(void)
wdenke2211742002-11-02 23:30:20 +0000123{
wdenke2211742002-11-02 23:30:20 +0000124 next_desc = 0;
Michal Simek5125ba12013-04-26 08:46:56 +0200125 memset(desc_table, 0, sizeof(desc_table));
wdenke2211742002-11-02 23:30:20 +0000126
Michal Simekaefbf8f2013-04-26 09:38:26 +0200127 debug("%s\n", __func__);
wdenke2211742002-11-02 23:30:20 +0000128}
129
Michal Simek5125ba12013-04-26 08:46:56 +0200130/*
131 * fpga_count
wdenke2211742002-11-02 23:30:20 +0000132 * Basic interface function to get the current number of devices available.
133 */
Michal Simek5125ba12013-04-26 08:46:56 +0200134int fpga_count(void)
wdenke2211742002-11-02 23:30:20 +0000135{
136 return next_desc;
137}
138
Michal Simek5125ba12013-04-26 08:46:56 +0200139/*
140 * fpga_add
Peter Tysercf8582c2009-09-21 11:20:32 -0500141 * Add the device descriptor to the device table.
wdenke2211742002-11-02 23:30:20 +0000142 */
Michal Simek5125ba12013-04-26 08:46:56 +0200143int fpga_add(fpga_type devtype, void *desc)
wdenke2211742002-11-02 23:30:20 +0000144{
145 int devnum = FPGA_INVALID_DEVICE;
146
Michal Simek3529c112018-01-26 13:17:04 +0100147 if (!desc) {
148 printf("%s: NULL device descriptor\n", __func__);
149 return devnum;
150 }
151
Michal Simek5125ba12013-04-26 08:46:56 +0200152 if (next_desc < 0) {
153 printf("%s: FPGA support not initialized!\n", __func__);
154 } else if ((devtype > fpga_min_type) && (devtype < fpga_undefined)) {
Michal Simek3529c112018-01-26 13:17:04 +0100155 if (next_desc < CONFIG_MAX_FPGA_DEVICES) {
156 devnum = next_desc;
157 desc_table[next_desc].devtype = devtype;
158 desc_table[next_desc++].devdesc = desc;
wdenke2211742002-11-02 23:30:20 +0000159 } else {
Michal Simek3529c112018-01-26 13:17:04 +0100160 printf("%s: Exceeded Max FPGA device count\n",
161 __func__);
wdenke2211742002-11-02 23:30:20 +0000162 }
163 } else {
Michal Simek5125ba12013-04-26 08:46:56 +0200164 printf("%s: Unsupported FPGA type %d\n", __func__, devtype);
wdenke2211742002-11-02 23:30:20 +0000165 }
166
167 return devnum;
168}
169
170/*
Goldschmidt Simon9179c812017-11-10 14:17:41 +0000171 * Return 1 if the fpga data is partial.
172 * This is only required for fpga drivers that support bitstream_type.
173 */
174int __weak fpga_is_partial_data(int devnum, size_t img_len)
175{
176 return 0;
177}
178
179/*
Michal Simekcd5a1cf2013-04-26 13:12:07 +0200180 * Convert bitstream data and load into the fpga
181 */
Michal Simek14663652014-05-02 14:09:30 +0200182int __weak fpga_loadbitstream(int devnum, char *fpgadata, size_t size,
183 bitstream_type bstype)
Michal Simekcd5a1cf2013-04-26 13:12:07 +0200184{
185 printf("Bitstream support not implemented for this FPGA device\n");
186 return FPGA_FAIL;
187}
188
Siva Durga Prasad Paladugu9112b4c2014-03-14 16:35:37 +0530189#if defined(CONFIG_CMD_FPGA_LOADFS)
190int fpga_fsload(int devnum, const void *buf, size_t size,
191 fpga_fs_info *fpga_fsinfo)
192{
193 int ret_val = FPGA_FAIL; /* assume failure */
194 const fpga_desc *desc = fpga_validate(devnum, buf, size,
195 (char *)__func__);
196
197 if (desc) {
198 switch (desc->devtype) {
199 case fpga_xilinx:
200#if defined(CONFIG_FPGA_XILINX)
201 ret_val = xilinx_loadfs(desc->devdesc, buf, size,
202 fpga_fsinfo);
203#else
204 fpga_no_sup((char *)__func__, "Xilinx devices");
205#endif
206 break;
207 default:
208 printf("%s: Invalid or unsupported device type %d\n",
209 __func__, desc->devtype);
210 }
211 }
212
213 return ret_val;
214}
215#endif
216
Oleksandr Suvorovfbe31bb2022-07-22 17:16:02 +0300217#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)
Siva Durga Prasad Paladugucce0cb02018-05-31 15:10:22 +0530218int fpga_loads(int devnum, const void *buf, size_t size,
219 struct fpga_secure_info *fpga_sec_info)
220{
221 int ret_val = FPGA_FAIL;
222
223 const fpga_desc *desc = fpga_validate(devnum, buf, size,
224 (char *)__func__);
225
226 if (desc) {
227 switch (desc->devtype) {
228 case fpga_xilinx:
229#if defined(CONFIG_FPGA_XILINX)
230 ret_val = xilinx_loads(desc->devdesc, buf, size,
231 fpga_sec_info);
232#else
233 fpga_no_sup((char *)__func__, "Xilinx devices");
234#endif
235 break;
236 default:
237 printf("%s: Invalid or unsupported device type %d\n",
238 __func__, desc->devtype);
239 }
240 }
241
242 return ret_val;
243}
244#endif
245
Christian Taedckedf369812023-07-20 09:27:24 +0200246static int fpga_load_event_notify(const void *buf, size_t bsize, int result)
247{
248 if (CONFIG_IS_ENABLED(EVENT)) {
249 struct event_fpga_load load = {
250 .buf = buf,
251 .bsize = bsize,
252 .result = result
253 };
254
255 return event_notify(EVT_FPGA_LOAD, &load, sizeof(load));
256 }
257
258 return 0;
259}
260
Michal Simekcd5a1cf2013-04-26 13:12:07 +0200261/*
Michal Simek5125ba12013-04-26 08:46:56 +0200262 * Generic multiplexing code
wdenke2211742002-11-02 23:30:20 +0000263 */
Oleksandr Suvorov4ff163d2022-07-22 17:16:07 +0300264int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype,
265 int flags)
wdenke2211742002-11-02 23:30:20 +0000266{
267 int ret_val = FPGA_FAIL; /* assume failure */
Christian Taedckedf369812023-07-20 09:27:24 +0200268 int ret_notify;
Michal Simek5125ba12013-04-26 08:46:56 +0200269 const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
270 (char *)__func__);
wdenke2211742002-11-02 23:30:20 +0000271
Michal Simek5125ba12013-04-26 08:46:56 +0200272 if (desc) {
273 switch (desc->devtype) {
wdenke2211742002-11-02 23:30:20 +0000274 case fpga_xilinx:
Matthias Fuchsa4400872007-12-27 17:12:34 +0100275#if defined(CONFIG_FPGA_XILINX)
Michal Simek14663652014-05-02 14:09:30 +0200276 ret_val = xilinx_load(desc->devdesc, buf, bsize,
Oleksandr Suvorov4ff163d2022-07-22 17:16:07 +0300277 bstype, flags);
wdenke2211742002-11-02 23:30:20 +0000278#else
Michal Simek5125ba12013-04-26 08:46:56 +0200279 fpga_no_sup((char *)__func__, "Xilinx devices");
wdenke2211742002-11-02 23:30:20 +0000280#endif
281 break;
282 case fpga_altera:
Matthias Fuchsa4400872007-12-27 17:12:34 +0100283#if defined(CONFIG_FPGA_ALTERA)
Michal Simek5125ba12013-04-26 08:46:56 +0200284 ret_val = altera_load(desc->devdesc, buf, bsize);
wdenke2211742002-11-02 23:30:20 +0000285#else
Michal Simek5125ba12013-04-26 08:46:56 +0200286 fpga_no_sup((char *)__func__, "Altera devices");
wdenke2211742002-11-02 23:30:20 +0000287#endif
288 break;
Stefano Babicec65c592010-06-29 11:47:48 +0200289 case fpga_lattice:
Wolfgang Denkace143a2010-10-18 21:32:14 +0200290#if defined(CONFIG_FPGA_LATTICE)
Stefano Babicec65c592010-06-29 11:47:48 +0200291 ret_val = lattice_load(desc->devdesc, buf, bsize);
Wolfgang Denkace143a2010-10-18 21:32:14 +0200292#else
Michal Simek5125ba12013-04-26 08:46:56 +0200293 fpga_no_sup((char *)__func__, "Lattice devices");
Wolfgang Denkace143a2010-10-18 21:32:14 +0200294#endif
Stefano Babicec65c592010-06-29 11:47:48 +0200295 break;
wdenke2211742002-11-02 23:30:20 +0000296 default:
Michal Simek5125ba12013-04-26 08:46:56 +0200297 printf("%s: Invalid or unsupported device type %d\n",
298 __func__, desc->devtype);
wdenke2211742002-11-02 23:30:20 +0000299 }
300 }
301
Christian Taedckedf369812023-07-20 09:27:24 +0200302 ret_notify = fpga_load_event_notify(buf, bsize, ret_val);
303 if (ret_notify)
304 return ret_notify;
305
wdenke2211742002-11-02 23:30:20 +0000306 return ret_val;
307}
308
Michal Simek5125ba12013-04-26 08:46:56 +0200309/*
310 * fpga_dump
wdenke2211742002-11-02 23:30:20 +0000311 * generic multiplexing code
312 */
Wolfgang Denk74f9b382011-07-30 13:33:49 +0000313int fpga_dump(int devnum, const void *buf, size_t bsize)
wdenke2211742002-11-02 23:30:20 +0000314{
315 int ret_val = FPGA_FAIL; /* assume failure */
Michal Simek5125ba12013-04-26 08:46:56 +0200316 const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
317 (char *)__func__);
wdenke2211742002-11-02 23:30:20 +0000318
Michal Simek5125ba12013-04-26 08:46:56 +0200319 if (desc) {
320 switch (desc->devtype) {
wdenke2211742002-11-02 23:30:20 +0000321 case fpga_xilinx:
Matthias Fuchsa4400872007-12-27 17:12:34 +0100322#if defined(CONFIG_FPGA_XILINX)
Michal Simek5125ba12013-04-26 08:46:56 +0200323 ret_val = xilinx_dump(desc->devdesc, buf, bsize);
wdenke2211742002-11-02 23:30:20 +0000324#else
Michal Simek5125ba12013-04-26 08:46:56 +0200325 fpga_no_sup((char *)__func__, "Xilinx devices");
wdenke2211742002-11-02 23:30:20 +0000326#endif
327 break;
328 case fpga_altera:
Matthias Fuchsa4400872007-12-27 17:12:34 +0100329#if defined(CONFIG_FPGA_ALTERA)
Michal Simek5125ba12013-04-26 08:46:56 +0200330 ret_val = altera_dump(desc->devdesc, buf, bsize);
wdenke2211742002-11-02 23:30:20 +0000331#else
Michal Simek5125ba12013-04-26 08:46:56 +0200332 fpga_no_sup((char *)__func__, "Altera devices");
wdenke2211742002-11-02 23:30:20 +0000333#endif
334 break;
Stefano Babicec65c592010-06-29 11:47:48 +0200335 case fpga_lattice:
Wolfgang Denkace143a2010-10-18 21:32:14 +0200336#if defined(CONFIG_FPGA_LATTICE)
Stefano Babicec65c592010-06-29 11:47:48 +0200337 ret_val = lattice_dump(desc->devdesc, buf, bsize);
Wolfgang Denkace143a2010-10-18 21:32:14 +0200338#else
Michal Simek5125ba12013-04-26 08:46:56 +0200339 fpga_no_sup((char *)__func__, "Lattice devices");
Wolfgang Denkace143a2010-10-18 21:32:14 +0200340#endif
Stefano Babicec65c592010-06-29 11:47:48 +0200341 break;
wdenke2211742002-11-02 23:30:20 +0000342 default:
Michal Simek5125ba12013-04-26 08:46:56 +0200343 printf("%s: Invalid or unsupported device type %d\n",
344 __func__, desc->devtype);
wdenke2211742002-11-02 23:30:20 +0000345 }
346 }
347
348 return ret_val;
349}
350
Michal Simek5125ba12013-04-26 08:46:56 +0200351/*
352 * fpga_info
wdenke2211742002-11-02 23:30:20 +0000353 * front end to fpga_dev_info. If devnum is invalid, report on all
354 * available devices.
355 */
Michal Simek5125ba12013-04-26 08:46:56 +0200356int fpga_info(int devnum)
wdenke2211742002-11-02 23:30:20 +0000357{
Michal Simek5125ba12013-04-26 08:46:56 +0200358 if (devnum == FPGA_INVALID_DEVICE) {
359 if (next_desc > 0) {
wdenke2211742002-11-02 23:30:20 +0000360 int dev;
361
Michal Simek5125ba12013-04-26 08:46:56 +0200362 for (dev = 0; dev < next_desc; dev++)
363 fpga_dev_info(dev);
364
wdenke2211742002-11-02 23:30:20 +0000365 return FPGA_SUCCESS;
366 } else {
Michal Simek5125ba12013-04-26 08:46:56 +0200367 printf("%s: No FPGA devices available.\n", __func__);
wdenke2211742002-11-02 23:30:20 +0000368 return FPGA_FAIL;
369 }
370 }
wdenke2211742002-11-02 23:30:20 +0000371
Michal Simek5125ba12013-04-26 08:46:56 +0200372 return fpga_dev_info(devnum);
373}
Oleksandr Suvorova4d95932022-07-22 17:16:08 +0300374
375#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)
376int fpga_compatible2flag(int devnum, const char *compatible)
377{
378 const fpga_desc * const desc = fpga_get_desc(devnum);
379
380 if (!desc)
381 return 0;
382
383 switch (desc->devtype) {
384#if defined(CONFIG_FPGA_XILINX)
385 case fpga_xilinx:
386 {
387 xilinx_desc *xdesc = (xilinx_desc *)desc->devdesc;
388
389 if (xdesc->operations && xdesc->operations->str2flag)
390 return xdesc->operations->str2flag(xdesc, compatible);
391 }
392#endif
393 default:
394 break;
395 }
396
397 return 0;
398}
399#endif