CFI: Do not use uninitialized cmd_reset
[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  * Copy memory to flash, returns:
1184  * 0 - OK
1185  * 1 - write timeout
1186  * 2 - Flash not erased
1187  */
1188 int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
1189 {
1190         ulong wp;
1191         uchar *p;
1192         int aln;
1193         cfiword_t cword;
1194         int i, rc;
1195
1196 #ifdef CFG_FLASH_USE_BUFFER_WRITE
1197         int buffered_size;
1198 #endif
1199         /* get lower aligned address */
1200         wp = (addr & ~(info->portwidth - 1));
1201
1202         /* handle unaligned start */
1203         if ((aln = addr - wp) != 0) {
1204                 cword.l = 0;
1205                 p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
1206                 for (i = 0; i < aln; ++i)
1207                         flash_add_byte (info, &cword, flash_read8(p + i));
1208
1209                 for (; (i < info->portwidth) && (cnt > 0); i++) {
1210                         flash_add_byte (info, &cword, *src++);
1211                         cnt--;
1212                 }
1213                 for (; (cnt == 0) && (i < info->portwidth); ++i)
1214                         flash_add_byte (info, &cword, flash_read8(p + i));
1215
1216                 rc = flash_write_cfiword (info, wp, cword);
1217                 unmap_physmem(p, info->portwidth);
1218                 if (rc != 0)
1219                         return rc;
1220
1221                 wp += i;
1222         }
1223
1224         /* handle the aligned part */
1225 #ifdef CFG_FLASH_USE_BUFFER_WRITE
1226         buffered_size = (info->portwidth / info->chipwidth);
1227         buffered_size *= info->buffer_size;
1228         while (cnt >= info->portwidth) {
1229                 /* prohibit buffer write when buffer_size is 1 */
1230                 if (info->buffer_size == 1) {
1231                         cword.l = 0;
1232                         for (i = 0; i < info->portwidth; i++)
1233                                 flash_add_byte (info, &cword, *src++);
1234                         if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
1235                                 return rc;
1236                         wp += info->portwidth;
1237                         cnt -= info->portwidth;
1238                         continue;
1239                 }
1240
1241                 /* write buffer until next buffered_size aligned boundary */
1242                 i = buffered_size - (wp % buffered_size);
1243                 if (i > cnt)
1244                         i = cnt;
1245                 if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)
1246                         return rc;
1247                 i -= i & (info->portwidth - 1);
1248                 wp += i;
1249                 src += i;
1250                 cnt -= i;
1251         }
1252 #else
1253         while (cnt >= info->portwidth) {
1254                 cword.l = 0;
1255                 for (i = 0; i < info->portwidth; i++) {
1256                         flash_add_byte (info, &cword, *src++);
1257                 }
1258                 if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
1259                         return rc;
1260                 wp += info->portwidth;
1261                 cnt -= info->portwidth;
1262         }
1263 #endif /* CFG_FLASH_USE_BUFFER_WRITE */
1264         if (cnt == 0) {
1265                 return (0);
1266         }
1267
1268         /*
1269          * handle unaligned tail bytes
1270          */
1271         cword.l = 0;
1272         p = map_physmem(wp, info->portwidth, MAP_NOCACHE);
1273         for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
1274                 flash_add_byte (info, &cword, *src++);
1275                 --cnt;
1276         }
1277         for (; i < info->portwidth; ++i)
1278                 flash_add_byte (info, &cword, flash_read8(p + i));
1279         unmap_physmem(p, info->portwidth);
1280
1281         return flash_write_cfiword (info, wp, cword);
1282 }
1283
1284 /*-----------------------------------------------------------------------
1285  */
1286 #ifdef CFG_FLASH_PROTECTION
1287
1288 int flash_real_protect (flash_info_t * info, long sector, int prot)
1289 {
1290         int retcode = 0;
1291
1292         flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
1293         flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
1294         if (prot)
1295                 flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
1296         else
1297                 flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
1298
1299         if ((retcode =
1300              flash_full_status_check (info, sector, info->erase_blk_tout,
1301                                       prot ? "protect" : "unprotect")) == 0) {
1302
1303                 info->protect[sector] = prot;
1304
1305                 /*
1306                  * On some of Intel's flash chips (marked via legacy_unlock)
1307                  * unprotect unprotects all locking.
1308                  */
1309                 if ((prot == 0) && (info->legacy_unlock)) {
1310                         flash_sect_t i;
1311
1312                         for (i = 0; i < info->sector_count; i++) {
1313                                 if (info->protect[i])
1314                                         flash_real_protect (info, i, 1);
1315                         }
1316                 }
1317         }
1318         return retcode;
1319 }
1320
1321 /*-----------------------------------------------------------------------
1322  * flash_read_user_serial - read the OneTimeProgramming cells
1323  */
1324 void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
1325                              int len)
1326 {
1327         uchar *src;
1328         uchar *dst;
1329
1330         dst = buffer;
1331         src = flash_map (info, 0, FLASH_OFFSET_USER_PROTECTION);
1332         flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
1333         memcpy (dst, src + offset, len);
1334         flash_write_cmd (info, 0, 0, info->cmd_reset);
1335         flash_unmap(info, 0, FLASH_OFFSET_USER_PROTECTION, src);
1336 }
1337
1338 /*
1339  * flash_read_factory_serial - read the device Id from the protection area
1340  */
1341 void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
1342                                 int len)
1343 {
1344         uchar *src;
1345
1346         src = flash_map (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
1347         flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
1348         memcpy (buffer, src + offset, len);
1349         flash_write_cmd (info, 0, 0, info->cmd_reset);
1350         flash_unmap(info, 0, FLASH_OFFSET_INTEL_PROTECTION, src);
1351 }
1352
1353 #endif /* CFG_FLASH_PROTECTION */
1354
1355 /*-----------------------------------------------------------------------
1356  * Reverse the order of the erase regions in the CFI QRY structure.
1357  * This is needed for chips that are either a) correctly detected as
1358  * top-boot, or b) buggy.
1359  */
1360 static void cfi_reverse_geometry(struct cfi_qry *qry)
1361 {
1362         unsigned int i, j;
1363         u32 tmp;
1364
1365         for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {
1366                 tmp = qry->erase_region_info[i];
1367                 qry->erase_region_info[i] = qry->erase_region_info[j];
1368                 qry->erase_region_info[j] = tmp;
1369         }
1370 }
1371
1372 /*-----------------------------------------------------------------------
1373  * read jedec ids from device and set corresponding fields in info struct
1374  *
1375  * Note: assume cfi->vendor, cfi->portwidth and cfi->chipwidth are correct
1376  *
1377  */
1378 static void cmdset_intel_read_jedec_ids(flash_info_t *info)
1379 {
1380         flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
1381         flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
1382         udelay(1000); /* some flash are slow to respond */
1383         info->manufacturer_id = flash_read_uchar (info,
1384                                         FLASH_OFFSET_MANUFACTURER_ID);
1385         info->device_id = flash_read_uchar (info,
1386                                         FLASH_OFFSET_DEVICE_ID);
1387         flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
1388 }
1389
1390 static int cmdset_intel_init(flash_info_t *info, struct cfi_qry *qry)
1391 {
1392         info->cmd_reset = FLASH_CMD_RESET;
1393
1394         cmdset_intel_read_jedec_ids(info);
1395         flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
1396
1397 #ifdef CFG_FLASH_PROTECTION
1398         /* read legacy lock/unlock bit from intel flash */
1399         if (info->ext_addr) {
1400                 info->legacy_unlock = flash_read_uchar (info,
1401                                 info->ext_addr + 5) & 0x08;
1402         }
1403 #endif
1404
1405         return 0;
1406 }
1407
1408 static void cmdset_amd_read_jedec_ids(flash_info_t *info)
1409 {
1410         flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
1411         flash_unlock_seq(info, 0);
1412         flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
1413         udelay(1000); /* some flash are slow to respond */
1414         info->manufacturer_id = flash_read_uchar (info,
1415                                         FLASH_OFFSET_MANUFACTURER_ID);
1416         info->device_id = flash_read_uchar (info,
1417                                         FLASH_OFFSET_DEVICE_ID);
1418         if (info->device_id == 0x7E) {
1419                 /* AMD 3-byte (expanded) device ids */
1420                 info->device_id2 = flash_read_uchar (info,
1421                                         FLASH_OFFSET_DEVICE_ID2);
1422                 info->device_id2 <<= 8;
1423                 info->device_id2 |= flash_read_uchar (info,
1424                                         FLASH_OFFSET_DEVICE_ID3);
1425         }
1426         flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
1427 }
1428
1429 static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
1430 {
1431         info->cmd_reset = AMD_CMD_RESET;
1432
1433         cmdset_amd_read_jedec_ids(info);
1434         flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);
1435
1436         return 0;
1437 }
1438
1439 #ifdef CONFIG_FLASH_CFI_LEGACY
1440 static void flash_read_jedec_ids (flash_info_t * info)
1441 {
1442         info->manufacturer_id = 0;
1443         info->device_id       = 0;
1444         info->device_id2      = 0;
1445
1446         switch (info->vendor) {
1447         case CFI_CMDSET_INTEL_STANDARD:
1448         case CFI_CMDSET_INTEL_EXTENDED:
1449                 cmdset_intel_read_jedec_ids(info);
1450                 break;
1451         case CFI_CMDSET_AMD_STANDARD:
1452         case CFI_CMDSET_AMD_EXTENDED:
1453                 cmdset_amd_read_jedec_ids(info);
1454                 break;
1455         default:
1456                 break;
1457         }
1458 }
1459
1460 /*-----------------------------------------------------------------------
1461  * Call board code to request info about non-CFI flash.
1462  * board_flash_get_legacy needs to fill in at least:
1463  * info->portwidth, info->chipwidth and info->interface for Jedec probing.
1464  */
1465 static int flash_detect_legacy(ulong base, int banknum)
1466 {
1467         flash_info_t *info = &flash_info[banknum];
1468
1469         if (board_flash_get_legacy(base, banknum, info)) {
1470                 /* board code may have filled info completely. If not, we
1471                    use JEDEC ID probing. */
1472                 if (!info->vendor) {
1473                         int modes[] = {
1474                                 CFI_CMDSET_AMD_STANDARD,
1475                                 CFI_CMDSET_INTEL_STANDARD
1476                         };
1477                         int i;
1478
1479                         for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) {
1480                                 info->vendor = modes[i];
1481                                 info->start[0] = base;
1482                                 if (info->portwidth == FLASH_CFI_8BIT
1483                                         && info->interface == FLASH_CFI_X8X16) {
1484                                         info->addr_unlock1 = 0x2AAA;
1485                                         info->addr_unlock2 = 0x5555;
1486                                 } else {
1487                                         info->addr_unlock1 = 0x5555;
1488                                         info->addr_unlock2 = 0x2AAA;
1489                                 }
1490                                 flash_read_jedec_ids(info);
1491                                 debug("JEDEC PROBE: ID %x %x %x\n",
1492                                                 info->manufacturer_id,
1493                                                 info->device_id,
1494                                                 info->device_id2);
1495                                 if (jedec_flash_match(info, base))
1496                                         break;
1497                         }
1498                 }
1499
1500                 switch(info->vendor) {
1501                 case CFI_CMDSET_INTEL_STANDARD:
1502                 case CFI_CMDSET_INTEL_EXTENDED:
1503                         info->cmd_reset = FLASH_CMD_RESET;
1504                         break;
1505                 case CFI_CMDSET_AMD_STANDARD:
1506                 case CFI_CMDSET_AMD_EXTENDED:
1507                 case CFI_CMDSET_AMD_LEGACY:
1508                         info->cmd_reset = AMD_CMD_RESET;
1509                         break;
1510                 }
1511                 info->flash_id = FLASH_MAN_CFI;
1512                 return 1;
1513         }
1514         return 0; /* use CFI */
1515 }
1516 #else
1517 static inline int flash_detect_legacy(ulong base, int banknum)
1518 {
1519         return 0; /* use CFI */
1520 }
1521 #endif
1522
1523 /*-----------------------------------------------------------------------
1524  * detect if flash is compatible with the Common Flash Interface (CFI)
1525  * http://www.jedec.org/download/search/jesd68.pdf
1526  */
1527 static void flash_read_cfi (flash_info_t *info, void *buf,
1528                 unsigned int start, size_t len)
1529 {
1530         u8 *p = buf;
1531         unsigned int i;
1532
1533         for (i = 0; i < len; i++)
1534                 p[i] = flash_read_uchar(info, start + i);
1535 }
1536
1537 static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
1538 {
1539         int cfi_offset;
1540
1541         /* We do not yet know what kind of commandset to use, so we issue
1542            the reset command in both Intel and AMD variants, in the hope
1543            that AMD flash roms ignore the Intel command. */
1544         flash_write_cmd (info, 0, 0, AMD_CMD_RESET);
1545         flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
1546
1547         for (cfi_offset=0;
1548              cfi_offset < sizeof(flash_offset_cfi) / sizeof(uint);
1549              cfi_offset++) {
1550                 flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset],
1551                                  FLASH_CMD_CFI);
1552                 if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
1553                     && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
1554                     && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
1555                         flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
1556                                         sizeof(struct cfi_qry));
1557                         info->interface = le16_to_cpu(qry->interface_desc);
1558
1559                         info->cfi_offset = flash_offset_cfi[cfi_offset];
1560                         debug ("device interface is %d\n",
1561                                info->interface);
1562                         debug ("found port %d chip %d ",
1563                                info->portwidth, info->chipwidth);
1564                         debug ("port %d bits chip %d bits\n",
1565                                info->portwidth << CFI_FLASH_SHIFT_WIDTH,
1566                                info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
1567
1568                         /* calculate command offsets as in the Linux driver */
1569                         info->addr_unlock1 = 0x555;
1570                         info->addr_unlock2 = 0x2aa;
1571
1572                         /*
1573                          * modify the unlock address if we are
1574                          * in compatibility mode
1575                          */
1576                         if (    /* x8/x16 in x8 mode */
1577                                 ((info->chipwidth == FLASH_CFI_BY8) &&
1578                                         (info->interface == FLASH_CFI_X8X16)) ||
1579                                 /* x16/x32 in x16 mode */
1580                                 ((info->chipwidth == FLASH_CFI_BY16) &&
1581                                         (info->interface == FLASH_CFI_X16X32)))
1582                         {
1583                                 info->addr_unlock1 = 0xaaa;
1584                                 info->addr_unlock2 = 0x555;
1585                         }
1586
1587                         info->name = "CFI conformant";
1588                         return 1;
1589                 }
1590         }
1591
1592         return 0;
1593 }
1594
1595 static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
1596 {
1597         debug ("flash detect cfi\n");
1598
1599         for (info->portwidth = CFG_FLASH_CFI_WIDTH;
1600              info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
1601                 for (info->chipwidth = FLASH_CFI_BY8;
1602                      info->chipwidth <= info->portwidth;
1603                      info->chipwidth <<= 1)
1604                         if (__flash_detect_cfi(info, qry))
1605                                 return 1;
1606         }
1607         debug ("not found\n");
1608         return 0;
1609 }
1610
1611 /*
1612  * Manufacturer-specific quirks. Add workarounds for geometry
1613  * reversal, etc. here.
1614  */
1615 static void flash_fixup_amd(flash_info_t *info, struct cfi_qry *qry)
1616 {
1617         /* check if flash geometry needs reversal */
1618         if (qry->num_erase_regions > 1) {
1619                 /* reverse geometry if top boot part */
1620                 if (info->cfi_version < 0x3131) {
1621                         /* CFI < 1.1, try to guess from device id */
1622                         if ((info->device_id & 0x80) != 0)
1623                                 cfi_reverse_geometry(qry);
1624                 } else if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
1625                         /* CFI >= 1.1, deduct from top/bottom flag */
1626                         /* note: ext_addr is valid since cfi_version > 0 */
1627                         cfi_reverse_geometry(qry);
1628                 }
1629         }
1630 }
1631
1632 static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry)
1633 {
1634         int reverse_geometry = 0;
1635
1636         /* Check the "top boot" bit in the PRI */
1637         if (info->ext_addr && !(flash_read_uchar(info, info->ext_addr + 6) & 1))
1638                 reverse_geometry = 1;
1639
1640         /* AT49BV6416(T) list the erase regions in the wrong order.
1641          * However, the device ID is identical with the non-broken
1642          * AT49BV642D since u-boot only reads the low byte (they
1643          * differ in the high byte.) So leave out this fixup for now.
1644          */
1645 #if 0
1646         if (info->device_id == 0xd6 || info->device_id == 0xd2)
1647                 reverse_geometry = !reverse_geometry;
1648 #endif
1649
1650         if (reverse_geometry)
1651                 cfi_reverse_geometry(qry);
1652 }
1653
1654 /*
1655  * The following code cannot be run from FLASH!
1656  *
1657  */
1658 ulong flash_get_size (ulong base, int banknum)
1659 {
1660         flash_info_t *info = &flash_info[banknum];
1661         int i, j;
1662         flash_sect_t sect_cnt;
1663         unsigned long sector;
1664         unsigned long tmp;
1665         int size_ratio;
1666         uchar num_erase_regions;
1667         int erase_region_size;
1668         int erase_region_count;
1669         struct cfi_qry qry;
1670
1671         info->ext_addr = 0;
1672         info->cfi_version = 0;
1673 #ifdef CFG_FLASH_PROTECTION
1674         info->legacy_unlock = 0;
1675 #endif
1676
1677         info->start[0] = base;
1678
1679         if (flash_detect_cfi (info, &qry)) {
1680                 info->vendor = le16_to_cpu(qry.p_id);
1681                 info->ext_addr = le16_to_cpu(qry.p_adr);
1682                 num_erase_regions = qry.num_erase_regions;
1683
1684                 if (info->ext_addr) {
1685                         info->cfi_version = (ushort) flash_read_uchar (info,
1686                                                 info->ext_addr + 3) << 8;
1687                         info->cfi_version |= (ushort) flash_read_uchar (info,
1688                                                 info->ext_addr + 4);
1689                 }
1690
1691 #ifdef DEBUG
1692                 flash_printqry (&qry);
1693 #endif
1694
1695                 switch (info->vendor) {
1696                 case CFI_CMDSET_INTEL_STANDARD:
1697                 case CFI_CMDSET_INTEL_EXTENDED:
1698                         cmdset_intel_init(info, &qry);
1699                         break;
1700                 case CFI_CMDSET_AMD_STANDARD:
1701                 case CFI_CMDSET_AMD_EXTENDED:
1702                         cmdset_amd_init(info, &qry);
1703                         break;
1704                 default:
1705                         printf("CFI: Unknown command set 0x%x\n",
1706                                         info->vendor);
1707                         /*
1708                          * Unfortunately, this means we don't know how
1709                          * to get the chip back to Read mode. Might
1710                          * as well try an Intel-style reset...
1711                          */
1712                         flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
1713                         return 0;
1714                 }
1715
1716                 /* Do manufacturer-specific fixups */
1717                 switch (info->manufacturer_id) {
1718                 case 0x0001:
1719                         flash_fixup_amd(info, &qry);
1720                         break;
1721                 case 0x001f:
1722                         flash_fixup_atmel(info, &qry);
1723                         break;
1724                 }
1725
1726                 debug ("manufacturer is %d\n", info->vendor);
1727                 debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
1728                 debug ("device id is 0x%x\n", info->device_id);
1729                 debug ("device id2 is 0x%x\n", info->device_id2);
1730                 debug ("cfi version is 0x%04x\n", info->cfi_version);
1731
1732                 size_ratio = info->portwidth / info->chipwidth;
1733                 /* if the chip is x8/x16 reduce the ratio by half */
1734                 if ((info->interface == FLASH_CFI_X8X16)
1735                     && (info->chipwidth == FLASH_CFI_BY8)) {
1736                         size_ratio >>= 1;
1737                 }
1738                 debug ("size_ratio %d port %d bits chip %d bits\n",
1739                        size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
1740                        info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
1741                 debug ("found %d erase regions\n", num_erase_regions);
1742                 sect_cnt = 0;
1743                 sector = base;
1744                 for (i = 0; i < num_erase_regions; i++) {
1745                         if (i > NUM_ERASE_REGIONS) {
1746                                 printf ("%d erase regions found, only %d used\n",
1747                                         num_erase_regions, NUM_ERASE_REGIONS);
1748                                 break;
1749                         }
1750
1751                         tmp = le32_to_cpu(qry.erase_region_info[i]);
1752                         debug("erase region %u: 0x%08lx\n", i, tmp);
1753
1754                         erase_region_count = (tmp & 0xffff) + 1;
1755                         tmp >>= 16;
1756                         erase_region_size =
1757                                 (tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
1758                         debug ("erase_region_count = %d erase_region_size = %d\n",
1759                                 erase_region_count, erase_region_size);
1760                         for (j = 0; j < erase_region_count; j++) {
1761                                 if (sect_cnt >= CFG_MAX_FLASH_SECT) {
1762                                         printf("ERROR: too many flash sectors\n");
1763                                         break;
1764                                 }
1765                                 info->start[sect_cnt] = sector;
1766                                 sector += (erase_region_size * size_ratio);
1767
1768                                 /*
1769                                  * Only read protection status from
1770                                  * supported devices (intel...)
1771                                  */
1772                                 switch (info->vendor) {
1773                                 case CFI_CMDSET_INTEL_EXTENDED:
1774                                 case CFI_CMDSET_INTEL_STANDARD:
1775                                         info->protect[sect_cnt] =
1776                                                 flash_isset (info, sect_cnt,
1777                                                              FLASH_OFFSET_PROTECT,
1778                                                              FLASH_STATUS_PROTECT);
1779                                         break;
1780                                 default:
1781                                         /* default: not protected */
1782                                         info->protect[sect_cnt] = 0;
1783                                 }
1784
1785                                 sect_cnt++;
1786                         }
1787                 }
1788
1789                 info->sector_count = sect_cnt;
1790                 info->size = 1 << qry.dev_size;
1791                 /* multiply the size by the number of chips */
1792                 info->size *= size_ratio;
1793                 info->buffer_size = 1 << le16_to_cpu(qry.max_buf_write_size);
1794                 tmp = 1 << qry.block_erase_timeout_typ;
1795                 info->erase_blk_tout = tmp *
1796                         (1 << qry.block_erase_timeout_max);
1797                 tmp = (1 << qry.buf_write_timeout_typ) *
1798                         (1 << qry.buf_write_timeout_max);
1799
1800                 /* round up when converting to ms */
1801                 info->buffer_write_tout = (tmp + 999) / 1000;
1802                 tmp = (1 << qry.word_write_timeout_typ) *
1803                         (1 << qry.word_write_timeout_max);
1804                 /* round up when converting to ms */
1805                 info->write_tout = (tmp + 999) / 1000;
1806                 info->flash_id = FLASH_MAN_CFI;
1807                 if ((info->interface == FLASH_CFI_X8X16) &&
1808                     (info->chipwidth == FLASH_CFI_BY8)) {
1809                         /* XXX - Need to test on x8/x16 in parallel. */
1810                         info->portwidth >>= 1;
1811                 }
1812         }
1813
1814         flash_write_cmd (info, 0, 0, info->cmd_reset);
1815         return (info->size);
1816 }
1817
1818 /*-----------------------------------------------------------------------
1819  */
1820 unsigned long flash_init (void)
1821 {
1822         unsigned long size = 0;
1823         int i;
1824
1825 #ifdef CFG_FLASH_PROTECTION
1826         char *s = getenv("unlock");
1827 #endif
1828
1829         /* Init: no FLASHes known */
1830         for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
1831                 flash_info[i].flash_id = FLASH_UNKNOWN;
1832
1833                 if (!flash_detect_legacy (bank_base[i], i))
1834                         flash_get_size (bank_base[i], i);
1835                 size += flash_info[i].size;
1836                 if (flash_info[i].flash_id == FLASH_UNKNOWN) {
1837 #ifndef CFG_FLASH_QUIET_TEST
1838                         printf ("## Unknown FLASH on Bank %d "
1839                                 "- Size = 0x%08lx = %ld MB\n",
1840                                 i+1, flash_info[i].size,
1841                                 flash_info[i].size << 20);
1842 #endif /* CFG_FLASH_QUIET_TEST */
1843                 }
1844 #ifdef CFG_FLASH_PROTECTION
1845                 else if ((s != NULL) && (strcmp(s, "yes") == 0)) {
1846                         /*
1847                          * Only the U-Boot image and it's environment
1848                          * is protected, all other sectors are
1849                          * unprotected (unlocked) if flash hardware
1850                          * protection is used (CFG_FLASH_PROTECTION)
1851                          * and the environment variable "unlock" is
1852                          * set to "yes".
1853                          */
1854                         if (flash_info[i].legacy_unlock) {
1855                                 int k;
1856
1857                                 /*
1858                                  * Disable legacy_unlock temporarily,
1859                                  * since flash_real_protect would
1860                                  * relock all other sectors again
1861                                  * otherwise.
1862                                  */
1863                                 flash_info[i].legacy_unlock = 0;
1864
1865                                 /*
1866                                  * Legacy unlocking (e.g. Intel J3) ->
1867                                  * unlock only one sector. This will
1868                                  * unlock all sectors.
1869                                  */
1870                                 flash_real_protect (&flash_info[i], 0, 0);
1871
1872                                 flash_info[i].legacy_unlock = 1;
1873
1874                                 /*
1875                                  * Manually mark other sectors as
1876                                  * unlocked (unprotected)
1877                                  */
1878                                 for (k = 1; k < flash_info[i].sector_count; k++)
1879                                         flash_info[i].protect[k] = 0;
1880                         } else {
1881                                 /*
1882                                  * No legancy unlocking -> unlock all sectors
1883                                  */
1884                                 flash_protect (FLAG_PROTECT_CLEAR,
1885                                                flash_info[i].start[0],
1886                                                flash_info[i].start[0]
1887                                                + flash_info[i].size - 1,
1888                                                &flash_info[i]);
1889                         }
1890                 }
1891 #endif /* CFG_FLASH_PROTECTION */
1892         }
1893
1894         /* Monitor protection ON by default */
1895 #if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
1896         flash_protect (FLAG_PROTECT_SET,
1897                        CFG_MONITOR_BASE,
1898                        CFG_MONITOR_BASE + monitor_flash_len  - 1,
1899                        flash_get_info(CFG_MONITOR_BASE));
1900 #endif
1901
1902         /* Environment protection ON by default */
1903 #ifdef CFG_ENV_IS_IN_FLASH
1904         flash_protect (FLAG_PROTECT_SET,
1905                        CFG_ENV_ADDR,
1906                        CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
1907                        flash_get_info(CFG_ENV_ADDR));
1908 #endif
1909
1910         /* Redundant environment protection ON by default */
1911 #ifdef CFG_ENV_ADDR_REDUND
1912         flash_protect (FLAG_PROTECT_SET,
1913                        CFG_ENV_ADDR_REDUND,
1914                        CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
1915                        flash_get_info(CFG_ENV_ADDR_REDUND));
1916 #endif
1917         return (size);
1918 }
1919
1920 #endif /* CFG_FLASH_CFI */