Home | History | Annotate | Download | only in fpga
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2002
      4  * Rich Ireland, Enterasys Networks, rireland (at) 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 #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
    221 int fpga_loads(int devnum, const void *buf, size_t size,
    222 	       struct fpga_secure_info *fpga_sec_info)
    223 {
    224 	int ret_val = FPGA_FAIL;
    225 
    226 	const fpga_desc *desc = fpga_validate(devnum, buf, size,
    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_loads(desc->devdesc, buf, size,
    234 					       fpga_sec_info);
    235 #else
    236 			fpga_no_sup((char *)__func__, "Xilinx devices");
    237 #endif
    238 			break;
    239 		default:
    240 			printf("%s: Invalid or unsupported device type %d\n",
    241 			       __func__, desc->devtype);
    242 		}
    243 	}
    244 
    245 	return ret_val;
    246 }
    247 #endif
    248 
    249 /*
    250  * Generic multiplexing code
    251  */
    252 int fpga_load(int devnum, const void *buf, size_t bsize, bitstream_type bstype)
    253 {
    254 	int ret_val = FPGA_FAIL;           /* assume failure */
    255 	const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
    256 					      (char *)__func__);
    257 
    258 	if (desc) {
    259 		switch (desc->devtype) {
    260 		case fpga_xilinx:
    261 #if defined(CONFIG_FPGA_XILINX)
    262 			ret_val = xilinx_load(desc->devdesc, buf, bsize,
    263 					      bstype);
    264 #else
    265 			fpga_no_sup((char *)__func__, "Xilinx devices");
    266 #endif
    267 			break;
    268 		case fpga_altera:
    269 #if defined(CONFIG_FPGA_ALTERA)
    270 			ret_val = altera_load(desc->devdesc, buf, bsize);
    271 #else
    272 			fpga_no_sup((char *)__func__, "Altera devices");
    273 #endif
    274 			break;
    275 		case fpga_lattice:
    276 #if defined(CONFIG_FPGA_LATTICE)
    277 			ret_val = lattice_load(desc->devdesc, buf, bsize);
    278 #else
    279 			fpga_no_sup((char *)__func__, "Lattice devices");
    280 #endif
    281 			break;
    282 		default:
    283 			printf("%s: Invalid or unsupported device type %d\n",
    284 			       __func__, desc->devtype);
    285 		}
    286 	}
    287 
    288 	return ret_val;
    289 }
    290 
    291 /*
    292  * fpga_dump
    293  *	generic multiplexing code
    294  */
    295 int fpga_dump(int devnum, const void *buf, size_t bsize)
    296 {
    297 	int ret_val = FPGA_FAIL;           /* assume failure */
    298 	const fpga_desc *desc = fpga_validate(devnum, buf, bsize,
    299 					      (char *)__func__);
    300 
    301 	if (desc) {
    302 		switch (desc->devtype) {
    303 		case fpga_xilinx:
    304 #if defined(CONFIG_FPGA_XILINX)
    305 			ret_val = xilinx_dump(desc->devdesc, buf, bsize);
    306 #else
    307 			fpga_no_sup((char *)__func__, "Xilinx devices");
    308 #endif
    309 			break;
    310 		case fpga_altera:
    311 #if defined(CONFIG_FPGA_ALTERA)
    312 			ret_val = altera_dump(desc->devdesc, buf, bsize);
    313 #else
    314 			fpga_no_sup((char *)__func__, "Altera devices");
    315 #endif
    316 			break;
    317 		case fpga_lattice:
    318 #if defined(CONFIG_FPGA_LATTICE)
    319 			ret_val = lattice_dump(desc->devdesc, buf, bsize);
    320 #else
    321 			fpga_no_sup((char *)__func__, "Lattice devices");
    322 #endif
    323 			break;
    324 		default:
    325 			printf("%s: Invalid or unsupported device type %d\n",
    326 			       __func__, desc->devtype);
    327 		}
    328 	}
    329 
    330 	return ret_val;
    331 }
    332 
    333 /*
    334  * fpga_info
    335  *	front end to fpga_dev_info.  If devnum is invalid, report on all
    336  *	available devices.
    337  */
    338 int fpga_info(int devnum)
    339 {
    340 	if (devnum == FPGA_INVALID_DEVICE) {
    341 		if (next_desc > 0) {
    342 			int dev;
    343 
    344 			for (dev = 0; dev < next_desc; dev++)
    345 				fpga_dev_info(dev);
    346 
    347 			return FPGA_SUCCESS;
    348 		} else {
    349 			printf("%s: No FPGA devices available.\n", __func__);
    350 			return FPGA_FAIL;
    351 		}
    352 	}
    353 
    354 	return fpga_dev_info(devnum);
    355 }
    356