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