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