]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/mtd/cfi_flash.c
Fix merge problems
[karo-tx-uboot.git] / drivers / mtd / 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  *
8  * Copyright (C) 2004
9  * Ed Okerson
10  *
11  * Copyright (C) 2006
12  * Tolunay Orkun <listmember@orkun.us>
13  *
14  * See file CREDITS for list of people who contributed to this
15  * project.
16  *
17  * This program is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License as
19  * published by the Free Software Foundation; either version 2 of
20  * the License, or (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30  * MA 02111-1307 USA
31  *
32  */
33
34 /* The DEBUG define must be before common to enable debugging */
35 /* #define DEBUG        */
36
37 #include <common.h>
38 #include <asm/processor.h>
39 #include <asm/io.h>
40 #include <asm/byteorder.h>
41 #include <environment.h>
42 #ifdef  CFG_FLASH_CFI_DRIVER
43
44 /*
45  * This file implements a Common Flash Interface (CFI) driver for
46  * U-Boot.
47  *
48  * The width of the port and the width of the chips are determined at
49  * initialization.  These widths are used to calculate the address for
50  * access CFI data structures.
51  *
52  * References
53  * JEDEC Standard JESD68 - Common Flash Interface (CFI)
54  * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
55  * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
56  * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
57  * AMD CFI Specification, Release 2.0 December 1, 2001
58  * AMD/Spansion Application Note: Migration from Single-byte to Three-byte
59  *   Device IDs, Publication Number 25538 Revision A, November 8, 2001
60  *
61  * Define CFG_WRITE_SWAPPED_DATA, if you have to swap the Bytes between
62  * reading and writing ... (yes there is such a Hardware).
63  */
64
65 #ifndef CFG_FLASH_BANKS_LIST
66 #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE }
67 #endif
68
69 #define FLASH_CMD_CFI                   0x98
70 #define FLASH_CMD_READ_ID               0x90
71 #define FLASH_CMD_RESET                 0xff
72 #define FLASH_CMD_BLOCK_ERASE           0x20
73 #define FLASH_CMD_ERASE_CONFIRM         0xD0
74 #define FLASH_CMD_WRITE                 0x40
75 #define FLASH_CMD_PROTECT               0x60
76 #define FLASH_CMD_PROTECT_SET           0x01
77 #define FLASH_CMD_PROTECT_CLEAR         0xD0
78 #define FLASH_CMD_CLEAR_STATUS          0x50
79 #define FLASH_CMD_READ_STATUS           0x70
80 #define FLASH_CMD_WRITE_TO_BUFFER       0xE8
81 #define FLASH_CMD_WRITE_BUFFER_PROG     0xE9
82 #define FLASH_CMD_WRITE_BUFFER_CONFIRM  0xD0
83
84 #define FLASH_STATUS_DONE               0x80
85 #define FLASH_STATUS_ESS                0x40
86 #define FLASH_STATUS_ECLBS              0x20
87 #define FLASH_STATUS_PSLBS              0x10
88 #define FLASH_STATUS_VPENS              0x08
89 #define FLASH_STATUS_PSS                0x04
90 #define FLASH_STATUS_DPS                0x02
91 #define FLASH_STATUS_R                  0x01
92 #define FLASH_STATUS_PROTECT            0x01
93
94 #define AMD_CMD_RESET                   0xF0
95 #define AMD_CMD_WRITE                   0xA0
96 #define AMD_CMD_ERASE_START             0x80
97 #define AMD_CMD_ERASE_SECTOR            0x30
98 #define AMD_CMD_UNLOCK_START            0xAA
99 #define AMD_CMD_UNLOCK_ACK              0x55
100 #define AMD_CMD_WRITE_TO_BUFFER         0x25
101 #define AMD_CMD_WRITE_BUFFER_CONFIRM    0x29
102
103 #define AMD_STATUS_TOGGLE               0x40
104 #define AMD_STATUS_ERROR                0x20
105
106 #define FLASH_OFFSET_MANUFACTURER_ID    0x00
107 #define FLASH_OFFSET_DEVICE_ID          0x01
108 #define FLASH_OFFSET_DEVICE_ID2         0x0E
109 #define FLASH_OFFSET_DEVICE_ID3         0x0F
110 #define FLASH_OFFSET_CFI                0x55
111 #define FLASH_OFFSET_CFI_ALT            0x555
112 #define FLASH_OFFSET_CFI_RESP           0x10
113 #define FLASH_OFFSET_PRIMARY_VENDOR     0x13
114 /* extended query table primary address */
115 #define FLASH_OFFSET_EXT_QUERY_T_P_ADDR 0x15
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 #define CFI_CMDSET_NONE                 0
134 #define CFI_CMDSET_INTEL_EXTENDED       1
135 #define CFI_CMDSET_AMD_STANDARD         2
136 #define CFI_CMDSET_INTEL_STANDARD       3
137 #define CFI_CMDSET_AMD_EXTENDED         4
138 #define CFI_CMDSET_MITSU_STANDARD       256
139 #define CFI_CMDSET_MITSU_EXTENDED       257
140 #define CFI_CMDSET_SST                  258
141 #define CFI_CMDSET_INTEL_PROG_REGIONS   512
142
143 #ifdef CFG_FLASH_CFI_AMD_RESET /* needed for STM_ID_29W320DB on UC100 */
144 # undef  FLASH_CMD_RESET
145 # define FLASH_CMD_RESET        AMD_CMD_RESET /* use AMD-Reset instead */
146 #endif
147
148 typedef union {
149         unsigned char c;
150         unsigned short w;
151         unsigned long l;
152         unsigned long long ll;
153 } cfiword_t;
154
155 #define NUM_ERASE_REGIONS       4 /* max. number of erase regions */
156
157 static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT };
158
159 /* use CFG_MAX_FLASH_BANKS_DETECT if defined */
160 #ifdef CFG_MAX_FLASH_BANKS_DETECT
161 static ulong bank_base[CFG_MAX_FLASH_BANKS_DETECT] = CFG_FLASH_BANKS_LIST;
162 flash_info_t flash_info[CFG_MAX_FLASH_BANKS_DETECT];    /* FLASH chips info */
163 #else
164 static ulong bank_base[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS_LIST;
165 flash_info_t flash_info[CFG_MAX_FLASH_BANKS];           /* FLASH chips info */
166 #endif
167
168 /*
169  * Check if chip width is defined. If not, start detecting with 8bit.
170  */
171 #ifndef CFG_FLASH_CFI_WIDTH
172 #define CFG_FLASH_CFI_WIDTH     FLASH_CFI_8BIT
173 #endif
174
175 typedef unsigned long flash_sect_t;
176
177 /* CFI standard query structure */
178 struct cfi_qry {
179         u8      qry[3];
180         u16     p_id;
181         u16     p_adr;
182         u16     a_id;
183         u16     a_adr;
184         u8      vcc_min;
185         u8      vcc_max;
186         u8      vpp_min;
187         u8      vpp_max;
188         u8      word_write_timeout_typ;
189         u8      buf_write_timeout_typ;
190         u8      block_erase_timeout_typ;
191         u8      chip_erase_timeout_typ;
192         u8      word_write_timeout_max;
193         u8      buf_write_timeout_max;
194         u8      block_erase_timeout_max;
195         u8      chip_erase_timeout_max;
196         u8      dev_size;
197         u16     interface_desc;
198         u16     max_buf_write_size;
199         u8      num_erase_regions;
200         u32     erase_region_info[NUM_ERASE_REGIONS];
201 } __attribute__((packed));
202
203 struct cfi_pri_hdr {
204         u8      pri[3];
205         u8      major_version;
206         u8      minor_version;
207 } __attribute__((packed));
208
209 static void flash_write8(u8 value, void *addr)
210 {
211         __raw_writeb(value, addr);
212 }
213
214 static void flash_write16(u16 value, void *addr)
215 {
216         __raw_writew(value, addr);
217 }
218
219 static void flash_write32(u32 value, void *addr)
220 {
221         __raw_writel(value, addr);
222 }
223
224 static void flash_write64(u64 value, void *addr)
225 {
226         /* No architectures currently implement __raw_writeq() */
227         *(volatile u64 *)addr = value;
228 }
229
230 static u8 flash_read8(void *addr)
231 {
232         return __raw_readb(addr);
233 }
234
235 static u16 flash_read16(void *addr)
236 {
237         return __raw_readw(addr);
238 }
239
240 static u32 flash_read32(void *addr)
241 {
242         return __raw_readl(addr);
243 }
244
245 static u64 __flash_read64(void *addr)
246 {
247         /* No architectures currently implement __raw_readq() */
248         return *(volatile u64 *)addr;
249 }
250
251 u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64")));
252
253 /*-----------------------------------------------------------------------
254  */
255 #if defined(CFG_ENV_IS_IN_FLASH) || defined(CFG_ENV_ADDR_REDUND) || (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
256 static flash_info_t *flash_get_info(ulong base)
257 {
258         int i;
259         flash_info_t * info = 0;
260
261         for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
262                 info = & flash_info[i];
263                 if (info->size && info->start[0] <= base &&
264                     base <= info->start[0] + info->size - 1)
265                         break;
266         }
267
268         return i == CFG_MAX_FLASH_BANKS ? 0 : info;
269 }
270 #endif
271
272 unsigned long flash_sector_size(flash_info_t *info, flash_sect_t sect)
273 {
274         if (sect != (info->sector_count - 1))
275                 return info->start[sect + 1] - info->start[sect];
276         else
277                 return info->start[0] + info->size - info->start[sect];
278 }
279
280 /*-----------------------------------------------------------------------
281  * create an address based on the offset and the port width
282  */
283 static inline void *
284 flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
285 {
286         unsigned int byte_offset = offset * info->portwidth;
287
288         return map_physmem(info->start[sect] + byte_offset,
289                         flash_sector_size(info, sect) - byte_offset,
290                         MAP_NOCACHE);
291 }
292
293 static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
294                 unsigned int offset, void *addr)
295 {
296         unsigned int byte_offset = offset * info->portwidth;
297
298         unmap_physmem(addr, flash_sector_size(info, sect) - byte_offset);
299 }
300
301 /*-----------------------------------------------------------------------
302  * make a proper sized command based on the port and chip widths
303  */
304 static void flash_make_cmd(flash_info_t *info, u32 cmd, void *cmdbuf)
305 {
306         int i;
307         int cword_offset;
308         int cp_offset;
309 #if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
310         u32 cmd_le = cpu_to_le32(cmd);
311 #endif
312         uchar val;
313         uchar *cp = (uchar *) cmdbuf;
314
315         for (i = info->portwidth; i > 0; i--){
316                 cword_offset = (info->portwidth-i)%info->chipwidth;
317 #if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
318                 cp_offset = info->portwidth - i;
319                 val = *((uchar*)&cmd_le + cword_offset);
320 #else
321                 cp_offset = i - 1;
322                 val = *((uchar*)&cmd + sizeof(u32) - cword_offset - 1);
323 #endif
324                 cp[cp_offset] = (cword_offset >= sizeof(u32)) ? 0x00 : val;
325         }
326 }
327
328 #ifdef DEBUG
329 /*-----------------------------------------------------------------------
330  * Debug support
331  */
332 static void print_longlong (char *str, unsigned long long data)
333 {
334         int i;
335         char *cp;
336
337         cp = (unsigned char *) &data;
338         for (i = 0; i < 8; i++)
339                 sprintf (&str[i * 2], "%2.2x", *cp++);
340 }
341
342 static void flash_printqry (struct cfi_qry *qry)
343 {
344         u8 *p = (u8 *)qry;
345         int x, y;
346
347         for (x = 0; x < sizeof(struct cfi_qry); x += 16) {
348                 debug("%02x : ", x);
349                 for (y = 0; y < 16; y++)
350                         debug("%2.2x ", p[x + y]);
351                 debug(" ");
352                 for (y = 0; y < 16; y++) {
353                         unsigned char c = p[x + y];
354                         if (c >= 0x20 && c <= 0x7e)
355                                 debug("%c", c);
356                         else
357                                 debug(".");
358                 }
359                 debug("\n");
360         }
361 }
362 #endif
363
364
365 /*-----------------------------------------------------------------------
366  * read a character at a port width address
367  */
368 static inline uchar flash_read_uchar (flash_info_t * info, uint offset)
369 {
370         uchar *cp;
371         uchar retval;
372
373         cp = flash_map (info, 0, offset);
374 #if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
375         retval = flash_read8(cp);
376 #else
377         retval = flash_read8(cp + info->portwidth - 1);
378 #endif
379         flash_unmap (info, 0, offset, cp);
380         return retval;
381 }
382
383 /*-----------------------------------------------------------------------
384  * read a word at a port width address, assume 16bit bus
385  */
386 static inline ushort flash_read_word (flash_info_t * info, uint offset)
387 {
388         ushort *addr, retval;
389
390         addr = flash_map (info, 0, offset);
391         retval = flash_read16 (addr);
392         flash_unmap (info, 0, offset, addr);
393         return retval;
394 }
395
396
397 /*-----------------------------------------------------------------------
398  * read a long word by picking the least significant byte of each maximum
399  * port size word. Swap for ppc format.
400  */
401 static ulong flash_read_long (flash_info_t * info, flash_sect_t sect,
402                               uint offset)
403 {
404         uchar *addr;
405         ulong retval;
406
407 #ifdef DEBUG
408         int x;
409 #endif
410         addr = flash_map (info, sect, offset);
411
412 #ifdef DEBUG
413         debug ("long addr is at %p info->portwidth = %d\n", addr,
414                info->portwidth);
415         for (x = 0; x < 4 * info->portwidth; x++) {
416                 debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
417         }
418 #endif
419 #if defined(__LITTLE_ENDIAN) || defined(CFG_WRITE_SWAPPED_DATA)
420         retval = ((flash_read8(addr) << 16) |
421                   (flash_read8(addr + info->portwidth) << 24) |
422                   (flash_read8(addr + 2 * info->portwidth)) |
423                   (flash_read8(addr + 3 * info->portwidth) << 8));
424 #else
425         retval = ((flash_read8(addr + 2 * info->portwidth - 1) << 24) |
426                   (flash_read8(addr + info->portwidth - 1) << 16) |
427                   (flash_read8(addr + 4 * info->portwidth - 1) << 8) |
428                   (flash_read8(addr + 3 * info->portwidth - 1)));
429 #endif
430         flash_unmap(info, sect, offset, addr);
431
432         return retval;
433 }
434
435 /*
436  * Write a proper sized command to the correct address
437  */
438 static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
439                              uint offset, u32 cmd)
440 {
441
442         void *addr;
443         cfiword_t cword;
444
445         addr = flash_map (info, sect, offset);
446         flash_make_cmd (info, cmd, &cword);
447         switch (info->portwidth) {
448         case FLASH_CFI_8BIT:
449                 debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr, cmd,
450                        cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
451                 flash_write8(cword.c, addr);
452                 break;
453         case FLASH_CFI_16BIT:
454                 debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr,
455                        cmd, cword.w,
456                        info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
457                 flash_write16(cword.w, addr);
458                 break;
459         case FLASH_CFI_32BIT:
460                 debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr,
461                        cmd, cword.l,
462                        info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
463                 flash_write32(cword.l, addr);
464                 break;
465         case FLASH_CFI_64BIT:
466 #ifdef DEBUG
467                 {
468                         char str[20];
469
470                         print_longlong (str, cword.ll);
471
472                         debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
473                                addr, cmd, str,
474                                info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
475                 }
476 #endif
477                 flash_write64(cword.ll, addr);
478                 break;
479         }
480
481         /* Ensure all the instructions are fully finished */
482         sync();
483
484         flash_unmap(info, sect, offset, addr);
485 }
486
487 static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
488 {
489         flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_UNLOCK_START);
490         flash_write_cmd (info, sect, info->addr_unlock2, AMD_CMD_UNLOCK_ACK);
491 }
492
493 /*-----------------------------------------------------------------------
494  */
495 static int flash_isequal (flash_info_t * info, flash_sect_t sect,
496                           uint offset, uchar cmd)
497 {
498         void *addr;
499         cfiword_t cword;
500         int retval;
501
502         addr = flash_map (info, sect, offset);
503         flash_make_cmd (info, cmd, &cword);
504
505         debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
506         switch (info->portwidth) {
507         case FLASH_CFI_8BIT:
508                 debug ("is= %x %x\n", flash_read8(addr), cword.c);
509                 retval = (flash_read8(addr) == cword.c);
510                 break;
511         case FLASH_CFI_16BIT:
512                 debug ("is= %4.4x %4.4x\n", flash_read16(addr), cword.w);
513                 retval = (flash_read16(addr) == cword.w);
514                 break;
515         case FLASH_CFI_32BIT:
516                 debug ("is= %8.8lx %8.8lx\n", flash_read32(addr), cword.l);
517                 retval = (flash_read32(addr) == cword.l);
518                 break;
519         case FLASH_CFI_64BIT:
520 #ifdef DEBUG
521                 {
522                         char str1[20];
523                         char str2[20];
524
525                         print_longlong (str1, flash_read64(addr));
526                         print_longlong (str2, cword.ll);
527                         debug ("is= %s %s\n", str1, str2);
528                 }
529 #endif
530                 retval = (flash_read64(addr) == cword.ll);
531                 break;
532         default:
533                 retval = 0;
534                 break;
535         }
536         flash_unmap(info, sect, offset, addr);
537
538         return retval;
539 }
540
541 /*-----------------------------------------------------------------------
542  */
543 static int flash_isset (flash_info_t * info, flash_sect_t sect,
544                         uint offset, uchar cmd)
545 {
546         void *addr;
547         cfiword_t cword;
548         int retval;
549
550         addr = flash_map (info, sect, offset);
551         flash_make_cmd (info, cmd, &cword);
552         switch (info->portwidth) {
553         case FLASH_CFI_8BIT:
554                 retval = ((flash_read8(addr) & cword.c) == cword.c);
555                 break;
556         case FLASH_CFI_16BIT:
557                 retval = ((flash_read16(addr) & cword.w) == cword.w);
558                 break;
559         case FLASH_CFI_32BIT:
560                 retval = ((flash_read32(addr) & cword.l) == cword.l);
561                 break;
562         case FLASH_CFI_64BIT:
563                 retval = ((flash_read64(addr) & cword.ll) == cword.ll);
564                 break;
565         default:
566                 retval = 0;
567                 break;
568         }
569         flash_unmap(info, sect, offset, addr);
570
571         return retval;
572 }
573
574 /*-----------------------------------------------------------------------
575  */
576 static int flash_toggle (flash_info_t * info, flash_sect_t sect,
577                          uint offset, uchar cmd)
578 {
579         void *addr;
580         cfiword_t cword;
581         int retval;
582
583         addr = flash_map (info, sect, offset);
584         flash_make_cmd (info, cmd, &cword);
585         switch (info->portwidth) {
586         case FLASH_CFI_8BIT:
587                 retval = flash_read8(addr) != flash_read8(addr);
588                 break;
589         case FLASH_CFI_16BIT:
590                 retval = flash_read16(addr) != flash_read16(addr);
591                 break;
592         case FLASH_CFI_32BIT:
593                 retval = flash_read32(addr) != flash_read32(addr);
594                 break;
595         case FLASH_CFI_64BIT:
596                 retval = flash_read64(addr) != flash_read64(addr);
597                 break;
598         default:
599                 retval = 0;
600                 break;
601         }
602         flash_unmap(info, sect, offset, addr);
603
604         return retval;
605 }
606
607 /*
608  * flash_is_busy - check to see if the flash is busy
609  *
610  * This routine checks the status of the chip and returns true if the
611  * chip is busy.
612  */
613 static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
614 {
615         int retval;
616
617         switch (info->vendor) {
618         case CFI_CMDSET_INTEL_PROG_REGIONS:
619         case CFI_CMDSET_INTEL_STANDARD:
620         case CFI_CMDSET_INTEL_EXTENDED:
621                 retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);
622                 break;
623         case CFI_CMDSET_AMD_STANDARD:
624         case CFI_CMDSET_AMD_EXTENDED:
625 #ifdef CONFIG_FLASH_CFI_LEGACY
626         case CFI_CMDSET_AMD_LEGACY:
627 #endif
628                 retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
629                 break;
630         default:
631                 retval = 0;
632         }
633         debug ("flash_is_busy: %d\n", retval);
634         return retval;
635 }
636
637 /*-----------------------------------------------------------------------
638  *  wait for XSR.7 to be set. Time out with an error if it does not.
639  *  This routine does not set the flash to read-array mode.
640  */
641 static int flash_status_check (flash_info_t * info, flash_sect_t sector,
642                                ulong tout, char *prompt)
643 {
644         ulong start;
645
646 #if CFG_HZ != 1000
647         tout *= CFG_HZ/1000;
648 #endif
649
650         /* Wait for command completion */
651         start = get_timer (0);
652         while (flash_is_busy (info, sector)) {
653                 if (get_timer (start) > tout) {
654                         printf ("Flash %s timeout at address %lx data %lx\n",
655                                 prompt, info->start[sector],
656                                 flash_read_long (info, sector, 0));
657                         flash_write_cmd (info, sector, 0, info->cmd_reset);
658                         return ERR_TIMOUT;
659                 }
660                 udelay (1);             /* also triggers watchdog */
661         }
662         return ERR_OK;
663 }
664
665 /*-----------------------------------------------------------------------
666  * Wait for XSR.7 to be set, if it times out print an error, otherwise
667  * do a full status check.
668  *
669  * This routine sets the flash to read-array mode.
670  */
671 static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
672                                     ulong tout, char *prompt)
673 {
674         int retcode;
675
676         retcode = flash_status_check (info, sector, tout, prompt);
677         switch (info->vendor) {
678         case CFI_CMDSET_INTEL_PROG_REGIONS:
679         case CFI_CMDSET_INTEL_EXTENDED:
680         case CFI_CMDSET_INTEL_STANDARD:
681                 if ((retcode == ERR_OK)
682                     && !flash_isequal (info, sector, 0, FLASH_STATUS_DONE)) {
683                         retcode = ERR_INVAL;
684                         printf ("Flash %s error at address %lx\n", prompt,
685                                 info->start[sector]);
686                         if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS |
687                                          FLASH_STATUS_PSLBS)) {
688                                 puts ("Command Sequence Error.\n");
689                         } else if (flash_isset (info, sector, 0,
690                                                 FLASH_STATUS_ECLBS)) {
691                                 puts ("Block Erase Error.\n");
692                                 retcode = ERR_NOT_ERASED;
693                         } else if (flash_isset (info, sector, 0,
694                                                 FLASH_STATUS_PSLBS)) {
695                                 puts ("Locking Error\n");
696                         }
697                         if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
698                                 puts ("Block locked.\n");
699                                 retcode = ERR_PROTECTED;
700                         }
701                         if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))
702                                 puts ("Vpp Low Error.\n");
703                 }
704                 flash_write_cmd (info, sector, 0, info->cmd_reset);
705                 break;
706         default:
707                 break;
708         }
709         return retcode;
710 }
711
712 /*-----------------------------------------------------------------------
713  */
714 static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
715 {
716 #if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
717         unsigned short  w;
718         unsigned int    l;
719         unsigned long long ll;
720 #endif
721
722         switch (info->portwidth) {
723         case FLASH_CFI_8BIT:
724                 cword->c = c;
725                 break;
726         case FLASH_CFI_16BIT:
727 #if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
728                 w = c;
729                 w <<= 8;
730                 cword->w = (cword->w >> 8) | w;
731 #else
732                 cword->w = (cword->w << 8) | c;
733 #endif
734                 break;
735         case FLASH_CFI_32BIT:
736 #if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
737                 l = c;
738                 l <<= 24;
739                 cword->l = (cword->l >> 8) | l;
740 #else
741                 cword->l = (cword->l << 8) | c;
742 #endif
743                 break;
744         case FLASH_CFI_64BIT:
745 #if defined(__LITTLE_ENDIAN) && !defined(CFG_WRITE_SWAPPED_DATA)
746                 ll = c;
747                 ll <<= 56;
748                 cword->ll = (cword->ll >> 8) | ll;
749 #else
750                 cword->ll = (cword->ll << 8) | c;
751 #endif
752                 break;
753         }
754 }
755
756 /* loop through the sectors from the highest address when the passed
757  * address is greater or equal to the sector address we have a match
758  */
759 static flash_sect_t find_sector (flash_info_t * info, ulong addr)
760 {
761         flash_sect_t sector;
762
763         for (sector = info->sector_count - 1; sector >= 0; sector--) {
764                 if (addr >= info->start[sector])
765                         break;
766         }
767         return sector;
768 }
769
770 /*-----------------------------------------------------------------------
771  */
772 static int flash_write_cfiword (flash_info_t * info, ulong dest,
773                                 cfiword_t cword)
774 {
775         void *dstaddr;
776         int flag;
777
778         dstaddr = map_physmem(dest, info->portwidth, MAP_NOCACHE);
779
780         /* Check if Flash is (sufficiently) erased */
781         switch (info->portwidth) {
782         case FLASH_CFI_8BIT:
783                 flag = ((flash_read8(dstaddr) & cword.c) == cword.c);
784                 break;
785         case FLASH_CFI_16BIT:
786                 flag = ((flash_read16(dstaddr) & cword.w) == cword.w);
787                 break;
788         case FLASH_CFI_32BIT:
789                 flag = ((flash_read32(dstaddr) & cword.l) == cword.l);
790                 break;
791         case FLASH_CFI_64BIT:
792                 flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);
793                 break;
794         default:
795                 flag = 0;
796                 break;
797         }
798         if (!flag) {
799                 unmap_physmem(dstaddr, info->portwidth);
800                 return ERR_NOT_ERASED;
801         }
802
803         /* Disable interrupts which might cause a timeout here */
804         flag = disable_interrupts ();
805
806         switch (info->vendor) {
807         case CFI_CMDSET_INTEL_PROG_REGIONS:
808         case CFI_CMDSET_INTEL_EXTENDED:
809         case CFI_CMDSET_INTEL_STANDARD:
810                 flash_write_cmd (info, 0, 0, FLASH_CMD_CLEAR_STATUS);
811                 flash_write_cmd (info, 0, 0, FLASH_CMD_WRITE);
812                 break;
813         case CFI_CMDSET_AMD_EXTENDED:
814         case CFI_CMDSET_AMD_STANDARD:
815 #ifdef CONFIG_FLASH_CFI_LEGACY
816         case CFI_CMDSET_AMD_LEGACY:
817 #endif
818                 flash_unlock_seq (info, 0);
819                 flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_WRITE);
820                 break;
821         }
822
823         switch (info->portwidth) {
824         case FLASH_CFI_8BIT:
825                 flash_write8(cword.c, dstaddr);
826                 break;
827         case FLASH_CFI_16BIT:
828                 flash_write16(cword.w, dstaddr);
829                 break;
830         case FLASH_CFI_32BIT:
831                 flash_write32(cword.l, dstaddr);
832                 break;
833         case FLASH_CFI_64BIT:
834                 flash_write64(cword.ll, dstaddr);
835                 break;
836         }
837
838         /* re-enable interrupts if necessary */
839         if (flag)
840                 enable_interrupts ();
841
842         unmap_physmem(dstaddr, info->portwidth);
843
844         return flash_full_status_check (info, find_sector (info, dest),
845                                         info->write_tout, "write");
846 }
847
848 #ifdef CFG_FLASH_USE_BUFFER_WRITE
849
850 static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
851                                   int len)
852 {
853         flash_sect_t sector;
854         int cnt;
855         int retcode;
856         void *src = cp;
857         void *dst = map_physmem(dest, len, MAP_NOCACHE);
858         void *dst2 = dst;
859         int flag = 0;
860         uint offset = 0;
861         unsigned int shift;
862         uchar write_cmd;
863
864         switch (info->portwidth) {
865         case FLASH_CFI_8BIT:
866                 shift = 0;
867                 break;
868         case FLASH_CFI_16BIT:
869                 shift = 1;
870                 break;
871         case FLASH_CFI_32BIT:
872                 shift = 2;
873                 break;
874         case FLASH_CFI_64BIT:
875                 shift = 3;
876                 break;
877         default:
878                 retcode = ERR_INVAL;
879                 goto out_unmap;
880         }
881
882         cnt = len >> shift;
883
884         while ((cnt-- > 0) && (flag == 0)) {
885                 switch (info->portwidth) {
886                 case FLASH_CFI_8BIT:
887                         flag = ((flash_read8(dst2) & flash_read8(src)) ==
888                                 flash_read8(src));
889                         src += 1, dst2 += 1;
890                         break;
891                 case FLASH_CFI_16BIT:
892                         flag = ((flash_read16(dst2) & flash_read16(src)) ==
893                                 flash_read16(src));
894                         src += 2, dst2 += 2;
895                         break;
896                 case FLASH_CFI_32BIT:
897                         flag = ((flash_read32(dst2) & flash_read32(src)) ==
898                                 flash_read32(src));
899                         src += 4, dst2 += 4;
900                         break;
901                 case FLASH_CFI_64BIT:
902                         flag = ((flash_read64(dst2) & flash_read64(src)) ==
903                                 flash_read64(src));
904                         src += 8, dst2 += 8;
905                         break;
906                 }
907         }
908         if (!flag) {
909                 retcode = ERR_NOT_ERASED;
910                 goto out_unmap;
911         }
912
913         src = cp;
914         sector = find_sector (info, dest);
915
916         switch (info->vendor) {
917         case CFI_CMDSET_INTEL_PROG_REGIONS:
918         case CFI_CMDSET_INTEL_STANDARD:
919         case CFI_CMDSET_INTEL_EXTENDED:
920                 write_cmd = (info->vendor == CFI_CMDSET_INTEL_PROG_REGIONS) ?
921                                         FLASH_CMD_WRITE_BUFFER_PROG : FLASH_CMD_WRITE_TO_BUFFER;
922                 flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
923                 flash_write_cmd (info, sector, 0, FLASH_CMD_READ_STATUS);
924                 flash_write_cmd (info, sector, 0, write_cmd);
925                 retcode = flash_status_check (info, sector,
926                                               info->buffer_write_tout,
927                                               "write to buffer");
928                 if (retcode == ERR_OK) {
929                         /* reduce the number of loops by the width of
930                          * the port */
931                         cnt = len >> shift;
932                         flash_write_cmd (info, sector, 0, cnt - 1);
933                         while (cnt-- > 0) {
934                                 switch (info->portwidth) {
935                                 case FLASH_CFI_8BIT:
936                                         flash_write8(flash_read8(src), dst);
937                                         src += 1, dst += 1;
938                                         break;
939                                 case FLASH_CFI_16BIT:
940                                         flash_write16(flash_read16(src), dst);
941                                         src += 2, dst += 2;
942                                         break;
943                                 case FLASH_CFI_32BIT:
944                                         flash_write32(flash_read32(src), dst);
945                                         src += 4, dst += 4;
946                                         break;
947                                 case FLASH_CFI_64BIT:
948                                         flash_write64(flash_read64(src), dst);
949                                         src += 8, dst += 8;
950                                         break;
951                                 default:
952                                         retcode = ERR_INVAL;
953                                         goto out_unmap;
954                                 }
955                         }
956                         flash_write_cmd (info, sector, 0,
957                                          FLASH_CMD_WRITE_BUFFER_CONFIRM);
958                         retcode = flash_full_status_check (
959                                 info, sector, info->buffer_write_tout,
960                                 "buffer write");
961                 }
962
963                 break;
964
965         case CFI_CMDSET_AMD_STANDARD:
966         case CFI_CMDSET_AMD_EXTENDED:
967                 flash_unlock_seq(info,0);
968
969 #ifdef CONFIG_FLASH_SPANSION_S29WS_N
970                 offset = ((unsigned long)dst - info->start[sector]) >> shift;
971 #endif
972                 flash_write_cmd(info, sector, offset, AMD_CMD_WRITE_TO_BUFFER);
973                 cnt = len >> shift;
974                 flash_write_cmd(info, sector, offset, (uchar)cnt - 1);
975
976                 switch (info->portwidth) {
977                 case FLASH_CFI_8BIT:
978                         while (cnt-- > 0) {
979                                 flash_write8(flash_read8(src), dst);
980                                 src += 1, dst += 1;
981                         }
982                         break;
983                 case FLASH_CFI_16BIT:
984                         while (cnt-- > 0) {
985                                 flash_write16(flash_read16(src), dst);
986                                 src += 2, dst += 2;
987                         }
988                         break;
989                 case FLASH_CFI_32BIT:
990                         while (cnt-- > 0) {
991                                 flash_write32(flash_read32(src), dst);
992                                 src += 4, dst += 4;
993                         }
994                         break;
995                 case FLASH_CFI_64BIT:
996                         while (cnt-- > 0) {
997                                 flash_write64(flash_read64(src), dst);
998                                 src += 8, dst += 8;
999                         }
1000                         break;
1001                 default:
1002                         retcode = ERR_INVAL;
1003                         goto out_unmap;
1004                 }
1005
1006                 flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
1007                 retcode = flash_full_status_check (info, sector,
1008                                                    info->buffer_write_tout,
1009                                                    "buffer write");
1010                 break;
1011
1012         default:
1013                 debug ("Unknown Command Set\n");
1014                 retcode = ERR_INVAL;
1015                 break;
1016         }
1017
1018 out_unmap:
1019         unmap_physmem(dst, len);
1020         return retcode;
1021 }
1022 #endif /* CFG_FLASH_USE_BUFFER_WRITE */
1023
1024
1025 /*-----------------------------------------------------------------------
1026  */
1027 int flash_erase (flash_info_t * info, int s_first, int s_last)
1028 {
1029         int rcode = 0;
1030         int prot;
1031         flash_sect_t sect;
1032
1033         if (info->flash_id != FLASH_MAN_CFI) {
1034                 puts ("Can't erase unknown flash type - aborted\n");
1035                 return 1;
1036         }
1037         if ((s_first < 0) || (s_first > s_last)) {
1038                 puts ("- no sectors to erase\n");
1039                 return 1;
1040         }
1041
1042         prot = 0;
1043         for (sect = s_first; sect <= s_last; ++sect) {
1044                 if (info->protect[sect]) {
1045                         prot++;
1046                 }
1047         }
1048         if (prot) {
1049                 printf ("- Warning: %d protected sectors will not be erased!\n",
1050                         prot);
1051         } else {
1052                 putc ('\n');
1053         }
1054
1055
1056         for (sect = s_first; sect <= s_last; sect++) {
1057                 if (info->protect[sect] == 0) { /* not protected */
1058                         switch (info->vendor) {
1059                         case CFI_CMDSET_INTEL_PROG_REGIONS:
1060                         case CFI_CMDSET_INTEL_STANDARD:
1061                         case CFI_CMDSET_INTEL_EXTENDED:
1062                                 flash_write_cmd (info, sect, 0,
1063                                                  FLASH_CMD_CLEAR_STATUS);
1064                                 flash_write_cmd (info, sect, 0,
1065                                                  FLASH_CMD_BLOCK_ERASE);
1066                                 flash_write_cmd (info, sect, 0,
1067                                                  FLASH_CMD_ERASE_CONFIRM);
1068                                 break;
1069                         case CFI_CMDSET_AMD_STANDARD:
1070                         case CFI_CMDSET_AMD_EXTENDED:
1071                                 flash_unlock_seq (info, sect);
1072                                 flash_write_cmd (info, sect,
1073                                                 info->addr_unlock1,
1074                                                 AMD_CMD_ERASE_START);
1075                                 flash_unlock_seq (info, sect);
1076                                 flash_write_cmd (info, sect, 0,
1077                                                  AMD_CMD_ERASE_SECTOR);
1078                                 break;
1079 #ifdef CONFIG_FLASH_CFI_LEGACY
1080                         case CFI_CMDSET_AMD_LEGACY:
1081                                 flash_unlock_seq (info, 0);
1082                                 flash_write_cmd (info, 0, info->addr_unlock1,
1083                                                 AMD_CMD_ERASE_START);
1084                                 flash_unlock_seq (info, 0);
1085                                 flash_write_cmd (info, sect, 0,
1086                                                 AMD_CMD_ERASE_SECTOR);
1087                                 break;
1088 #endif
1089                         default:
1090                                 debug ("Unkown flash vendor %d\n",
1091                                        info->vendor);
1092                                 break;
1093                         }
1094
1095                         if (flash_full_status_check
1096                             (info, sect, info->erase_blk_tout, "erase")) {
1097                                 rcode = 1;
1098                         } else
1099                                 putc ('.');
1100                 }
1101         }
1102         puts (" done\n");
1103         return rcode;
1104 }
1105
1106 /*-----------------------------------------------------------------------
1107  */
1108 void flash_print_info (flash_info_t * info)
1109 {
1110         int i;
1111
1112         if (info->flash_id != FLASH_MAN_CFI) {
1113                 puts ("missing or unknown FLASH type\n");
1114                 return;
1115         }
1116
1117         printf ("%s FLASH (%d x %d)",
1118                 info->name,
1119                 (info->portwidth << 3), (info->chipwidth << 3));
1120         if (info->size < 1024*1024)
1121                 printf ("  Size: %ld kB in %d Sectors\n",
1122                         info->size >> 10, info->sector_count);
1123         else
1124                 printf ("  Size: %ld MB in %d Sectors\n",
1125                         info->size >> 20, info->sector_count);
1126         printf ("  ");
1127         switch (info->vendor) {
1128                 case CFI_CMDSET_INTEL_PROG_REGIONS:
1129                         printf ("Intel Prog Regions");
1130                         break;
1131                 case CFI_CMDSET_INTEL_STANDARD:
1132                         printf ("Intel Standard");
1133                         break;
1134                 case CFI_CMDSET_INTEL_EXTENDED:
1135                         printf ("Intel Extended");
1136                         break;
1137                 case CFI_CMDSET_AMD_STANDARD:
1138                         printf ("AMD Standard");
1139                         break;
1140                 case CFI_CMDSET_AMD_EXTENDED:
1141                         printf ("AMD Extended");
1142                         break;
1143 #ifdef CONFIG_FLASH_CFI_LEGACY
1144                 case CFI_CMDSET_AMD_LEGACY:
1145                         printf ("AMD Legacy");
1146                         break;
1147 #endif
1148                 default:
1149                         printf ("Unknown (%d)", info->vendor);
1150                         break;
1151         }
1152         printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x%02X",
1153                 info->manufacturer_id, info->device_id);
1154         if (info->device_id == 0x7E) {
1155                 printf("%04X", info->device_id2);
1156         }
1157         printf ("\n  Erase timeout: %ld ms, write timeout: %ld ms\n",
1158                 info->erase_blk_tout,
1159                 info->write_tout);
1160         if (info->buffer_size > 1) {
1161                 printf ("  Buffer write timeout: %ld ms, "
1162                         "buffer size: %d bytes\n",
1163                 info->buffer_write_tout,
1164                 info->buffer_size);
1165         }
1166
1167         puts ("\n  Sector Start Addresses:");
1168         for (i = 0; i < info->sector_count; ++i) {
1169                 if ((i % 5) == 0)
1170                         printf ("\n");
1171 #ifdef CFG_FLASH_EMPTY_INFO
1172                 int k;
1173                 int size;
1174                 int erased;
1175                 volatile unsigned long *flash;
1176
1177                 /*
1178                  * Check if whole sector is erased
1179                  */
1180                 size = flash_sector_size(info, i);
1181                 erased = 1;
1182                 flash = (volatile unsigned long *) info->start[i];
1183                 size = size >> 2;       /* divide by 4 for longword access */
1184                 for (k = 0; k < size; k++) {
1185                         if (*flash++ != 0xffffffff) {
1186                                 erased = 0;
1187                                 break;
1188                         }
1189                 }
1190
1191                 /* print empty and read-only info */
1192                 printf ("  %08lX %c %s ",
1193                         info->start[i],
1194                         erased ? 'E' : ' ',
1195                         info->protect[i] ? "RO" : "  ");
1196 #else   /* ! CFG_FLASH_EMPTY_INFO */
1197                 printf ("  %08lX   %s ",
1198                         info->start[i],
1199                         info->protect[i] ? "RO" : "  ");
1200 #endif
1201         }
1202         putc ('\n');
1203         return;
1204 }
1205
1206 /*-----------------------------------------------------------------------
1207  * This is used in a few places in write_buf() to show programming
1208  * progress.  Making it a function is nasty because it needs to do side
1209  * effect updates to digit and dots.  Repeated code is nasty too, so
1210  * we define it once here.
1211  */
1212 #ifdef CONFIG_FLASH_SHOW_PROGRESS
1213 #define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) \
1214         dots -= dots_sub; \
1215         if ((scale > 0) && (dots <= 0)) { \
1216                 if ((digit % 5) == 0) \
1217                         printf ("%d", digit / 5); \
1218                 else \
1219                         putc ('.'); \
1220                 digit--; \
1221                 dots += scale; \
1222         }
1223 #else
1224 #define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub)
1225 #endif
1226
1227 /*-----------------------------------------------------------------------
1228  * Copy memory to flash, returns:
1229  * 0 - OK
1230  * 1 - write timeout
1231  * 2 - Flash not erased
1232  */
1233 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
1234 {
1235         ulong wp;
1236         uchar *p;
1237         int aln;
1238         cfiword_t cword;
1239         int i, rc;
1240 #ifdef CFG_FLASH_USE_BUFFER_WRITE
1241         int buffered_size;
1242 #endif
1243 #ifdef CONFIG_FLASH_SHOW_PROGRESS
1244         int digit = CONFIG_FLASH_SHOW_PROGRESS;
1245         int scale = 0;
1246         int dots  = 0;
1247
1248         /*
1249          * Suppress if there are fewer than CONFIG_FLASH_SHOW_PROGRESS writes.
1250          */
1251         if (cnt >= CONFIG_FLASH_SHOW_PROGRESS) {
1252                 scale = (int)((cnt + CONFIG_FLASH_SHOW_PROGRESS - 1) /
1253                         CONFIG_FLASH_SHOW_PROGRESS);
1254         }
1255 #endif
1256
1257         /* get lower aligned address */
1258         wp = (addr & ~(info->portwidth - 1));
1259
1260         /* handle unaligned start */
1261         if ((aln = addr - wp) != 0) {
1262                 cword.l = 0;
1263                 p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
1264                 for (i = 0; i < aln; ++i)
1265                         flash_add_byte (info, &cword, flash_read8(p + i));
1266
1267                 for (; (i < info->portwidth) && (cnt > 0); i++) {
1268                         flash_add_byte (info, &cword, *src++);
1269                         cnt--;
1270                 }
1271                 for (; (cnt == 0) && (i < info->portwidth); ++i)
1272                         flash_add_byte (info, &cword, flash_read8(p + i));
1273
1274                 rc = flash_write_cfiword (info, wp, cword);
1275                 unmap_physmem(p, info->portwidth);
1276                 if (rc != 0)
1277                         return rc;
1278
1279                 wp += i;
1280                 FLASH_SHOW_PROGRESS(scale, dots, digit, i);
1281         }
1282
1283         /* handle the aligned part */
1284 #ifdef CFG_FLASH_USE_BUFFER_WRITE
1285         buffered_size = (info->portwidth / info->chipwidth);
1286         buffered_size *= info->buffer_size;
1287         while (cnt >= info->portwidth) {
1288                 /* prohibit buffer write when buffer_size is 1 */
1289                 if (info->buffer_size == 1) {
1290                         cword.l = 0;
1291                         for (i = 0; i < info->portwidth; i++)
1292                                 flash_add_byte (info, &cword, *src++);
1293                         if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
1294                                 return rc;
1295                         wp += info->portwidth;
1296                         cnt -= info->portwidth;
1297                         continue;
1298                 }
1299
1300                 /* write buffer until next buffered_size aligned boundary */
1301                 i = buffered_size - (wp % buffered_size);
1302                 if (i > cnt)
1303                         i = cnt;
1304                 if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)
1305                         return rc;
1306                 i -= i & (info->portwidth - 1);
1307                 wp += i;
1308                 src += i;
1309                 cnt -= i;
1310                 FLASH_SHOW_PROGRESS(scale, dots, digit, i);
1311         }
1312 #else
1313         while (cnt >= info->portwidth) {
1314                 cword.l = 0;
1315                 for (i = 0; i < info->portwidth; i++) {
1316                         flash_add_byte (info, &cword, *src++);
1317                 }
1318                 if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
1319                         return rc;
1320                 wp += info->portwidth;
1321                 cnt -= info->portwidth;
1322                 FLASH_SHOW_PROGRESS(scale, dots, digit, info->portwidth);
1323         }
1324 #endif /* CFG_FLASH_USE_BUFFER_WRITE */
1325
1326         if (cnt == 0) {
1327                 return (0);
1328         }
1329
1330         /*
1331          * handle unaligned tail bytes
1332          */
1333         cword.l = 0;
1334         p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
1335         for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
1336                 flash_add_byte (info, &cword, *src++);
1337                 --cnt;
1338         }
1339         for (; i < info->portwidth; ++i)
1340                 flash_add_byte (info, &cword, flash_read8(p + i));
1341         unmap_physmem(p, info->portwidth);
1342
1343         return flash_write_cfiword (info, wp, cword);
1344 }
1345
1346 /*-----------------------------------------------------------------------
1347  */
1348 #ifdef CFG_FLASH_PROTECTION
1349
1350 int flash_real_protect (flash_info_t * info, long sector, int prot)
1351 {
1352         int retcode = 0;
1353
1354         flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
1355         flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
1356         if (prot)
1357                 flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
1358         else
1359                 flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
1360
1361         if ((retcode =
1362              flash_full_status_check (info, sector, info->erase_blk_tout,
1363                                       prot ? "protect" : "unprotect")) == 0) {
1364
1365                 info->protect[sector] = prot;
1366
1367                 /*
1368                  * On some of Intel's flash chips (marked via legacy_unlock)
1369                  * unprotect unprotects all locking.
1370                  */
1371                 if ((prot == 0) && (info->legacy_unlock)) {
1372                         flash_sect_t i;
1373
1374                         for (i = 0; i < info->sector_count; i++) {
1375                                 if (info->protect[i])
1376                                         flash_real_protect (info, i, 1);
1377                         }
1378                 }
1379         }
1380         return retcode;
1381 }
1382
1383 /*-----------------------------------------------------------------------
1384  * flash_read_user_serial - read the OneTimeProgramming cells
1385  */
1386 void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
1387                              int len)
1388 {
1389         uchar *src;
1390         uchar *dst;
1391
1392         dst = buffer;
1393         src = flash_map (info, 0, FLASH_OFFSET_USER_PROTECTION);
1394         flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
1395         memcpy (dst, src + offset, len);
1396         flash_write_cmd (info, 0, 0, info->cmd_reset);
1397         flash_unmap(info, 0, FLASH_OFFSET_USER_PROTECTION, src);
1398 }
1399
1400 /*
1401  * flash_read_factory_serial - read the device Id from the protection area
1402  */
1403 void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
1404                                 int len)
1405 {
1406         uchar *src;
1407
1408         src = flash_map (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
1409         flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
1410         memcpy (buffer, src + offset, len);
1411         flash_write_cmd (info, 0, 0, info->cmd_reset);
1412         flash_unmap(info, 0, FLASH_OFFSET_INTEL_PROTECTION, src);
1413 }
1414
1415 #endif /* CFG_FLASH_PROTECTION */
1416
1417 /*-----------------------------------------------------------------------
1418  * Reverse the order of the erase regions in the CFI QRY structure.
1419  * This is needed for chips that are either a) correctly detected as
1420  * top-boot, or b) buggy.
1421  */
1422 static void cfi_reverse_geometry(struct cfi_qry *qry)
1423 {
1424         unsigned int i, j;
1425         u32 tmp;
1426
1427         for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {
1428                 tmp = qry->erase_region_info[i];
1429                 qry->erase_region_info[i] = qry->erase_region_info[j];
1430                 qry->erase_region_info[j] = tmp;
1431         }
1432 }
1433
1434 /*-----------------------------------------------------------------------
1435  * read jedec ids from device and set corresponding fields in info struct
1436  *
1437  * Note: assume cfi->vendor, cfi->portwidth and cfi->chipwidth are correct
1438  *
1439  */
1440 static void cmdset_intel_read_jedec_ids(flash_info_t *info)
1441 {
1442         flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
1443         flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
1444         udelay(1000); /* some flash are slow to respond */
1445         info->manufacturer_id = flash_read_uchar (info,
1446                                         FLASH_OFFSET_MANUFACTURER_ID);
1447         info->device_id = flash_read_uchar (info,
1448                                         FLASH_OFFSET_DEVICE_ID);
1449         flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
1450 }
1451
1452 static int cmdset_intel_init(flash_info_t *info, struct cfi_qry *qry)
1453 {
1454         info->cmd_reset = FLASH_CMD_RESET;
1455
1456         cmdset_intel_read_jedec_ids(info);
1457         flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
1458
1459 #ifdef CFG_FLASH_PROTECTION
1460         /* read legacy lock/unlock bit from intel flash */
1461         if (info->ext_addr) {
1462                 info->legacy_unlock = flash_read_uchar (info,
1463                                 info->ext_addr + 5) & 0x08;
1464         }
1465 #endif
1466
1467         return 0;
1468 }
1469
1470 static void cmdset_amd_read_jedec_ids(flash_info_t *info)
1471 {
1472         flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
1473         flash_unlock_seq(info, 0);
1474         flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
1475         udelay(1000); /* some flash are slow to respond */
1476
1477         info->manufacturer_id = flash_read_uchar (info,
1478                                         FLASH_OFFSET_MANUFACTURER_ID);
1479
1480         switch (info->chipwidth){
1481         case FLASH_CFI_8BIT:
1482                 info->device_id = flash_read_uchar (info,
1483                                                 FLASH_OFFSET_DEVICE_ID);
1484                 if (info->device_id == 0x7E) {
1485                         /* AMD 3-byte (expanded) device ids */
1486                         info->device_id2 = flash_read_uchar (info,
1487                                                 FLASH_OFFSET_DEVICE_ID2);
1488                         info->device_id2 <<= 8;
1489                         info->device_id2 |= flash_read_uchar (info,
1490                                                 FLASH_OFFSET_DEVICE_ID3);
1491                 }
1492                 break;
1493         case FLASH_CFI_16BIT:
1494                 info->device_id = flash_read_word (info,
1495                                                 FLASH_OFFSET_DEVICE_ID);
1496                 break;
1497         default:
1498                 break;
1499         }
1500         flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
1501 }
1502
1503 static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
1504 {
1505         info->cmd_reset = AMD_CMD_RESET;
1506
1507         cmdset_amd_read_jedec_ids(info);
1508         flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
1509
1510         return 0;
1511 }
1512
1513 #ifdef CONFIG_FLASH_CFI_LEGACY
1514 static void flash_read_jedec_ids (flash_info_t * info)
1515 {
1516         info->manufacturer_id = 0;
1517         info->device_id       = 0;
1518         info->device_id2      = 0;
1519
1520         switch (info->vendor) {
1521         case CFI_CMDSET_INTEL_PROG_REGIONS:
1522         case CFI_CMDSET_INTEL_STANDARD:
1523         case CFI_CMDSET_INTEL_EXTENDED:
1524                 cmdset_intel_read_jedec_ids(info);
1525                 break;
1526         case CFI_CMDSET_AMD_STANDARD:
1527         case CFI_CMDSET_AMD_EXTENDED:
1528                 cmdset_amd_read_jedec_ids(info);
1529                 break;
1530         default:
1531                 break;
1532         }
1533 }
1534
1535 /*-----------------------------------------------------------------------
1536  * Call board code to request info about non-CFI flash.
1537  * board_flash_get_legacy needs to fill in at least:
1538  * info->portwidth, info->chipwidth and info->interface for Jedec probing.
1539  */
1540 static int flash_detect_legacy(ulong base, int banknum)
1541 {
1542         flash_info_t *info = &flash_info[banknum];
1543
1544         if (board_flash_get_legacy(base, banknum, info)) {
1545                 /* board code may have filled info completely. If not, we
1546                    use JEDEC ID probing. */
1547                 if (!info->vendor) {
1548                         int modes[] = {
1549                                 CFI_CMDSET_AMD_STANDARD,
1550                                 CFI_CMDSET_INTEL_STANDARD
1551                         };
1552                         int i;
1553
1554                         for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) {
1555                                 info->vendor = modes[i];
1556                                 info->start[0] = base;
1557                                 if (info->portwidth == FLASH_CFI_8BIT
1558                                         && info->interface == FLASH_CFI_X8X16) {
1559                                         info->addr_unlock1 = 0x2AAA;
1560                                         info->addr_unlock2 = 0x5555;
1561                                 } else {
1562                                         info->addr_unlock1 = 0x5555;
1563                                         info->addr_unlock2 = 0x2AAA;
1564                                 }
1565                                 flash_read_jedec_ids(info);
1566                                 debug("JEDEC PROBE: ID %x %x %x\n",
1567                                                 info->manufacturer_id,
1568                                                 info->device_id,
1569                                                 info->device_id2);
1570                                 if (jedec_flash_match(info, base))
1571                                         break;
1572                         }
1573                 }
1574
1575                 switch(info->vendor) {
1576                 case CFI_CMDSET_INTEL_PROG_REGIONS:
1577                 case CFI_CMDSET_INTEL_STANDARD:
1578                 case CFI_CMDSET_INTEL_EXTENDED:
1579                         info->cmd_reset = FLASH_CMD_RESET;
1580                         break;
1581                 case CFI_CMDSET_AMD_STANDARD:
1582                 case CFI_CMDSET_AMD_EXTENDED:
1583                 case CFI_CMDSET_AMD_LEGACY:
1584                         info->cmd_reset = AMD_CMD_RESET;
1585                         break;
1586                 }
1587                 info->flash_id = FLASH_MAN_CFI;
1588                 return 1;
1589         }
1590         return 0; /* use CFI */
1591 }
1592 #else
1593 static inline int flash_detect_legacy(ulong base, int banknum)
1594 {
1595         return 0; /* use CFI */
1596 }
1597 #endif
1598
1599 /*-----------------------------------------------------------------------
1600  * detect if flash is compatible with the Common Flash Interface (CFI)
1601  * http://www.jedec.org/download/search/jesd68.pdf
1602  */
1603 static void flash_read_cfi (flash_info_t *info, void *buf,
1604                 unsigned int start, size_t len)
1605 {
1606         u8 *p = buf;
1607         unsigned int i;
1608
1609         for (i = 0; i < len; i++)
1610                 p[i] = flash_read_uchar(info, start + i);
1611 }
1612
1613 static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
1614 {
1615         int cfi_offset;
1616
1617         /* We do not yet know what kind of commandset to use, so we issue
1618            the reset command in both Intel and AMD variants, in the hope
1619            that AMD flash roms ignore the Intel command. */
1620         flash_write_cmd (info, 0, 0, AMD_CMD_RESET);
1621         flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
1622
1623         for (cfi_offset=0;
1624              cfi_offset < sizeof(flash_offset_cfi) / sizeof(uint);
1625              cfi_offset++) {
1626                 flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset],
1627                                  FLASH_CMD_CFI);
1628                 if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
1629                     && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
1630                     && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
1631                         flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
1632                                         sizeof(struct cfi_qry));
1633                         info->interface = le16_to_cpu(qry->interface_desc);
1634
1635                         info->cfi_offset = flash_offset_cfi[cfi_offset];
1636                         debug ("device interface is %d\n",
1637                                info->interface);
1638                         debug ("found port %d chip %d ",
1639                                info->portwidth, info->chipwidth);
1640                         debug ("port %d bits chip %d bits\n",
1641                                info->portwidth << CFI_FLASH_SHIFT_WIDTH,
1642                                info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
1643
1644                         /* calculate command offsets as in the Linux driver */
1645                         info->addr_unlock1 = 0x555;
1646                         info->addr_unlock2 = 0x2aa;
1647
1648                         /*
1649                          * modify the unlock address if we are
1650                          * in compatibility mode
1651                          */
1652                         if (    /* x8/x16 in x8 mode */
1653                                 ((info->chipwidth == FLASH_CFI_BY8) &&
1654                                         (info->interface == FLASH_CFI_X8X16)) ||
1655                                 /* x16/x32 in x16 mode */
1656                                 ((info->chipwidth == FLASH_CFI_BY16) &&
1657                                         (info->interface == FLASH_CFI_X16X32)))
1658                         {
1659                                 info->addr_unlock1 = 0xaaa;
1660                                 info->addr_unlock2 = 0x555;
1661                         }
1662
1663                         info->name = "CFI conformant";
1664                         return 1;
1665                 }
1666         }
1667
1668         return 0;
1669 }
1670
1671 static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
1672 {
1673         debug ("flash detect cfi\n");
1674
1675         for (info->portwidth = CFG_FLASH_CFI_WIDTH;
1676              info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
1677                 for (info->chipwidth = FLASH_CFI_BY8;
1678                      info->chipwidth <= info->portwidth;
1679                      info->chipwidth <<= 1)
1680                         if (__flash_detect_cfi(info, qry))
1681                                 return 1;
1682         }
1683         debug ("not found\n");
1684         return 0;
1685 }
1686
1687 /*
1688  * Manufacturer-specific quirks. Add workarounds for geometry
1689  * reversal, etc. here.
1690  */
1691 static void flash_fixup_amd(flash_info_t *info, struct cfi_qry *qry)
1692 {
1693         /* check if flash geometry needs reversal */
1694         if (qry->num_erase_regions > 1) {
1695                 /* reverse geometry if top boot part */
1696                 if (info->cfi_version < 0x3131) {
1697                         /* CFI < 1.1, try to guess from device id */
1698                         if ((info->device_id & 0x80) != 0)
1699                                 cfi_reverse_geometry(qry);
1700                 } else if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
1701                         /* CFI >= 1.1, deduct from top/bottom flag */
1702                         /* note: ext_addr is valid since cfi_version > 0 */
1703                         cfi_reverse_geometry(qry);
1704                 }
1705         }
1706 }
1707
1708 static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry)
1709 {
1710         int reverse_geometry = 0;
1711
1712         /* Check the "top boot" bit in the PRI */
1713         if (info->ext_addr && !(flash_read_uchar(info, info->ext_addr + 6) & 1))
1714                 reverse_geometry = 1;
1715
1716         /* AT49BV6416(T) list the erase regions in the wrong order.
1717          * However, the device ID is identical with the non-broken
1718          * AT49BV642D since u-boot only reads the low byte (they
1719          * differ in the high byte.) So leave out this fixup for now.
1720          */
1721 #if 0
1722         if (info->device_id == 0xd6 || info->device_id == 0xd2)
1723                 reverse_geometry = !reverse_geometry;
1724 #endif
1725
1726         if (reverse_geometry)
1727                 cfi_reverse_geometry(qry);
1728 }
1729
1730 /*
1731  * The following code cannot be run from FLASH!
1732  *
1733  */
1734 ulong flash_get_size (ulong base, int banknum)
1735 {
1736         flash_info_t *info = &flash_info[banknum];
1737         int i, j;
1738         flash_sect_t sect_cnt;
1739         unsigned long sector;
1740         unsigned long tmp;
1741         int size_ratio;
1742         uchar num_erase_regions;
1743         int erase_region_size;
1744         int erase_region_count;
1745         struct cfi_qry qry;
1746
1747         memset(&qry, 0, sizeof(qry));
1748
1749         info->ext_addr = 0;
1750         info->cfi_version = 0;
1751 #ifdef CFG_FLASH_PROTECTION
1752         info->legacy_unlock = 0;
1753 #endif
1754
1755         info->start[0] = base;
1756
1757         if (flash_detect_cfi (info, &qry)) {
1758                 info->vendor = le16_to_cpu(qry.p_id);
1759                 info->ext_addr = le16_to_cpu(qry.p_adr);
1760                 num_erase_regions = qry.num_erase_regions;
1761
1762                 if (info->ext_addr) {
1763                         info->cfi_version = (ushort) flash_read_uchar (info,
1764                                                 info->ext_addr + 3) << 8;
1765                         info->cfi_version |= (ushort) flash_read_uchar (info,
1766                                                 info->ext_addr + 4);
1767                 }
1768
1769 #ifdef DEBUG
1770                 flash_printqry (&qry);
1771 #endif
1772
1773                 switch (info->vendor) {
1774                 case CFI_CMDSET_INTEL_PROG_REGIONS:
1775                 case CFI_CMDSET_INTEL_STANDARD:
1776                 case CFI_CMDSET_INTEL_EXTENDED:
1777                         cmdset_intel_init(info, &qry);
1778                         break;
1779                 case CFI_CMDSET_AMD_STANDARD:
1780                 case CFI_CMDSET_AMD_EXTENDED:
1781                         cmdset_amd_init(info, &qry);
1782                         break;
1783                 default:
1784                         printf("CFI: Unknown command set 0x%x\n",
1785                                         info->vendor);
1786                         /*
1787                          * Unfortunately, this means we don't know how
1788                          * to get the chip back to Read mode. Might
1789                          * as well try an Intel-style reset...
1790                          */
1791                         flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
1792                         return 0;
1793                 }
1794
1795                 /* Do manufacturer-specific fixups */
1796                 switch (info->manufacturer_id) {
1797                 case 0x0001:
1798                         flash_fixup_amd(info, &qry);
1799                         break;
1800                 case 0x001f:
1801                         flash_fixup_atmel(info, &qry);
1802                         break;
1803                 }
1804
1805                 debug ("manufacturer is %d\n", info->vendor);
1806                 debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
1807                 debug ("device id is 0x%x\n", info->device_id);
1808                 debug ("device id2 is 0x%x\n", info->device_id2);
1809                 debug ("cfi version is 0x%04x\n", info->cfi_version);
1810
1811                 size_ratio = info->portwidth / info->chipwidth;
1812                 /* if the chip is x8/x16 reduce the ratio by half */
1813                 if ((info->interface == FLASH_CFI_X8X16)
1814                     && (info->chipwidth == FLASH_CFI_BY8)) {
1815                         size_ratio >>= 1;
1816                 }
1817                 debug ("size_ratio %d port %d bits chip %d bits\n",
1818                        size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
1819                        info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
1820                 debug ("found %d erase regions\n", num_erase_regions);
1821                 sect_cnt = 0;
1822                 sector = base;
1823                 for (i = 0; i < num_erase_regions; i++) {
1824                         if (i > NUM_ERASE_REGIONS) {
1825                                 printf ("%d erase regions found, only %d used\n",
1826                                         num_erase_regions, NUM_ERASE_REGIONS);
1827                                 break;
1828                         }
1829
1830                         tmp = le32_to_cpu(qry.erase_region_info[i]);
1831                         debug("erase region %u: 0x%08lx\n", i, tmp);
1832
1833                         erase_region_count = (tmp & 0xffff) + 1;
1834                         tmp >>= 16;
1835                         erase_region_size =
1836                                 (tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
1837                         debug ("erase_region_count = %d erase_region_size = %d\n",
1838                                 erase_region_count, erase_region_size);
1839                         for (j = 0; j < erase_region_count; j++) {
1840                                 if (sect_cnt >= CFG_MAX_FLASH_SECT) {
1841                                         printf("ERROR: too many flash sectors\n");
1842                                         break;
1843                                 }
1844                                 info->start[sect_cnt] = sector;
1845                                 sector += (erase_region_size * size_ratio);
1846
1847                                 /*
1848                                  * Only read protection status from
1849                                  * supported devices (intel...)
1850                                  */
1851                                 switch (info->vendor) {
1852                                 case CFI_CMDSET_INTEL_PROG_REGIONS:
1853                                 case CFI_CMDSET_INTEL_EXTENDED:
1854                                 case CFI_CMDSET_INTEL_STANDARD:
1855                                         info->protect[sect_cnt] =
1856                                                 flash_isset (info, sect_cnt,
1857                                                              FLASH_OFFSET_PROTECT,
1858                                                              FLASH_STATUS_PROTECT);
1859                                         break;
1860                                 default:
1861                                         /* default: not protected */
1862                                         info->protect[sect_cnt] = 0;
1863                                 }
1864
1865                                 sect_cnt++;
1866                         }
1867                 }
1868
1869                 info->sector_count = sect_cnt;
1870                 info->size = 1 << qry.dev_size;
1871                 /* multiply the size by the number of chips */
1872                 info->size *= size_ratio;
1873                 info->buffer_size = 1 << le16_to_cpu(qry.max_buf_write_size);
1874                 tmp = 1 << qry.block_erase_timeout_typ;
1875                 info->erase_blk_tout = tmp *
1876                         (1 << qry.block_erase_timeout_max);
1877                 tmp = (1 << qry.buf_write_timeout_typ) *
1878                         (1 << qry.buf_write_timeout_max);
1879
1880                 /* round up when converting to ms */
1881                 info->buffer_write_tout = (tmp + 999) / 1000;
1882                 tmp = (1 << qry.word_write_timeout_typ) *
1883                         (1 << qry.word_write_timeout_max);
1884                 /* round up when converting to ms */
1885                 info->write_tout = (tmp + 999) / 1000;
1886                 info->flash_id = FLASH_MAN_CFI;
1887                 if ((info->interface == FLASH_CFI_X8X16) &&
1888                     (info->chipwidth == FLASH_CFI_BY8)) {
1889                         /* XXX - Need to test on x8/x16 in parallel. */
1890                         info->portwidth >>= 1;
1891                 }
1892         }
1893
1894         flash_write_cmd (info, 0, 0, info->cmd_reset);
1895         return (info->size);
1896 }
1897
1898 /*-----------------------------------------------------------------------
1899  */
1900 unsigned long flash_init (void)
1901 {
1902         unsigned long size = 0;
1903         int i;
1904 #if defined(CFG_FLASH_AUTOPROTECT_LIST)
1905         struct apl_s {
1906                 ulong start;
1907                 ulong size;
1908         } apl[] = CFG_FLASH_AUTOPROTECT_LIST;
1909 #endif
1910
1911 #ifdef CFG_FLASH_PROTECTION
1912         char *s = getenv("unlock");
1913 #endif
1914
1915         /* Init: no FLASHes known */
1916         for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
1917                 flash_info[i].flash_id = FLASH_UNKNOWN;
1918
1919                 if (!flash_detect_legacy (bank_base[i], i))
1920                         flash_get_size (bank_base[i], i);
1921                 size += flash_info[i].size;
1922                 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
1923 #ifndef CFG_FLASH_QUIET_TEST
1924                         printf ("## Unknown FLASH on Bank %d "
1925                                 "- Size = 0x%08lx = %ld MB\n",
1926                                 i+1, flash_info[i].size,
1927                                 flash_info[i].size << 20);
1928 #endif /* CFG_FLASH_QUIET_TEST */
1929                 }
1930 #ifdef CFG_FLASH_PROTECTION
1931                 else if ((s != NULL) && (strcmp(s, "yes") == 0)) {
1932                         /*
1933                          * Only the U-Boot image and it's environment
1934                          * is protected, all other sectors are
1935                          * unprotected (unlocked) if flash hardware
1936                          * protection is used (CFG_FLASH_PROTECTION)
1937                          * and the environment variable "unlock" is
1938                          * set to "yes".
1939                          */
1940                         if (flash_info[i].legacy_unlock) {
1941                                 int k;
1942
1943                                 /*
1944                                  * Disable legacy_unlock temporarily,
1945                                  * since flash_real_protect would
1946                                  * relock all other sectors again
1947                                  * otherwise.
1948                                  */
1949                                 flash_info[i].legacy_unlock = 0;
1950
1951                                 /*
1952                                  * Legacy unlocking (e.g. Intel J3) ->
1953                                  * unlock only one sector. This will
1954                                  * unlock all sectors.
1955                                  */
1956                                 flash_real_protect (&flash_info[i], 0, 0);
1957
1958                                 flash_info[i].legacy_unlock = 1;
1959
1960                                 /*
1961                                  * Manually mark other sectors as
1962                                  * unlocked (unprotected)
1963                                  */
1964                                 for (k = 1; k < flash_info[i].sector_count; k++)
1965                                         flash_info[i].protect[k] = 0;
1966                         } else {
1967                                 /*
1968                                  * No legancy unlocking -> unlock all sectors
1969                                  */
1970                                 flash_protect (FLAG_PROTECT_CLEAR,
1971                                                flash_info[i].start[0],
1972                                                flash_info[i].start[0]
1973                                                + flash_info[i].size - 1,
1974                                                &flash_info[i]);
1975                         }
1976                 }
1977 #endif /* CFG_FLASH_PROTECTION */
1978         }
1979
1980         /* Monitor protection ON by default */
1981 #if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
1982         flash_protect (FLAG_PROTECT_SET,
1983                        CFG_MONITOR_BASE,
1984                        CFG_MONITOR_BASE + monitor_flash_len  - 1,
1985                        flash_get_info(CFG_MONITOR_BASE));
1986 #endif
1987
1988         /* Environment protection ON by default */
1989 #ifdef CFG_ENV_IS_IN_FLASH
1990         flash_protect (FLAG_PROTECT_SET,
1991                        CFG_ENV_ADDR,
1992                        CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
1993                        flash_get_info(CFG_ENV_ADDR));
1994 #endif
1995
1996         /* Redundant environment protection ON by default */
1997 #ifdef CFG_ENV_ADDR_REDUND
1998         flash_protect (FLAG_PROTECT_SET,
1999                        CFG_ENV_ADDR_REDUND,
2000                        CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
2001                        flash_get_info(CFG_ENV_ADDR_REDUND));
2002 #endif
2003
2004 #if defined(CFG_FLASH_AUTOPROTECT_LIST)
2005         for (i = 0; i < (sizeof(apl) / sizeof(struct apl_s)); i++) {
2006                 debug("autoprotecting from %08x to %08x\n",
2007                       apl[i].start, apl[i].start + apl[i].size - 1);
2008                 flash_protect (FLAG_PROTECT_SET,
2009                                apl[i].start,
2010                                apl[i].start + apl[i].size - 1,
2011                                flash_get_info(apl[i].start));
2012         }
2013 #endif
2014         return (size);
2015 }
2016
2017 #endif /* CFG_FLASH_CFI */