]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/spi/imx_spi_nor_atmel.c
applied patches from Freescale and Ka-Ro
[karo-tx-uboot.git] / drivers / mtd / spi / imx_spi_nor_atmel.c
1 /*
2  * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include <config.h>
24 #include <common.h>
25 #include <spi.h>
26 #include <spi_flash.h>
27 #include <asm/errno.h>
28 #include <linux/types.h>
29 #include <malloc.h>
30
31 #include <imx_spi.h>
32 #include <imx_spi_nor.h>
33
34 static u8 g_tx_buf[256];
35 static u8 g_rx_buf[256];
36
37 #define WRITE_ENABLE(a)                  spi_nor_cmd_1byte(a, WREN)
38 #define ENABLE_WRITE_STATUS(a)   spi_nor_cmd_1byte(a, EWSR)
39
40 struct imx_spi_flash_params {
41         u8              idcode1;
42         u32             block_size;
43         u32             block_count;
44         u32             device_size;
45         const char      *name;
46 };
47
48 struct imx_spi_flash {
49         const struct imx_spi_flash_params *params;
50         struct spi_flash flash;
51 };
52
53 static inline struct imx_spi_flash *
54 to_imx_spi_flash(struct spi_flash *flash)
55 {
56         return container_of(flash, struct imx_spi_flash, flash);
57 }
58
59 static const struct imx_spi_flash_params imx_spi_flash_table[] = {
60         {
61                 .idcode1                = 0x27,
62                 .block_size             = SZ_64K,
63                 .block_count            = 64,
64                 .device_size            = SZ_64K * 64,
65                 .name                   = "AT45DB321D - 4MB",
66         },
67 };
68
69 static s32 spi_nor_flash_query(struct spi_flash *flash, void* data)
70 {
71         u8 au8Tmp[4] = { 0 };
72         u8 *pData = (u8 *)data;
73
74         g_tx_buf[3] = JEDEC_ID;
75
76         if (spi_xfer(flash->spi, (4 << 3), g_tx_buf, au8Tmp,
77                                 SPI_XFER_BEGIN | SPI_XFER_END)) {
78                 return -1;
79         }
80
81         printf("JEDEC ID: 0x%02x:0x%02x:0x%02x\n",
82                         au8Tmp[2], au8Tmp[1], au8Tmp[0]);
83
84         pData[0] = au8Tmp[2];
85         pData[1] = au8Tmp[1];
86         pData[2] = au8Tmp[0];
87
88         return 0;
89 }
90
91 static s32 spi_nor_status(struct spi_flash *flash)
92 {
93         g_tx_buf[1] = STAT_READ;
94
95         if (spi_xfer(flash->spi, 2 << 3, g_tx_buf, g_rx_buf,
96                         SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
97                 printf("Error: %s(): %d\n", __func__, __LINE__);
98                 return 0;
99         }
100         return g_rx_buf[0];
101 }
102
103 #if 0
104 /*!
105  * Erase a block_size data from block_addr offset in the flash
106  */
107 static int spi_nor_erase_page(struct spi_flash *flash,
108                                 void *page_addr)
109 {
110         u32 addr = (u32)page_addr;
111
112         if ((addr & 512) != 0) {
113                 printf("Error - page_addr is not "
114                                 "512 Bytes aligned: %p\n",
115                                 page_addr);
116                 return -1;
117         }
118
119         /* now do the block erase */
120         if (spi_xfer(flash->spi, 4 << 3, g_tx_buf, g_rx_buf,
121                         SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
122                 return -1;
123         }
124
125         while (spi_nor_status(flash) & RDSR_BUSY)
126                 ;
127
128         return 0;
129 }
130 #endif
131
132 static int spi_nor_flash_read(struct spi_flash *flash, u32 offset,
133                 size_t len, void *buf)
134 {
135         struct imx_spi_flash *imx_sf = to_imx_spi_flash(flash);
136         u32 *cmd = (u32 *)g_tx_buf;
137         u32 max_rx_sz = (MAX_SPI_BYTES) - 4;
138         u8 *d_buf = (u8 *)buf;
139         u8 *s_buf;
140         s32 s32remain_size = len;
141         int i;
142
143         if (!(flash->spi))
144                 return -1;
145
146         printf("Reading SPI NOR flash 0x%x [0x%x bytes] -> ram 0x%p\n",
147                 offset, len, buf);
148         debug("%s(from flash=0x%08x to ram=%p len=0x%x)\n",
149                 __func__,
150                 offset, buf, len);
151
152         if (len == 0)
153                 return 0;
154
155         *cmd = (READ << 24) | ((u32)offset & 0x00FFFFFF);
156
157         for (; s32remain_size > 0;
158                         s32remain_size -= max_rx_sz, *cmd += max_rx_sz) {
159                 debug("Addr:0x%p=>Offset:0x%08x, %d bytes transferred\n",
160                                 d_buf,
161                                 (*cmd & 0x00FFFFFF),
162                                 (len - s32remain_size));
163                 debug("%d%% completed\n", ((len - s32remain_size) * 100 / len));
164
165                 if (s32remain_size < max_rx_sz) {
166                         debug("100%% completed\n");
167
168                         if (spi_xfer(flash->spi, (s32remain_size + 4) << 3,
169                                 g_tx_buf, g_rx_buf,
170                                 SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
171                                 printf("Error: %s(%d): failed\n",
172                                         __FILE__, __LINE__);
173                                 return -1;
174                         }
175                         /* throw away 4 bytes (5th received bytes is real) */
176                         s_buf = g_rx_buf + 4;
177
178                         /* now adjust the endianness */
179                         for (i = s32remain_size; i >= 0; i -= 4, s_buf += 4) {
180                                 if (i < 4) {
181                                         if (i == 1) {
182                                                 *d_buf = s_buf[0];
183                                         } else if (i == 2) {
184                                                 *d_buf++ = s_buf[1];
185                                                 *d_buf++ = s_buf[0];
186                                         } else if (i == 3) {
187                                                 *d_buf++ = s_buf[2];
188                                                 *d_buf++ = s_buf[1];
189                                                 *d_buf++ = s_buf[0];
190                                         }
191                                         printf("SUCCESS\n\n");
192                                         return 0;
193                                 }
194                                 /* copy 4 bytes */
195                                 *d_buf++ = s_buf[3];
196                                 *d_buf++ = s_buf[2];
197                                 *d_buf++ = s_buf[1];
198                                 *d_buf++ = s_buf[0];
199                         }
200                 }
201
202                 /* now grab max_rx_sz data (+4 is
203                 *needed due to 4-throw away bytes */
204                 if (spi_xfer(flash->spi, (max_rx_sz + 4) << 3,
205                         g_tx_buf, g_rx_buf,
206                         SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
207                         printf("Error: %s(%d): failed\n", __FILE__, __LINE__);
208                         return -1;
209                 }
210                 /* throw away 4 bytes (5th received bytes is real) */
211                 s_buf = g_rx_buf + 4;
212                 /* now adjust the endianness */
213                 for (i = 0; i < max_rx_sz; i += 4, s_buf += 4) {
214                         *d_buf++ = s_buf[3];
215                         *d_buf++ = s_buf[2];
216                         *d_buf++ = s_buf[1];
217                         *d_buf++ = s_buf[0];
218                 }
219
220                 if ((s32remain_size % imx_sf->params->block_size) == 0)
221                         printf(".");
222         }
223         printf("SUCCESS\n\n");
224
225         return -1;
226 }
227
228 static int spi_nor_flash_write(struct spi_flash *flash, u32 offset,
229                 size_t len, const void *buf)
230 {
231         u32 d_addr = offset;
232         u8 *s_buf = (u8 *)buf;
233         unsigned int final_addr = 0;
234         int page_size = 528, trans_bytes = 0, buf_ptr = 0,
235                 bytes_sent = 0, byte_sent_per_iter = 0;
236         int page_no = 0, buf_addr = 0, page_off = 0,
237                 i = 0, j = 0, k = 0, fifo_size = 32;
238         int remain_len = 0;
239
240         if (!(flash->spi))
241                 return -1;
242
243         if (len == 0)
244                 return 0;
245
246         printf("Writing SPI NOR flash 0x%x [0x%x bytes] <- ram 0x%p\n",
247                 offset, len, buf);
248         debug("%s(flash addr=0x%08x, ram=%p, len=0x%x)\n",
249                         __func__, offset, buf, len);
250
251         /* Read the status register to get the Page size */
252         if (spi_nor_status(flash) & STAT_PG_SZ) {
253                 page_size = 512;
254         } else {
255                 puts("Unsupported Page Size of 528 bytes\n");
256                 g_tx_buf[0] = CONFIG_REG4;
257                 g_tx_buf[1] = CONFIG_REG3;
258                 g_tx_buf[2] = CONFIG_REG2;
259                 g_tx_buf[3] = CONFIG_REG1;
260
261                 if (spi_xfer(flash->spi, 4 << 3, g_tx_buf, g_rx_buf,
262                                 SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
263                         printf("Error: %s(): %d", __func__, __LINE__);
264                         return -1;
265                 }
266
267                 while (!(spi_nor_status(flash) & STAT_BUSY))
268                         ;
269
270                 puts("Reprogrammed the Page Size to 512 bytes\n");
271                 puts("Please Power Cycle the board for the change to take effect\n");
272
273                 return -1;
274         }
275
276         /* Due to the way CSPI operates send data less
277            that 4 bytes in a different manner */
278         remain_len = len % 4;
279         if (remain_len)
280                 len -= remain_len;
281
282         while (1) {
283                 page_no = d_addr / page_size;
284                 /* Get the offset within the page
285                 if address is not page-aligned */
286                 page_off = (d_addr % page_size);
287                 if (page_off) {
288                         if (page_no == 0)
289                                 buf_addr = d_addr;
290                         else
291                                 buf_addr = page_off;
292
293                         trans_bytes = page_size - buf_addr;
294                 } else {
295                         buf_addr = 0;
296                         trans_bytes = page_size;
297                 }
298
299                 if (len <= 0)
300                         break;
301
302                 if (trans_bytes > len)
303                         trans_bytes = len;
304
305                 bytes_sent = trans_bytes;
306                 /* Write the data to the SPI-NOR Buffer first */
307                 while (trans_bytes > 0) {
308                         final_addr = (buf_addr & 0x3FF);
309                         g_tx_buf[0] = final_addr;
310                         g_tx_buf[1] = final_addr >> 8;
311                         g_tx_buf[2] = final_addr >> 16;
312                         g_tx_buf[3] = BUF1_WR; /*Opcode */
313
314                         /* 4 bytes already used for Opcode & address bytes,
315                         check to ensure we do not overflow the SPI TX buffer */
316                         if (trans_bytes > (fifo_size - 4))
317                                 byte_sent_per_iter = fifo_size;
318                         else
319                                 byte_sent_per_iter = trans_bytes + 4;
320
321                         for (i = 4; i < byte_sent_per_iter; i += 4) {
322                                 g_tx_buf[i + 3] = s_buf[buf_ptr++];
323                                 g_tx_buf[i + 2] = s_buf[buf_ptr++];
324                                 g_tx_buf[i + 1] = s_buf[buf_ptr++];
325                                 g_tx_buf[i] = s_buf[buf_ptr++];
326                         }
327
328                         if (spi_xfer(flash->spi, byte_sent_per_iter << 3,
329                                         g_tx_buf, g_rx_buf,
330                                         SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
331                                 printf("Error: %s(%d): failed\n",
332                                         __FILE__, __LINE__);
333                                 return -1;
334                         }
335
336                         while (!(spi_nor_status(flash) & STAT_BUSY))
337                                 ;
338
339                         /* Deduct 4 bytes as it is used for Opcode & address bytes */
340                         trans_bytes -= (byte_sent_per_iter - 4);
341                         /* Update the destination buffer address */
342                         buf_addr += (byte_sent_per_iter - 4);
343                 }
344
345                 /* Send the command to write data from the SPI-NOR Buffer to Flash memory */
346                 final_addr = (page_size == 512) ? ((page_no & 0x1FFF) << 9) : \
347                                 ((page_no & 0x1FFF) << 10);
348
349                 /* Specify the Page address in Flash where the data should be written to */
350                 g_tx_buf[0] = final_addr;
351                 g_tx_buf[1] = final_addr >> 8;
352                 g_tx_buf[2] = final_addr >> 16;
353                 g_tx_buf[3] = BUF1_TO_MEM; /*Opcode */
354                 if (spi_xfer(flash->spi, 4 << 3, g_tx_buf, g_rx_buf,
355                                 SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
356                         printf("Error: %s(%d): failed\n", __FILE__, __LINE__);
357                         return -1;
358                 }
359
360                 while (!(spi_nor_status(flash) & STAT_BUSY))
361                         ;
362
363                 d_addr += bytes_sent;
364                 len -= bytes_sent;
365                 if (d_addr % (page_size * 50) == 0)
366                         puts(".");
367         }
368
369         if (remain_len) {
370                 buf_ptr += remain_len;
371                 /* Write the remaining data bytes first */
372                 for (i = 0; i < remain_len; ++i)
373                         g_tx_buf[i] = s_buf[buf_ptr--];
374
375                 /* Write the address bytes next in the same word
376                 as the data byte from the next byte */
377                 for (j = i, k = 0; j < 4; j++, k++)
378                         g_tx_buf[j] = final_addr >> (k * 8);
379
380                 /* Write the remaining address bytes in the next word */
381                 j = 0;
382                 final_addr = (buf_addr & 0x3FF);
383
384                 for (j = 0; k < 3; j++, k++)
385                         g_tx_buf[j] = final_addr >> (k * 8);
386
387                 /* Finally the Opcode to write the data to the buffer */
388                 g_tx_buf[j] = BUF1_WR; /*Opcode */
389
390                 if (spi_xfer(flash->spi, (remain_len + 4) << 3,
391                         g_tx_buf, g_rx_buf,
392                         SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
393                         printf("Error: %s(%d): failed\n", __FILE__, __LINE__);
394                         return -1;
395                 }
396
397                 while (!(spi_nor_status(flash) & STAT_BUSY))
398                         ;
399
400                 if (page_size == 512)
401                         final_addr = (page_no & 0x1FFF) << 9;
402                 else
403                         final_addr = (page_no & 0x1FFF) << 10;
404
405                 g_tx_buf[0] = final_addr;
406                 g_tx_buf[1] = final_addr >> 8;
407                 g_tx_buf[2] = final_addr >> 16;
408                 g_tx_buf[3] = BUF1_TO_MEM; /*Opcode */
409                 if (spi_xfer(flash->spi, 4 << 3, g_tx_buf, g_rx_buf,
410                         SPI_XFER_BEGIN | SPI_XFER_END) != 0) {
411                         printf("Error: %s(%d): failed\n", __FILE__, __LINE__);
412                                 return -1;
413                 }
414
415                 while (!(spi_nor_status(flash) & STAT_BUSY))
416                                 ;
417         }
418
419         printf("SUCCESS\n\n");
420
421         return 0;
422 }
423
424 static int spi_nor_flash_erase(struct spi_flash *flash, u32 offset,
425                 size_t len)
426 {
427         printf("Erase is built in program.\n");
428
429         return 0;
430 }
431
432 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int spi_mode)
433 {
434         struct spi_slave *spi = NULL;
435         const struct imx_spi_flash_params *params = NULL;
436         struct imx_spi_flash *imx_sf = NULL;
437         u8  idcode[4] = { 0 };
438         u32 i = 0;
439         s32 ret = 0;
440
441         if (CONFIG_SPI_FLASH_CS != cs) {
442                 printf("Invalid cs for SPI NOR.\n");
443                 return NULL;
444         }
445
446         spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
447
448         if (!spi) {
449                 debug("SF: Failed to set up slave\n");
450                 return NULL;
451         }
452
453         ret = spi_claim_bus(spi);
454         if (ret) {
455                 debug("SF: Failed to claim SPI bus: %d\n", ret);
456                 goto err_claim_bus;
457         }
458
459         imx_sf = (struct imx_spi_flash *)malloc(sizeof(struct imx_spi_flash));
460
461         if (!imx_sf) {
462                 debug("SF: Failed to allocate memory\n");
463                 spi_free_slave(spi);
464                 return NULL;
465         }
466
467         imx_sf->flash.spi = spi;
468
469         /* Read the ID codes */
470         ret = spi_nor_flash_query(&(imx_sf->flash), idcode);
471         if (ret)
472                 goto err_read_id;
473
474         for (i = 0; i < ARRAY_SIZE(imx_spi_flash_table); ++i) {
475                 params = &imx_spi_flash_table[i];
476                 if (params->idcode1 == idcode[1])
477                         break;
478         }
479
480         if (i == ARRAY_SIZE(imx_spi_flash_table)) {
481                 debug("SF: Unsupported DataFlash ID %02x\n",
482                                 idcode[1]);
483
484                 goto err_invalid_dev;
485         }
486
487         imx_sf->params = params;
488
489         imx_sf->flash.name = params->name;
490         imx_sf->flash.size = params->device_size;
491
492         imx_sf->flash.read  = spi_nor_flash_read;
493         imx_sf->flash.write = spi_nor_flash_write;
494         imx_sf->flash.erase = spi_nor_flash_erase;
495
496         debug("SF: Detected %s with block size %lu, "
497                         "block count %lu, total %u bytes\n",
498                         params->name,
499                         params->block_size,
500                         params->block_count,
501                         params->device_size);
502
503         return &(imx_sf->flash);
504
505 err_read_id:
506         spi_release_bus(spi);
507 err_invalid_dev:
508         if (imx_sf)
509                 free(imx_sf);
510 err_claim_bus:
511         if (spi)
512                 spi_free_slave(spi);
513         return NULL;
514 }
515
516 void spi_flash_free(struct spi_flash *flash)
517 {
518         struct imx_spi_flash *imx_sf = NULL;
519
520         if (!flash)
521                 return;
522
523         imx_sf = to_imx_spi_flash(flash);
524
525         if (flash->spi) {
526                 spi_free_slave(flash->spi);
527                 flash->spi = NULL;
528         }
529
530         free(imx_sf);
531 }
532