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