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