]>
Commit | Line | Data |
---|---|---|
e2211743 WD |
1 | /* |
2 | * (C) Copyright 2002 | |
3 | * Rich Ireland, Enterasys Networks, [email protected]. | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | * | |
23 | */ | |
24 | ||
f6555d90 | 25 | /* Generic FPGA support */ |
e2211743 WD |
26 | #include <common.h> /* core U-Boot definitions */ |
27 | #include <xilinx.h> /* xilinx specific definitions */ | |
28 | #include <altera.h> /* altera specific definitions */ | |
3b8ac464 | 29 | #include <lattice.h> |
e2211743 | 30 | |
e2211743 WD |
31 | /* Local definitions */ |
32 | #ifndef CONFIG_MAX_FPGA_DEVICES | |
33 | #define CONFIG_MAX_FPGA_DEVICES 5 | |
34 | #endif | |
35 | ||
e2211743 | 36 | /* Local static data */ |
e2211743 WD |
37 | static int next_desc = FPGA_INVALID_DEVICE; |
38 | static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES]; | |
39 | ||
f6555d90 MS |
40 | /* |
41 | * fpga_no_sup | |
e2211743 WD |
42 | * 'no support' message function |
43 | */ | |
f6555d90 | 44 | static void fpga_no_sup(char *fn, char *msg) |
e2211743 | 45 | { |
f6555d90 MS |
46 | if (fn && msg) |
47 | printf("%s: No support for %s.\n", fn, msg); | |
48 | else if (msg) | |
49 | printf("No support for %s.\n", msg); | |
50 | else | |
51 | printf("No FPGA suport!\n"); | |
e2211743 WD |
52 | } |
53 | ||
54 | ||
55 | /* fpga_get_desc | |
56 | * map a device number to a descriptor | |
57 | */ | |
f6555d90 | 58 | static const fpga_desc *const fpga_get_desc(int devnum) |
e2211743 | 59 | { |
f6555d90 | 60 | fpga_desc *desc = (fpga_desc *)NULL; |
e2211743 | 61 | |
f6555d90 | 62 | if ((devnum >= 0) && (devnum < next_desc)) { |
e2211743 | 63 | desc = &desc_table[devnum]; |
f6555d90 MS |
64 | debug("%s: found fpga descriptor #%d @ 0x%p\n", |
65 | __func__, devnum, desc); | |
e2211743 WD |
66 | } |
67 | ||
68 | return desc; | |
69 | } | |
70 | ||
f6555d90 MS |
71 | /* |
72 | * fpga_validate | |
e2211743 WD |
73 | * generic parameter checking code |
74 | */ | |
6631db47 MS |
75 | const fpga_desc *const fpga_validate(int devnum, const void *buf, |
76 | size_t bsize, char *fn) | |
e2211743 | 77 | { |
f6555d90 | 78 | const fpga_desc *desc = fpga_get_desc(devnum); |
e2211743 | 79 | |
f6555d90 MS |
80 | if (!desc) |
81 | printf("%s: Invalid device number %d\n", fn, devnum); | |
e2211743 | 82 | |
f6555d90 MS |
83 | if (!buf) { |
84 | printf("%s: Null buffer.\n", fn); | |
e2211743 WD |
85 | return (fpga_desc * const)NULL; |
86 | } | |
e2211743 WD |
87 | return desc; |
88 | } | |
89 | ||
f6555d90 MS |
90 | /* |
91 | * fpga_dev_info | |
e2211743 WD |
92 | * generic multiplexing code |
93 | */ | |
f6555d90 | 94 | static int fpga_dev_info(int devnum) |
e2211743 | 95 | { |
f6555d90 MS |
96 | int ret_val = FPGA_FAIL; /* assume failure */ |
97 | const fpga_desc * const desc = fpga_get_desc(devnum); | |
e2211743 | 98 | |
f6555d90 MS |
99 | if (desc) { |
100 | debug("%s: Device Descriptor @ 0x%p\n", | |
101 | __func__, desc->devdesc); | |
e2211743 | 102 | |
f6555d90 | 103 | switch (desc->devtype) { |
e2211743 | 104 | case fpga_xilinx: |
0133502e | 105 | #if defined(CONFIG_FPGA_XILINX) |
f6555d90 MS |
106 | printf("Xilinx Device\nDescriptor @ 0x%p\n", desc); |
107 | ret_val = xilinx_info(desc->devdesc); | |
e2211743 | 108 | #else |
f6555d90 | 109 | fpga_no_sup((char *)__func__, "Xilinx devices"); |
e2211743 WD |
110 | #endif |
111 | break; | |
112 | case fpga_altera: | |
0133502e | 113 | #if defined(CONFIG_FPGA_ALTERA) |
f6555d90 MS |
114 | printf("Altera Device\nDescriptor @ 0x%p\n", desc); |
115 | ret_val = altera_info(desc->devdesc); | |
e2211743 | 116 | #else |
f6555d90 | 117 | fpga_no_sup((char *)__func__, "Altera devices"); |
e2211743 WD |
118 | #endif |
119 | break; | |
3b8ac464 | 120 | case fpga_lattice: |
439f6f7e | 121 | #if defined(CONFIG_FPGA_LATTICE) |
3b8ac464 SB |
122 | printf("Lattice Device\nDescriptor @ 0x%p\n", desc); |
123 | ret_val = lattice_info(desc->devdesc); | |
439f6f7e | 124 | #else |
f6555d90 | 125 | fpga_no_sup((char *)__func__, "Lattice devices"); |
439f6f7e | 126 | #endif |
3b8ac464 | 127 | break; |
e2211743 | 128 | default: |
f6555d90 MS |
129 | printf("%s: Invalid or unsupported device type %d\n", |
130 | __func__, desc->devtype); | |
e2211743 WD |
131 | } |
132 | } else { | |
f6555d90 | 133 | printf("%s: Invalid device number %d\n", __func__, devnum); |
e2211743 WD |
134 | } |
135 | ||
136 | return ret_val; | |
137 | } | |
138 | ||
f6555d90 MS |
139 | /* |
140 | * fgpa_init is usually called from misc_init_r() and MUST be called | |
e2211743 WD |
141 | * before any of the other fpga functions are used. |
142 | */ | |
6385b281 | 143 | void fpga_init(void) |
e2211743 | 144 | { |
e2211743 | 145 | next_desc = 0; |
f6555d90 | 146 | memset(desc_table, 0, sizeof(desc_table)); |
e2211743 | 147 | |
ee976c1b | 148 | debug("%s\n", __func__); |
e2211743 WD |
149 | } |
150 | ||
f6555d90 MS |
151 | /* |
152 | * fpga_count | |
e2211743 WD |
153 | * Basic interface function to get the current number of devices available. |
154 | */ | |
f6555d90 | 155 | int fpga_count(void) |
e2211743 WD |
156 | { |
157 | return next_desc; | |
158 | } | |
159 | ||
f6555d90 MS |
160 | /* |
161 | * fpga_add | |
6385b281 | 162 | * Add the device descriptor to the device table. |
e2211743 | 163 | */ |
f6555d90 | 164 | int fpga_add(fpga_type devtype, void *desc) |
e2211743 WD |
165 | { |
166 | int devnum = FPGA_INVALID_DEVICE; | |
167 | ||
f6555d90 MS |
168 | if (next_desc < 0) { |
169 | printf("%s: FPGA support not initialized!\n", __func__); | |
170 | } else if ((devtype > fpga_min_type) && (devtype < fpga_undefined)) { | |
171 | if (desc) { | |
172 | if (next_desc < CONFIG_MAX_FPGA_DEVICES) { | |
6385b281 PT |
173 | devnum = next_desc; |
174 | desc_table[next_desc].devtype = devtype; | |
175 | desc_table[next_desc++].devdesc = desc; | |
e2211743 | 176 | } else { |
f6555d90 MS |
177 | printf("%s: Exceeded Max FPGA device count\n", |
178 | __func__); | |
e2211743 WD |
179 | } |
180 | } else { | |
f6555d90 | 181 | printf("%s: NULL device descriptor\n", __func__); |
e2211743 WD |
182 | } |
183 | } else { | |
f6555d90 | 184 | printf("%s: Unsupported FPGA type %d\n", __func__, devtype); |
e2211743 WD |
185 | } |
186 | ||
187 | return devnum; | |
188 | } | |
189 | ||
52c20644 MS |
190 | /* |
191 | * Convert bitstream data and load into the fpga | |
192 | */ | |
23f4bd75 | 193 | int __weak fpga_loadbitstream(int devnum, char *fpgadata, size_t size) |
52c20644 MS |
194 | { |
195 | printf("Bitstream support not implemented for this FPGA device\n"); | |
196 | return FPGA_FAIL; | |
197 | } | |
198 | ||
e2211743 | 199 | /* |
f6555d90 | 200 | * Generic multiplexing code |
e2211743 | 201 | */ |
e6a857da | 202 | int fpga_load(int devnum, const void *buf, size_t bsize) |
e2211743 WD |
203 | { |
204 | int ret_val = FPGA_FAIL; /* assume failure */ | |
f6555d90 MS |
205 | const fpga_desc *desc = fpga_validate(devnum, buf, bsize, |
206 | (char *)__func__); | |
e2211743 | 207 | |
f6555d90 MS |
208 | if (desc) { |
209 | switch (desc->devtype) { | |
e2211743 | 210 | case fpga_xilinx: |
0133502e | 211 | #if defined(CONFIG_FPGA_XILINX) |
f6555d90 | 212 | ret_val = xilinx_load(desc->devdesc, buf, bsize); |
e2211743 | 213 | #else |
f6555d90 | 214 | fpga_no_sup((char *)__func__, "Xilinx devices"); |
e2211743 WD |
215 | #endif |
216 | break; | |
217 | case fpga_altera: | |
0133502e | 218 | #if defined(CONFIG_FPGA_ALTERA) |
f6555d90 | 219 | ret_val = altera_load(desc->devdesc, buf, bsize); |
e2211743 | 220 | #else |
f6555d90 | 221 | fpga_no_sup((char *)__func__, "Altera devices"); |
e2211743 WD |
222 | #endif |
223 | break; | |
3b8ac464 | 224 | case fpga_lattice: |
439f6f7e | 225 | #if defined(CONFIG_FPGA_LATTICE) |
3b8ac464 | 226 | ret_val = lattice_load(desc->devdesc, buf, bsize); |
439f6f7e | 227 | #else |
f6555d90 | 228 | fpga_no_sup((char *)__func__, "Lattice devices"); |
439f6f7e | 229 | #endif |
3b8ac464 | 230 | break; |
e2211743 | 231 | default: |
f6555d90 MS |
232 | printf("%s: Invalid or unsupported device type %d\n", |
233 | __func__, desc->devtype); | |
e2211743 WD |
234 | } |
235 | } | |
236 | ||
237 | return ret_val; | |
238 | } | |
239 | ||
f6555d90 MS |
240 | /* |
241 | * fpga_dump | |
e2211743 WD |
242 | * generic multiplexing code |
243 | */ | |
e6a857da | 244 | int fpga_dump(int devnum, const void *buf, size_t bsize) |
e2211743 WD |
245 | { |
246 | int ret_val = FPGA_FAIL; /* assume failure */ | |
f6555d90 MS |
247 | const fpga_desc *desc = fpga_validate(devnum, buf, bsize, |
248 | (char *)__func__); | |
e2211743 | 249 | |
f6555d90 MS |
250 | if (desc) { |
251 | switch (desc->devtype) { | |
e2211743 | 252 | case fpga_xilinx: |
0133502e | 253 | #if defined(CONFIG_FPGA_XILINX) |
f6555d90 | 254 | ret_val = xilinx_dump(desc->devdesc, buf, bsize); |
e2211743 | 255 | #else |
f6555d90 | 256 | fpga_no_sup((char *)__func__, "Xilinx devices"); |
e2211743 WD |
257 | #endif |
258 | break; | |
259 | case fpga_altera: | |
0133502e | 260 | #if defined(CONFIG_FPGA_ALTERA) |
f6555d90 | 261 | ret_val = altera_dump(desc->devdesc, buf, bsize); |
e2211743 | 262 | #else |
f6555d90 | 263 | fpga_no_sup((char *)__func__, "Altera devices"); |
e2211743 WD |
264 | #endif |
265 | break; | |
3b8ac464 | 266 | case fpga_lattice: |
439f6f7e | 267 | #if defined(CONFIG_FPGA_LATTICE) |
3b8ac464 | 268 | ret_val = lattice_dump(desc->devdesc, buf, bsize); |
439f6f7e | 269 | #else |
f6555d90 | 270 | fpga_no_sup((char *)__func__, "Lattice devices"); |
439f6f7e | 271 | #endif |
3b8ac464 | 272 | break; |
e2211743 | 273 | default: |
f6555d90 MS |
274 | printf("%s: Invalid or unsupported device type %d\n", |
275 | __func__, desc->devtype); | |
e2211743 WD |
276 | } |
277 | } | |
278 | ||
279 | return ret_val; | |
280 | } | |
281 | ||
f6555d90 MS |
282 | /* |
283 | * fpga_info | |
e2211743 WD |
284 | * front end to fpga_dev_info. If devnum is invalid, report on all |
285 | * available devices. | |
286 | */ | |
f6555d90 | 287 | int fpga_info(int devnum) |
e2211743 | 288 | { |
f6555d90 MS |
289 | if (devnum == FPGA_INVALID_DEVICE) { |
290 | if (next_desc > 0) { | |
e2211743 WD |
291 | int dev; |
292 | ||
f6555d90 MS |
293 | for (dev = 0; dev < next_desc; dev++) |
294 | fpga_dev_info(dev); | |
295 | ||
e2211743 WD |
296 | return FPGA_SUCCESS; |
297 | } else { | |
f6555d90 | 298 | printf("%s: No FPGA devices available.\n", __func__); |
e2211743 WD |
299 | return FPGA_FAIL; |
300 | } | |
301 | } | |
e2211743 | 302 | |
f6555d90 MS |
303 | return fpga_dev_info(devnum); |
304 | } |