1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/debugfs.h> 4 #include <linux/mtd/spi-nor.h> 5 #include <linux/spi/spi.h> 6 #include <linux/spi/spi-mem.h> 7 8 #include "core.h" 9 10 #define SPI_NOR_DEBUGFS_ROOT "spi-nor" 11 12 #define SNOR_F_NAME(name) [ilog2(SNOR_F_##name)] = #name 13 static const char *const snor_f_names[] = { 14 SNOR_F_NAME(HAS_SR_TB), 15 SNOR_F_NAME(NO_OP_CHIP_ERASE), 16 SNOR_F_NAME(BROKEN_RESET), 17 SNOR_F_NAME(4B_OPCODES), 18 SNOR_F_NAME(HAS_4BAIT), 19 SNOR_F_NAME(HAS_LOCK), 20 SNOR_F_NAME(HAS_16BIT_SR), 21 SNOR_F_NAME(NO_READ_CR), 22 SNOR_F_NAME(HAS_SR_TB_BIT6), 23 SNOR_F_NAME(HAS_4BIT_BP), 24 SNOR_F_NAME(HAS_SR_BP3_BIT6), 25 SNOR_F_NAME(IO_MODE_EN_VOLATILE), 26 SNOR_F_NAME(SOFT_RESET), 27 SNOR_F_NAME(SWP_IS_VOLATILE), 28 }; 29 #undef SNOR_F_NAME 30 31 static const char *spi_nor_protocol_name(enum spi_nor_protocol proto) 32 { 33 switch (proto) { 34 case SNOR_PROTO_1_1_1: return "1S-1S-1S"; 35 case SNOR_PROTO_1_1_2: return "1S-1S-2S"; 36 case SNOR_PROTO_1_1_4: return "1S-1S-4S"; 37 case SNOR_PROTO_1_1_8: return "1S-1S-8S"; 38 case SNOR_PROTO_1_2_2: return "1S-2S-2S"; 39 case SNOR_PROTO_1_4_4: return "1S-4S-4S"; 40 case SNOR_PROTO_1_8_8: return "1S-8S-8S"; 41 case SNOR_PROTO_2_2_2: return "2S-2S-2S"; 42 case SNOR_PROTO_4_4_4: return "4S-4S-4S"; 43 case SNOR_PROTO_8_8_8: return "8S-8S-8S"; 44 case SNOR_PROTO_1_1_1_DTR: return "1D-1D-1D"; 45 case SNOR_PROTO_1_2_2_DTR: return "1D-2D-2D"; 46 case SNOR_PROTO_1_4_4_DTR: return "1D-4D-4D"; 47 case SNOR_PROTO_1_8_8_DTR: return "1D-8D-8D"; 48 case SNOR_PROTO_8_8_8_DTR: return "8D-8D-8D"; 49 } 50 51 return "<unknown>"; 52 } 53 54 static void spi_nor_print_flags(struct seq_file *s, unsigned long flags, 55 const char *const *names, int names_len) 56 { 57 bool sep = false; 58 int i; 59 60 for (i = 0; i < sizeof(flags) * BITS_PER_BYTE; i++) { 61 if (!(flags & BIT(i))) 62 continue; 63 if (sep) 64 seq_puts(s, " | "); 65 sep = true; 66 if (i < names_len && names[i]) 67 seq_puts(s, names[i]); 68 else 69 seq_printf(s, "1<<%d", i); 70 } 71 } 72 73 static int spi_nor_params_show(struct seq_file *s, void *data) 74 { 75 struct spi_nor *nor = s->private; 76 struct spi_nor_flash_parameter *params = nor->params; 77 struct spi_nor_erase_map *erase_map = ¶ms->erase_map; 78 struct spi_nor_erase_region *region; 79 const struct flash_info *info = nor->info; 80 char buf[16], *str; 81 int i; 82 83 seq_printf(s, "name\t\t%s\n", info->name); 84 seq_printf(s, "id\t\t%*ph\n", SPI_NOR_MAX_ID_LEN, nor->id); 85 string_get_size(params->size, 1, STRING_UNITS_2, buf, sizeof(buf)); 86 seq_printf(s, "size\t\t%s\n", buf); 87 seq_printf(s, "write size\t%u\n", params->writesize); 88 seq_printf(s, "page size\t%u\n", params->page_size); 89 seq_printf(s, "address nbytes\t%u\n", nor->addr_nbytes); 90 91 seq_puts(s, "flags\t\t"); 92 spi_nor_print_flags(s, nor->flags, snor_f_names, sizeof(snor_f_names)); 93 seq_puts(s, "\n"); 94 95 seq_puts(s, "\nopcodes\n"); 96 seq_printf(s, " read\t\t0x%02x\n", nor->read_opcode); 97 seq_printf(s, " dummy cycles\t%u\n", nor->read_dummy); 98 seq_printf(s, " erase\t\t0x%02x\n", nor->erase_opcode); 99 seq_printf(s, " program\t0x%02x\n", nor->program_opcode); 100 101 switch (nor->cmd_ext_type) { 102 case SPI_NOR_EXT_NONE: 103 str = "none"; 104 break; 105 case SPI_NOR_EXT_REPEAT: 106 str = "repeat"; 107 break; 108 case SPI_NOR_EXT_INVERT: 109 str = "invert"; 110 break; 111 default: 112 str = "<unknown>"; 113 break; 114 } 115 seq_printf(s, " 8D extension\t%s\n", str); 116 117 seq_puts(s, "\nprotocols\n"); 118 seq_printf(s, " read\t\t%s\n", 119 spi_nor_protocol_name(nor->read_proto)); 120 seq_printf(s, " write\t\t%s\n", 121 spi_nor_protocol_name(nor->write_proto)); 122 seq_printf(s, " register\t%s\n", 123 spi_nor_protocol_name(nor->reg_proto)); 124 125 seq_puts(s, "\nerase commands\n"); 126 for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) { 127 struct spi_nor_erase_type *et = &erase_map->erase_type[i]; 128 129 if (et->size) { 130 string_get_size(et->size, 1, STRING_UNITS_2, buf, 131 sizeof(buf)); 132 seq_printf(s, " %02x (%s) [%d]\n", et->opcode, buf, i); 133 } 134 } 135 136 if (!(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) { 137 string_get_size(params->size, 1, STRING_UNITS_2, buf, sizeof(buf)); 138 seq_printf(s, " %02x (%s)\n", SPINOR_OP_CHIP_ERASE, buf); 139 } 140 141 seq_puts(s, "\nsector map\n"); 142 seq_puts(s, " region (in hex) | erase mask | flags\n"); 143 seq_puts(s, " ------------------+------------+----------\n"); 144 for (region = erase_map->regions; 145 region; 146 region = spi_nor_region_next(region)) { 147 u64 start = region->offset & ~SNOR_ERASE_FLAGS_MASK; 148 u64 flags = region->offset & SNOR_ERASE_FLAGS_MASK; 149 u64 end = start + region->size - 1; 150 151 seq_printf(s, " %08llx-%08llx | [%c%c%c%c] | %s\n", 152 start, end, 153 flags & BIT(0) ? '0' : ' ', 154 flags & BIT(1) ? '1' : ' ', 155 flags & BIT(2) ? '2' : ' ', 156 flags & BIT(3) ? '3' : ' ', 157 flags & SNOR_OVERLAID_REGION ? "overlaid" : ""); 158 } 159 160 return 0; 161 } 162 DEFINE_SHOW_ATTRIBUTE(spi_nor_params); 163 164 static void spi_nor_print_read_cmd(struct seq_file *s, u32 cap, 165 struct spi_nor_read_command *cmd) 166 { 167 seq_printf(s, " %s%s\n", spi_nor_protocol_name(cmd->proto), 168 cap == SNOR_HWCAPS_READ_FAST ? " (fast read)" : ""); 169 seq_printf(s, " opcode\t0x%02x\n", cmd->opcode); 170 seq_printf(s, " mode cycles\t%u\n", cmd->num_mode_clocks); 171 seq_printf(s, " dummy cycles\t%u\n", cmd->num_wait_states); 172 } 173 174 static void spi_nor_print_pp_cmd(struct seq_file *s, 175 struct spi_nor_pp_command *cmd) 176 { 177 seq_printf(s, " %s\n", spi_nor_protocol_name(cmd->proto)); 178 seq_printf(s, " opcode\t0x%02x\n", cmd->opcode); 179 } 180 181 static int spi_nor_capabilities_show(struct seq_file *s, void *data) 182 { 183 struct spi_nor *nor = s->private; 184 struct spi_nor_flash_parameter *params = nor->params; 185 u32 hwcaps = params->hwcaps.mask; 186 int i, cmd; 187 188 seq_puts(s, "Supported read modes by the flash\n"); 189 for (i = 0; i < sizeof(hwcaps) * BITS_PER_BYTE; i++) { 190 if (!(hwcaps & BIT(i))) 191 continue; 192 193 cmd = spi_nor_hwcaps_read2cmd(BIT(i)); 194 if (cmd < 0) 195 continue; 196 197 spi_nor_print_read_cmd(s, BIT(i), ¶ms->reads[cmd]); 198 hwcaps &= ~BIT(i); 199 } 200 201 seq_puts(s, "\nSupported page program modes by the flash\n"); 202 for (i = 0; i < sizeof(hwcaps) * BITS_PER_BYTE; i++) { 203 if (!(hwcaps & BIT(i))) 204 continue; 205 206 cmd = spi_nor_hwcaps_pp2cmd(BIT(i)); 207 if (cmd < 0) 208 continue; 209 210 spi_nor_print_pp_cmd(s, ¶ms->page_programs[cmd]); 211 hwcaps &= ~BIT(i); 212 } 213 214 if (hwcaps) 215 seq_printf(s, "\nunknown hwcaps 0x%x\n", hwcaps); 216 217 return 0; 218 } 219 DEFINE_SHOW_ATTRIBUTE(spi_nor_capabilities); 220 221 static void spi_nor_debugfs_unregister(void *data) 222 { 223 struct spi_nor *nor = data; 224 225 debugfs_remove(nor->debugfs_root); 226 nor->debugfs_root = NULL; 227 } 228 229 static struct dentry *rootdir; 230 231 void spi_nor_debugfs_register(struct spi_nor *nor) 232 { 233 struct dentry *d; 234 int ret; 235 236 if (!rootdir) 237 rootdir = debugfs_create_dir(SPI_NOR_DEBUGFS_ROOT, NULL); 238 239 ret = devm_add_action(nor->dev, spi_nor_debugfs_unregister, nor); 240 if (ret) 241 return; 242 243 d = debugfs_create_dir(dev_name(nor->dev), rootdir); 244 nor->debugfs_root = d; 245 246 debugfs_create_file("params", 0444, d, nor, &spi_nor_params_fops); 247 debugfs_create_file("capabilities", 0444, d, nor, 248 &spi_nor_capabilities_fops); 249 } 250 251 void spi_nor_debugfs_shutdown(void) 252 { 253 debugfs_remove(rootdir); 254 } 255