1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2013
4  * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc
5  *
6  * based on cmd_mem.c
7  * (C) Copyright 2000
8  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
9  */
10 
11 #include <common.h>
12 #include <command.h>
13 #include <console.h>
14 
15 #include <gdsys_fpga.h>
16 
17 static uint	dp_last_fpga;
18 static uint	dp_last_addr;
19 static uint	dp_last_length = 0x40;
20 
21 /*
22  * FPGA Memory Display
23  *
24  * Syntax:
25  *	fpgad {fpga} {addr} {len}
26  */
27 #define DISP_LINE_LEN	16
do_fpga_md(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])28 int do_fpga_md(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
29 {
30 	unsigned int k;
31 	unsigned int fpga;
32 	ulong	addr, length;
33 	int rc = 0;
34 	u16 linebuf[DISP_LINE_LEN/sizeof(u16)];
35 	ulong nbytes;
36 
37 	/*
38 	 * We use the last specified parameters, unless new ones are
39 	 * entered.
40 	 */
41 	fpga = dp_last_fpga;
42 	addr = dp_last_addr;
43 	length = dp_last_length;
44 
45 	if (argc < 3)
46 		return CMD_RET_USAGE;
47 
48 	if ((flag & CMD_FLAG_REPEAT) == 0) {
49 		/*
50 		 * FPGA is specified since argc > 2
51 		 */
52 		fpga = simple_strtoul(argv[1], NULL, 16);
53 
54 		/*
55 		 * Address is specified since argc > 2
56 		 */
57 		addr = simple_strtoul(argv[2], NULL, 16);
58 
59 		/*
60 		 * If another parameter, it is the length to display.
61 		 * Length is the number of objects, not number of bytes.
62 		 */
63 		if (argc > 3)
64 			length = simple_strtoul(argv[3], NULL, 16);
65 	}
66 
67 	nbytes = length * sizeof(u16);
68 	do {
69 		ulong linebytes = (nbytes > DISP_LINE_LEN) ?
70 				  DISP_LINE_LEN : nbytes;
71 
72 		for (k = 0; k < linebytes / sizeof(u16); ++k)
73 			fpga_get_reg(fpga,
74 				     (u16 *)fpga_ptr[fpga] + addr
75 				     / sizeof(u16) + k,
76 				     addr + k * sizeof(u16),
77 				     &linebuf[k]);
78 		print_buffer(addr, (void *)linebuf, sizeof(u16),
79 			     linebytes / sizeof(u16),
80 			     DISP_LINE_LEN / sizeof(u16));
81 
82 		nbytes -= linebytes;
83 		addr += linebytes;
84 		if (ctrlc()) {
85 			rc = 1;
86 			break;
87 		}
88 	} while (nbytes > 0);
89 
90 	dp_last_fpga = fpga;
91 	dp_last_addr = addr;
92 	dp_last_length = length;
93 	return rc;
94 }
95 
96 U_BOOT_CMD(
97 	fpgad,	4,	1,	do_fpga_md,
98 	"fpga register display",
99 	"fpga address [# of objects]"
100 );
101