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