xref: /openbmc/u-boot/cmd/fpga.c (revision d1e15041)
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 
do_fpga_get_device(char * arg)16f4c7a4aeSMichal Simek static long do_fpga_get_device(char *arg)
17f4c7a4aeSMichal Simek {
18f4c7a4aeSMichal Simek 	long dev = FPGA_INVALID_DEVICE;
19f4c7a4aeSMichal Simek 	char *devstr = env_get("fpga");
20f4c7a4aeSMichal Simek 
21f4c7a4aeSMichal Simek 	if (devstr)
22f4c7a4aeSMichal Simek 		/* Should be strtol to handle -1 cases */
23f4c7a4aeSMichal Simek 		dev = simple_strtol(devstr, NULL, 16);
24f4c7a4aeSMichal Simek 
258c75f794SMichal Simek 	if (dev == FPGA_INVALID_DEVICE && arg)
26f4c7a4aeSMichal Simek 		dev = simple_strtol(arg, NULL, 16);
27f4c7a4aeSMichal Simek 
28f4c7a4aeSMichal Simek 	debug("%s: device = %ld\n", __func__, dev);
29f4c7a4aeSMichal Simek 
30f4c7a4aeSMichal Simek 	return dev;
31f4c7a4aeSMichal Simek }
32f4c7a4aeSMichal Simek 
do_fpga_check_params(long * dev,long * fpga_data,size_t * data_size,cmd_tbl_t * cmdtp,int argc,char * const argv[])3385754795SMichal Simek static int do_fpga_check_params(long *dev, long *fpga_data, size_t *data_size,
3485754795SMichal Simek 				cmd_tbl_t *cmdtp, int argc, char *const argv[])
3585754795SMichal Simek {
3685754795SMichal Simek 	size_t local_data_size;
3785754795SMichal Simek 	long local_fpga_data;
3885754795SMichal Simek 
3985754795SMichal Simek 	debug("%s %d, %d\n", __func__, argc, cmdtp->maxargs);
4085754795SMichal Simek 
4185754795SMichal Simek 	if (argc != cmdtp->maxargs) {
4285754795SMichal Simek 		debug("fpga: incorrect parameters passed\n");
4385754795SMichal Simek 		return CMD_RET_USAGE;
4485754795SMichal Simek 	}
4585754795SMichal Simek 
4685754795SMichal Simek 	*dev = do_fpga_get_device(argv[0]);
4785754795SMichal Simek 
4885754795SMichal Simek 	local_fpga_data = simple_strtol(argv[1], NULL, 16);
4985754795SMichal Simek 	if (!local_fpga_data) {
5085754795SMichal Simek 		debug("fpga: zero fpga_data address\n");
5185754795SMichal Simek 		return CMD_RET_USAGE;
5285754795SMichal Simek 	}
5385754795SMichal Simek 	*fpga_data = local_fpga_data;
5485754795SMichal Simek 
5585754795SMichal Simek 	local_data_size = simple_strtoul(argv[2], NULL, 16);
5685754795SMichal Simek 	if (!local_data_size) {
5785754795SMichal Simek 		debug("fpga: zero size\n");
5885754795SMichal Simek 		return CMD_RET_USAGE;
5985754795SMichal Simek 	}
6085754795SMichal Simek 	*data_size = local_data_size;
6185754795SMichal Simek 
6285754795SMichal Simek 	return 0;
6385754795SMichal Simek }
6485754795SMichal Simek 
65323fe38eSMichal Simek #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
do_fpga_loads(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])66*b5d19a93SMichal Simek int do_fpga_loads(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
672e192b24SSimon Glass {
682e192b24SSimon Glass 	size_t data_size = 0;
69*b5d19a93SMichal Simek 	long fpga_data, dev;
70*b5d19a93SMichal Simek 	int ret;
71cedd48e2SSiva Durga Prasad Paladugu 	struct fpga_secure_info fpga_sec_info;
72cedd48e2SSiva Durga Prasad Paladugu 
73cedd48e2SSiva Durga Prasad Paladugu 	memset(&fpga_sec_info, 0, sizeof(fpga_sec_info));
742e192b24SSimon Glass 
75*b5d19a93SMichal Simek 	if (argc < 5) {
76*b5d19a93SMichal Simek 		debug("fpga: incorrect parameters passed\n");
77f5953610SSiva Durga Prasad Paladugu 		return CMD_RET_USAGE;
78f5953610SSiva Durga Prasad Paladugu 	}
79f5953610SSiva Durga Prasad Paladugu 
80*b5d19a93SMichal Simek 	if (argc == 6)
81cedd48e2SSiva Durga Prasad Paladugu 		fpga_sec_info.userkey_addr = (u8 *)(uintptr_t)
82*b5d19a93SMichal Simek 					      simple_strtoull(argv[5],
83cedd48e2SSiva Durga Prasad Paladugu 							      NULL, 16);
84*b5d19a93SMichal Simek 	else
85*b5d19a93SMichal Simek 		/*
86*b5d19a93SMichal Simek 		 * If 6th parameter is not passed then do_fpga_check_params
87*b5d19a93SMichal Simek 		 * will get 5 instead of expected 6 which means that function
88*b5d19a93SMichal Simek 		 * return CMD_RET_USAGE. Increase number of params +1 to pass
89*b5d19a93SMichal Simek 		 * this.
90*b5d19a93SMichal Simek 		 */
91*b5d19a93SMichal Simek 		argc++;
92*b5d19a93SMichal Simek 
93*b5d19a93SMichal Simek 	fpga_sec_info.encflag = (u8)simple_strtoul(argv[4], NULL, 16);
94*b5d19a93SMichal Simek 	fpga_sec_info.authflag = (u8)simple_strtoul(argv[3], NULL, 16);
9544d839bdSMichal Simek 
9644d839bdSMichal Simek 	if (fpga_sec_info.authflag >= FPGA_NO_ENC_OR_NO_AUTH &&
9744d839bdSMichal Simek 	    fpga_sec_info.encflag >= FPGA_NO_ENC_OR_NO_AUTH) {
98*b5d19a93SMichal Simek 		debug("fpga: Use <fpga load> for NonSecure bitstream\n");
9944d839bdSMichal Simek 		return CMD_RET_USAGE;
10044d839bdSMichal Simek 	}
10144d839bdSMichal Simek 
10244d839bdSMichal Simek 	if (fpga_sec_info.encflag == FPGA_ENC_USR_KEY &&
10344d839bdSMichal Simek 	    !fpga_sec_info.userkey_addr) {
104*b5d19a93SMichal Simek 		debug("fpga: User key not provided\n");
10544d839bdSMichal Simek 		return CMD_RET_USAGE;
10644d839bdSMichal Simek 	}
10744d839bdSMichal Simek 
108*b5d19a93SMichal Simek 	ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
109*b5d19a93SMichal Simek 				   cmdtp, argc, argv);
110*b5d19a93SMichal Simek 	if (ret)
111*b5d19a93SMichal Simek 		return ret;
112*b5d19a93SMichal Simek 
113*b5d19a93SMichal Simek 	return fpga_loads(dev, (void *)fpga_data, data_size, &fpga_sec_info);
114*b5d19a93SMichal Simek }
115cedd48e2SSiva Durga Prasad Paladugu #endif
1162e192b24SSimon Glass 
11749503f9aSMichal Simek #if defined(CONFIG_CMD_FPGA_LOADFS)
do_fpga_loadfs(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])11849503f9aSMichal Simek static int do_fpga_loadfs(cmd_tbl_t *cmdtp, int flag, int argc,
11949503f9aSMichal Simek 			  char *const argv[])
12049503f9aSMichal Simek {
12149503f9aSMichal Simek 	size_t data_size = 0;
12249503f9aSMichal Simek 	long fpga_data, dev;
12349503f9aSMichal Simek 	int ret;
12449503f9aSMichal Simek 	fpga_fs_info fpga_fsinfo;
12549503f9aSMichal Simek 
12649503f9aSMichal Simek 	ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
12749503f9aSMichal Simek 				   cmdtp, argc, argv);
12849503f9aSMichal Simek 	if (ret)
12949503f9aSMichal Simek 		return ret;
13049503f9aSMichal Simek 
13149503f9aSMichal Simek 	fpga_fsinfo.fstype = FS_TYPE_ANY;
13249503f9aSMichal Simek 	fpga_fsinfo.blocksize = (unsigned int)simple_strtoul(argv[3], NULL, 16);
13349503f9aSMichal Simek 	fpga_fsinfo.interface = argv[4];
13449503f9aSMichal Simek 	fpga_fsinfo.dev_part = argv[5];
13549503f9aSMichal Simek 	fpga_fsinfo.filename = argv[6];
13649503f9aSMichal Simek 
13749503f9aSMichal Simek 	return fpga_fsload(dev, (void *)fpga_data, data_size, &fpga_fsinfo);
13849503f9aSMichal Simek }
13949503f9aSMichal Simek #endif
14049503f9aSMichal Simek 
do_fpga_info(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])141f4c7a4aeSMichal Simek static int do_fpga_info(cmd_tbl_t *cmdtp, int flag, int argc,
142f4c7a4aeSMichal Simek 			char * const argv[])
143f4c7a4aeSMichal Simek {
144f4c7a4aeSMichal Simek 	long dev = do_fpga_get_device(argv[0]);
145f4c7a4aeSMichal Simek 
146f4c7a4aeSMichal Simek 	return fpga_info(dev);
147f4c7a4aeSMichal Simek }
148f4c7a4aeSMichal Simek 
do_fpga_dump(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])14985754795SMichal Simek static int do_fpga_dump(cmd_tbl_t *cmdtp, int flag, int argc,
15085754795SMichal Simek 			char * const argv[])
15185754795SMichal Simek {
15285754795SMichal Simek 	size_t data_size = 0;
15385754795SMichal Simek 	long fpga_data, dev;
15485754795SMichal Simek 	int ret;
15585754795SMichal Simek 
15685754795SMichal Simek 	ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
15785754795SMichal Simek 				   cmdtp, argc, argv);
15885754795SMichal Simek 	if (ret)
15985754795SMichal Simek 		return ret;
16085754795SMichal Simek 
16185754795SMichal Simek 	return fpga_dump(dev, (void *)fpga_data, data_size);
16285754795SMichal Simek }
16385754795SMichal Simek 
do_fpga_load(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])16485754795SMichal Simek static int do_fpga_load(cmd_tbl_t *cmdtp, int flag, int argc,
16585754795SMichal Simek 			char * const argv[])
16685754795SMichal Simek {
16785754795SMichal Simek 	size_t data_size = 0;
16885754795SMichal Simek 	long fpga_data, dev;
16985754795SMichal Simek 	int ret;
17085754795SMichal Simek 
17185754795SMichal Simek 	ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
17285754795SMichal Simek 				   cmdtp, argc, argv);
17385754795SMichal Simek 	if (ret)
17485754795SMichal Simek 		return ret;
17585754795SMichal Simek 
17685754795SMichal Simek 	return fpga_load(dev, (void *)fpga_data, data_size, BIT_FULL);
17785754795SMichal Simek }
17885754795SMichal Simek 
do_fpga_loadb(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])17985754795SMichal Simek static int do_fpga_loadb(cmd_tbl_t *cmdtp, int flag, int argc,
18085754795SMichal Simek 			 char * const argv[])
18185754795SMichal Simek {
18285754795SMichal Simek 	size_t data_size = 0;
18385754795SMichal Simek 	long fpga_data, dev;
18485754795SMichal Simek 	int ret;
18585754795SMichal Simek 
18685754795SMichal Simek 	ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
18785754795SMichal Simek 				   cmdtp, argc, argv);
18885754795SMichal Simek 	if (ret)
18985754795SMichal Simek 		return ret;
19085754795SMichal Simek 
19185754795SMichal Simek 	return fpga_loadbitstream(dev, (void *)fpga_data, data_size, BIT_FULL);
19285754795SMichal Simek }
19385754795SMichal Simek 
19485754795SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADP)
do_fpga_loadp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])19585754795SMichal Simek static int do_fpga_loadp(cmd_tbl_t *cmdtp, int flag, int argc,
19685754795SMichal Simek 			 char * const argv[])
19785754795SMichal Simek {
19885754795SMichal Simek 	size_t data_size = 0;
19985754795SMichal Simek 	long fpga_data, dev;
20085754795SMichal Simek 	int ret;
20185754795SMichal Simek 
20285754795SMichal Simek 	ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
20385754795SMichal Simek 				   cmdtp, argc, argv);
20485754795SMichal Simek 	if (ret)
20585754795SMichal Simek 		return ret;
20685754795SMichal Simek 
20785754795SMichal Simek 	return fpga_load(dev, (void *)fpga_data, data_size, BIT_PARTIAL);
20885754795SMichal Simek }
20985754795SMichal Simek #endif
21085754795SMichal Simek 
21185754795SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADBP)
do_fpga_loadbp(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])21285754795SMichal Simek static int do_fpga_loadbp(cmd_tbl_t *cmdtp, int flag, int argc,
21385754795SMichal Simek 			  char * const argv[])
21485754795SMichal Simek {
21585754795SMichal Simek 	size_t data_size = 0;
21685754795SMichal Simek 	long fpga_data, dev;
21785754795SMichal Simek 	int ret;
21885754795SMichal Simek 
21985754795SMichal Simek 	ret = do_fpga_check_params(&dev, &fpga_data, &data_size,
22085754795SMichal Simek 				   cmdtp, argc, argv);
22185754795SMichal Simek 	if (ret)
22285754795SMichal Simek 		return ret;
22385754795SMichal Simek 
22485754795SMichal Simek 	return fpga_loadbitstream(dev, (void *)fpga_data, data_size,
22585754795SMichal Simek 				  BIT_PARTIAL);
22685754795SMichal Simek }
22785754795SMichal Simek #endif
22885754795SMichal Simek 
2292892fe80SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADMK)
do_fpga_loadmk(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])2302892fe80SMichal Simek static int do_fpga_loadmk(cmd_tbl_t *cmdtp, int flag, int argc,
2312892fe80SMichal Simek 			  char * const argv[])
2322892fe80SMichal Simek {
2332892fe80SMichal Simek 	size_t data_size = 0;
2342892fe80SMichal Simek 	void *fpga_data = NULL;
2352892fe80SMichal Simek #if defined(CONFIG_FIT)
2362892fe80SMichal Simek 	const char *fit_uname = NULL;
2372892fe80SMichal Simek 	ulong fit_addr;
2382892fe80SMichal Simek #endif
2392892fe80SMichal Simek 	ulong dev = do_fpga_get_device(argv[0]);
2402892fe80SMichal Simek 	char *datastr = env_get("fpgadata");
2412892fe80SMichal Simek 
2428c75f794SMichal Simek 	debug("fpga: argc %x, dev %lx, datastr %s\n", argc, dev, datastr);
2438c75f794SMichal Simek 
2448c75f794SMichal Simek 	if (dev == FPGA_INVALID_DEVICE) {
2458c75f794SMichal Simek 		debug("fpga: Invalid fpga device\n");
2468c75f794SMichal Simek 		return CMD_RET_USAGE;
2478c75f794SMichal Simek 	}
2488c75f794SMichal Simek 
2498c75f794SMichal Simek 	if (argc == 0 && !datastr) {
2508c75f794SMichal Simek 		debug("fpga: No datastr passed\n");
2518c75f794SMichal Simek 		return CMD_RET_USAGE;
2528c75f794SMichal Simek 	}
2532892fe80SMichal Simek 
2542892fe80SMichal Simek 	if (argc == 2) {
2558c75f794SMichal Simek 		datastr = argv[1];
2568c75f794SMichal Simek 		debug("fpga: Full command with two args\n");
2578c75f794SMichal Simek 	} else if (argc == 1 && !datastr) {
2588c75f794SMichal Simek 		debug("fpga: Dev is setup - fpgadata passed\n");
2598c75f794SMichal Simek 		datastr = argv[0];
2608c75f794SMichal Simek 	}
2618c75f794SMichal Simek 
2622892fe80SMichal Simek #if defined(CONFIG_FIT)
2638c75f794SMichal Simek 	if (fit_parse_subimage(datastr, (ulong)fpga_data,
2642892fe80SMichal Simek 			       &fit_addr, &fit_uname)) {
2652892fe80SMichal Simek 		fpga_data = (void *)fit_addr;
2662892fe80SMichal Simek 		debug("*  fpga: subimage '%s' from FIT image ",
2672892fe80SMichal Simek 		      fit_uname);
2682892fe80SMichal Simek 		debug("at 0x%08lx\n", fit_addr);
2692892fe80SMichal Simek 	} else
2702892fe80SMichal Simek #endif
2712892fe80SMichal Simek 	{
2728c75f794SMichal Simek 		fpga_data = (void *)simple_strtoul(datastr, NULL, 16);
2732892fe80SMichal Simek 		debug("*  fpga: cmdline image address = 0x%08lx\n",
2742892fe80SMichal Simek 		      (ulong)fpga_data);
2752892fe80SMichal Simek 	}
2762892fe80SMichal Simek 	debug("%s: fpga_data = 0x%lx\n", __func__, (ulong)fpga_data);
2772892fe80SMichal Simek 	if (!fpga_data) {
2782892fe80SMichal Simek 		puts("Zero fpga_data address\n");
2792892fe80SMichal Simek 		return CMD_RET_USAGE;
2802892fe80SMichal Simek 	}
2812892fe80SMichal Simek 
2822892fe80SMichal Simek 	switch (genimg_get_format(fpga_data)) {
2832892fe80SMichal Simek #if defined(CONFIG_IMAGE_FORMAT_LEGACY)
2842892fe80SMichal Simek 	case IMAGE_FORMAT_LEGACY:
2852892fe80SMichal Simek 	{
2862892fe80SMichal Simek 		image_header_t *hdr = (image_header_t *)fpga_data;
2872892fe80SMichal Simek 		ulong data;
2882892fe80SMichal Simek 		u8 comp;
2892892fe80SMichal Simek 
2902892fe80SMichal Simek 		comp = image_get_comp(hdr);
2912892fe80SMichal Simek 		if (comp == IH_COMP_GZIP) {
2922892fe80SMichal Simek #if defined(CONFIG_GZIP)
2932892fe80SMichal Simek 			ulong image_buf = image_get_data(hdr);
2942892fe80SMichal Simek 			ulong image_size = ~0UL;
2952892fe80SMichal Simek 
2962892fe80SMichal Simek 			data = image_get_load(hdr);
2972892fe80SMichal Simek 
2982892fe80SMichal Simek 			if (gunzip((void *)data, ~0UL, (void *)image_buf,
2992892fe80SMichal Simek 				   &image_size) != 0) {
3002892fe80SMichal Simek 				puts("GUNZIP: error\n");
301a2d1033bSMichal Simek 				return CMD_RET_FAILURE;
3022892fe80SMichal Simek 			}
3032892fe80SMichal Simek 			data_size = image_size;
3042892fe80SMichal Simek #else
3052892fe80SMichal Simek 			puts("Gunzip image is not supported\n");
3062892fe80SMichal Simek 			return 1;
3072892fe80SMichal Simek #endif
3082892fe80SMichal Simek 		} else {
3092892fe80SMichal Simek 			data = (ulong)image_get_data(hdr);
3102892fe80SMichal Simek 			data_size = image_get_data_size(hdr);
3112892fe80SMichal Simek 		}
3122892fe80SMichal Simek 		return fpga_load(dev, (void *)data, data_size,
3132892fe80SMichal Simek 				  BIT_FULL);
3142892fe80SMichal Simek 	}
3152892fe80SMichal Simek #endif
3162892fe80SMichal Simek #if defined(CONFIG_FIT)
3172892fe80SMichal Simek 	case IMAGE_FORMAT_FIT:
3182892fe80SMichal Simek 	{
3192892fe80SMichal Simek 		const void *fit_hdr = (const void *)fpga_data;
3202892fe80SMichal Simek 		int noffset;
3212892fe80SMichal Simek 		const void *fit_data;
3222892fe80SMichal Simek 
3232892fe80SMichal Simek 		if (!fit_uname) {
3242892fe80SMichal Simek 			puts("No FIT subimage unit name\n");
325a2d1033bSMichal Simek 			return CMD_RET_FAILURE;
3262892fe80SMichal Simek 		}
3272892fe80SMichal Simek 
3282892fe80SMichal Simek 		if (!fit_check_format(fit_hdr)) {
3292892fe80SMichal Simek 			puts("Bad FIT image format\n");
330a2d1033bSMichal Simek 			return CMD_RET_FAILURE;
3312892fe80SMichal Simek 		}
3322892fe80SMichal Simek 
3332892fe80SMichal Simek 		/* get fpga component image node offset */
3342892fe80SMichal Simek 		noffset = fit_image_get_node(fit_hdr, fit_uname);
3352892fe80SMichal Simek 		if (noffset < 0) {
3362892fe80SMichal Simek 			printf("Can't find '%s' FIT subimage\n", fit_uname);
337a2d1033bSMichal Simek 			return CMD_RET_FAILURE;
3382892fe80SMichal Simek 		}
3392892fe80SMichal Simek 
3402892fe80SMichal Simek 		/* verify integrity */
3412892fe80SMichal Simek 		if (!fit_image_verify(fit_hdr, noffset)) {
3422892fe80SMichal Simek 			puts("Bad Data Hash\n");
343a2d1033bSMichal Simek 			return CMD_RET_FAILURE;
3442892fe80SMichal Simek 		}
3452892fe80SMichal Simek 
3462892fe80SMichal Simek 		/* get fpga subimage data address and length */
3472892fe80SMichal Simek 		if (fit_image_get_data(fit_hdr, noffset, &fit_data,
3482892fe80SMichal Simek 				       &data_size)) {
3492892fe80SMichal Simek 			puts("Fpga subimage data not found\n");
350a2d1033bSMichal Simek 			return CMD_RET_FAILURE;
3512892fe80SMichal Simek 		}
3522892fe80SMichal Simek 
3532892fe80SMichal Simek 		return fpga_load(dev, fit_data, data_size, BIT_FULL);
3542892fe80SMichal Simek 	}
3552892fe80SMichal Simek #endif
3562892fe80SMichal Simek 	default:
3572892fe80SMichal Simek 		puts("** Unknown image type\n");
358a2d1033bSMichal Simek 		return CMD_RET_FAILURE;
3592892fe80SMichal Simek 	}
3602892fe80SMichal Simek }
3612892fe80SMichal Simek #endif
3622892fe80SMichal Simek 
3639657d97cSMichal Simek static cmd_tbl_t fpga_commands[] = {
364f4c7a4aeSMichal Simek 	U_BOOT_CMD_MKENT(info, 1, 1, do_fpga_info, "", ""),
36585754795SMichal Simek 	U_BOOT_CMD_MKENT(dump, 3, 1, do_fpga_dump, "", ""),
36685754795SMichal Simek 	U_BOOT_CMD_MKENT(load, 3, 1, do_fpga_load, "", ""),
36785754795SMichal Simek 	U_BOOT_CMD_MKENT(loadb, 3, 1, do_fpga_loadb, "", ""),
36885754795SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADP)
36985754795SMichal Simek 	U_BOOT_CMD_MKENT(loadp, 3, 1, do_fpga_loadp, "", ""),
37085754795SMichal Simek #endif
37185754795SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADBP)
37285754795SMichal Simek 	U_BOOT_CMD_MKENT(loadbp, 3, 1, do_fpga_loadbp, "", ""),
37385754795SMichal Simek #endif
37449503f9aSMichal Simek #if defined(CONFIG_CMD_FPGA_LOADFS)
37549503f9aSMichal Simek 	U_BOOT_CMD_MKENT(loadfs, 7, 1, do_fpga_loadfs, "", ""),
37649503f9aSMichal Simek #endif
3772892fe80SMichal Simek #if defined(CONFIG_CMD_FPGA_LOADMK)
3782892fe80SMichal Simek 	U_BOOT_CMD_MKENT(loadmk, 2, 1, do_fpga_loadmk, "", ""),
3792892fe80SMichal Simek #endif
380*b5d19a93SMichal Simek #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
381*b5d19a93SMichal Simek 	U_BOOT_CMD_MKENT(loads, 6, 1, do_fpga_loads, "", ""),
382*b5d19a93SMichal Simek #endif
3839657d97cSMichal Simek };
3849657d97cSMichal Simek 
do_fpga_wrapper(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])3859657d97cSMichal Simek static int do_fpga_wrapper(cmd_tbl_t *cmdtp, int flag, int argc,
3869657d97cSMichal Simek 			   char *const argv[])
3879657d97cSMichal Simek {
3889657d97cSMichal Simek 	cmd_tbl_t *fpga_cmd;
3899657d97cSMichal Simek 	int ret;
3909657d97cSMichal Simek 
3919657d97cSMichal Simek 	if (argc < 2)
3929657d97cSMichal Simek 		return CMD_RET_USAGE;
3939657d97cSMichal Simek 
3949657d97cSMichal Simek 	fpga_cmd = find_cmd_tbl(argv[1], fpga_commands,
3959657d97cSMichal Simek 				ARRAY_SIZE(fpga_commands));
3969657d97cSMichal Simek 	if (!fpga_cmd) {
3979657d97cSMichal Simek 		debug("fpga: non existing command\n");
3989657d97cSMichal Simek 		return CMD_RET_USAGE;
3999657d97cSMichal Simek 	}
4009657d97cSMichal Simek 
4019657d97cSMichal Simek 	argc -= 2;
4029657d97cSMichal Simek 	argv += 2;
4039657d97cSMichal Simek 
4049657d97cSMichal Simek 	if (argc > fpga_cmd->maxargs) {
4059657d97cSMichal Simek 		debug("fpga: more parameters passed\n");
4069657d97cSMichal Simek 		return CMD_RET_USAGE;
4079657d97cSMichal Simek 	}
4089657d97cSMichal Simek 
4099657d97cSMichal Simek 	ret = fpga_cmd->cmd(fpga_cmd, flag, argc, argv);
4109657d97cSMichal Simek 
4119657d97cSMichal Simek 	return cmd_process_error(fpga_cmd, ret);
4129657d97cSMichal Simek }
4139657d97cSMichal Simek 
414cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOADFS) || defined(CONFIG_CMD_FPGA_LOAD_SECURE)
4159657d97cSMichal Simek U_BOOT_CMD(fpga, 9, 1, do_fpga_wrapper,
4162e192b24SSimon Glass #else
4179657d97cSMichal Simek U_BOOT_CMD(fpga, 6, 1, do_fpga_wrapper,
4182e192b24SSimon Glass #endif
4192e192b24SSimon Glass 	   "loadable FPGA image support",
4202e192b24SSimon Glass 	   "[operation type] [device number] [image address] [image size]\n"
4212e192b24SSimon Glass 	   "fpga operations:\n"
4222e192b24SSimon Glass 	   "  dump\t[dev] [address] [size]\tLoad device to memory buffer\n"
4232e192b24SSimon Glass 	   "  info\t[dev]\t\t\tlist known device information\n"
4242e192b24SSimon Glass 	   "  load\t[dev] [address] [size]\tLoad device from memory buffer\n"
4252e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADP)
4262e192b24SSimon Glass 	   "  loadp\t[dev] [address] [size]\t"
4272e192b24SSimon Glass 	   "Load device from memory buffer with partial bitstream\n"
4282e192b24SSimon Glass #endif
4292e192b24SSimon Glass 	   "  loadb\t[dev] [address] [size]\t"
4302e192b24SSimon Glass 	   "Load device from bitstream buffer (Xilinx only)\n"
4312e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADBP)
4322e192b24SSimon Glass 	   "  loadbp\t[dev] [address] [size]\t"
4332e192b24SSimon Glass 	   "Load device from bitstream buffer with partial bitstream"
4342e192b24SSimon Glass 	   "(Xilinx only)\n"
4352e192b24SSimon Glass #endif
4362e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADFS)
4372e192b24SSimon Glass 	   "Load device from filesystem (FAT by default) (Xilinx only)\n"
4382e192b24SSimon Glass 	   "  loadfs [dev] [address] [image size] [blocksize] <interface>\n"
4392e192b24SSimon Glass 	   "        [<dev[:part]>] <filename>\n"
4402e192b24SSimon Glass #endif
4412e192b24SSimon Glass #if defined(CONFIG_CMD_FPGA_LOADMK)
4422e192b24SSimon Glass 	   "  loadmk [dev] [address]\tLoad device generated with mkimage"
4432e192b24SSimon Glass #if defined(CONFIG_FIT)
4442e192b24SSimon Glass 	   "\n"
4452e192b24SSimon Glass 	   "\tFor loadmk operating on FIT format uImage address must include\n"
4462e192b24SSimon Glass 	   "\tsubimage unit name in the form of addr:<subimg_uname>"
4472e192b24SSimon Glass #endif
4482e192b24SSimon Glass #endif
449cedd48e2SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
450cedd48e2SSiva Durga Prasad Paladugu 	   "Load encrypted bitstream (Xilinx only)\n"
451cedd48e2SSiva Durga Prasad Paladugu 	   "  loads [dev] [address] [size] [auth-OCM-0/DDR-1/noauth-2]\n"
452cedd48e2SSiva Durga Prasad Paladugu 	   "        [enc-devkey(0)/userkey(1)/nenc(2) [Userkey address]\n"
453cedd48e2SSiva Durga Prasad Paladugu 	   "Loads the secure bistreams(authenticated/encrypted/both\n"
454cedd48e2SSiva Durga Prasad Paladugu 	   "authenticated and encrypted) of [size] from [address].\n"
455cedd48e2SSiva Durga Prasad Paladugu 	   "The auth-OCM/DDR flag specifies to perform authentication\n"
456cedd48e2SSiva Durga Prasad Paladugu 	   "in OCM or in DDR. 0 for OCM, 1 for DDR, 2 for no authentication.\n"
457cedd48e2SSiva Durga Prasad Paladugu 	   "The enc flag specifies which key to be used for decryption\n"
458cedd48e2SSiva Durga Prasad Paladugu 	   "0-device key, 1-user key, 2-no encryption.\n"
459cedd48e2SSiva Durga Prasad Paladugu 	   "The optional Userkey address specifies from which address key\n"
460cedd48e2SSiva Durga Prasad Paladugu 	   "has to be used for decryption if user key is selected.\n"
461cedd48e2SSiva Durga Prasad Paladugu 	   "NOTE: the sceure bitstream has to be created using xilinx\n"
462cedd48e2SSiva Durga Prasad Paladugu 	   "bootgen tool only.\n"
463cedd48e2SSiva Durga Prasad Paladugu #endif
4642e192b24SSimon Glass );
465