]> git.sur5r.net Git - u-boot/blob - drivers/cfi_flash.c
* Some code cleanup
[u-boot] / drivers / cfi_flash.c
1 /*
2  * (C) Copyright 2002-2004
3  * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
4  *
5  * Copyright (C) 2003 Arabella Software Ltd.
6  * Yuli Barcohen <yuli@arabellasw.com>
7  * Modified to work with AMD flashes
8  *
9  * Copyright (C) 2004
10  * Ed Okerson
11  * Modified to work with little-endian systems.
12  *
13  * See file CREDITS for list of people who contributed to this
14  * project.
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License as
18  * published by the Free Software Foundation; either version 2 of
19  * the License, or (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29  * MA 02111-1307 USA
30  *
31  * History
32  * 01/20/2004 - combined variants of original driver.
33  * 01/22/2004 - Write performance enhancements for parallel chips (Tolunay)
34  * 01/23/2004 - Support for x8/x16 chips (Rune Raknerud)
35  * 01/27/2004 - Little endian support Ed Okerson
36  *
37  * Tested Architectures
38  * Port Width  Chip Width    # of banks    Flash Chip  Board
39  * 32          16            1             23F128J3    seranoa/eagle
40  * 64          16            1             23F128J3    seranoa/falcon
41  *
42  */
43
44 /* The DEBUG define must be before common to enable debugging */
45 #undef  DEBUG
46 #include <common.h>
47 #include <asm/processor.h>
48 #ifdef  CFG_FLASH_CFI_DRIVER
49 /*
50  * This file implements a Common Flash Interface (CFI) driver for U-Boot.
51  * The width of the port and the width of the chips are determined at initialization.
52  * These widths are used to calculate the address for access CFI data structures.
53  * It has been tested on an Intel Strataflash implementation and AMD 29F016D.
54  *
55  * References
56  * JEDEC Standard JESD68 - Common Flash Interface (CFI)
57  * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
58  * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
59  * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
60  *
61  * TODO
62  *
63  * Use Primary Extended Query table (PRI) and Alternate Algorithm Query
64  * Table (ALT) to determine if protection is available
65  *
66  * Add support for other command sets Use the PRI and ALT to determine command set
67  * Verify erase and program timeouts.
68  */
69
70 #ifndef CFG_FLASH_BANKS_LIST
71 #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE }
72 #endif
73
74 #define FLASH_CMD_CFI                   0x98
75 #define FLASH_CMD_READ_ID               0x90
76 #define FLASH_CMD_RESET                 0xff
77 #define FLASH_CMD_BLOCK_ERASE           0x20
78 #define FLASH_CMD_ERASE_CONFIRM         0xD0
79 #define FLASH_CMD_WRITE                 0x40
80 #define FLASH_CMD_PROTECT               0x60
81 #define FLASH_CMD_PROTECT_SET           0x01
82 #define FLASH_CMD_PROTECT_CLEAR         0xD0
83 #define FLASH_CMD_CLEAR_STATUS          0x50
84 #define FLASH_CMD_WRITE_TO_BUFFER       0xE8
85 #define FLASH_CMD_WRITE_BUFFER_CONFIRM  0xD0
86
87 #define FLASH_STATUS_DONE               0x80
88 #define FLASH_STATUS_ESS                0x40
89 #define FLASH_STATUS_ECLBS              0x20
90 #define FLASH_STATUS_PSLBS              0x10
91 #define FLASH_STATUS_VPENS              0x08
92 #define FLASH_STATUS_PSS                0x04
93 #define FLASH_STATUS_DPS                0x02
94 #define FLASH_STATUS_R                  0x01
95 #define FLASH_STATUS_PROTECT            0x01
96
97 #define AMD_CMD_RESET                   0xF0
98 #define AMD_CMD_WRITE                   0xA0
99 #define AMD_CMD_ERASE_START             0x80
100 #define AMD_CMD_ERASE_SECTOR            0x30
101
102 #define AMD_STATUS_TOGGLE               0x40
103 #define AMD_STATUS_ERROR                0x20
104
105 #define FLASH_OFFSET_CFI                0x55
106 #define FLASH_OFFSET_CFI_RESP           0x10
107 #define FLASH_OFFSET_PRIMARY_VENDOR     0x13
108 #define FLASH_OFFSET_WTOUT              0x1F
109 #define FLASH_OFFSET_WBTOUT             0x20
110 #define FLASH_OFFSET_ETOUT              0x21
111 #define FLASH_OFFSET_CETOUT             0x22
112 #define FLASH_OFFSET_WMAX_TOUT          0x23
113 #define FLASH_OFFSET_WBMAX_TOUT         0x24
114 #define FLASH_OFFSET_EMAX_TOUT          0x25
115 #define FLASH_OFFSET_CEMAX_TOUT         0x26
116 #define FLASH_OFFSET_SIZE               0x27
117 #define FLASH_OFFSET_INTERFACE          0x28
118 #define FLASH_OFFSET_BUFFER_SIZE        0x2A
119 #define FLASH_OFFSET_NUM_ERASE_REGIONS  0x2C
120 #define FLASH_OFFSET_ERASE_REGIONS      0x2D
121 #define FLASH_OFFSET_PROTECT            0x02
122 #define FLASH_OFFSET_USER_PROTECTION    0x85
123 #define FLASH_OFFSET_INTEL_PROTECTION   0x81
124
125
126 #define FLASH_MAN_CFI                   0x01000000
127
128 #define CFI_CMDSET_NONE             0
129 #define CFI_CMDSET_INTEL_EXTENDED   1
130 #define CFI_CMDSET_AMD_STANDARD     2
131 #define CFI_CMDSET_INTEL_STANDARD   3
132 #define CFI_CMDSET_AMD_EXTENDED     4
133 #define CFI_CMDSET_MITSU_STANDARD   256
134 #define CFI_CMDSET_MITSU_EXTENDED   257
135 #define CFI_CMDSET_SST              258
136
137
138 typedef union {
139         unsigned char c;
140         unsigned short w;
141         unsigned long l;
142         unsigned long long ll;
143 } cfiword_t;
144
145 typedef union {
146         volatile unsigned char *cp;
147         volatile unsigned short *wp;
148         volatile unsigned long *lp;
149         volatile unsigned long long *llp;
150 } cfiptr_t;
151
152 #define NUM_ERASE_REGIONS 4
153
154 static ulong bank_base[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS_LIST;
155
156 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];   /* info for FLASH chips   */
157
158 /*-----------------------------------------------------------------------
159  * Functions
160  */
161
162 typedef unsigned long flash_sect_t;
163
164 static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c);
165 static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf);
166 static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
167                              uint offset, uchar cmd);
168 static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect);
169 static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset,
170                           uchar cmd);
171 static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset,
172                         uchar cmd);
173 static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset,
174                          uchar cmd);
175 static int flash_detect_cfi (flash_info_t * info);
176 static ulong flash_get_size (ulong base, int banknum);
177 static int flash_write_cfiword (flash_info_t * info, ulong dest,
178                                 cfiword_t cword);
179 static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
180                                     ulong tout, char *prompt);
181 #ifdef CFG_FLASH_USE_BUFFER_WRITE
182 static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
183                                   int len);
184 #endif
185
186 /*-----------------------------------------------------------------------
187  * create an address based on the offset and the port width
188  */
189 inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect,
190                                uint offset)
191 {
192         return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
193 }
194
195 #ifdef DEBUG
196 /*-----------------------------------------------------------------------
197  * Debug support
198  */
199 void print_longlong (char *str, unsigned long long data)
200 {
201         int i;
202         char *cp;
203
204         cp = (unsigned char *) &data;
205         for (i = 0; i < 8; i++)
206                 sprintf (&str[i * 2], "%2.2x", *cp++);
207 }
208 static void flash_printqry (flash_info_t * info, flash_sect_t sect)
209 {
210         cfiptr_t cptr;
211         int x, y;
212
213         for (x = 0; x < 0x40; x += 16 / info->portwidth) {
214                 cptr.cp =
215                         flash_make_addr (info, sect,
216                                          x + FLASH_OFFSET_CFI_RESP);
217                 debug ("%p : ", cptr.cp);
218                 for (y = 0; y < 16; y++) {
219                         debug ("%2.2x ", cptr.cp[y]);
220                 }
221                 debug (" ");
222                 for (y = 0; y < 16; y++) {
223                         if (cptr.cp[y] >= 0x20 && cptr.cp[y] <= 0x7e) {
224                                 debug ("%c", cptr.cp[y]);
225                         } else {
226                                 debug (".");
227                         }
228                 }
229                 debug ("\n");
230         }
231 }
232
233 #endif
234
235
236 /*-----------------------------------------------------------------------
237  * read a character at a port width address
238  */
239 inline uchar flash_read_uchar (flash_info_t * info, uint offset)
240 {
241         uchar *cp;
242
243         cp = flash_make_addr (info, 0, offset);
244 #if defined(__LITTLE_ENDIAN)
245         return (cp[0]);
246 #else
247         return (cp[info->portwidth - 1]);
248 #endif
249 }
250
251 /*-----------------------------------------------------------------------
252  * read a short word by swapping for ppc format.
253  */
254 ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
255 {
256         uchar *addr;
257         ushort retval;
258
259 #ifdef DEBUG
260         int x;
261 #endif
262         addr = flash_make_addr (info, sect, offset);
263
264 #ifdef DEBUG
265         debug ("ushort addr is at %p info->portwidth = %d\n", addr,
266                info->portwidth);
267         for (x = 0; x < 2 * info->portwidth; x++) {
268                 debug ("addr[%x] = 0x%x\n", x, addr[x]);
269         }
270 #endif
271 #if defined(__LITTLE_ENDIAN)
272         retval = ((addr[(info->portwidth)] << 8) | addr[0]);
273 #else
274         retval = ((addr[(2 * info->portwidth) - 1] << 8) |
275                   addr[info->portwidth - 1]);
276 #endif
277
278         debug ("retval = 0x%x\n", retval);
279         return retval;
280 }
281
282 /*-----------------------------------------------------------------------
283  * read a long word by picking the least significant byte of each maiximum
284  * port size word. Swap for ppc format.
285  */
286 ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
287 {
288
289         uchar *addr;
290         ulong retval;
291
292 #ifdef DEBUG
293         int x;
294 #endif
295         addr = flash_make_addr (info, sect, offset);
296
297 #ifdef DEBUG
298         debug ("long addr is at %p info->portwidth = %d\n", addr,
299                info->portwidth);
300         for (x = 0; x < 4 * info->portwidth; x++) {
301                 debug ("addr[%x] = 0x%x\n", x, addr[x]);
302         }
303 #endif
304 #if defined(__LITTLE_ENDIAN)
305         retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) |
306                 (addr[(2 * info->portwidth)]) | (addr[(3 * info->portwidth)]
307                                                  << 8);
308 #else
309         retval = (addr[(2 * info->portwidth) - 1] << 24) |
310                 (addr[(info->portwidth) - 1] << 16) |
311                 (addr[(4 * info->portwidth) - 1] << 8) |
312                 addr[(3 * info->portwidth) - 1];
313 #endif
314         return retval;
315 }
316
317 /*-----------------------------------------------------------------------
318  */
319 unsigned long flash_init (void)
320 {
321         unsigned long size = 0;
322         int i;
323
324         /* Init: no FLASHes known */
325         for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
326                 flash_info[i].flash_id = FLASH_UNKNOWN;
327                 size += flash_info[i].size = flash_get_size (bank_base[i], i);
328                 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
329                         printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", i, flash_info[i].size, flash_info[i].size << 20);
330                 }
331         }
332
333         /* Monitor protection ON by default */
334 #if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
335         flash_protect (FLAG_PROTECT_SET,
336                        CFG_MONITOR_BASE,
337                        CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
338                        &flash_info[0]);
339 #endif
340
341         return (size);
342 }
343
344 /*-----------------------------------------------------------------------
345  */
346 int flash_erase (flash_info_t * info, int s_first, int s_last)
347 {
348         int rcode = 0;
349         int prot;
350         flash_sect_t sect;
351
352         if (info->flash_id != FLASH_MAN_CFI) {
353                 printf ("Can't erase unknown flash type - aborted\n");
354                 return 1;
355         }
356         if ((s_first < 0) || (s_first > s_last)) {
357                 printf ("- no sectors to erase\n");
358                 return 1;
359         }
360
361         prot = 0;
362         for (sect = s_first; sect <= s_last; ++sect) {
363                 if (info->protect[sect]) {
364                         prot++;
365                 }
366         }
367         if (prot) {
368                 printf ("- Warning: %d protected sectors will not be erased!\n", prot);
369         } else {
370                 printf ("\n");
371         }
372
373
374         for (sect = s_first; sect <= s_last; sect++) {
375                 if (info->protect[sect] == 0) { /* not protected */
376                         switch (info->vendor) {
377                         case CFI_CMDSET_INTEL_STANDARD:
378                         case CFI_CMDSET_INTEL_EXTENDED:
379                                 flash_write_cmd (info, sect, 0,
380                                                  FLASH_CMD_CLEAR_STATUS);
381                                 flash_write_cmd (info, sect, 0,
382                                                  FLASH_CMD_BLOCK_ERASE);
383                                 flash_write_cmd (info, sect, 0,
384                                                  FLASH_CMD_ERASE_CONFIRM);
385                                 break;
386                         case CFI_CMDSET_AMD_STANDARD:
387                         case CFI_CMDSET_AMD_EXTENDED:
388                                 flash_unlock_seq (info, sect);
389                                 flash_write_cmd (info, sect, 0x555,
390                                                  AMD_CMD_ERASE_START);
391                                 flash_unlock_seq (info, sect);
392                                 flash_write_cmd (info, sect, 0,
393                                                  AMD_CMD_ERASE_SECTOR);
394                                 break;
395                         default:
396                                 debug ("Unkown flash vendor %d\n",
397                                        info->vendor);
398                                 break;
399                         }
400
401                         if (flash_full_status_check
402                             (info, sect, info->erase_blk_tout, "erase")) {
403                                 rcode = 1;
404                         } else
405                                 printf (".");
406                 }
407         }
408         printf (" done\n");
409         return rcode;
410 }
411
412 /*-----------------------------------------------------------------------
413  */
414 void flash_print_info (flash_info_t * info)
415 {
416         int i;
417
418         if (info->flash_id != FLASH_MAN_CFI) {
419                 printf ("missing or unknown FLASH type\n");
420                 return;
421         }
422
423         printf ("CFI conformant FLASH (%d x %d)",
424                 (info->portwidth << 3), (info->chipwidth << 3));
425         printf ("  Size: %ld MB in %d Sectors\n",
426                 info->size >> 20, info->sector_count);
427         printf (" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n", info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size);
428
429         printf ("  Sector Start Addresses:");
430         for (i = 0; i < info->sector_count; ++i) {
431 #ifdef CFG_FLASH_EMPTY_INFO
432                 int k;
433                 int size;
434                 int erased;
435                 volatile unsigned long *flash;
436
437                 /*
438                  * Check if whole sector is erased
439                  */
440                 if (i != (info->sector_count - 1))
441                         size = info->start[i + 1] - info->start[i];
442                 else
443                         size = info->start[0] + info->size - info->start[i];
444                 erased = 1;
445                 flash = (volatile unsigned long *) info->start[i];
446                 size = size >> 2;       /* divide by 4 for longword access */
447                 for (k = 0; k < size; k++) {
448                         if (*flash++ != 0xffffffff) {
449                                 erased = 0;
450                                 break;
451                         }
452                 }
453
454                 if ((i % 5) == 0)
455                         printf ("\n");
456                 /* print empty and read-only info */
457                 printf (" %08lX%s%s",
458                         info->start[i],
459                         erased ? " E" : "  ",
460                         info->protect[i] ? "RO " : "   ");
461 #else
462                 if ((i % 5) == 0)
463                         printf ("\n   ");
464                 printf (" %08lX%s",
465                         info->start[i], info->protect[i] ? " (RO)" : "     ");
466 #endif
467         }
468         printf ("\n");
469         return;
470 }
471
472 /*-----------------------------------------------------------------------
473  * Copy memory to flash, returns:
474  * 0 - OK
475  * 1 - write timeout
476  * 2 - Flash not erased
477  */
478 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
479 {
480         ulong wp;
481         ulong cp;
482         int aln;
483         cfiword_t cword;
484         int i, rc;
485
486 #ifdef CFG_FLASH_USE_BUFFER_WRITE
487         int buffered_size;
488 #endif
489         int x8mode = 0;
490
491         /* special handling of 16 bit devices in 8 bit mode */
492         if ((info->interface == FLASH_CFI_X8X16)
493             && (info->chipwidth == FLASH_CFI_BY8)) {
494                 switch (info->vendor) {
495                 case CFI_CMDSET_INTEL_STANDARD:
496                 case CFI_CMDSET_INTEL_EXTENDED:
497                         x8mode = info->portwidth;
498                         info->portwidth >>= 1;  /* XXX - Need to test on x9/x16 in parallel. */
499                         /*info->portwidth = FLASH_CFI_8BIT; */ /* XXX - Need to test on x9/x16 in parallel. */
500                         break;
501                 case CFI_CMDSET_AMD_STANDARD:
502                 case CFI_CMDSET_AMD_EXTENDED:
503                 default:
504                         break;
505                 }
506         }
507         /* get lower aligned address */
508         /* get lower aligned address */
509         wp = (addr & ~(info->portwidth - 1));
510
511         /* handle unaligned start */
512         if ((aln = addr - wp) != 0) {
513                 cword.l = 0;
514                 cp = wp;
515                 for (i = 0; i < aln; ++i, ++cp)
516                         flash_add_byte (info, &cword, (*(uchar *) cp));
517
518                 for (; (i < info->portwidth) && (cnt > 0); i++) {
519                         flash_add_byte (info, &cword, *src++);
520                         cnt--;
521                         cp++;
522                 }
523                 for (; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
524                         flash_add_byte (info, &cword, (*(uchar *) cp));
525                 if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
526                         return rc;
527                 wp = cp;
528         }
529
530         /* handle the aligned part */
531 #ifdef CFG_FLASH_USE_BUFFER_WRITE
532         buffered_size = (info->portwidth / info->chipwidth);
533         buffered_size *= info->buffer_size;
534         while (cnt >= info->portwidth) {
535                 i = buffered_size > cnt ? cnt : buffered_size;
536                 if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)
537                         return rc;
538                 wp += i;
539                 src += i;
540                 cnt -= i;
541         }
542 #else
543         while (cnt >= info->portwidth) {
544                 cword.l = 0;
545                 for (i = 0; i < info->portwidth; i++) {
546                         flash_add_byte (info, &cword, *src++);
547                 }
548                 if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
549                         return rc;
550                 wp += info->portwidth;
551                 cnt -= info->portwidth;
552         }
553 #endif /* CFG_FLASH_USE_BUFFER_WRITE */
554         if (cnt == 0) {
555                 return (0);
556         }
557
558         /*
559          * handle unaligned tail bytes
560          */
561         cword.l = 0;
562         for (i = 0, cp = wp; (i < info->portwidth) && (cnt > 0); ++i, ++cp) {
563                 flash_add_byte (info, &cword, *src++);
564                 --cnt;
565         }
566         for (; i < info->portwidth; ++i, ++cp) {
567                 flash_add_byte (info, &cword, (*(uchar *) cp));
568         }
569
570         /* special handling of 16 bit devices in 8 bit mode */
571         if (x8mode) {
572                 info->portwidth = x8mode;;
573         }
574         return flash_write_cfiword (info, wp, cword);
575 }
576
577 /*-----------------------------------------------------------------------
578  */
579 #ifdef CFG_FLASH_PROTECTION
580
581 int flash_real_protect (flash_info_t * info, long sector, int prot)
582 {
583         int retcode = 0;
584
585         flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
586         flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
587         if (prot)
588                 flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
589         else
590                 flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
591
592         if ((retcode =
593              flash_full_status_check (info, sector, info->erase_blk_tout,
594                                       prot ? "protect" : "unprotect")) == 0) {
595
596                 info->protect[sector] = prot;
597                 /* Intel's unprotect unprotects all locking */
598                 if (prot == 0) {
599                         flash_sect_t i;
600
601                         for (i = 0; i < info->sector_count; i++) {
602                                 if (info->protect[i])
603                                         flash_real_protect (info, i, 1);
604                         }
605                 }
606         }
607
608         return retcode;
609 }
610
611 /*-----------------------------------------------------------------------
612  * flash_read_user_serial - read the OneTimeProgramming cells
613  */
614 void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
615                              int len)
616 {
617         uchar *src;
618         uchar *dst;
619
620         dst = buffer;
621         src = flash_make_addr (info, 0, FLASH_OFFSET_USER_PROTECTION);
622         flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
623         memcpy (dst, src + offset, len);
624         flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
625 }
626
627 /*
628  * flash_read_factory_serial - read the device Id from the protection area
629  */
630 void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
631                                 int len)
632 {
633         uchar *src;
634
635         src = flash_make_addr (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
636         flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
637         memcpy (buffer, src + offset, len);
638         flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
639 }
640
641 #endif /* CFG_FLASH_PROTECTION */
642
643 /*
644  * flash_is_busy - check to see if the flash is busy
645  * This routine checks the status of the chip and returns true if the chip is busy
646  */
647 static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
648 {
649         int retval;
650
651         switch (info->vendor) {
652         case CFI_CMDSET_INTEL_STANDARD:
653         case CFI_CMDSET_INTEL_EXTENDED:
654                 retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);
655                 break;
656         case CFI_CMDSET_AMD_STANDARD:
657         case CFI_CMDSET_AMD_EXTENDED:
658                 retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
659                 break;
660         default:
661                 retval = 0;
662         }
663         debug ("flash_is_busy: %d\n", retval);
664         return retval;
665 }
666
667 /*-----------------------------------------------------------------------
668  *  wait for XSR.7 to be set. Time out with an error if it does not.
669  *  This routine does not set the flash to read-array mode.
670  */
671 static int flash_status_check (flash_info_t * info, flash_sect_t sector,
672                                ulong tout, char *prompt)
673 {
674         ulong start;
675
676         /* Wait for command completion */
677         start = get_timer (0);
678         while (flash_is_busy (info, sector)) {
679                 if (get_timer (start) > info->erase_blk_tout * CFG_HZ) {
680                         printf ("Flash %s timeout at address %lx data %lx\n",
681                                 prompt, info->start[sector],
682                                 flash_read_long (info, sector, 0));
683                         flash_write_cmd (info, sector, 0, info->cmd_reset);
684                         return ERR_TIMOUT;
685                 }
686         }
687         return ERR_OK;
688 }
689
690 /*-----------------------------------------------------------------------
691  * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
692  * This routine sets the flash to read-array mode.
693  */
694 static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
695                                     ulong tout, char *prompt)
696 {
697         int retcode;
698
699         retcode = flash_status_check (info, sector, tout, prompt);
700         switch (info->vendor) {
701         case CFI_CMDSET_INTEL_EXTENDED:
702         case CFI_CMDSET_INTEL_STANDARD:
703                 if ((retcode != ERR_OK)
704                     && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
705                         retcode = ERR_INVAL;
706                         printf ("Flash %s error at address %lx\n", prompt,
707                                 info->start[sector]);
708                         if (flash_isset
709                             (info, sector, 0,
710                              FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
711                                 printf ("Command Sequence Error.\n");
712                         } else if (flash_isset
713                                    (info, sector, 0, FLASH_STATUS_ECLBS)) {
714                                 printf ("Block Erase Error.\n");
715                                 retcode = ERR_NOT_ERASED;
716                         } else if (flash_isset
717                                    (info, sector, 0, FLASH_STATUS_PSLBS)) {
718                                 printf ("Locking Error\n");
719                         }
720                         if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
721                                 printf ("Block locked.\n");
722                                 retcode = ERR_PROTECTED;
723                         }
724                         if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))
725                                 printf ("Vpp Low Error.\n");
726                 }
727                 flash_write_cmd (info, sector, 0, FLASH_CMD_RESET);
728                 break;
729         default:
730                 break;
731         }
732         return retcode;
733 }
734
735 /*-----------------------------------------------------------------------
736  */
737 static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
738 {
739         switch (info->portwidth) {
740         case FLASH_CFI_8BIT:
741                 cword->c = c;
742                 break;
743         case FLASH_CFI_16BIT:
744                 cword->w = (cword->w << 8) | c;
745                 break;
746         case FLASH_CFI_32BIT:
747                 cword->l = (cword->l << 8) | c;
748                 break;
749         case FLASH_CFI_64BIT:
750                 cword->ll = (cword->ll << 8) | c;
751                 break;
752         }
753 }
754
755
756 /*-----------------------------------------------------------------------
757  * make a proper sized command based on the port and chip widths
758  */
759 static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
760 {
761         int i;
762
763 #if defined(__LITTLE_ENDIAN)
764         ushort stmp;
765 #endif
766         uchar *cp = (uchar *) cmdbuf;
767
768         for (i = 0; i < info->portwidth; i++)
769                 *cp++ = ((i + 1) % info->chipwidth) ? '\0' : cmd;
770 #if defined(__LITTLE_ENDIAN)
771         if (info->portwidth == 2) {
772                 stmp = *(ushort *) cmdbuf;
773                 *(ushort *) cmdbuf = swab16 (stmp);
774         }
775 #endif
776 }
777
778 /*
779  * Write a proper sized command to the correct address
780  */
781 static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
782                              uint offset, uchar cmd)
783 {
784
785         volatile cfiptr_t addr;
786         cfiword_t cword;
787
788         addr.cp = flash_make_addr (info, sect, offset);
789         flash_make_cmd (info, cmd, &cword);
790         switch (info->portwidth) {
791         case FLASH_CFI_8BIT:
792                 debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr.cp, cmd,
793                        cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
794                 *addr.cp = cword.c;
795                 break;
796         case FLASH_CFI_16BIT:
797                 debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr.wp,
798                        cmd, cword.w,
799                        info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
800                 *addr.wp = cword.w;
801                 break;
802         case FLASH_CFI_32BIT:
803                 debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr.lp,
804                        cmd, cword.l,
805                        info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
806                 *addr.lp = cword.l;
807                 break;
808         case FLASH_CFI_64BIT:
809 #ifdef DEBUG
810                 {
811                         char str[20];
812
813                         print_longlong (str, cword.ll);
814
815                         debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
816                                addr.llp, cmd, str,
817                                info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
818                 }
819 #endif
820                 *addr.llp = cword.ll;
821                 break;
822         }
823 }
824
825 static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
826 {
827         flash_write_cmd (info, sect, 0x555, 0xAA);
828         flash_write_cmd (info, sect, 0x2AA, 0x55);
829 }
830
831 /*-----------------------------------------------------------------------
832  */
833 static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset,
834                           uchar cmd)
835 {
836         cfiptr_t cptr;
837         cfiword_t cword;
838         int retval;
839
840         cptr.cp = flash_make_addr (info, sect, offset);
841         flash_make_cmd (info, cmd, &cword);
842
843         debug ("is= cmd %x(%c) addr %p ", cmd, cmd, cptr.cp);
844         switch (info->portwidth) {
845         case FLASH_CFI_8BIT:
846                 debug ("is= %x %x\n", cptr.cp[0], cword.c);
847                 retval = (cptr.cp[0] == cword.c);
848                 break;
849         case FLASH_CFI_16BIT:
850                 debug ("is= %4.4x %4.4x\n", cptr.wp[0], cword.w);
851                 retval = (cptr.wp[0] == cword.w);
852                 break;
853         case FLASH_CFI_32BIT:
854                 debug ("is= %8.8lx %8.8lx\n", cptr.lp[0], cword.l);
855                 retval = (cptr.lp[0] == cword.l);
856                 break;
857         case FLASH_CFI_64BIT:
858 #ifdef DEBUG
859                 {
860                         char str1[20];
861                         char str2[20];
862
863                         print_longlong (str1, cptr.llp[0]);
864                         print_longlong (str2, cword.ll);
865                         debug ("is= %s %s\n", str1, str2);
866                 }
867 #endif
868                 retval = (cptr.llp[0] == cword.ll);
869                 break;
870         default:
871                 retval = 0;
872                 break;
873         }
874         return retval;
875 }
876
877 /*-----------------------------------------------------------------------
878  */
879 static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset,
880                         uchar cmd)
881 {
882         cfiptr_t cptr;
883         cfiword_t cword;
884         int retval;
885
886         cptr.cp = flash_make_addr (info, sect, offset);
887         flash_make_cmd (info, cmd, &cword);
888         switch (info->portwidth) {
889         case FLASH_CFI_8BIT:
890                 retval = ((cptr.cp[0] & cword.c) == cword.c);
891                 break;
892         case FLASH_CFI_16BIT:
893                 retval = ((cptr.wp[0] & cword.w) == cword.w);
894                 break;
895         case FLASH_CFI_32BIT:
896                 retval = ((cptr.lp[0] & cword.l) == cword.l);
897                 break;
898         case FLASH_CFI_64BIT:
899                 retval = ((cptr.llp[0] & cword.ll) == cword.ll);
900                 break;
901         default:
902                 retval = 0;
903                 break;
904         }
905         return retval;
906 }
907
908 /*-----------------------------------------------------------------------
909  */
910 static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset,
911                          uchar cmd)
912 {
913         cfiptr_t cptr;
914         cfiword_t cword;
915         int retval;
916
917         cptr.cp = flash_make_addr (info, sect, offset);
918         flash_make_cmd (info, cmd, &cword);
919         switch (info->portwidth) {
920         case FLASH_CFI_8BIT:
921                 retval = ((cptr.cp[0] & cword.c) != (cptr.cp[0] & cword.c));
922                 break;
923         case FLASH_CFI_16BIT:
924                 retval = ((cptr.wp[0] & cword.w) != (cptr.wp[0] & cword.w));
925                 break;
926         case FLASH_CFI_32BIT:
927                 retval = ((cptr.lp[0] & cword.l) != (cptr.lp[0] & cword.l));
928                 break;
929         case FLASH_CFI_64BIT:
930                 retval = ((cptr.llp[0] & cword.ll) !=
931                           (cptr.llp[0] & cword.ll));
932                 break;
933         default:
934                 retval = 0;
935                 break;
936         }
937         return retval;
938 }
939
940 /*-----------------------------------------------------------------------
941  * detect if flash is compatible with the Common Flash Interface (CFI)
942  * http://www.jedec.org/download/search/jesd68.pdf
943  *
944 */
945 static int flash_detect_cfi (flash_info_t * info)
946 {
947         debug ("flash detect cfi\n");
948
949         for (info->portwidth = FLASH_CFI_8BIT;
950              info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
951                 for (info->chipwidth = FLASH_CFI_BY8;
952                      info->chipwidth <= info->portwidth;
953                      info->chipwidth <<= 1) {
954                         flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
955                         flash_write_cmd (info, 0, FLASH_OFFSET_CFI,
956                                          FLASH_CMD_CFI);
957                         if (flash_isequal
958                             (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
959                             && flash_isequal (info, 0,
960                                               FLASH_OFFSET_CFI_RESP + 1, 'R')
961                             && flash_isequal (info, 0,
962                                               FLASH_OFFSET_CFI_RESP + 2,
963                                               'Y')) {
964                                 info->interface =
965                                         flash_read_ushort (info, 0,
966                                                            FLASH_OFFSET_INTERFACE);
967                                 debug ("device interface is %d\n",
968                                        info->interface);
969                                 debug ("found port %d chip %d ",
970                                        info->portwidth, info->chipwidth);
971                                 debug ("port %d bits chip %d bits\n",
972                                        info->
973                                        portwidth << CFI_FLASH_SHIFT_WIDTH,
974                                        info->
975                                        chipwidth << CFI_FLASH_SHIFT_WIDTH);
976                                 return 1;
977                         }
978                 }
979         }
980         debug ("not found\n");
981         return 0;
982 }
983
984 /*
985  * The following code cannot be run from FLASH!
986  *
987  */
988 static ulong flash_get_size (ulong base, int banknum)
989 {
990         flash_info_t *info = &flash_info[banknum];
991         int i, j;
992         flash_sect_t sect_cnt;
993         unsigned long sector;
994         unsigned long tmp;
995         int size_ratio;
996         uchar num_erase_regions;
997         int erase_region_size;
998         int erase_region_count;
999
1000         info->start[0] = base;
1001
1002         if (flash_detect_cfi (info)) {
1003                 info->vendor =
1004                         flash_read_ushort (info, 0,
1005                                            FLASH_OFFSET_PRIMARY_VENDOR);
1006 #ifdef DEBUG
1007                 flash_printqry (info, 0);
1008 #endif
1009                 switch (info->vendor) {
1010                 case CFI_CMDSET_INTEL_STANDARD:
1011                 case CFI_CMDSET_INTEL_EXTENDED:
1012                 default:
1013                         info->cmd_reset = FLASH_CMD_RESET;
1014                         break;
1015                 case CFI_CMDSET_AMD_STANDARD:
1016                 case CFI_CMDSET_AMD_EXTENDED:
1017                         info->cmd_reset = AMD_CMD_RESET;
1018                         break;
1019                 }
1020
1021                 debug ("manufacturer is %d\n", info->vendor);
1022                 size_ratio = info->portwidth / info->chipwidth;
1023                 /* if the chip is x8/x16 reduce the ratio by half */
1024                 if ((info->interface == FLASH_CFI_X8X16)
1025                     && (info->chipwidth == FLASH_CFI_BY8)) {
1026                         size_ratio >>= 1;
1027                 }
1028                 num_erase_regions =
1029                         flash_read_uchar (info,
1030                                           FLASH_OFFSET_NUM_ERASE_REGIONS);
1031                 debug ("size_ratio %d port %d bits chip %d bits\n",
1032                        size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
1033                        info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
1034                 debug ("found %d erase regions\n", num_erase_regions);
1035                 sect_cnt = 0;
1036                 sector = base;
1037                 for (i = 0; i < num_erase_regions; i++) {
1038                         if (i > NUM_ERASE_REGIONS) {
1039                                 printf ("%d erase regions found, only %d used\n", num_erase_regions, NUM_ERASE_REGIONS);
1040                                 break;
1041                         }
1042                         tmp = flash_read_long (info, 0,
1043                                                FLASH_OFFSET_ERASE_REGIONS +
1044                                                i * 4);
1045                         erase_region_size =
1046                                 (tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
1047                         tmp >>= 16;
1048                         erase_region_count = (tmp & 0xffff) + 1;
1049                         printf ("erase_region_count = %d erase_region_size = %d\n", erase_region_count, erase_region_size);
1050                         for (j = 0; j < erase_region_count; j++) {
1051                                 info->start[sect_cnt] = sector;
1052                                 sector += (erase_region_size * size_ratio);
1053                                 info->protect[sect_cnt] =
1054                                         flash_isset (info, sect_cnt,
1055                                                      FLASH_OFFSET_PROTECT,
1056                                                      FLASH_STATUS_PROTECT);
1057                                 sect_cnt++;
1058                         }
1059                 }
1060
1061                 info->sector_count = sect_cnt;
1062                 /* multiply the size by the number of chips */
1063                 info->size =
1064                         (1 << flash_read_uchar (info, FLASH_OFFSET_SIZE)) *
1065                         size_ratio;
1066                 info->buffer_size =
1067                         (1 <<
1068                          flash_read_ushort (info, 0,
1069                                             FLASH_OFFSET_BUFFER_SIZE));
1070                 tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_ETOUT);
1071                 info->erase_blk_tout =
1072                         (tmp *
1073                          (1 <<
1074                           flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT)));
1075                 tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT);
1076                 info->buffer_write_tout =
1077                         (tmp *
1078                          (1 <<
1079                           flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT)));
1080                 tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT);
1081                 info->write_tout =
1082                         (tmp *
1083                          (1 <<
1084                           flash_read_uchar (info,
1085                                             FLASH_OFFSET_WMAX_TOUT))) / 1000;
1086                 info->flash_id = FLASH_MAN_CFI;
1087         }
1088
1089         flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
1090         return (info->size);
1091 }
1092
1093
1094 /*-----------------------------------------------------------------------
1095  */
1096 static int flash_write_cfiword (flash_info_t * info, ulong dest,
1097                                 cfiword_t cword)
1098 {
1099
1100         cfiptr_t ctladdr;
1101         cfiptr_t cptr;
1102         int flag;
1103
1104         ctladdr.cp = flash_make_addr (info, 0, 0);
1105         cptr.cp = (uchar *) dest;
1106
1107
1108         /* Check if Flash is (sufficiently) erased */
1109         switch (info->portwidth) {
1110         case FLASH_CFI_8BIT:
1111                 flag = ((cptr.cp[0] & cword.c) == cword.c);
1112                 break;
1113         case FLASH_CFI_16BIT:
1114                 flag = ((cptr.wp[0] & cword.w) == cword.w);
1115                 break;
1116         case FLASH_CFI_32BIT:
1117                 flag = ((cptr.lp[0] & cword.l) == cword.l);
1118                 break;
1119         case FLASH_CFI_64BIT:
1120                 flag = ((cptr.lp[0] & cword.ll) == cword.ll);
1121                 break;
1122         default:
1123                 return 2;
1124         }
1125         if (!flag)
1126                 return 2;
1127
1128         /* Disable interrupts which might cause a timeout here */
1129         flag = disable_interrupts ();
1130
1131         switch (info->vendor) {
1132         case CFI_CMDSET_INTEL_EXTENDED:
1133         case CFI_CMDSET_INTEL_STANDARD:
1134                 flash_write_cmd (info, 0, 0, FLASH_CMD_CLEAR_STATUS);
1135                 flash_write_cmd (info, 0, 0, FLASH_CMD_WRITE);
1136                 break;
1137         case CFI_CMDSET_AMD_EXTENDED:
1138         case CFI_CMDSET_AMD_STANDARD:
1139                 flash_unlock_seq (info, 0);
1140                 flash_write_cmd (info, 0, 0x555, AMD_CMD_WRITE);
1141                 break;
1142         }
1143
1144         switch (info->portwidth) {
1145         case FLASH_CFI_8BIT:
1146                 cptr.cp[0] = cword.c;
1147                 break;
1148         case FLASH_CFI_16BIT:
1149                 cptr.wp[0] = cword.w;
1150                 break;
1151         case FLASH_CFI_32BIT:
1152                 cptr.lp[0] = cword.l;
1153                 break;
1154         case FLASH_CFI_64BIT:
1155                 cptr.llp[0] = cword.ll;
1156                 break;
1157         }
1158
1159         /* re-enable interrupts if necessary */
1160         if (flag)
1161                 enable_interrupts ();
1162
1163         return flash_full_status_check (info, 0, info->write_tout, "write");
1164 }
1165
1166 #ifdef CFG_FLASH_USE_BUFFER_WRITE
1167
1168 /* loop through the sectors from the highest address
1169  * when the passed address is greater or equal to the sector address
1170  * we have a match
1171  */
1172 static flash_sect_t find_sector (flash_info_t * info, ulong addr)
1173 {
1174         flash_sect_t sector;
1175
1176         for (sector = info->sector_count - 1; sector >= 0; sector--) {
1177                 if (addr >= info->start[sector])
1178                         break;
1179         }
1180         return sector;
1181 }
1182
1183 static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
1184                                   int len)
1185 {
1186         flash_sect_t sector;
1187         int cnt;
1188         int retcode;
1189         volatile cfiptr_t src;
1190         volatile cfiptr_t dst;
1191
1192         src.cp = cp;
1193         dst.cp = (uchar *) dest;
1194         sector = find_sector (info, dest);
1195         flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
1196         flash_write_cmd (info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
1197         if ((retcode =
1198              flash_status_check (info, sector, info->buffer_write_tout,
1199                                  "write to buffer")) == ERR_OK) {
1200                 /* reduce the number of loops by the width of the port  */
1201                 switch (info->portwidth) {
1202                 case FLASH_CFI_8BIT:
1203                         cnt = len;
1204                         break;
1205                 case FLASH_CFI_16BIT:
1206                         cnt = len >> 1;
1207                         break;
1208                 case FLASH_CFI_32BIT:
1209                         cnt = len >> 2;
1210                         break;
1211                 case FLASH_CFI_64BIT:
1212                         cnt = len >> 3;
1213                         break;
1214                 default:
1215                         return ERR_INVAL;
1216                         break;
1217                 }
1218                 flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
1219                 while (cnt-- > 0) {
1220                         switch (info->portwidth) {
1221                         case FLASH_CFI_8BIT:
1222                                 *dst.cp++ = *src.cp++;
1223                                 break;
1224                         case FLASH_CFI_16BIT:
1225                                 *dst.wp++ = *src.wp++;
1226                                 break;
1227                         case FLASH_CFI_32BIT:
1228                                 *dst.lp++ = *src.lp++;
1229                                 break;
1230                         case FLASH_CFI_64BIT:
1231                                 *dst.llp++ = *src.llp++;
1232                                 break;
1233                         default:
1234                                 return ERR_INVAL;
1235                                 break;
1236                         }
1237                 }
1238                 flash_write_cmd (info, sector, 0,
1239                                  FLASH_CMD_WRITE_BUFFER_CONFIRM);
1240                 retcode =
1241                         flash_full_status_check (info, sector,
1242                                                  info->buffer_write_tout,
1243                                                  "buffer write");
1244         }
1245         flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
1246         return retcode;
1247 }
1248 #endif /* CFG_USE_FLASH_BUFFER_WRITE */
1249 #endif /* CFG_FLASH_CFI */