987b05dd9393812b74e833812b9ac32ee72ae1a9
[platform/kernel/u-boot.git] / drivers / mtd / spi / sandbox.c
1 /*
2  * Simulate a SPI flash
3  *
4  * Copyright (c) 2011-2013 The Chromium OS Authors.
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * Licensed under the GPL-2 or later.
9  */
10
11 #include <common.h>
12 #include <dm.h>
13 #include <malloc.h>
14 #include <spi.h>
15 #include <os.h>
16
17 #include <spi_flash.h>
18 #include "sf_internal.h"
19
20 #include <asm/getopt.h>
21 #include <asm/spi.h>
22 #include <asm/state.h>
23 #include <dm/device-internal.h>
24 #include <dm/lists.h>
25 #include <dm/uclass-internal.h>
26
27 /*
28  * The different states that our SPI flash transitions between.
29  * We need to keep track of this across multiple xfer calls since
30  * the SPI bus could possibly call down into us multiple times.
31  */
32 enum sandbox_sf_state {
33         SF_CMD,   /* default state -- we're awaiting a command */
34         SF_ID,    /* read the flash's (jedec) ID code */
35         SF_ADDR,  /* processing the offset in the flash to read/etc... */
36         SF_READ,  /* reading data from the flash */
37         SF_WRITE, /* writing data to the flash, i.e. page programming */
38         SF_ERASE, /* erase the flash */
39         SF_READ_STATUS, /* read the flash's status register */
40         SF_READ_STATUS1, /* read the flash's status register upper 8 bits*/
41         SF_WRITE_STATUS, /* write the flash's status register */
42 };
43
44 static const char *sandbox_sf_state_name(enum sandbox_sf_state state)
45 {
46         static const char * const states[] = {
47                 "CMD", "ID", "ADDR", "READ", "WRITE", "ERASE", "READ_STATUS",
48                 "READ_STATUS1", "WRITE_STATUS",
49         };
50         return states[state];
51 }
52
53 /* Bits for the status register */
54 #define STAT_WIP        (1 << 0)
55 #define STAT_WEL        (1 << 1)
56
57 /* Assume all SPI flashes have 3 byte addresses since they do atm */
58 #define SF_ADDR_LEN     3
59
60 #define IDCODE_LEN 3
61
62 /* Used to quickly bulk erase backing store */
63 static u8 sandbox_sf_0xff[0x1000];
64
65 /* Internal state data for each SPI flash */
66 struct sandbox_spi_flash {
67         unsigned int cs;        /* Chip select we are attached to */
68         /*
69          * As we receive data over the SPI bus, our flash transitions
70          * between states.  For example, we start off in the SF_CMD
71          * state where the first byte tells us what operation to perform
72          * (such as read or write the flash).  But the operation itself
73          * can go through a few states such as first reading in the
74          * offset in the flash to perform the requested operation.
75          * Thus "state" stores the exact state that our machine is in
76          * while "cmd" stores the overall command we're processing.
77          */
78         enum sandbox_sf_state state;
79         uint cmd;
80         /* Erase size of current erase command */
81         uint erase_size;
82         /* Current position in the flash; used when reading/writing/etc... */
83         uint off;
84         /* How many address bytes we've consumed */
85         uint addr_bytes, pad_addr_bytes;
86         /* The current flash status (see STAT_XXX defines above) */
87         u16 status;
88         /* Data describing the flash we're emulating */
89         const struct spi_flash_info *data;
90         /* The file on disk to serv up data from */
91         int fd;
92 };
93
94 struct sandbox_spi_flash_plat_data {
95         const char *filename;
96         const char *device_name;
97         int bus;
98         int cs;
99 };
100
101 /**
102  * This is a very strange probe function. If it has platform data (which may
103  * have come from the device tree) then this function gets the filename and
104  * device type from there.
105  */
106 static int sandbox_sf_probe(struct udevice *dev)
107 {
108         /* spec = idcode:file */
109         struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
110         size_t len, idname_len;
111         const struct spi_flash_info *data;
112         struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev);
113         struct sandbox_state *state = state_get_current();
114         struct udevice *bus = dev->parent;
115         const char *spec = NULL;
116         int ret = 0;
117         int cs = -1;
118         int i;
119
120         debug("%s: bus %d, looking for emul=%p: ", __func__, bus->seq, dev);
121         if (bus->seq >= 0 && bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS) {
122                 for (i = 0; i < CONFIG_SANDBOX_SPI_MAX_CS; i++) {
123                         if (state->spi[bus->seq][i].emul == dev)
124                                 cs = i;
125                 }
126         }
127         if (cs == -1) {
128                 printf("Error: Unknown chip select for device '%s'\n",
129                        dev->name);
130                 return -EINVAL;
131         }
132         debug("found at cs %d\n", cs);
133
134         if (!pdata->filename) {
135                 printf("Error: No filename available\n");
136                 return -EINVAL;
137         }
138         spec = strchr(pdata->device_name, ',');
139         if (spec)
140                 spec++;
141         else
142                 spec = pdata->device_name;
143         idname_len = strlen(spec);
144         debug("%s: device='%s'\n", __func__, spec);
145
146         for (data = spi_flash_ids; data->name; data++) {
147                 len = strlen(data->name);
148                 if (idname_len != len)
149                         continue;
150                 if (!strncasecmp(spec, data->name, len))
151                         break;
152         }
153         if (!data->name) {
154                 printf("%s: unknown flash '%*s'\n", __func__, (int)idname_len,
155                        spec);
156                 ret = -EINVAL;
157                 goto error;
158         }
159
160         if (sandbox_sf_0xff[0] == 0x00)
161                 memset(sandbox_sf_0xff, 0xff, sizeof(sandbox_sf_0xff));
162
163         sbsf->fd = os_open(pdata->filename, 02);
164         if (sbsf->fd == -1) {
165                 printf("%s: unable to open file '%s'\n", __func__,
166                        pdata->filename);
167                 ret = -EIO;
168                 goto error;
169         }
170
171         sbsf->data = data;
172         sbsf->cs = cs;
173
174         return 0;
175
176  error:
177         debug("%s: Got error %d\n", __func__, ret);
178         return ret;
179 }
180
181 static int sandbox_sf_remove(struct udevice *dev)
182 {
183         struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
184
185         os_close(sbsf->fd);
186
187         return 0;
188 }
189
190 static void sandbox_sf_cs_activate(struct udevice *dev)
191 {
192         struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
193
194         debug("sandbox_sf: CS activated; state is fresh!\n");
195
196         /* CS is asserted, so reset state */
197         sbsf->off = 0;
198         sbsf->addr_bytes = 0;
199         sbsf->pad_addr_bytes = 0;
200         sbsf->state = SF_CMD;
201         sbsf->cmd = SF_CMD;
202 }
203
204 static void sandbox_sf_cs_deactivate(struct udevice *dev)
205 {
206         debug("sandbox_sf: CS deactivated; cmd done processing!\n");
207 }
208
209 /*
210  * There are times when the data lines are allowed to tristate.  What
211  * is actually sensed on the line depends on the hardware.  It could
212  * always be 0xFF/0x00 (if there are pull ups/downs), or things could
213  * float and so we'd get garbage back.  This func encapsulates that
214  * scenario so we can worry about the details here.
215  */
216 static void sandbox_spi_tristate(u8 *buf, uint len)
217 {
218         /* XXX: make this into a user config option ? */
219         memset(buf, 0xff, len);
220 }
221
222 /* Figure out what command this stream is telling us to do */
223 static int sandbox_sf_process_cmd(struct sandbox_spi_flash *sbsf, const u8 *rx,
224                                   u8 *tx)
225 {
226         enum sandbox_sf_state oldstate = sbsf->state;
227
228         /* We need to output a byte for the cmd byte we just ate */
229         if (tx)
230                 sandbox_spi_tristate(tx, 1);
231
232         sbsf->cmd = rx[0];
233         switch (sbsf->cmd) {
234         case CMD_READ_ID:
235                 sbsf->state = SF_ID;
236                 sbsf->cmd = SF_ID;
237                 break;
238         case CMD_READ_ARRAY_FAST:
239                 sbsf->pad_addr_bytes = 1;
240         case CMD_READ_ARRAY_SLOW:
241         case CMD_PAGE_PROGRAM:
242                 sbsf->state = SF_ADDR;
243                 break;
244         case CMD_WRITE_DISABLE:
245                 debug(" write disabled\n");
246                 sbsf->status &= ~STAT_WEL;
247                 break;
248         case CMD_READ_STATUS:
249                 sbsf->state = SF_READ_STATUS;
250                 break;
251         case CMD_READ_STATUS1:
252                 sbsf->state = SF_READ_STATUS1;
253                 break;
254         case CMD_WRITE_ENABLE:
255                 debug(" write enabled\n");
256                 sbsf->status |= STAT_WEL;
257                 break;
258         case CMD_WRITE_STATUS:
259                 sbsf->state = SF_WRITE_STATUS;
260                 break;
261         default: {
262                 int flags = sbsf->data->flags;
263
264                 /* we only support erase here */
265                 if (sbsf->cmd == CMD_ERASE_CHIP) {
266                         sbsf->erase_size = sbsf->data->sector_size *
267                                 sbsf->data->n_sectors;
268                 } else if (sbsf->cmd == CMD_ERASE_4K && (flags & SECT_4K)) {
269                         sbsf->erase_size = 4 << 10;
270                 } else if (sbsf->cmd == CMD_ERASE_64K && !(flags & SECT_4K)) {
271                         sbsf->erase_size = 64 << 10;
272                 } else {
273                         debug(" cmd unknown: %#x\n", sbsf->cmd);
274                         return -EIO;
275                 }
276                 sbsf->state = SF_ADDR;
277                 break;
278         }
279         }
280
281         if (oldstate != sbsf->state)
282                 debug(" cmd: transition to %s state\n",
283                       sandbox_sf_state_name(sbsf->state));
284
285         return 0;
286 }
287
288 int sandbox_erase_part(struct sandbox_spi_flash *sbsf, int size)
289 {
290         int todo;
291         int ret;
292
293         while (size > 0) {
294                 todo = min(size, (int)sizeof(sandbox_sf_0xff));
295                 ret = os_write(sbsf->fd, sandbox_sf_0xff, todo);
296                 if (ret != todo)
297                         return ret;
298                 size -= todo;
299         }
300
301         return 0;
302 }
303
304 static int sandbox_sf_xfer(struct udevice *dev, unsigned int bitlen,
305                            const void *rxp, void *txp, unsigned long flags)
306 {
307         struct sandbox_spi_flash *sbsf = dev_get_priv(dev);
308         const uint8_t *rx = rxp;
309         uint8_t *tx = txp;
310         uint cnt, pos = 0;
311         int bytes = bitlen / 8;
312         int ret;
313
314         debug("sandbox_sf: state:%x(%s) bytes:%u\n", sbsf->state,
315               sandbox_sf_state_name(sbsf->state), bytes);
316
317         if ((flags & SPI_XFER_BEGIN))
318                 sandbox_sf_cs_activate(dev);
319
320         if (sbsf->state == SF_CMD) {
321                 /* Figure out the initial state */
322                 ret = sandbox_sf_process_cmd(sbsf, rx, tx);
323                 if (ret)
324                         return ret;
325                 ++pos;
326         }
327
328         /* Process the remaining data */
329         while (pos < bytes) {
330                 switch (sbsf->state) {
331                 case SF_ID: {
332                         u8 id;
333
334                         debug(" id: off:%u tx:", sbsf->off);
335                         if (sbsf->off < IDCODE_LEN) {
336                                 /* Extract correct byte from ID 0x00aabbcc */
337                                 id = ((JEDEC_MFR(sbsf->data) << 16) |
338                                         JEDEC_ID(sbsf->data)) >>
339                                         (8 * (IDCODE_LEN - 1 - sbsf->off));
340                         } else {
341                                 id = 0;
342                         }
343                         debug("%d %02x\n", sbsf->off, id);
344                         tx[pos++] = id;
345                         ++sbsf->off;
346                         break;
347                 }
348                 case SF_ADDR:
349                         debug(" addr: bytes:%u rx:%02x ", sbsf->addr_bytes,
350                               rx[pos]);
351
352                         if (sbsf->addr_bytes++ < SF_ADDR_LEN)
353                                 sbsf->off = (sbsf->off << 8) | rx[pos];
354                         debug("addr:%06x\n", sbsf->off);
355
356                         if (tx)
357                                 sandbox_spi_tristate(&tx[pos], 1);
358                         pos++;
359
360                         /* See if we're done processing */
361                         if (sbsf->addr_bytes <
362                                         SF_ADDR_LEN + sbsf->pad_addr_bytes)
363                                 break;
364
365                         /* Next state! */
366                         if (os_lseek(sbsf->fd, sbsf->off, OS_SEEK_SET) < 0) {
367                                 puts("sandbox_sf: os_lseek() failed");
368                                 return -EIO;
369                         }
370                         switch (sbsf->cmd) {
371                         case CMD_READ_ARRAY_FAST:
372                         case CMD_READ_ARRAY_SLOW:
373                                 sbsf->state = SF_READ;
374                                 break;
375                         case CMD_PAGE_PROGRAM:
376                                 sbsf->state = SF_WRITE;
377                                 break;
378                         default:
379                                 /* assume erase state ... */
380                                 sbsf->state = SF_ERASE;
381                                 goto case_sf_erase;
382                         }
383                         debug(" cmd: transition to %s state\n",
384                               sandbox_sf_state_name(sbsf->state));
385                         break;
386                 case SF_READ:
387                         /*
388                          * XXX: need to handle exotic behavior:
389                          *      - reading past end of device
390                          */
391
392                         cnt = bytes - pos;
393                         debug(" tx: read(%u)\n", cnt);
394                         assert(tx);
395                         ret = os_read(sbsf->fd, tx + pos, cnt);
396                         if (ret < 0) {
397                                 puts("sandbox_sf: os_read() failed\n");
398                                 return -EIO;
399                         }
400                         pos += ret;
401                         break;
402                 case SF_READ_STATUS:
403                         debug(" read status: %#x\n", sbsf->status);
404                         cnt = bytes - pos;
405                         memset(tx + pos, sbsf->status, cnt);
406                         pos += cnt;
407                         break;
408                 case SF_READ_STATUS1:
409                         debug(" read status: %#x\n", sbsf->status);
410                         cnt = bytes - pos;
411                         memset(tx + pos, sbsf->status >> 8, cnt);
412                         pos += cnt;
413                         break;
414                 case SF_WRITE_STATUS:
415                         debug(" write status: %#x (ignored)\n", rx[pos]);
416                         pos = bytes;
417                         break;
418                 case SF_WRITE:
419                         /*
420                          * XXX: need to handle exotic behavior:
421                          *      - unaligned addresses
422                          *      - more than a page (256) worth of data
423                          *      - reading past end of device
424                          */
425                         if (!(sbsf->status & STAT_WEL)) {
426                                 puts("sandbox_sf: write enable not set before write\n");
427                                 goto done;
428                         }
429
430                         cnt = bytes - pos;
431                         debug(" rx: write(%u)\n", cnt);
432                         if (tx)
433                                 sandbox_spi_tristate(&tx[pos], cnt);
434                         ret = os_write(sbsf->fd, rx + pos, cnt);
435                         if (ret < 0) {
436                                 puts("sandbox_spi: os_write() failed\n");
437                                 return -EIO;
438                         }
439                         pos += ret;
440                         sbsf->status &= ~STAT_WEL;
441                         break;
442                 case SF_ERASE:
443  case_sf_erase: {
444                         if (!(sbsf->status & STAT_WEL)) {
445                                 puts("sandbox_sf: write enable not set before erase\n");
446                                 goto done;
447                         }
448
449                         /* verify address is aligned */
450                         if (sbsf->off & (sbsf->erase_size - 1)) {
451                                 debug(" sector erase: cmd:%#x needs align:%#x, but we got %#x\n",
452                                       sbsf->cmd, sbsf->erase_size,
453                                       sbsf->off);
454                                 sbsf->status &= ~STAT_WEL;
455                                 goto done;
456                         }
457
458                         debug(" sector erase addr: %u, size: %u\n", sbsf->off,
459                               sbsf->erase_size);
460
461                         cnt = bytes - pos;
462                         if (tx)
463                                 sandbox_spi_tristate(&tx[pos], cnt);
464                         pos += cnt;
465
466                         /*
467                          * TODO(vapier@gentoo.org): latch WIP in status, and
468                          * delay before clearing it ?
469                          */
470                         ret = sandbox_erase_part(sbsf, sbsf->erase_size);
471                         sbsf->status &= ~STAT_WEL;
472                         if (ret) {
473                                 debug("sandbox_sf: Erase failed\n");
474                                 goto done;
475                         }
476                         goto done;
477                 }
478                 default:
479                         debug(" ??? no idea what to do ???\n");
480                         goto done;
481                 }
482         }
483
484  done:
485         if (flags & SPI_XFER_END)
486                 sandbox_sf_cs_deactivate(dev);
487         return pos == bytes ? 0 : -EIO;
488 }
489
490 int sandbox_sf_ofdata_to_platdata(struct udevice *dev)
491 {
492         struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev);
493
494         pdata->filename = dev_read_string(dev, "sandbox,filename");
495         pdata->device_name = dev_read_string(dev, "compatible");
496         if (!pdata->filename || !pdata->device_name) {
497                 debug("%s: Missing properties, filename=%s, device_name=%s\n",
498                       __func__, pdata->filename, pdata->device_name);
499                 return -EINVAL;
500         }
501
502         return 0;
503 }
504
505 static const struct dm_spi_emul_ops sandbox_sf_emul_ops = {
506         .xfer          = sandbox_sf_xfer,
507 };
508
509 #ifdef CONFIG_SPI_FLASH
510 int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
511                          struct udevice *bus, ofnode node, const char *spec)
512 {
513         struct udevice *emul;
514         char name[20], *str;
515         struct driver *drv;
516         int ret;
517
518         /* now the emulator */
519         strncpy(name, spec, sizeof(name) - 6);
520         name[sizeof(name) - 6] = '\0';
521         strcat(name, "-emul");
522         drv = lists_driver_lookup_name("sandbox_sf_emul");
523         if (!drv) {
524                 puts("Cannot find sandbox_sf_emul driver\n");
525                 return -ENOENT;
526         }
527         str = strdup(name);
528         if (!str)
529                 return -ENOMEM;
530         ret = device_bind_ofnode(bus, drv, str, NULL, node, &emul);
531         if (ret) {
532                 free(str);
533                 printf("Cannot create emul device for spec '%s' (err=%d)\n",
534                        spec, ret);
535                 return ret;
536         }
537         state->spi[busnum][cs].emul = emul;
538
539         return 0;
540 }
541
542 void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs)
543 {
544         struct udevice *dev;
545
546         dev = state->spi[busnum][cs].emul;
547         device_remove(dev, DM_REMOVE_NORMAL);
548         device_unbind(dev);
549         state->spi[busnum][cs].emul = NULL;
550 }
551
552 int sandbox_spi_get_emul(struct sandbox_state *state,
553                          struct udevice *bus, struct udevice *slave,
554                          struct udevice **emulp)
555 {
556         struct sandbox_spi_info *info;
557         int busnum = bus->seq;
558         int cs = spi_chip_select(slave);
559         int ret;
560
561         info = &state->spi[busnum][cs];
562         if (!info->emul) {
563                 /* Use the same device tree node as the SPI flash device */
564                 debug("%s: busnum=%u, cs=%u: binding SPI flash emulation: ",
565                       __func__, busnum, cs);
566                 ret = sandbox_sf_bind_emul(state, busnum, cs, bus,
567                                            dev_ofnode(slave), slave->name);
568                 if (ret) {
569                         debug("failed (err=%d)\n", ret);
570                         return ret;
571                 }
572                 debug("OK\n");
573         }
574         *emulp = info->emul;
575
576         return 0;
577 }
578 #endif
579
580 static const struct udevice_id sandbox_sf_ids[] = {
581         { .compatible = "sandbox,spi-flash" },
582         { }
583 };
584
585 U_BOOT_DRIVER(sandbox_sf_emul) = {
586         .name           = "sandbox_sf_emul",
587         .id             = UCLASS_SPI_EMUL,
588         .of_match       = sandbox_sf_ids,
589         .ofdata_to_platdata = sandbox_sf_ofdata_to_platdata,
590         .probe          = sandbox_sf_probe,
591         .remove         = sandbox_sf_remove,
592         .priv_auto_alloc_size = sizeof(struct sandbox_spi_flash),
593         .platdata_auto_alloc_size = sizeof(struct sandbox_spi_flash_plat_data),
594         .ops            = &sandbox_sf_emul_ops,
595 };