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