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