Commit 110bdee00f70ba2cae90a8db39e8d3e854141a56

Authored by Simon Glass
1 parent f9860cf081

sandbox: Convert SPI flash emulation to use sf_params

At present sandbox has its own table of supported SPI flash chips. Now that
the SPI flash system is fully consolidated and has its own list, sandbox
should use that.

This enables us to expand the number of chips that sandbox supports.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>

Showing 1 changed file with 38 additions and 76 deletions Side-by-side Diff

drivers/mtd/spi/sandbox.c
... ... @@ -51,47 +51,8 @@
51 51 /* Assume all SPI flashes have 3 byte addresses since they do atm */
52 52 #define SF_ADDR_LEN 3
53 53  
54   -struct sandbox_spi_flash_erase_commands {
55   - u8 cmd;
56   - u32 size;
57   -};
58   -#define IDCODE_LEN 5
59   -#define MAX_ERASE_CMDS 3
60   -struct sandbox_spi_flash_data {
61   - const char *name;
62   - u8 idcode[IDCODE_LEN];
63   - u32 size;
64   - const struct sandbox_spi_flash_erase_commands
65   - erase_cmds[MAX_ERASE_CMDS];
66   -};
  54 +#define IDCODE_LEN 3
67 55  
68   -/* Structure describing all the flashes we know how to emulate */
69   -static const struct sandbox_spi_flash_data sandbox_sf_flashes[] = {
70   - {
71   - "M25P16", { 0x20, 0x20, 0x15 }, (2 << 20),
72   - { /* erase commands */
73   - { 0xd8, (64 << 10), }, /* sector */
74   - { 0xc7, (2 << 20), }, /* bulk */
75   - },
76   - },
77   - {
78   - "W25Q32", { 0xef, 0x40, 0x16 }, (4 << 20),
79   - { /* erase commands */
80   - { 0x20, (4 << 10), }, /* 4KB */
81   - { 0xd8, (64 << 10), }, /* sector */
82   - { 0xc7, (4 << 20), }, /* bulk */
83   - },
84   - },
85   - {
86   - "W25Q128", { 0xef, 0x40, 0x18 }, (16 << 20),
87   - { /* erase commands */
88   - { 0x20, (4 << 10), }, /* 4KB */
89   - { 0xd8, (64 << 10), }, /* sector */
90   - { 0xc7, (16 << 20), }, /* bulk */
91   - },
92   - },
93   -};
94   -
95 56 /* Used to quickly bulk erase backing store */
96 57 static u8 sandbox_sf_0xff[0x1000];
97 58  
... ... @@ -109,7 +70,8 @@
109 70 */
110 71 enum sandbox_sf_state state;
111 72 uint cmd;
112   - const void *cmd_data;
  73 + /* Erase size of current erase command */
  74 + uint erase_size;
113 75 /* Current position in the flash; used when reading/writing/etc... */
114 76 uint off;
115 77 /* How many address bytes we've consumed */
... ... @@ -117,7 +79,7 @@
117 79 /* The current flash status (see STAT_XXX defines above) */
118 80 u16 status;
119 81 /* Data describing the flash we're emulating */
120   - const struct sandbox_spi_flash_data *data;
  82 + const struct spi_flash_params *data;
121 83 /* The file on disk to serv up data from */
122 84 int fd;
123 85 };
... ... @@ -127,8 +89,8 @@
127 89 /* spec = idcode:file */
128 90 struct sandbox_spi_flash *sbsf;
129 91 const char *file;
130   - size_t i, len, idname_len;
131   - const struct sandbox_spi_flash_data *data;
  92 + size_t len, idname_len;
  93 + const struct spi_flash_params *data;
