]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/spi/atmel.c
Merge branch 'misc' of git://git.denx.de/u-boot-blackfin
[karo-tx-uboot.git] / drivers / mtd / spi / atmel.c
1 /*
2  * Atmel SPI DataFlash support
3  *
4  * Copyright (C) 2008 Atmel Corporation
5  * Licensed under the GPL-2 or later.
6  */
7
8 #include <common.h>
9 #include <malloc.h>
10 #include <spi_flash.h>
11
12 #include "spi_flash_internal.h"
13
14 /* AT45-specific commands */
15 #define CMD_AT45_READ_STATUS            0xd7
16 #define CMD_AT45_ERASE_PAGE             0x81
17 #define CMD_AT45_LOAD_PROG_BUF1         0x82
18 #define CMD_AT45_LOAD_BUF1              0x84
19 #define CMD_AT45_LOAD_PROG_BUF2         0x85
20 #define CMD_AT45_LOAD_BUF2              0x87
21 #define CMD_AT45_PROG_BUF1              0x88
22 #define CMD_AT45_PROG_BUF2              0x89
23
24 /* AT45 status register bits */
25 #define AT45_STATUS_P2_PAGE_SIZE        (1 << 0)
26 #define AT45_STATUS_READY               (1 << 7)
27
28 /* DataFlash family IDs, as obtained from the second idcode byte */
29 #define DF_FAMILY_AT26F                 0
30 #define DF_FAMILY_AT45                  1
31 #define DF_FAMILY_AT26DF                2       /* AT25DF and AT26DF */
32
33 struct atmel_spi_flash_params {
34         u8              idcode1;
35         /* Log2 of page size in power-of-two mode */
36         u8              l2_page_size;
37         u8              pages_per_block;
38         u8              blocks_per_sector;
39         u8              nr_sectors;
40         const char      *name;
41 };
42
43 /* spi_flash needs to be first so upper layers can free() it */
44 struct atmel_spi_flash {
45         struct spi_flash flash;
46         const struct atmel_spi_flash_params *params;
47 };
48
49 static inline struct atmel_spi_flash *
50 to_atmel_spi_flash(struct spi_flash *flash)
51 {
52         return container_of(flash, struct atmel_spi_flash, flash);
53 }
54
55 static const struct atmel_spi_flash_params atmel_spi_flash_table[] = {
56         {
57                 .idcode1                = 0x22,
58                 .l2_page_size           = 8,
59                 .pages_per_block        = 8,
60                 .blocks_per_sector      = 16,
61                 .nr_sectors             = 4,
62                 .name                   = "AT45DB011D",
63         },
64         {
65                 .idcode1                = 0x23,
66                 .l2_page_size           = 8,
67                 .pages_per_block        = 8,
68                 .blocks_per_sector      = 16,
69                 .nr_sectors             = 8,
70                 .name                   = "AT45DB021D",
71         },
72         {
73                 .idcode1                = 0x24,
74                 .l2_page_size           = 8,
75                 .pages_per_block        = 8,
76                 .blocks_per_sector      = 32,
77                 .nr_sectors             = 8,
78                 .name                   = "AT45DB041D",
79         },
80         {
81                 .idcode1                = 0x25,
82                 .l2_page_size           = 8,
83                 .pages_per_block        = 8,
84                 .blocks_per_sector      = 32,
85                 .nr_sectors             = 16,
86                 .name                   = "AT45DB081D",
87         },
88         {
89                 .idcode1                = 0x26,
90                 .l2_page_size           = 9,
91                 .pages_per_block        = 8,
92                 .blocks_per_sector      = 32,
93                 .nr_sectors             = 16,
94                 .name                   = "AT45DB161D",
95         },
96         {
97                 .idcode1                = 0x27,
98                 .l2_page_size           = 9,
99                 .pages_per_block        = 8,
100                 .blocks_per_sector      = 64,
101                 .nr_sectors             = 64,
102                 .name                   = "AT45DB321D",
103         },
104         {
105                 .idcode1                = 0x28,
106                 .l2_page_size           = 10,
107                 .pages_per_block        = 8,
108                 .blocks_per_sector      = 32,
109                 .nr_sectors             = 32,
110                 .name                   = "AT45DB642D",
111         },
112 };
113
114 static int at45_wait_ready(struct spi_flash *flash, unsigned long timeout)
115 {
116         struct spi_slave *spi = flash->spi;
117         unsigned long timebase;
118         int ret;
119         u8 cmd = CMD_AT45_READ_STATUS;
120         u8 status;
121
122         timebase = get_timer(0);
123
124         ret = spi_xfer(spi, 8, &cmd, NULL, SPI_XFER_BEGIN);
125         if (ret)
126                 return -1;
127
128         do {
129                 ret = spi_xfer(spi, 8, NULL, &status, 0);
130                 if (ret)
131                         return -1;
132
133                 if (status & AT45_STATUS_READY)
134                         break;
135         } while (get_timer(timebase) < timeout);
136
137         /* Deactivate CS */
138         spi_xfer(spi, 0, NULL, NULL, SPI_XFER_END);
139
140         if (status & AT45_STATUS_READY)
141                 return 0;
142
143         /* Timed out */
144         return -1;
145 }
146
147 /*
148  * Assemble the address part of a command for AT45 devices in
149  * non-power-of-two page size mode.
150  */
151 static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset)
152 {
153         unsigned long page_addr;
154         unsigned long byte_addr;
155         unsigned long page_size;
156         unsigned int page_shift;
157
158         /*
159          * The "extra" space per page is the power-of-two page size
160          * divided by 32.
161          */
162         page_shift = asf->params->l2_page_size;
163         page_size = (1 << page_shift) + (1 << (page_shift - 5));
164         page_shift++;
165         page_addr = offset / page_size;
166         byte_addr = offset % page_size;
167
168         cmd[0] = page_addr >> (16 - page_shift);
169         cmd[1] = page_addr << (page_shift - 8) | (byte_addr >> 8);
170         cmd[2] = byte_addr;
171 }
172
173 static int dataflash_read_fast_at45(struct spi_flash *flash,
174                 u32 offset, size_t len, void *buf)
175 {
176         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
177         u8 cmd[5];
178
179         cmd[0] = CMD_READ_ARRAY_FAST;
180         at45_build_address(asf, cmd + 1, offset);
181         cmd[4] = 0x00;
182
183         return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
184 }
185
186 /*
187  * TODO: the two write funcs (_p2/_at45) should get unified ...
188  */
189 static int dataflash_write_p2(struct spi_flash *flash,
190                 u32 offset, size_t len, const void *buf)
191 {
192         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
193         unsigned long page_size;
194         u32 addr = offset;
195         size_t chunk_len;
196         size_t actual;
197         int ret;
198         u8 cmd[4];
199
200         /*
201          * TODO: This function currently uses only page buffer #1.  We can
202          * speed this up by using both buffers and loading one buffer while
203          * the other is being programmed into main memory.
204          */
205
206         page_size = (1 << asf->params->l2_page_size);
207
208         ret = spi_claim_bus(flash->spi);
209         if (ret) {
210                 debug("SF: Unable to claim SPI bus\n");
211                 return ret;
212         }
213
214         for (actual = 0; actual < len; actual += chunk_len) {
215                 chunk_len = min(len - actual, page_size - (addr % page_size));
216
217                 /* Use the same address bits for both commands */
218                 cmd[0] = CMD_AT45_LOAD_BUF1;
219                 cmd[1] = addr >> 16;
220                 cmd[2] = addr >> 8;
221                 cmd[3] = addr;
222
223                 ret = spi_flash_cmd_write(flash->spi, cmd, 4,
224                                 buf + actual, chunk_len);
225                 if (ret < 0) {
226                         debug("SF: Loading AT45 buffer failed\n");
227                         goto out;
228                 }
229
230                 cmd[0] = CMD_AT45_PROG_BUF1;
231                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
232                 if (ret < 0) {
233                         debug("SF: AT45 page programming failed\n");
234                         goto out;
235                 }
236
237                 ret = at45_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
238                 if (ret < 0) {
239                         debug("SF: AT45 page programming timed out\n");
240                         goto out;
241                 }
242
243                 addr += chunk_len;
244         }
245
246         debug("SF: AT45: Successfully programmed %zu bytes @ 0x%x\n",
247                         len, offset);
248         ret = 0;
249
250 out:
251         spi_release_bus(flash->spi);
252         return ret;
253 }
254
255 static int dataflash_write_at45(struct spi_flash *flash,
256                 u32 offset, size_t len, const void *buf)
257 {
258         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
259         unsigned long page_addr;
260         unsigned long byte_addr;
261         unsigned long page_size;
262         unsigned int page_shift;
263         size_t chunk_len;
264         size_t actual;
265         int ret;
266         u8 cmd[4];
267
268         /*
269          * TODO: This function currently uses only page buffer #1.  We can
270          * speed this up by using both buffers and loading one buffer while
271          * the other is being programmed into main memory.
272          */
273
274         page_shift = asf->params->l2_page_size;
275         page_size = (1 << page_shift) + (1 << (page_shift - 5));
276         page_shift++;
277         page_addr = offset / page_size;
278         byte_addr = offset % page_size;
279
280         ret = spi_claim_bus(flash->spi);
281         if (ret) {
282                 debug("SF: Unable to claim SPI bus\n");
283                 return ret;
284         }
285
286         for (actual = 0; actual < len; actual += chunk_len) {
287                 chunk_len = min(len - actual, page_size - byte_addr);
288
289                 /* Use the same address bits for both commands */
290                 cmd[0] = CMD_AT45_LOAD_BUF1;
291                 cmd[1] = page_addr >> (16 - page_shift);
292                 cmd[2] = page_addr << (page_shift - 8) | (byte_addr >> 8);
293                 cmd[3] = byte_addr;
294
295                 ret = spi_flash_cmd_write(flash->spi, cmd, 4,
296                                 buf + actual, chunk_len);
297                 if (ret < 0) {
298                         debug("SF: Loading AT45 buffer failed\n");
299                         goto out;
300                 }
301
302                 cmd[0] = CMD_AT45_PROG_BUF1;
303                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
304                 if (ret < 0) {
305                         debug("SF: AT45 page programming failed\n");
306                         goto out;
307                 }
308
309                 ret = at45_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
310                 if (ret < 0) {
311                         debug("SF: AT45 page programming timed out\n");
312                         goto out;
313                 }
314
315                 page_addr++;
316                 byte_addr = 0;
317         }
318
319         debug("SF: AT45: Successfully programmed %zu bytes @ 0x%x\n",
320                         len, offset);
321         ret = 0;
322
323 out:
324         spi_release_bus(flash->spi);
325         return ret;
326 }
327
328 /*
329  * TODO: the two erase funcs (_p2/_at45) should get unified ...
330  */
331 static int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len)
332 {
333         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
334         unsigned long page_size;
335
336         size_t actual;
337         int ret;
338         u8 cmd[4];
339
340         /*
341          * TODO: This function currently uses page erase only. We can
342          * probably speed things up by using block and/or sector erase
343          * when possible.
344          */
345
346         page_size = (1 << asf->params->l2_page_size);
347
348         if (offset % page_size || len % page_size) {
349                 debug("SF: Erase offset/length not multiple of page size\n");
350                 return -1;
351         }
352
353         cmd[0] = CMD_AT45_ERASE_PAGE;
354         cmd[3] = 0x00;
355
356         ret = spi_claim_bus(flash->spi);
357         if (ret) {
358                 debug("SF: Unable to claim SPI bus\n");
359                 return ret;
360         }
361
362         for (actual = 0; actual < len; actual += page_size) {
363                 cmd[1] = offset >> 16;
364                 cmd[2] = offset >> 8;
365
366                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
367                 if (ret < 0) {
368                         debug("SF: AT45 page erase failed\n");
369                         goto out;
370                 }
371
372                 ret = at45_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
373                 if (ret < 0) {
374                         debug("SF: AT45 page erase timed out\n");
375                         goto out;
376                 }
377
378                 offset += page_size;
379         }
380
381         debug("SF: AT45: Successfully erased %zu bytes @ 0x%x\n",
382                         len, offset);
383         ret = 0;
384
385 out:
386         spi_release_bus(flash->spi);
387         return ret;
388 }
389
390 static int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len)
391 {
392         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
393         unsigned long page_addr;
394         unsigned long page_size;
395         unsigned int page_shift;
396         size_t actual;
397         int ret;
398         u8 cmd[4];
399
400         /*
401          * TODO: This function currently uses page erase only. We can
402          * probably speed things up by using block and/or sector erase
403          * when possible.
404          */
405
406         page_shift = asf->params->l2_page_size;
407         page_size = (1 << page_shift) + (1 << (page_shift - 5));
408         page_shift++;
409         page_addr = offset / page_size;
410
411         if (offset % page_size || len % page_size) {
412                 debug("SF: Erase offset/length not multiple of page size\n");
413                 return -1;
414         }
415
416         cmd[0] = CMD_AT45_ERASE_PAGE;
417         cmd[3] = 0x00;
418
419         ret = spi_claim_bus(flash->spi);
420         if (ret) {
421                 debug("SF: Unable to claim SPI bus\n");
422                 return ret;
423         }
424
425         for (actual = 0; actual < len; actual += page_size) {
426                 cmd[1] = page_addr >> (16 - page_shift);
427                 cmd[2] = page_addr << (page_shift - 8);
428
429                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
430                 if (ret < 0) {
431                         debug("SF: AT45 page erase failed\n");
432                         goto out;
433                 }
434
435                 ret = at45_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
436                 if (ret < 0) {
437                         debug("SF: AT45 page erase timed out\n");
438                         goto out;
439                 }
440
441                 page_addr++;
442         }
443
444         debug("SF: AT45: Successfully erased %zu bytes @ 0x%x\n",
445                         len, offset);
446         ret = 0;
447
448 out:
449         spi_release_bus(flash->spi);
450         return ret;
451 }
452
453 struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
454 {
455         const struct atmel_spi_flash_params *params;
456         unsigned page_size;
457         unsigned int family;
458         struct atmel_spi_flash *asf;
459         unsigned int i;
460         int ret;
461         u8 status;
462
463         for (i = 0; i < ARRAY_SIZE(atmel_spi_flash_table); i++) {
464                 params = &atmel_spi_flash_table[i];
465                 if (params->idcode1 == idcode[1])
466                         break;
467         }
468
469         if (i == ARRAY_SIZE(atmel_spi_flash_table)) {
470                 debug("SF: Unsupported DataFlash ID %02x\n",
471                                 idcode[1]);
472                 return NULL;
473         }
474
475         asf = malloc(sizeof(struct atmel_spi_flash));
476         if (!asf) {
477                 debug("SF: Failed to allocate memory\n");
478                 return NULL;
479         }
480
481         asf->params = params;
482         asf->flash.spi = spi;
483         asf->flash.name = params->name;
484
485         /* Assuming power-of-two page size initially. */
486         page_size = 1 << params->l2_page_size;
487
488         family = idcode[1] >> 5;
489
490         switch (family) {
491         case DF_FAMILY_AT45:
492                 /*
493                  * AT45 chips have configurable page size. The status
494                  * register indicates which configuration is active.
495                  */
496                 ret = spi_flash_cmd(spi, CMD_AT45_READ_STATUS, &status, 1);
497                 if (ret)
498                         goto err;
499
500                 debug("SF: AT45 status register: %02x\n", status);
501
502                 if (!(status & AT45_STATUS_P2_PAGE_SIZE)) {
503                         asf->flash.read = dataflash_read_fast_at45;
504                         asf->flash.write = dataflash_write_at45;
505                         asf->flash.erase = dataflash_erase_at45;
506                         page_size += 1 << (params->l2_page_size - 5);
507                 } else {
508                         asf->flash.read = spi_flash_cmd_read_fast;
509                         asf->flash.write = dataflash_write_p2;
510                         asf->flash.erase = dataflash_erase_p2;
511                 }
512
513                 break;
514
515         case DF_FAMILY_AT26F:
516         case DF_FAMILY_AT26DF:
517                 asf->flash.read = spi_flash_cmd_read_fast;
518                 break;
519
520         default:
521                 debug("SF: Unsupported DataFlash family %u\n", family);
522                 goto err;
523         }
524
525         asf->flash.sector_size = page_size;
526         asf->flash.size = page_size * params->pages_per_block
527                                 * params->blocks_per_sector
528                                 * params->nr_sectors;
529
530         return &asf->flash;
531
532 err:
533         free(asf);
534         return NULL;
535 }