Changeset 1115 for trunk/spi25.c
- Timestamp:
- 07/29/10 15:09:18 (22 months ago)
- File:
-
- 1 edited
-
trunk/spi25.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/spi25.c
r1112 r1115 313 313 314 314 /* Prettyprint the status register. Common definitions. */ 315 void spi_prettyprint_status_register_common(uint8_t status) 315 static void spi_prettyprint_status_register_welwip(uint8_t status) 316 { 317 msg_cdbg("Chip status register: Write Enable Latch (WEL) is " 318 "%sset\n", (status & (1 << 1)) ? "" : "not "); 319 msg_cdbg("Chip status register: Write In Progress (WIP/BUSY) is " 320 "%sset\n", (status & (1 << 0)) ? "" : "not "); 321 } 322 323 /* Prettyprint the status register. Common definitions. */ 324 static void spi_prettyprint_status_register_common(uint8_t status) 316 325 { 317 326 msg_cdbg("Chip status register: Bit 5 / Block Protect 3 (BP3) is " … … 323 332 msg_cdbg("Chip status register: Bit 2 / Block Protect 0 (BP0) is " 324 333 "%sset\n", (status & (1 << 2)) ? "" : "not "); 325 msg_cdbg("Chip status register: Write Enable Latch (WEL) is " 326 "%sset\n", (status & (1 << 1)) ? "" : "not "); 327 msg_cdbg("Chip status register: Write In Progress (WIP/BUSY) is " 328 "%sset\n", (status & (1 << 0)) ? "" : "not "); 334 spi_prettyprint_status_register_welwip(status); 329 335 } 330 336 … … 337 343 "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not "); 338 344 spi_prettyprint_status_register_common(status); 345 } 346 347 /* Prettyprint the status register. Common definitions. */ 348 static void spi_prettyprint_status_register_at25_srplepewpp(uint8_t status) 349 { 350 msg_cdbg("Chip status register: Sector Protection Register Lock (SRPL) " 351 "is %sset\n", (status & (1 << 7)) ? "" : "not "); 352 msg_cdbg("Chip status register: Bit 6 " 353 "is %sset\n", (status & (1 << 6)) ? "" : "not "); 354 msg_cdbg("Chip status register: Erase/Program Error (EPE) " 355 "is %sset\n", (status & (1 << 5)) ? "" : "not "); 356 msg_cdbg("Chip status register: WP# pin (WPP) " 357 "is %sactive\n", (status & (1 << 4)) ? "not " : ""); 358 } 359 360 int spi_prettyprint_status_register_at25df(struct flashchip *flash) 361 { 362 uint8_t status; 363 364 status = spi_read_status_register(); 365 msg_cdbg("Chip status register is %02x\n", status); 366 367 spi_prettyprint_status_register_at25_srplepewpp(status); 368 msg_cdbg("Chip status register: Software Protection Status (SWP): "); 369 switch (status & (3 << 2)) { 370 case 0x0 << 2: 371 msg_cdbg("no sectors are protected\n"); 372 break; 373 case 0x1 << 2: 374 msg_cdbg("some sectors are protected\n"); 375 /* FIXME: Read individual Sector Protection Registers. */ 376 break; 377 case 0x3 << 2: 378 msg_cdbg("all sectors are protected\n"); 379 break; 380 default: 381 msg_cdbg("reserved for future use\n"); 382 break; 383 } 384 spi_prettyprint_status_register_welwip(status); 385 return 0; 386 } 387 388 int spi_prettyprint_status_register_at25df_sec(struct flashchip *flash) 389 { 390 /* FIXME: We should check the security lockdown. */ 391 msg_cdbg("Ignoring security lockdown (if present)\n"); 392 msg_cdbg("Ignoring status register byte 2\n"); 393 return spi_prettyprint_status_register_at25df(flash); 394 } 395 396 int spi_prettyprint_status_register_at25f(struct flashchip *flash) 397 { 398 uint8_t status; 399 400 status = spi_read_status_register(); 401 msg_cdbg("Chip status register is %02x\n", status); 402 403 spi_prettyprint_status_register_at25_srplepewpp(status); 404 msg_cdbg("Chip status register: Bit 3 " 405 "is %sset\n", (status & (1 << 3)) ? "" : "not "); 406 msg_cdbg("Chip status register: Block Protect 0 (BP0) is " 407 "%sset, %s sectors are protected\n", 408 (status & (1 << 2)) ? "" : "not ", 409 (status & (1 << 2)) ? "all" : "no"); 410 spi_prettyprint_status_register_welwip(status); 411 return 0; 412 } 413 414 int spi_prettyprint_status_register_at25fs010(struct flashchip *flash) 415 { 416 uint8_t status; 417 418 status = spi_read_status_register(); 419 msg_cdbg("Chip status register is %02x\n", status); 420 421 msg_cdbg("Chip status register: Status Register Write Protect (WPEN) " 422 "is %sset\n", (status & (1 << 7)) ? "" : "not "); 423 msg_cdbg("Chip status register: Bit 6 / Block Protect 4 (BP4) is " 424 "%sset\n", (status & (1 << 6)) ? "" : "not "); 425 msg_cdbg("Chip status register: Bit 5 / Block Protect 3 (BP3) is " 426 "%sset\n", (status & (1 << 5)) ? "" : "not "); 427 msg_cdbg("Chip status register: Bit 4 is " 428 "%sset\n", (status & (1 << 4)) ? "" : "not "); 429 msg_cdbg("Chip status register: Bit 3 / Block Protect 1 (BP1) is " 430 "%sset\n", (status & (1 << 3)) ? "" : "not "); 431 msg_cdbg("Chip status register: Bit 2 / Block Protect 0 (BP0) is " 432 "%sset\n", (status & (1 << 2)) ? "" : "not "); 433 /* FIXME: Pretty-print detailed sector protection status. */ 434 spi_prettyprint_status_register_welwip(status); 435 return 0; 436 } 437 438 int spi_prettyprint_status_register_at25fs040(struct flashchip *flash) 439 { 440 uint8_t status; 441 442 status = spi_read_status_register(); 443 msg_cdbg("Chip status register is %02x\n", status); 444 445 msg_cdbg("Chip status register: Status Register Write Protect (WPEN) " 446 "is %sset\n", (status & (1 << 7)) ? "" : "not "); 447 msg_cdbg("Chip status register: Bit 6 / Block Protect 4 (BP4) is " 448 "%sset\n", (status & (1 << 6)) ? "" : "not "); 449 msg_cdbg("Chip status register: Bit 5 / Block Protect 3 (BP3) is " 450 "%sset\n", (status & (1 << 5)) ? "" : "not "); 451 msg_cdbg("Chip status register: Bit 4 / Block Protect 2 (BP2) is " 452 "%sset\n", (status & (1 << 4)) ? "" : "not "); 453 msg_cdbg("Chip status register: Bit 3 / Block Protect 1 (BP1) is " 454 "%sset\n", (status & (1 << 3)) ? "" : "not "); 455 msg_cdbg("Chip status register: Bit 2 / Block Protect 0 (BP0) is " 456 "%sset\n", (status & (1 << 2)) ? "" : "not "); 457 /* FIXME: Pretty-print detailed sector protection status. */ 458 spi_prettyprint_status_register_welwip(status); 459 return 0; 339 460 } 340 461 … … 733 854 * generic that this... 734 855 */ 735 int spi_write_status_register(int status)856 static int spi_write_status_register_ewsr(struct flashchip *flash, int status) 736 857 { 737 858 int result; 738 859 struct spi_command cmds[] = { 739 860 { 740 /* FIXME:WRSR requires either EWSR or WREN depending on chip type. */861 /* WRSR requires either EWSR or WREN depending on chip type. */ 741 862 .writecnt = JEDEC_EWSR_OUTSIZE, 742 863 .writearr = (const unsigned char[]){ JEDEC_EWSR }, … … 760 881 __func__); 761 882 } 883 /* WRSR performs a self-timed erase before the changes take effect. */ 884 programmer_delay(100 * 1000); 762 885 return result; 886 } 887 888 static int spi_write_status_register_wren(struct flashchip *flash, int status) 889 { 890 int result; 891 struct spi_command cmds[] = { 892 { 893 /* WRSR requires either EWSR or WREN depending on chip type. */ 894 .writecnt = JEDEC_WREN_OUTSIZE, 895 .writearr = (const unsigned char[]){ JEDEC_WREN }, 896 .readcnt = 0, 897 .readarr = NULL, 898 }, { 899 .writecnt = JEDEC_WRSR_OUTSIZE, 900 .writearr = (const unsigned char[]){ JEDEC_WRSR, (unsigned char) status }, 901 .readcnt = 0, 902 .readarr = NULL, 903 }, { 904 .writecnt = 0, 905 .writearr = NULL, 906 .readcnt = 0, 907 .readarr = NULL, 908 }}; 909 910 result = spi_send_multicommand(cmds); 911 if (result) { 912 msg_cerr("%s failed during command execution\n", 913 __func__); 914 } 915 /* WRSR performs a self-timed erase before the changes take effect. */ 916 programmer_delay(100 * 1000); 917 return result; 918 } 919 920 static int spi_write_status_register(struct flashchip *flash, int status) 921 { 922 int ret = 1; 923 924 if (!(flash->feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) { 925 msg_cdbg("Missing status register write definition, assuming " 926 "EWSR is needed\n"); 927 flash->feature_bits |= FEATURE_WRSR_EWSR; 928 } 929 if (flash->feature_bits & FEATURE_WRSR_WREN) 930 ret = spi_write_status_register_wren(flash, status); 931 if (ret && (flash->feature_bits & FEATURE_WRSR_EWSR)) 932 ret = spi_write_status_register_ewsr(flash, status); 933 return ret; 763 934 } 764 935 … … 845 1016 } 846 1017 1018 /* A generic brute-force block protection disable works like this: 1019 * Write 0x00 to the status register. Check if any locks are still set (that 1020 * part is chip specific). Repeat once. 1021 */ 847 1022 int spi_disable_blockprotect(struct flashchip *flash) 848 1023 { … … 851 1026 852 1027 status = spi_read_status_register(); 853 /* If there is block protection in effect, unprotect it first. */ 1028 /* If block protection is disabled, stop here. */ 1029 if ((status & 0x3c) == 0) 1030 return 0; 1031 1032 msg_cdbg("Some block protection in effect, disabling\n"); 1033 result = spi_write_status_register(flash, status & ~0x3c); 1034 if (result) { 1035 msg_cerr("spi_write_status_register failed\n"); 1036 return result; 1037 } 1038 status = spi_read_status_register(); 854 1039 if ((status & 0x3c) != 0) { 855 msg_cdbg("Some block protection in effect, disabling\n"); 856 result = spi_write_status_register(status & ~0x3c); 1040 msg_cerr("Block protection could not be disabled!\n"); 1041 return 1; 1042 } 1043 return 0; 1044 } 1045 1046 int spi_disable_blockprotect_at25df(struct flashchip *flash) 1047 { 1048 uint8_t status; 1049 int result; 1050 1051 status = spi_read_status_register(); 1052 /* If block protection is disabled, stop here. */ 1053 if ((status & (3 << 2)) == 0) 1054 return 0; 1055 1056 msg_cdbg("Some block protection in effect, disabling\n"); 1057 if (status & (1 << 7)) { 1058 msg_cdbg("Need to disable Sector Protection Register Lock\n"); 1059 if ((status & (1 << 4)) == 0) { 1060 msg_cerr("WP# pin is active, disabling " 1061 "write protection is impossible.\n"); 1062 return 1; 1063 } 1064 /* All bits except bit 7 (SPRL) are readonly. */ 1065 result = spi_write_status_register(flash, status & ~(1 << 7)); 857 1066 if (result) { 858 1067 msg_cerr("spi_write_status_register failed\n"); 859 1068 return result; 860 1069 } 861 status = spi_read_status_register(); 862 if ((status & 0x3c) != 0) { 863 msg_cerr("Block protection could not be disabled!\n"); 864 return 1; 1070 1071 } 1072 /* Global unprotect. Make sure to mask SPRL as well. */ 1073 result = spi_write_status_register(flash, status & ~0xbc); 1074 if (result) { 1075 msg_cerr("spi_write_status_register failed\n"); 1076 return result; 1077 } 1078 status = spi_read_status_register(); 1079 if ((status & (3 << 2)) != 0) { 1080 msg_cerr("Block protection could not be disabled!\n"); 1081 return 1; 1082 } 1083 return 0; 1084 } 1085 1086 int spi_disable_blockprotect_at25df_sec(struct flashchip *flash) 1087 { 1088 /* FIXME: We should check the security lockdown. */ 1089 msg_cinfo("Ignoring security lockdown (if present)\n"); 1090 return spi_disable_blockprotect_at25df(flash); 1091 } 1092 1093 int spi_disable_blockprotect_at25f(struct flashchip *flash) 1094 { 1095 /* spi_disable_blockprotect_at25df is not really the right way to do 1096 * this, but the side effects of said function work here as well. 1097 */ 1098 return spi_disable_blockprotect_at25df(flash); 1099 } 1100 1101 int spi_disable_blockprotect_at25fs010(struct flashchip *flash) 1102 { 1103 uint8_t status; 1104 int result; 1105 1106 status = spi_read_status_register(); 1107 /* If block protection is disabled, stop here. */ 1108 if ((status & 0x6c) == 0) 1109 return 0; 1110 1111 msg_cdbg("Some block protection in effect, disabling\n"); 1112 if (status & (1 << 7)) { 1113 msg_cdbg("Need to disable Status Register Write Protect\n"); 1114 /* Clear bit 7 (WPEN). */ 1115 result = spi_write_status_register(flash, status & ~(1 << 7)); 1116 if (result) { 1117 msg_cerr("spi_write_status_register failed\n"); 1118 return result; 865 1119 } 1120 } 1121 /* Global unprotect. Make sure to mask WPEN as well. */ 1122 result = spi_write_status_register(flash, status & ~0xec); 1123 if (result) { 1124 msg_cerr("spi_write_status_register failed\n"); 1125 return result; 1126 } 1127 status = spi_read_status_register(); 1128 if ((status & 0x6c) != 0) { 1129 msg_cerr("Block protection could not be disabled!\n"); 1130 return 1; 1131 } 1132 return 0; 1133 } 1134 int spi_disable_blockprotect_at25fs040(struct flashchip *flash) 1135 { 1136 uint8_t status; 1137 int result; 1138 1139 status = spi_read_status_register(); 1140 /* If block protection is disabled, stop here. */ 1141 if ((status & 0x7c) == 0) 1142 return 0; 1143 1144 msg_cdbg("Some block protection in effect, disabling\n"); 1145 if (status & (1 << 7)) { 1146 msg_cdbg("Need to disable Status Register Write Protect\n"); 1147 /* Clear bit 7 (WPEN). */ 1148 result = spi_write_status_register(flash, status & ~(1 << 7)); 1149 if (result) { 1150 msg_cerr("spi_write_status_register failed\n"); 1151 return result; 1152 } 1153 } 1154 /* Global unprotect. Make sure to mask WPEN as well. */ 1155 result = spi_write_status_register(flash, status & ~0xfc); 1156 if (result) { 1157 msg_cerr("spi_write_status_register failed\n"); 1158 return result; 1159 } 1160 status = spi_read_status_register(); 1161 if ((status & 0x7c) != 0) { 1162 msg_cerr("Block protection could not be disabled!\n"); 1163 return 1; 866 1164 } 867 1165 return 0;
Note: See TracChangeset
for help on using the changeset viewer.
