0001
0002
0003 #include <linux/mtd/spi-nor.h>
0004 #include <linux/spi/spi.h>
0005 #include <linux/spi/spi-mem.h>
0006 #include <linux/debugfs.h>
0007
0008 #include "core.h"
0009
0010 #define SPI_NOR_DEBUGFS_ROOT "spi-nor"
0011
0012 #define SNOR_F_NAME(name) [ilog2(SNOR_F_##name)] = #name
0013 static const char *const snor_f_names[] = {
0014 SNOR_F_NAME(HAS_SR_TB),
0015 SNOR_F_NAME(NO_OP_CHIP_ERASE),
0016 SNOR_F_NAME(BROKEN_RESET),
0017 SNOR_F_NAME(4B_OPCODES),
0018 SNOR_F_NAME(HAS_4BAIT),
0019 SNOR_F_NAME(HAS_LOCK),
0020 SNOR_F_NAME(HAS_16BIT_SR),
0021 SNOR_F_NAME(NO_READ_CR),
0022 SNOR_F_NAME(HAS_SR_TB_BIT6),
0023 SNOR_F_NAME(HAS_4BIT_BP),
0024 SNOR_F_NAME(HAS_SR_BP3_BIT6),
0025 SNOR_F_NAME(IO_MODE_EN_VOLATILE),
0026 SNOR_F_NAME(SOFT_RESET),
0027 SNOR_F_NAME(SWP_IS_VOLATILE),
0028 };
0029 #undef SNOR_F_NAME
0030
0031 static const char *spi_nor_protocol_name(enum spi_nor_protocol proto)
0032 {
0033 switch (proto) {
0034 case SNOR_PROTO_1_1_1: return "1S-1S-1S";
0035 case SNOR_PROTO_1_1_2: return "1S-1S-2S";
0036 case SNOR_PROTO_1_1_4: return "1S-1S-4S";
0037 case SNOR_PROTO_1_1_8: return "1S-1S-8S";
0038 case SNOR_PROTO_1_2_2: return "1S-2S-2S";
0039 case SNOR_PROTO_1_4_4: return "1S-4S-4S";
0040 case SNOR_PROTO_1_8_8: return "1S-8S-8S";
0041 case SNOR_PROTO_2_2_2: return "2S-2S-2S";
0042 case SNOR_PROTO_4_4_4: return "4S-4S-4S";
0043 case SNOR_PROTO_8_8_8: return "8S-8S-8S";
0044 case SNOR_PROTO_1_1_1_DTR: return "1D-1D-1D";
0045 case SNOR_PROTO_1_2_2_DTR: return "1D-2D-2D";
0046 case SNOR_PROTO_1_4_4_DTR: return "1D-4D-4D";
0047 case SNOR_PROTO_1_8_8_DTR: return "1D-8D-8D";
0048 case SNOR_PROTO_8_8_8_DTR: return "8D-8D-8D";
0049 }
0050
0051 return "<unknown>";
0052 }
0053
0054 static void spi_nor_print_flags(struct seq_file *s, unsigned long flags,
0055 const char *const *names, int names_len)
0056 {
0057 bool sep = false;
0058 int i;
0059
0060 for (i = 0; i < sizeof(flags) * BITS_PER_BYTE; i++) {
0061 if (!(flags & BIT(i)))
0062 continue;
0063 if (sep)
0064 seq_puts(s, " | ");
0065 sep = true;
0066 if (i < names_len && names[i])
0067 seq_puts(s, names[i]);
0068 else
0069 seq_printf(s, "1<<%d", i);
0070 }
0071 }
0072
0073 static int spi_nor_params_show(struct seq_file *s, void *data)
0074 {
0075 struct spi_nor *nor = s->private;
0076 struct spi_nor_flash_parameter *params = nor->params;
0077 struct spi_nor_erase_map *erase_map = ¶ms->erase_map;
0078 struct spi_nor_erase_region *region;
0079 const struct flash_info *info = nor->info;
0080 char buf[16], *str;
0081 int i;
0082
0083 seq_printf(s, "name\t\t%s\n", info->name);
0084 seq_printf(s, "id\t\t%*ph\n", info->id_len, info->id);
0085 string_get_size(params->size, 1, STRING_UNITS_2, buf, sizeof(buf));
0086 seq_printf(s, "size\t\t%s\n", buf);
0087 seq_printf(s, "write size\t%u\n", params->writesize);
0088 seq_printf(s, "page size\t%u\n", params->page_size);
0089 seq_printf(s, "address nbytes\t%u\n", nor->addr_nbytes);
0090
0091 seq_puts(s, "flags\t\t");
0092 spi_nor_print_flags(s, nor->flags, snor_f_names, sizeof(snor_f_names));
0093 seq_puts(s, "\n");
0094
0095 seq_puts(s, "\nopcodes\n");
0096 seq_printf(s, " read\t\t0x%02x\n", nor->read_opcode);
0097 seq_printf(s, " dummy cycles\t%u\n", nor->read_dummy);
0098 seq_printf(s, " erase\t\t0x%02x\n", nor->erase_opcode);
0099 seq_printf(s, " program\t0x%02x\n", nor->program_opcode);
0100
0101 switch (nor->cmd_ext_type) {
0102 case SPI_NOR_EXT_NONE:
0103 str = "none";
0104 break;
0105 case SPI_NOR_EXT_REPEAT:
0106 str = "repeat";
0107 break;
0108 case SPI_NOR_EXT_INVERT:
0109 str = "invert";
0110 break;
0111 default:
0112 str = "<unknown>";
0113 break;
0114 }
0115 seq_printf(s, " 8D extension\t%s\n", str);
0116
0117 seq_puts(s, "\nprotocols\n");
0118 seq_printf(s, " read\t\t%s\n",
0119 spi_nor_protocol_name(nor->read_proto));
0120 seq_printf(s, " write\t\t%s\n",
0121 spi_nor_protocol_name(nor->write_proto));
0122 seq_printf(s, " register\t%s\n",
0123 spi_nor_protocol_name(nor->reg_proto));
0124
0125 seq_puts(s, "\nerase commands\n");
0126 for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
0127 struct spi_nor_erase_type *et = &erase_map->erase_type[i];
0128
0129 if (et->size) {
0130 string_get_size(et->size, 1, STRING_UNITS_2, buf,
0131 sizeof(buf));
0132 seq_printf(s, " %02x (%s) [%d]\n", et->opcode, buf, i);
0133 }
0134 }
0135
0136 if (!(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
0137 string_get_size(params->size, 1, STRING_UNITS_2, buf, sizeof(buf));
0138 seq_printf(s, " %02x (%s)\n", SPINOR_OP_CHIP_ERASE, buf);
0139 }
0140
0141 seq_puts(s, "\nsector map\n");
0142 seq_puts(s, " region (in hex) | erase mask | flags\n");
0143 seq_puts(s, " ------------------+------------+----------\n");
0144 for (region = erase_map->regions;
0145 region;
0146 region = spi_nor_region_next(region)) {
0147 u64 start = region->offset & ~SNOR_ERASE_FLAGS_MASK;
0148 u64 flags = region->offset & SNOR_ERASE_FLAGS_MASK;
0149 u64 end = start + region->size - 1;
0150
0151 seq_printf(s, " %08llx-%08llx | [%c%c%c%c] | %s\n",
0152 start, end,
0153 flags & BIT(0) ? '0' : ' ',
0154 flags & BIT(1) ? '1' : ' ',
0155 flags & BIT(2) ? '2' : ' ',
0156 flags & BIT(3) ? '3' : ' ',
0157 flags & SNOR_OVERLAID_REGION ? "overlaid" : "");
0158 }
0159
0160 return 0;
0161 }
0162 DEFINE_SHOW_ATTRIBUTE(spi_nor_params);
0163
0164 static void spi_nor_print_read_cmd(struct seq_file *s, u32 cap,
0165 struct spi_nor_read_command *cmd)
0166 {
0167 seq_printf(s, " %s%s\n", spi_nor_protocol_name(cmd->proto),
0168 cap == SNOR_HWCAPS_READ_FAST ? " (fast read)" : "");
0169 seq_printf(s, " opcode\t0x%02x\n", cmd->opcode);
0170 seq_printf(s, " mode cycles\t%u\n", cmd->num_mode_clocks);
0171 seq_printf(s, " dummy cycles\t%u\n", cmd->num_wait_states);
0172 }
0173
0174 static void spi_nor_print_pp_cmd(struct seq_file *s,
0175 struct spi_nor_pp_command *cmd)
0176 {
0177 seq_printf(s, " %s\n", spi_nor_protocol_name(cmd->proto));
0178 seq_printf(s, " opcode\t0x%02x\n", cmd->opcode);
0179 }
0180
0181 static int spi_nor_capabilities_show(struct seq_file *s, void *data)
0182 {
0183 struct spi_nor *nor = s->private;
0184 struct spi_nor_flash_parameter *params = nor->params;
0185 u32 hwcaps = params->hwcaps.mask;
0186 int i, cmd;
0187
0188 seq_puts(s, "Supported read modes by the flash\n");
0189 for (i = 0; i < sizeof(hwcaps) * BITS_PER_BYTE; i++) {
0190 if (!(hwcaps & BIT(i)))
0191 continue;
0192
0193 cmd = spi_nor_hwcaps_read2cmd(BIT(i));
0194 if (cmd < 0)
0195 continue;
0196
0197 spi_nor_print_read_cmd(s, BIT(i), ¶ms->reads[cmd]);
0198 hwcaps &= ~BIT(i);
0199 }
0200
0201 seq_puts(s, "\nSupported page program modes by the flash\n");
0202 for (i = 0; i < sizeof(hwcaps) * BITS_PER_BYTE; i++) {
0203 if (!(hwcaps & BIT(i)))
0204 continue;
0205
0206 cmd = spi_nor_hwcaps_pp2cmd(BIT(i));
0207 if (cmd < 0)
0208 continue;
0209
0210 spi_nor_print_pp_cmd(s, ¶ms->page_programs[cmd]);
0211 hwcaps &= ~BIT(i);
0212 }
0213
0214 if (hwcaps)
0215 seq_printf(s, "\nunknown hwcaps 0x%x\n", hwcaps);
0216
0217 return 0;
0218 }
0219 DEFINE_SHOW_ATTRIBUTE(spi_nor_capabilities);
0220
0221 static void spi_nor_debugfs_unregister(void *data)
0222 {
0223 struct spi_nor *nor = data;
0224
0225 debugfs_remove(nor->debugfs_root);
0226 nor->debugfs_root = NULL;
0227 }
0228
0229 void spi_nor_debugfs_register(struct spi_nor *nor)
0230 {
0231 struct dentry *rootdir, *d;
0232 int ret;
0233
0234
0235 rootdir = debugfs_lookup(SPI_NOR_DEBUGFS_ROOT, NULL);
0236 if (!rootdir)
0237 rootdir = debugfs_create_dir(SPI_NOR_DEBUGFS_ROOT, NULL);
0238
0239 ret = devm_add_action(nor->dev, spi_nor_debugfs_unregister, nor);
0240 if (ret)
0241 return;
0242
0243 d = debugfs_create_dir(dev_name(nor->dev), rootdir);
0244 nor->debugfs_root = d;
0245
0246 debugfs_create_file("params", 0444, d, nor, &spi_nor_params_fops);
0247 debugfs_create_file("capabilities", 0444, d, nor,
0248 &spi_nor_capabilities_fops);
0249 }