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