]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/spi/atmel.c
Merge branch 'master' of git://git.denx.de/u-boot-x86
[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         return spi_flash_cmd_poll_bit(flash, timeout,
117                 CMD_AT45_READ_STATUS, AT45_STATUS_READY);
118 }
119
120 /*
121  * Assemble the address part of a command for AT45 devices in
122  * non-power-of-two page size mode.
123  */
124 static void at45_build_address(struct atmel_spi_flash *asf, u8 *cmd, u32 offset)
125 {
126         unsigned long page_addr;
127         unsigned long byte_addr;
128         unsigned long page_size;
129         unsigned int page_shift;
130
131         /*
132          * The "extra" space per page is the power-of-two page size
133          * divided by 32.
134          */
135         page_shift = asf->params->l2_page_size;
136         page_size = (1 << page_shift) + (1 << (page_shift - 5));
137         page_shift++;
138         page_addr = offset / page_size;
139         byte_addr = offset % page_size;
140
141         cmd[0] = page_addr >> (16 - page_shift);
142         cmd[1] = page_addr << (page_shift - 8) | (byte_addr >> 8);
143         cmd[2] = byte_addr;
144 }
145
146 static int dataflash_read_fast_at45(struct spi_flash *flash,
147                 u32 offset, size_t len, void *buf)
148 {
149         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
150         u8 cmd[5];
151
152         cmd[0] = CMD_READ_ARRAY_FAST;
153         at45_build_address(asf, cmd + 1, offset);
154         cmd[4] = 0x00;
155
156         return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len);
157 }
158
159 /*
160  * TODO: the two write funcs (_p2/_at45) should get unified ...
161  */
162 static int dataflash_write_p2(struct spi_flash *flash,
163                 u32 offset, size_t len, const void *buf)
164 {
165         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
166         unsigned long page_size;
167         u32 addr = offset;
168         size_t chunk_len;
169         size_t actual;
170         int ret;
171         u8 cmd[4];
172
173         /*
174          * TODO: This function currently uses only page buffer #1.  We can
175          * speed this up by using both buffers and loading one buffer while
176          * the other is being programmed into main memory.
177          */
178
179         page_size = (1 << asf->params->l2_page_size);
180
181         ret = spi_claim_bus(flash->spi);
182         if (ret) {
183                 debug("SF: Unable to claim SPI bus\n");
184                 return ret;
185         }
186
187         for (actual = 0; actual < len; actual += chunk_len) {
188                 chunk_len = min(len - actual, page_size - (addr % page_size));
189
190                 /* Use the same address bits for both commands */
191                 cmd[0] = CMD_AT45_LOAD_BUF1;
192                 cmd[1] = addr >> 16;
193                 cmd[2] = addr >> 8;
194                 cmd[3] = addr;
195
196                 ret = spi_flash_cmd_write(flash->spi, cmd, 4,
197                                 buf + actual, chunk_len);
198                 if (ret < 0) {
199                         debug("SF: Loading AT45 buffer failed\n");
200                         goto out;
201                 }
202
203                 cmd[0] = CMD_AT45_PROG_BUF1;
204                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
205                 if (ret < 0) {
206                         debug("SF: AT45 page programming failed\n");
207                         goto out;
208                 }
209
210                 ret = at45_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
211                 if (ret < 0) {
212                         debug("SF: AT45 page programming timed out\n");
213                         goto out;
214                 }
215
216                 addr += chunk_len;
217         }
218
219         debug("SF: AT45: Successfully programmed %zu bytes @ 0x%x\n",
220                         len, offset);
221         ret = 0;
222
223 out:
224         spi_release_bus(flash->spi);
225         return ret;
226 }
227
228 static int dataflash_write_at45(struct spi_flash *flash,
229                 u32 offset, size_t len, const void *buf)
230 {
231         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
232         unsigned long page_addr;
233         unsigned long byte_addr;
234         unsigned long page_size;
235         unsigned int page_shift;
236         size_t chunk_len;
237         size_t actual;
238         int ret;
239         u8 cmd[4];
240
241         /*
242          * TODO: This function currently uses only page buffer #1.  We can
243          * speed this up by using both buffers and loading one buffer while
244          * the other is being programmed into main memory.
245          */
246
247         page_shift = asf->params->l2_page_size;
248         page_size = (1 << page_shift) + (1 << (page_shift - 5));
249         page_shift++;
250         page_addr = offset / page_size;
251         byte_addr = offset % page_size;
252
253         ret = spi_claim_bus(flash->spi);
254         if (ret) {
255                 debug("SF: Unable to claim SPI bus\n");
256                 return ret;
257         }
258
259         for (actual = 0; actual < len; actual += chunk_len) {
260                 chunk_len = min(len - actual, page_size - byte_addr);
261
262                 /* Use the same address bits for both commands */
263                 cmd[0] = CMD_AT45_LOAD_BUF1;
264                 cmd[1] = page_addr >> (16 - page_shift);
265                 cmd[2] = page_addr << (page_shift - 8) | (byte_addr >> 8);
266                 cmd[3] = byte_addr;
267
268                 ret = spi_flash_cmd_write(flash->spi, cmd, 4,
269                                 buf + actual, chunk_len);
270                 if (ret < 0) {
271                         debug("SF: Loading AT45 buffer failed\n");
272                         goto out;
273                 }
274
275                 cmd[0] = CMD_AT45_PROG_BUF1;
276                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
277                 if (ret < 0) {
278                         debug("SF: AT45 page programming failed\n");
279                         goto out;
280                 }
281
282                 ret = at45_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT);
283                 if (ret < 0) {
284                         debug("SF: AT45 page programming timed out\n");
285                         goto out;
286                 }
287
288                 page_addr++;
289                 byte_addr = 0;
290         }
291
292         debug("SF: AT45: Successfully programmed %zu bytes @ 0x%x\n",
293                         len, offset);
294         ret = 0;
295
296 out:
297         spi_release_bus(flash->spi);
298         return ret;
299 }
300
301 /*
302  * TODO: the two erase funcs (_p2/_at45) should get unified ...
303  */
304 int dataflash_erase_p2(struct spi_flash *flash, u32 offset, size_t len)
305 {
306         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
307         unsigned long page_size;
308
309         size_t actual;
310         int ret;
311         u8 cmd[4];
312
313         /*
314          * TODO: This function currently uses page erase only. We can
315          * probably speed things up by using block and/or sector erase
316          * when possible.
317          */
318
319         page_size = (1 << asf->params->l2_page_size);
320
321         if (offset % page_size || len % page_size) {
322                 debug("SF: Erase offset/length not multiple of page size\n");
323                 return -1;
324         }
325
326         cmd[0] = CMD_AT45_ERASE_PAGE;
327         cmd[3] = 0x00;
328
329         ret = spi_claim_bus(flash->spi);
330         if (ret) {
331                 debug("SF: Unable to claim SPI bus\n");
332                 return ret;
333         }
334
335         for (actual = 0; actual < len; actual += page_size) {
336                 cmd[1] = offset >> 16;
337                 cmd[2] = offset >> 8;
338
339                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
340                 if (ret < 0) {
341                         debug("SF: AT45 page erase failed\n");
342                         goto out;
343                 }
344
345                 ret = at45_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
346                 if (ret < 0) {
347                         debug("SF: AT45 page erase timed out\n");
348                         goto out;
349                 }
350
351                 offset += page_size;
352         }
353
354         debug("SF: AT45: Successfully erased %zu bytes @ 0x%x\n",
355                         len, offset);
356         ret = 0;
357
358 out:
359         spi_release_bus(flash->spi);
360         return ret;
361 }
362
363 int dataflash_erase_at45(struct spi_flash *flash, u32 offset, size_t len)
364 {
365         struct atmel_spi_flash *asf = to_atmel_spi_flash(flash);
366         unsigned long page_addr;
367         unsigned long page_size;
368         unsigned int page_shift;
369         size_t actual;
370         int ret;
371         u8 cmd[4];
372
373         /*
374          * TODO: This function currently uses page erase only. We can
375          * probably speed things up by using block and/or sector erase
376          * when possible.
377          */
378
379         page_shift = asf->params->l2_page_size;
380         page_size = (1 << page_shift) + (1 << (page_shift - 5));
381         page_shift++;
382         page_addr = offset / page_size;
383
384         if (offset % page_size || len % page_size) {
385                 debug("SF: Erase offset/length not multiple of page size\n");
386                 return -1;
387         }
388
389         cmd[0] = CMD_AT45_ERASE_PAGE;
390         cmd[3] = 0x00;
391
392         ret = spi_claim_bus(flash->spi);
393         if (ret) {
394                 debug("SF: Unable to claim SPI bus\n");
395                 return ret;
396         }
397
398         for (actual = 0; actual < len; actual += page_size) {
399                 cmd[1] = page_addr >> (16 - page_shift);
400                 cmd[2] = page_addr << (page_shift - 8);
401
402                 ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0);
403                 if (ret < 0) {
404                         debug("SF: AT45 page erase failed\n");
405                         goto out;
406                 }
407
408                 ret = at45_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT);
409                 if (ret < 0) {
410                         debug("SF: AT45 page erase timed out\n");
411                         goto out;
412                 }
413
414                 page_addr++;
415         }
416
417         debug("SF: AT45: Successfully erased %zu bytes @ 0x%x\n",
418                         len, offset);
419         ret = 0;
420
421 out:
422         spi_release_bus(flash->spi);
423         return ret;
424 }
425
426 struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
427 {
428         const struct atmel_spi_flash_params *params;
429         unsigned page_size;
430         unsigned int family;
431         struct atmel_spi_flash *asf;
432         unsigned int i;
433         int ret;
434         u8 status;
435
436         for (i = 0; i < ARRAY_SIZE(atmel_spi_flash_table); i++) {
437                 params = &atmel_spi_flash_table[i];
438                 if (params->idcode1 == idcode[1])
439                         break;
440         }
441
442         if (i == ARRAY_SIZE(atmel_spi_flash_table)) {
443                 debug("SF: Unsupported DataFlash ID %02x\n",
444                                 idcode[1]);
445                 return NULL;
446         }
447
448         asf = malloc(sizeof(struct atmel_spi_flash));
449         if (!asf) {
450                 debug("SF: Failed to allocate memory\n");
451                 return NULL;
452         }
453
454         asf->params = params;
455         asf->flash.spi = spi;
456         asf->flash.name = params->name;
457
458         /* Assuming power-of-two page size initially. */
459         page_size = 1 << params->l2_page_size;
460
461         family = idcode[1] >> 5;
462
463         switch (family) {
464         case DF_FAMILY_AT45:
465                 /*
466                  * AT45 chips have configurable page size. The status
467                  * register indicates which configuration is active.
468                  */
469                 ret = spi_flash_cmd(spi, CMD_AT45_READ_STATUS, &status, 1);
470                 if (ret)
471                         goto err;
472
473                 debug("SF: AT45 status register: %02x\n", status);
474
475                 if (!(status & AT45_STATUS_P2_PAGE_SIZE)) {
476                         asf->flash.read = dataflash_read_fast_at45;
477                         asf->flash.write = dataflash_write_at45;
478                         asf->flash.erase = dataflash_erase_at45;
479                         page_size += 1 << (params->l2_page_size - 5);
480                 } else {
481                         asf->flash.read = spi_flash_cmd_read_fast;
482                         asf->flash.write = dataflash_write_p2;
483                         asf->flash.erase = dataflash_erase_p2;
484                 }
485
486                 break;
487
488         case DF_FAMILY_AT26F:
489         case DF_FAMILY_AT26DF:
490                 asf->flash.read = spi_flash_cmd_read_fast;
491                 break;
492
493         default:
494                 debug("SF: Unsupported DataFlash family %u\n", family);
495                 goto err;
496         }
497
498         asf->flash.size = page_size * params->pages_per_block
499                                 * params->blocks_per_sector
500                                 * params->nr_sectors;
501
502         printf("SF: Detected %s with page size %u, total ",
503                params->name, page_size);
504         print_size(asf->flash.size, "\n");
505
506         return &asf->flash;
507
508 err:
509         free(asf);
510         return NULL;
511 }