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#include <display_options.h>
15
16#include <gdsys_fpga.h>
17
18static uint	dp_last_fpga;
19static uint	dp_last_addr;
20static uint	dp_last_length = 0x40;
21
22/*
23 * FPGA Memory Display
24 *
25 * Syntax:
26 *	fpgad {fpga} {addr} {len}
27 */
28#define DISP_LINE_LEN	16
29int do_fpga_md(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
30{
31	unsigned int k;
32	unsigned int fpga;
33	ulong	addr, length;
34	int rc = 0;
35	u16 linebuf[DISP_LINE_LEN/sizeof(u16)];
36	ulong nbytes;
37
38	/*
39	 * We use the last specified parameters, unless new ones are
40	 * entered.
41	 */
42	fpga = dp_last_fpga;
43	addr = dp_last_addr;
44	length = dp_last_length;
45
46	if (argc < 3)
47		return CMD_RET_USAGE;
48
49	if ((flag & CMD_FLAG_REPEAT) == 0) {
50		/*
51		 * FPGA is specified since argc > 2
52		 */
53		fpga = hextoul(argv[1], NULL);
54
55		/*
56		 * Address is specified since argc > 2
57		 */
58		addr = hextoul(argv[2], NULL);
59
60		/*
61		 * If another parameter, it is the length to display.
62		 * Length is the number of objects, not number of bytes.
63		 */
64		if (argc > 3)
65			length = hextoul(argv[3], NULL);
66	}
67
68	nbytes = length * sizeof(u16);
69	do {
70		ulong linebytes = (nbytes > DISP_LINE_LEN) ?
71				  DISP_LINE_LEN : nbytes;
72
73		for (k = 0; k < linebytes / sizeof(u16); ++k)
74			fpga_get_reg(fpga,
75				     (u16 *)fpga_ptr[fpga] + addr
76				     / sizeof(u16) + k,
77				     addr + k * sizeof(u16),
78				     &linebuf[k]);
79		print_buffer(addr, (void *)linebuf, sizeof(u16),
80			     linebytes / sizeof(u16),
81			     DISP_LINE_LEN / sizeof(u16));
82
83		nbytes -= linebytes;
84		addr += linebytes;
85		if (ctrlc()) {
86			rc = 1;
87			break;
88		}
89	} while (nbytes > 0);
90
91	dp_last_fpga = fpga;
92	dp_last_addr = addr;
93	dp_last_length = length;
94	return rc;
95}
96
97U_BOOT_CMD(
98	fpgad,	4,	1,	do_fpga_md,
99	"fpga register display",
100	"fpga address [# of objects]"
101);
102