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