xref: /openbmc/u-boot/cmd/fpga.c (revision 55010969)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
22e192b24SSimon Glass /*
32e192b24SSimon Glass  * (C) Copyright 2000, 2001
42e192b24SSimon Glass  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
52e192b24SSimon Glass  */
62e192b24SSimon Glass 
72e192b24SSimon Glass /*
82e192b24SSimon Glass  *  FPGA support
92e192b24SSimon Glass  */
102e192b24SSimon Glass #include <common.h>
112e192b24SSimon Glass #include <command.h>
122e192b24SSimon Glass #include <fpga.h>
132e192b24SSimon Glass #include <fs.h>
142e192b24SSimon Glass #include <malloc.h>
152e192b24SSimon Glass 
162e192b24SSimon Glass /* Local functions */
172e192b24SSimon Glass static int fpga_get_op(char *opstr);
182e192b24SSimon Glass 
192e192b24SSimon Glass /* Local defines */
205cf22289SMichal Simek enum {
215cf22289SMichal Simek 	FPGA_NONE = -1,
225cf22289SMichal Simek 	FPGA_INFO,
235cf22289SMichal Simek 	FPGA_LOAD,
245cf22289SMichal Simek 	FPGA_LOADB,
255cf22289SMichal Simek 	FPGA_DUMP,
265cf22289SMichal Simek 	FPGA_LOADMK,
275cf22289SMichal Simek 	FPGA_LOADP,
285cf22289SMichal Simek 	FPGA_LOADBP,
295cf22289SMichal Simek 	FPGA_LOADFS,
30cedd48e2SSiva Durga Prasad Paladugu 	FPGA_LOADS,
315cf22289SMichal Simek };
322e192b24SSimon Glass 
332e192b24SSimon Glass /* ------------------------------------------------------------------------- */
342e192b24SSimon Glass /* command form:
352e192b24SSimon Glass  *   fpga <op> <device number> <data addr> <datasize>
362e192b24SSimon Glass  * where op is 'load', 'dump', or 'info'
372e192b24SSimon Glass  * If there is no device number field, the fpga environment variable is used.
382e192b24SSimon Glass  * If there is no data addr field, the fpgadata environment variable is used.
392e192b24SSimon Glass  * The info command requires no data address field.
402e192b24SSimon Glass  */
412e192b24SSimon Glass int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
422e192b24SSimon Glass {
432e192b24SSimon Glass 	int op, dev = FPGA_INVALID_DEVICE;
442e192b24SSimon Glass 	size_t data_size = 0;
452e192b24SSimon Glass 	void *fpga_data = NULL;
4600caae6dSSimon Glass 	char *devstr = env_get("fpga");
4700caae6dSSimon Glass 	char *datastr = env_get("fpgadata");
482e192b24SSimon Glass 	int rc = FPGA_FAIL;
492e192b24SSimon Glass 	int wrong_parms = 0;
502e192b24SSimon Glass #if defined(CONFIG_FIT)
512e192b24SSimon Glass 	const char *fit_uname = NULL;
522e192b24SSimon Glass 	ulong fit_addr;
532e192b24SSimon Glass #endif
542e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADFS)
552e192b24SSimon Glass 	fpga_fs_info fpga_fsinfo;
562e192b24SSimon Glass 	fpga_fsinfo.fstype = FS_TYPE_ANY;
572e192b24SSimon Glass #endif
58cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
59cedd48e2SSiva Durga Prasad Paladugu 	struct fpga_secure_info fpga_sec_info;
60cedd48e2SSiva Durga Prasad Paladugu 
61cedd48e2SSiva Durga Prasad Paladugu 	memset(&fpga_sec_info, 0, sizeof(fpga_sec_info));
62cedd48e2SSiva Durga Prasad Paladugu #endif
632e192b24SSimon Glass 
642e192b24SSimon Glass 	if (devstr)
652e192b24SSimon Glass 		dev = (int) simple_strtoul(devstr, NULL, 16);
662e192b24SSimon Glass 	if (datastr)
672e192b24SSimon Glass 		fpga_data = (void *)simple_strtoul(datastr, NULL, 16);
682e192b24SSimon Glass 
69f5953610SSiva Durga Prasad Paladugu 	if (argc > 9 || argc < 2) {
70f5953610SSiva Durga Prasad Paladugu 		debug("%s: Too many or too few args (%d)\n", __func__, argc);
71f5953610SSiva Durga Prasad Paladugu 		return CMD_RET_USAGE;
72f5953610SSiva Durga Prasad Paladugu 	}
73f5953610SSiva Durga Prasad Paladugu 
74f5953610SSiva Durga Prasad Paladugu 	op = (int)fpga_get_op(argv[1]);
75f5953610SSiva Durga Prasad Paladugu 
76f5953610SSiva Durga Prasad Paladugu 	switch (op) {
77*55010969SMichal Simek 	case FPGA_NONE:
78*55010969SMichal Simek 		printf("Unknown fpga operation \"%s\"\n", argv[1]);
79*55010969SMichal Simek 		return CMD_RET_USAGE;
802e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADFS)
81f5953610SSiva Durga Prasad Paladugu 	case FPGA_LOADFS:
82f5953610SSiva Durga Prasad Paladugu 		if (argc < 9)
83f5953610SSiva Durga Prasad Paladugu 			return CMD_RET_USAGE;
842e192b24SSimon Glass 		fpga_fsinfo.blocksize = (unsigned int)
852e192b24SSimon Glass 					simple_strtoul(argv[5], NULL, 16);
862e192b24SSimon Glass 		fpga_fsinfo.interface = argv[6];
872e192b24SSimon Glass 		fpga_fsinfo.dev_part = argv[7];
882e192b24SSimon Glass 		fpga_fsinfo.filename = argv[8];
89f5953610SSiva Durga Prasad Paladugu 		argc = 5;
90f5953610SSiva Durga Prasad Paladugu 		break;
912e192b24SSimon Glass #endif
92cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
93cedd48e2SSiva Durga Prasad Paladugu 	case FPGA_LOADS:
94cedd48e2SSiva Durga Prasad Paladugu 		if (argc < 7)
95cedd48e2SSiva Durga Prasad Paladugu 			return CMD_RET_USAGE;
96cedd48e2SSiva Durga Prasad Paladugu 		if (argc == 8)
97cedd48e2SSiva Durga Prasad Paladugu 			fpga_sec_info.userkey_addr = (u8 *)(uintptr_t)
98cedd48e2SSiva Durga Prasad Paladugu 						     simple_strtoull(argv[7],
99cedd48e2SSiva Durga Prasad Paladugu 								     NULL, 16);
100cedd48e2SSiva Durga Prasad Paladugu 		fpga_sec_info.encflag = (u8)simple_strtoul(argv[6], NULL, 16);
101cedd48e2SSiva Durga Prasad Paladugu 		fpga_sec_info.authflag = (u8)simple_strtoul(argv[5], NULL, 16);
102cedd48e2SSiva Durga Prasad Paladugu 		argc = 5;
103cedd48e2SSiva Durga Prasad Paladugu 		break;
104cedd48e2SSiva Durga Prasad Paladugu #endif
105f5953610SSiva Durga Prasad Paladugu 	default:
106f5953610SSiva Durga Prasad Paladugu 		break;
107f5953610SSiva Durga Prasad Paladugu 	}
108f5953610SSiva Durga Prasad Paladugu 
109f5953610SSiva Durga Prasad Paladugu 	switch (argc) {
1102e192b24SSimon Glass 	case 5:		/* fpga <op> <dev> <data> <datasize> */
1112e192b24SSimon Glass 		data_size = simple_strtoul(argv[4], NULL, 16);
1122e192b24SSimon Glass 
1132e192b24SSimon Glass 	case 4:		/* fpga <op> <dev> <data> */
1142e192b24SSimon Glass #if defined(CONFIG_FIT)
1152e192b24SSimon Glass 		if (fit_parse_subimage(argv[3], (ulong)fpga_data,
1162e192b24SSimon Glass 				       &fit_addr, &fit_uname)) {
1172e192b24SSimon Glass 			fpga_data = (void *)fit_addr;
1182e192b24SSimon Glass 			debug("*  fpga: subimage '%s' from FIT image ",
1192e192b24SSimon Glass 			      fit_uname);
1202e192b24SSimon Glass 			debug("at 0x%08lx\n", fit_addr);
1212e192b24SSimon Glass 		} else
1222e192b24SSimon Glass #endif
1232e192b24SSimon Glass 		{
1242e192b24SSimon Glass 			fpga_data = (void *)simple_strtoul(argv[3], NULL, 16);
1252e192b24SSimon Glass 			debug("*  fpga: cmdline image address = 0x%08lx\n",
1262e192b24SSimon Glass 			      (ulong)fpga_data);
1272e192b24SSimon Glass 		}
128455ad585SMichal Simek 		debug("%s: fpga_data = 0x%lx\n", __func__, (ulong)fpga_data);
1292e192b24SSimon Glass 
1302e192b24SSimon Glass 	case 3:		/* fpga <op> <dev | data addr> */
1312e192b24SSimon Glass 		dev = (int)simple_strtoul(argv[2], NULL, 16);
1322e192b24SSimon Glass 		debug("%s: device = %d\n", __func__, dev);
1332e192b24SSimon Glass 	}
1342e192b24SSimon Glass 
1352e192b24SSimon Glass 	if (dev == FPGA_INVALID_DEVICE) {
1362e192b24SSimon Glass 		puts("FPGA device not specified\n");
1372e192b24SSimon Glass 		op = FPGA_NONE;
1382e192b24SSimon Glass 	}
1392e192b24SSimon Glass 
1402e192b24SSimon Glass 	switch (op) {
1412e192b24SSimon Glass 	case FPGA_NONE:
1422e192b24SSimon Glass 	case FPGA_INFO:
1432e192b24SSimon Glass 		break;
1442e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADFS)
1452e192b24SSimon Glass 	case FPGA_LOADFS:
1462e192b24SSimon Glass 		/* Blocksize can be zero */
1472e192b24SSimon Glass 		if (!fpga_fsinfo.interface || !fpga_fsinfo.dev_part ||
1482e192b24SSimon Glass 		    !fpga_fsinfo.filename)
1492e192b24SSimon Glass 			wrong_parms = 1;
150cedd48e2SSiva Durga Prasad Paladugu 		break;
151cedd48e2SSiva Durga Prasad Paladugu #endif
152cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
153cedd48e2SSiva Durga Prasad Paladugu 	case FPGA_LOADS:
154cedd48e2SSiva Durga Prasad Paladugu 		if (fpga_sec_info.authflag >= FPGA_NO_ENC_OR_NO_AUTH &&
155cedd48e2SSiva Durga Prasad Paladugu 		    fpga_sec_info.encflag >= FPGA_NO_ENC_OR_NO_AUTH) {
156cedd48e2SSiva Durga Prasad Paladugu 			puts("ERR: use <fpga load> for NonSecure bitstream\n");
157cedd48e2SSiva Durga Prasad Paladugu 			wrong_parms = 1;
158cedd48e2SSiva Durga Prasad Paladugu 		}
159cedd48e2SSiva Durga Prasad Paladugu 
160cedd48e2SSiva Durga Prasad Paladugu 		if (fpga_sec_info.encflag == FPGA_ENC_USR_KEY &&
161cedd48e2SSiva Durga Prasad Paladugu 		    !fpga_sec_info.userkey_addr) {
162cedd48e2SSiva Durga Prasad Paladugu 			wrong_parms = 1;
163cedd48e2SSiva Durga Prasad Paladugu 			puts("ERR:User key not provided\n");
164cedd48e2SSiva Durga Prasad Paladugu 		}
165cedd48e2SSiva Durga Prasad Paladugu 		break;
1662e192b24SSimon Glass #endif
1672e192b24SSimon Glass 	case FPGA_LOAD:
1682e192b24SSimon Glass 	case FPGA_LOADP:
1692e192b24SSimon Glass 	case FPGA_LOADB:
1702e192b24SSimon Glass 	case FPGA_LOADBP:
1712e192b24SSimon Glass 	case FPGA_DUMP:
1722e192b24SSimon Glass 		if (!fpga_data || !data_size)
1732e192b24SSimon Glass 			wrong_parms = 1;
1742e192b24SSimon Glass 		break;
1752e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADMK)
1762e192b24SSimon Glass 	case FPGA_LOADMK:
1772e192b24SSimon Glass 		if (!fpga_data)
1782e192b24SSimon Glass 			wrong_parms = 1;
1792e192b24SSimon Glass 		break;
1802e192b24SSimon Glass #endif
1812e192b24SSimon Glass 	}
1822e192b24SSimon Glass 
1832e192b24SSimon Glass 	if (wrong_parms) {
1842e192b24SSimon Glass 		puts("Wrong parameters for FPGA request\n");
1852e192b24SSimon Glass 		op = FPGA_NONE;
1862e192b24SSimon Glass 	}
1872e192b24SSimon Glass 
1882e192b24SSimon Glass 	switch (op) {
1892e192b24SSimon Glass 	case FPGA_NONE:
1902e192b24SSimon Glass 		return CMD_RET_USAGE;
1912e192b24SSimon Glass 
1922e192b24SSimon Glass 	case FPGA_INFO:
1932e192b24SSimon Glass 		rc = fpga_info(dev);
1942e192b24SSimon Glass 		break;
1952e192b24SSimon Glass 
1962e192b24SSimon Glass 	case FPGA_LOAD:
1972e192b24SSimon Glass 		rc = fpga_load(dev, fpga_data, data_size, BIT_FULL);
1982e192b24SSimon Glass 		break;
1992e192b24SSimon Glass 
2002e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADP)
2012e192b24SSimon Glass 	case FPGA_LOADP:
2022e192b24SSimon Glass 		rc = fpga_load(dev, fpga_data, data_size, BIT_PARTIAL);
2032e192b24SSimon Glass 		break;
2042e192b24SSimon Glass #endif
2052e192b24SSimon Glass 
2062e192b24SSimon Glass 	case FPGA_LOADB:
2072e192b24SSimon Glass 		rc = fpga_loadbitstream(dev, fpga_data, data_size, BIT_FULL);
2082e192b24SSimon Glass 		break;
2092e192b24SSimon Glass 
2102e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADBP)
2112e192b24SSimon Glass 	case FPGA_LOADBP:
2122e192b24SSimon Glass 		rc = fpga_loadbitstream(dev, fpga_data, data_size, BIT_PARTIAL);
2132e192b24SSimon Glass 		break;
2142e192b24SSimon Glass #endif
2152e192b24SSimon Glass 
2162e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADFS)
2172e192b24SSimon Glass 	case FPGA_LOADFS:
2182e192b24SSimon Glass 		rc = fpga_fsload(dev, fpga_data, data_size, &fpga_fsinfo);
2192e192b24SSimon Glass 		break;
2202e192b24SSimon Glass #endif
2212e192b24SSimon Glass 
222cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
223cedd48e2SSiva Durga Prasad Paladugu 	case FPGA_LOADS:
224cedd48e2SSiva Durga Prasad Paladugu 		rc = fpga_loads(dev, fpga_data, data_size, &fpga_sec_info);
225cedd48e2SSiva Durga Prasad Paladugu 		break;
226cedd48e2SSiva Durga Prasad Paladugu #endif
227cedd48e2SSiva Durga Prasad Paladugu 
2282e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADMK)
2292e192b24SSimon Glass 	case FPGA_LOADMK:
2302e192b24SSimon Glass 		switch (genimg_get_format(fpga_data)) {
2312e192b24SSimon Glass #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
2322e192b24SSimon Glass 		case IMAGE_FORMAT_LEGACY:
2332e192b24SSimon Glass 			{
2342e192b24SSimon Glass 				image_header_t *hdr =
2352e192b24SSimon Glass 						(image_header_t *)fpga_data;
2362e192b24SSimon Glass 				ulong data;
2372e192b24SSimon Glass 				uint8_t comp;
2382e192b24SSimon Glass 
2392e192b24SSimon Glass 				comp = image_get_comp(hdr);
2402e192b24SSimon Glass 				if (comp == IH_COMP_GZIP) {
2412e192b24SSimon Glass #if defined(CONFIG_GZIP)
2422e192b24SSimon Glass 					ulong image_buf = image_get_data(hdr);
2432e192b24SSimon Glass 					data = image_get_load(hdr);
2442e192b24SSimon Glass 					ulong image_size = ~0UL;
2452e192b24SSimon Glass 
2462e192b24SSimon Glass 					if (gunzip((void *)data, ~0UL,
2472e192b24SSimon Glass 						   (void *)image_buf,
2482e192b24SSimon Glass 						   &image_size) != 0) {
2492e192b24SSimon Glass 						puts("GUNZIP: error\n");
2502e192b24SSimon Glass 						return 1;
2512e192b24SSimon Glass 					}
2522e192b24SSimon Glass 					data_size = image_size;
2532e192b24SSimon Glass #else
2542e192b24SSimon Glass 					puts("Gunzip image is not supported\n");
2552e192b24SSimon Glass 					return 1;
2562e192b24SSimon Glass #endif
2572e192b24SSimon Glass 				} else {
2582e192b24SSimon Glass 					data = (ulong)image_get_data(hdr);
2592e192b24SSimon Glass 					data_size = image_get_data_size(hdr);
2602e192b24SSimon Glass 				}
2612e192b24SSimon Glass 				rc = fpga_load(dev, (void *)data, data_size,
2622e192b24SSimon Glass 					       BIT_FULL);
2632e192b24SSimon Glass 			}
2642e192b24SSimon Glass 			break;
2652e192b24SSimon Glass #endif
2662e192b24SSimon Glass #if defined(CONFIG_FIT)
2672e192b24SSimon Glass 		case IMAGE_FORMAT_FIT:
2682e192b24SSimon Glass 			{
2692e192b24SSimon Glass 				const void *fit_hdr = (const void *)fpga_data;
2702e192b24SSimon Glass 				int noffset;
2712e192b24SSimon Glass 				const void *fit_data;
2722e192b24SSimon Glass 
2732e192b24SSimon Glass 				if (fit_uname == NULL) {
2742e192b24SSimon Glass 					puts("No FIT subimage unit name\n");
2752e192b24SSimon Glass 					return 1;
2762e192b24SSimon Glass 				}
2772e192b24SSimon Glass 
2782e192b24SSimon Glass 				if (!fit_check_format(fit_hdr)) {
2792e192b24SSimon Glass 					puts("Bad FIT image format\n");
2802e192b24SSimon Glass 					return 1;
2812e192b24SSimon Glass 				}
2822e192b24SSimon Glass 
2832e192b24SSimon Glass 				/* get fpga component image node offset */
2842e192b24SSimon Glass 				noffset = fit_image_get_node(fit_hdr,
2852e192b24SSimon Glass 							     fit_uname);
2862e192b24SSimon Glass 				if (noffset < 0) {
2872e192b24SSimon Glass 					printf("Can't find '%s' FIT subimage\n",
2882e192b24SSimon Glass 					       fit_uname);
2892e192b24SSimon Glass 					return 1;
2902e192b24SSimon Glass 				}
2912e192b24SSimon Glass 
2922e192b24SSimon Glass 				/* verify integrity */
2932e192b24SSimon Glass 				if (!fit_image_verify(fit_hdr, noffset)) {
2942e192b24SSimon Glass 					puts ("Bad Data Hash\n");
2952e192b24SSimon Glass 					return 1;
2962e192b24SSimon Glass 				}
2972e192b24SSimon Glass 
2982e192b24SSimon Glass 				/* get fpga subimage data address and length */
2992e192b24SSimon Glass 				if (fit_image_get_data(fit_hdr, noffset,
3002e192b24SSimon Glass 						       &fit_data, &data_size)) {
3012e192b24SSimon Glass 					puts("Fpga subimage data not found\n");
3022e192b24SSimon Glass 					return 1;
3032e192b24SSimon Glass 				}
3042e192b24SSimon Glass 
3052e192b24SSimon Glass 				rc = fpga_load(dev, fit_data, data_size,
3062e192b24SSimon Glass 					       BIT_FULL);
3072e192b24SSimon Glass 			}
3082e192b24SSimon Glass 			break;
3092e192b24SSimon Glass #endif
3102e192b24SSimon Glass 		default:
3112e192b24SSimon Glass 			puts("** Unknown image type\n");
3122e192b24SSimon Glass 			rc = FPGA_FAIL;
3132e192b24SSimon Glass 			break;
3142e192b24SSimon Glass 		}
3152e192b24SSimon Glass 		break;
3162e192b24SSimon Glass #endif
3172e192b24SSimon Glass 
3182e192b24SSimon Glass 	case FPGA_DUMP:
3192e192b24SSimon Glass 		rc = fpga_dump(dev, fpga_data, data_size);
3202e192b24SSimon Glass 		break;
3212e192b24SSimon Glass 
3222e192b24SSimon Glass 	default:
3232e192b24SSimon Glass 		printf("Unknown operation\n");
3242e192b24SSimon Glass 		return CMD_RET_USAGE;
3252e192b24SSimon Glass 	}
3262e192b24SSimon Glass 	return rc;
3272e192b24SSimon Glass }
3282e192b24SSimon Glass 
3292e192b24SSimon Glass /*
3302e192b24SSimon Glass  * Map op to supported operations.  We don't use a table since we
3312e192b24SSimon Glass  * would just have to relocate it from flash anyway.
3322e192b24SSimon Glass  */
3332e192b24SSimon Glass static int fpga_get_op(char *opstr)
3342e192b24SSimon Glass {
3352e192b24SSimon Glass 	int op = FPGA_NONE;
3362e192b24SSimon Glass 
3372e192b24SSimon Glass 	if (!strcmp("info", opstr))
3382e192b24SSimon Glass 		op = FPGA_INFO;
3392e192b24SSimon Glass 	else if (!strcmp("loadb", opstr))
3402e192b24SSimon Glass 		op = FPGA_LOADB;
3412e192b24SSimon Glass 	else if (!strcmp("load", opstr))
3422e192b24SSimon Glass 		op = FPGA_LOAD;
3432e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADP)
3442e192b24SSimon Glass 	else if (!strcmp("loadp", opstr))
3452e192b24SSimon Glass 		op = FPGA_LOADP;
3462e192b24SSimon Glass #endif
3472e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADBP)
3482e192b24SSimon Glass 	else if (!strcmp("loadbp", opstr))
3492e192b24SSimon Glass 		op = FPGA_LOADBP;
3502e192b24SSimon Glass #endif
3512e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADFS)
3522e192b24SSimon Glass 	else if (!strcmp("loadfs", opstr))
3532e192b24SSimon Glass 		op = FPGA_LOADFS;
3542e192b24SSimon Glass #endif
3552e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADMK)
3562e192b24SSimon Glass 	else if (!strcmp("loadmk", opstr))
3572e192b24SSimon Glass 		op = FPGA_LOADMK;
3582e192b24SSimon Glass #endif
3592e192b24SSimon Glass 	else if (!strcmp("dump", opstr))
3602e192b24SSimon Glass 		op = FPGA_DUMP;
361cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
362cedd48e2SSiva Durga Prasad Paladugu 	else if (!strcmp("loads", opstr))
363cedd48e2SSiva Durga Prasad Paladugu 		op = FPGA_LOADS;
364cedd48e2SSiva Durga Prasad Paladugu #endif
3652e192b24SSimon Glass 
3662e192b24SSimon Glass 	return op;
3672e192b24SSimon Glass }
3682e192b24SSimon Glass 
369cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOADFS) || defined(CONFIG_CMD_FPGA_LOAD_SECURE)
3702e192b24SSimon Glass U_BOOT_CMD(fpga, 9, 1, do_fpga,
3712e192b24SSimon Glass #else
3722e192b24SSimon Glass U_BOOT_CMD(fpga, 6, 1, do_fpga,
3732e192b24SSimon Glass #endif
3742e192b24SSimon Glass 	   "loadable FPGA image support",
3752e192b24SSimon Glass 	   "[operation type] [device number] [image address] [image size]\n"
3762e192b24SSimon Glass 	   "fpga operations:\n"
3772e192b24SSimon Glass 	   "  dump\t[dev] [address] [size]\tLoad device to memory buffer\n"
3782e192b24SSimon Glass 	   "  info\t[dev]\t\t\tlist known device information\n"
3792e192b24SSimon Glass 	   "  load\t[dev] [address] [size]\tLoad device from memory buffer\n"
3802e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADP)
3812e192b24SSimon Glass 	   "  loadp\t[dev] [address] [size]\t"
3822e192b24SSimon Glass 	   "Load device from memory buffer with partial bitstream\n"
3832e192b24SSimon Glass #endif
3842e192b24SSimon Glass 	   "  loadb\t[dev] [address] [size]\t"
3852e192b24SSimon Glass 	   "Load device from bitstream buffer (Xilinx only)\n"
3862e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADBP)
3872e192b24SSimon Glass 	   "  loadbp\t[dev] [address] [size]\t"
3882e192b24SSimon Glass 	   "Load device from bitstream buffer with partial bitstream"
3892e192b24SSimon Glass 	   "(Xilinx only)\n"
3902e192b24SSimon Glass #endif
3912e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADFS)
3922e192b24SSimon Glass 	   "Load device from filesystem (FAT by default) (Xilinx only)\n"
3932e192b24SSimon Glass 	   "  loadfs [dev] [address] [image size] [blocksize] <interface>\n"
3942e192b24SSimon Glass 	   "        [<dev[:part]>] <filename>\n"
3952e192b24SSimon Glass #endif
3962e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADMK)
3972e192b24SSimon Glass 	   "  loadmk [dev] [address]\tLoad device generated with mkimage"
3982e192b24SSimon Glass #if defined(CONFIG_FIT)
3992e192b24SSimon Glass 	   "\n"
4002e192b24SSimon Glass 	   "\tFor loadmk operating on FIT format uImage address must include\n"
4012e192b24SSimon Glass 	   "\tsubimage unit name in the form of addr:<subimg_uname>"
4022e192b24SSimon Glass #endif
4032e192b24SSimon Glass #endif
404cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
405cedd48e2SSiva Durga Prasad Paladugu 	   "Load encrypted bitstream (Xilinx only)\n"
406cedd48e2SSiva Durga Prasad Paladugu 	   "  loads [dev] [address] [size] [auth-OCM-0/DDR-1/noauth-2]\n"
407cedd48e2SSiva Durga Prasad Paladugu 	   "        [enc-devkey(0)/userkey(1)/nenc(2) [Userkey address]\n"
408cedd48e2SSiva Durga Prasad Paladugu 	   "Loads the secure bistreams(authenticated/encrypted/both\n"
409cedd48e2SSiva Durga Prasad Paladugu 	   "authenticated and encrypted) of [size] from [address].\n"
410cedd48e2SSiva Durga Prasad Paladugu 	   "The auth-OCM/DDR flag specifies to perform authentication\n"
411cedd48e2SSiva Durga Prasad Paladugu 	   "in OCM or in DDR. 0 for OCM, 1 for DDR, 2 for no authentication.\n"
412cedd48e2SSiva Durga Prasad Paladugu 	   "The enc flag specifies which key to be used for decryption\n"
413cedd48e2SSiva Durga Prasad Paladugu 	   "0-device key, 1-user key, 2-no encryption.\n"
414cedd48e2SSiva Durga Prasad Paladugu 	   "The optional Userkey address specifies from which address key\n"
415cedd48e2SSiva Durga Prasad Paladugu 	   "has to be used for decryption if user key is selected.\n"
416cedd48e2SSiva Durga Prasad Paladugu 	   "NOTE: the sceure bitstream has to be created using xilinx\n"
417cedd48e2SSiva Durga Prasad Paladugu 	   "bootgen tool only.\n"
418cedd48e2SSiva Durga Prasad Paladugu #endif
4192e192b24SSimon Glass );
420