132 94  
133 95 file = strchr(spec, ':');
134 96 if (!file) {
135 97  
... ... @@ -138,15 +100,14 @@
138 100 idname_len = file - spec;
139 101 ++file;
140 102  
141   - for (i = 0; i < ARRAY_SIZE(sandbox_sf_flashes); ++i) {
142   - data = &sandbox_sf_flashes[i];
  103 + for (data = spi_flash_params_table; data->name; data++) {
143 104 len = strlen(data->name);
144 105 if (idname_len != len)
145 106 continue;
146 107 if (!memcmp(spec, data->name, len))
147 108 break;
148 109 }
149   - if (i == ARRAY_SIZE(sandbox_sf_flashes)) {
  110 + if (!data->name) {
150 111 printf("sandbox_sf: unknown flash '%*s'\n", (int)idname_len,
151 112 spec);
152 113 goto error;
... ... @@ -223,7 +184,6 @@
223 184 sbsf->pad_addr_bytes = 1;
224 185 case CMD_READ_ARRAY_SLOW:
225 186 case CMD_PAGE_PROGRAM:
226   - state_addr:
227 187 sbsf->state = SF_ADDR;
228 188 break;
229 189 case CMD_WRITE_DISABLE:
230 190  
231 191  
... ... @@ -241,24 +201,25 @@
241 201 sbsf->status |= STAT_WEL;
242 202 break;
243 203 default: {
244   - size_t i;
  204 + int flags = sbsf->data->flags;
245 205  
246   - /* handle erase commands first */
247   - for (i = 0; i < MAX_ERASE_CMDS; ++i) {
248   - const struct sandbox_spi_flash_erase_commands *
249   - erase_cmd = &sbsf->data->erase_cmds[i];
250   -
251   - if (erase_cmd->cmd == 0x00)
252   - continue;
253   - if (sbsf->cmd != erase_cmd->cmd)
254   - continue;
255   -
256   - sbsf->cmd_data = erase_cmd;
257   - goto state_addr;
  206 + /* we only support erase here */
  207 + if (sbsf->cmd == CMD_ERASE_CHIP) {
  208 + sbsf->erase_size = sbsf->data->sector_size *
  209 + sbsf->data->nr_sectors;
  210 + } else if (sbsf->cmd == CMD_ERASE_4K && (flags & SECT_4K)) {
  211 + sbsf->erase_size = 4 << 10;
  212 + } else if (sbsf->cmd == CMD_ERASE_32K && (flags & SECT_32K)) {
  213 + sbsf->erase_size = 32 << 10;
  214 + } else if (sbsf->cmd == CMD_ERASE_64K &&
  215 + !(flags & (SECT_4K | SECT_32K))) {
  216 + sbsf->erase_size = 64 << 10;
  217 + } else {
  218 + debug(" cmd unknown: %#x\n", sbsf->cmd);
  219 + return 1;
258 220 }
259   -
260   - debug(" cmd unknown: %#x\n", sbsf->cmd);
261   - return 1;
  221 + sbsf->state = SF_ADDR;
  222 + break;
262 223 }
263 224 }
264 225  
265 226  
... ... @@ -309,11 +270,14 @@
309 270 u8 id;
310 271  
311 272 debug(" id: off:%u tx:", sbsf->off);
312   - if (sbsf->off < IDCODE_LEN)
313   - id = sbsf->data->idcode[sbsf->off];
314   - else
  273 + if (sbsf->off < IDCODE_LEN) {
  274 + /* Extract correct byte from ID 0x00aabbcc */
  275 + id = sbsf->data->jedec >>
  276 + (8 * (IDCODE_LEN - 1 - sbsf->off));
  277 + } else {
315 278 id = 0;
316   - debug("%02x\n", id);
  279 + }
  280 + debug("%d %02x\n", sbsf->off, id);
317 281 tx[pos++] = id;
318 282 ++sbsf->off;
319 283 break;
320 284  
321 285  
322 286  
... ... @@ -406,24 +370,22 @@
406 370 break;
407 371 case SF_ERASE:
408 372 case_sf_erase: {
409   - const struct sandbox_spi_flash_erase_commands *
410   - erase_cmd = sbsf->cmd_data;
411   -
412 373 if (!(sbsf->status & STAT_WEL)) {
413 374 puts("sandbox_sf: write enable not set before erase\n");
414 375 goto done;
415 376 }
416 377  
417 378 /* verify address is aligned */
418   - if (sbsf->off & (erase_cmd->size - 1)) {
  379 + if (sbsf->off & (sbsf->erase_size - 1)) {
419 380 debug(" sector erase: cmd:%#x needs align:%#x, but we got %#x\n",
420   - erase_cmd->cmd, erase_cmd->size,
  381 + sbsf->cmd, sbsf->erase_size,
421 382 sbsf->off);
422 383 sbsf->status &= ~STAT_WEL;
423 384 goto done;
424 385 }
425 386  
426   - debug(" sector erase addr: %u\n", sbsf->off);
  387 + debug(" sector erase addr: %u, size: %u\n", sbsf->off,
  388 + sbsf->erase_size);
427 389  
428 390 cnt = bytes - pos;
429 391 sandbox_spi_tristate(&tx[pos], cnt);
... ... @@ -433,7 +395,7 @@
433 395 * TODO(vapier@gentoo.org): latch WIP in status, and
434 396 * delay before clearing it ?
435 397 */
436   - ret = sandbox_erase_part(sbsf, erase_cmd->size);
  398 + ret = sandbox_erase_part(sbsf, sbsf->erase_size);
437 399 sbsf->status &= ~STAT_WEL;
438 400 if (ret) {
439 401 debug("sandbox_sf: Erase failed\n");