xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/iomem.c (revision d035dcf8b31a7ebde50aef2fc4975a27c8a32e58)
1737e1216SJoseph Chen /*
2737e1216SJoseph Chen  * SPDX-License-Identifier:     GPL-2.0+
3737e1216SJoseph Chen  *
4737e1216SJoseph Chen  * (C) Copyright 2018 Rockchip Electronics Co., Ltd
5737e1216SJoseph Chen  *
6737e1216SJoseph Chen  */
7737e1216SJoseph Chen 
8737e1216SJoseph Chen #include <asm/io.h>
9737e1216SJoseph Chen #include <common.h>
10737e1216SJoseph Chen #include <dm.h>
11737e1216SJoseph Chen #include <fdtdec.h>
12737e1216SJoseph Chen 
13fe2fac95SJoseph Chen enum ops {
14fe2fac95SJoseph Chen 	SEARCH_NAME,
15fe2fac95SJoseph Chen 	SEARCH_COMP,
16fe2fac95SJoseph Chen };
17fe2fac95SJoseph Chen 
iomem_show(const char * label,unsigned long base,size_t start,size_t end)18737e1216SJoseph Chen void iomem_show(const char *label, unsigned long base, size_t start, size_t end)
19737e1216SJoseph Chen {
20737e1216SJoseph Chen 	unsigned long val, offset = start, nr = 0;
21737e1216SJoseph Chen 
22737e1216SJoseph Chen 	if (label)
23737e1216SJoseph Chen 		printf("%s:\n", label);
24737e1216SJoseph Chen 
25737e1216SJoseph Chen 	printf("%08lx:  ", base + offset);
26737e1216SJoseph Chen 	for (offset = start; offset <= end; offset += 0x04) {
27737e1216SJoseph Chen 		if (nr >= 4) {
28737e1216SJoseph Chen 			printf("\n%08lx:  ", base + offset);
29737e1216SJoseph Chen 			nr = 0;
30737e1216SJoseph Chen 		}
31737e1216SJoseph Chen 		val = readl((void __iomem *)base + offset);
32737e1216SJoseph Chen 		printf("%08lx ", val);
33737e1216SJoseph Chen 		nr++;
34737e1216SJoseph Chen 	}
35737e1216SJoseph Chen 	printf("\n");
36737e1216SJoseph Chen }
37737e1216SJoseph Chen 
iomem_show_by_match(enum ops op,const char * search,size_t start,size_t end)38fe2fac95SJoseph Chen static int iomem_show_by_match(enum ops op, const char *search,
39fe2fac95SJoseph Chen 			       size_t start, size_t end)
40737e1216SJoseph Chen {
41737e1216SJoseph Chen 	const void *fdt = gd->fdt_blob;
42fe2fac95SJoseph Chen 	const char *name;
43737e1216SJoseph Chen 	fdt_addr_t addr;
44fe2fac95SJoseph Chen 	int found = 0;
45737e1216SJoseph Chen 	int offset;
46737e1216SJoseph Chen 
47737e1216SJoseph Chen 	for (offset = fdt_next_node(fdt, 0, NULL);
48737e1216SJoseph Chen 	     offset >= 0;
49737e1216SJoseph Chen 	     offset = fdt_next_node(fdt, offset, NULL)) {
50fe2fac95SJoseph Chen 		if (op == SEARCH_COMP)
51fe2fac95SJoseph Chen 			name = fdt_getprop(fdt, offset, "compatible", NULL);
52fe2fac95SJoseph Chen 		else if (op == SEARCH_NAME)
53fe2fac95SJoseph Chen 			name = fdt_get_name(fdt, offset, NULL);
54fe2fac95SJoseph Chen 		else
55fe2fac95SJoseph Chen 			goto out;
56fe2fac95SJoseph Chen 
57fe2fac95SJoseph Chen 		if (!name)
58737e1216SJoseph Chen 			continue;
59737e1216SJoseph Chen 
60fe2fac95SJoseph Chen 		if (strstr(name, search)) {
61737e1216SJoseph Chen 			addr = fdtdec_get_addr_size_auto_noparent(fdt, offset,
62737e1216SJoseph Chen 							"reg", 0, NULL, false);
63fe2fac95SJoseph Chen 			if (addr == FDT_ADDR_T_NONE)
64fe2fac95SJoseph Chen 				goto out;
65fe2fac95SJoseph Chen 
66fe2fac95SJoseph Chen 			iomem_show(name, addr, start, end);
67fe2fac95SJoseph Chen 			found = 1;
68737e1216SJoseph Chen 			break;
69737e1216SJoseph Chen 		}
70737e1216SJoseph Chen 	}
71737e1216SJoseph Chen 	printf("\n");
72fe2fac95SJoseph Chen 
73fe2fac95SJoseph Chen out:
74fe2fac95SJoseph Chen 	return found;
75737e1216SJoseph Chen }
76737e1216SJoseph Chen 
iomem_show_by_compatible(const char * compat,size_t start,size_t end)77fe2fac95SJoseph Chen void iomem_show_by_compatible(const char *compat, size_t start, size_t end)
78fe2fac95SJoseph Chen {
79fe2fac95SJoseph Chen 	iomem_show_by_match(SEARCH_COMP, compat, start, end);
80fe2fac95SJoseph Chen }
81fe2fac95SJoseph Chen 
do_iomem_by_match(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])82fe2fac95SJoseph Chen static int do_iomem_by_match(cmd_tbl_t *cmdtp, int flag,
83fe2fac95SJoseph Chen 			     int argc, char *const argv[])
84737e1216SJoseph Chen {
85737e1216SJoseph Chen 	size_t start, end;
86fe2fac95SJoseph Chen 	const char *search;
87737e1216SJoseph Chen 
88737e1216SJoseph Chen 	if (argc != 4)
89737e1216SJoseph Chen 		return CMD_RET_USAGE;
90737e1216SJoseph Chen 
91fe2fac95SJoseph Chen 	search = argv[1];
92737e1216SJoseph Chen 	start = simple_strtoul(argv[2], NULL, 0);
93737e1216SJoseph Chen 	end = simple_strtoul(argv[3], NULL, 0);
94*d035dcf8SJoseph Chen 	if (start > end) {
95*d035dcf8SJoseph Chen 		printf("Invalid: 0x%lx > 0x%lx\n", (ulong)start, (ulong)end);
96*d035dcf8SJoseph Chen 		return CMD_RET_FAILURE;
97*d035dcf8SJoseph Chen 	}
98737e1216SJoseph Chen 
99fe2fac95SJoseph Chen 	if (!iomem_show_by_match(SEARCH_COMP, search, start, end))
100fe2fac95SJoseph Chen 		iomem_show_by_match(SEARCH_NAME, search, start, end);
101737e1216SJoseph Chen 
102737e1216SJoseph Chen 	return 0;
103737e1216SJoseph Chen }
104737e1216SJoseph Chen 
105737e1216SJoseph Chen U_BOOT_CMD(
106fe2fac95SJoseph Chen 	iomem, 4, 1, do_iomem_by_match,
107fe2fac95SJoseph Chen 	"Show iomem data by device compatible(high priority) or node name",
108fe2fac95SJoseph Chen 	"iomem <compatible or node name> <start offset>  <end offset>\n"
109737e1216SJoseph Chen 	"  eg: iomem -grf  0x0 0x200"
110fe2fac95SJoseph Chen 	"  eg: iomem gpio3 0x0 0x200"
111737e1216SJoseph Chen );
112