1 /* 2 * SPDX-License-Identifier: GPL-2.0+ 3 * 4 * (C) Copyright 2018 Rockchip Electronics Co., Ltd 5 * 6 */ 7 8 #include <asm/io.h> 9 #include <common.h> 10 #include <dm.h> 11 #include <fdtdec.h> 12 13 enum ops { 14 SEARCH_NAME, 15 SEARCH_COMP, 16 }; 17 18 void iomem_show(const char *label, unsigned long base, size_t start, size_t end) 19 { 20 unsigned long val, offset = start, nr = 0; 21 22 if (label) 23 printf("%s:\n", label); 24 25 printf("%08lx: ", base + offset); 26 for (offset = start; offset <= end; offset += 0x04) { 27 if (nr >= 4) { 28 printf("\n%08lx: ", base + offset); 29 nr = 0; 30 } 31 val = readl((void __iomem *)base + offset); 32 printf("%08lx ", val); 33 nr++; 34 } 35 printf("\n"); 36 } 37 38 static int iomem_show_by_match(enum ops op, const char *search, 39 size_t start, size_t end) 40 { 41 const void *fdt = gd->fdt_blob; 42 const char *name; 43 fdt_addr_t addr; 44 int found = 0; 45 int offset; 46 47 for (offset = fdt_next_node(fdt, 0, NULL); 48 offset >= 0; 49 offset = fdt_next_node(fdt, offset, NULL)) { 50 if (op == SEARCH_COMP) 51 name = fdt_getprop(fdt, offset, "compatible", NULL); 52 else if (op == SEARCH_NAME) 53 name = fdt_get_name(fdt, offset, NULL); 54 else 55 goto out; 56 57 if (!name) 58 continue; 59 60 if (strstr(name, search)) { 61 addr = fdtdec_get_addr_size_auto_noparent(fdt, offset, 62 "reg", 0, NULL, false); 63 if (addr == FDT_ADDR_T_NONE) 64 goto out; 65 66 iomem_show(name, addr, start, end); 67 found = 1; 68 break; 69 } 70 } 71 printf("\n"); 72 73 out: 74 return found; 75 } 76 77 void iomem_show_by_compatible(const char *compat, size_t start, size_t end) 78 { 79 iomem_show_by_match(SEARCH_COMP, compat, start, end); 80 } 81 82 static int do_iomem_by_match(cmd_tbl_t *cmdtp, int flag, 83 int argc, char *const argv[]) 84 { 85 size_t start, end; 86 const char *search; 87 88 if (argc != 4) 89 return CMD_RET_USAGE; 90 91 search = argv[1]; 92 start = simple_strtoul(argv[2], NULL, 0); 93 end = simple_strtoul(argv[3], NULL, 0); 94 95 if (!iomem_show_by_match(SEARCH_COMP, search, start, end)) 96 iomem_show_by_match(SEARCH_NAME, search, start, end); 97 98 return 0; 99 } 100 101 U_BOOT_CMD( 102 iomem, 4, 1, do_iomem_by_match, 103 "Show iomem data by device compatible(high priority) or node name", 104 "iomem <compatible or node name> <start offset> <end offset>\n" 105 " eg: iomem -grf 0x0 0x200" 106 " eg: iomem gpio3 0x0 0x200" 107 ); 108