Changeset 1115


Ignore:
Timestamp:
07/29/10 15:09:18 (18 months ago)
Author:
hailfinger
Message:

Add detailed status register printing and unlocking for all ATMEL AT25*
chips.

Add support for Atmel AT25DF081A and AT25DQ161.

Some chips require EWSR before WRSR, others require WREN before WRSR,
and some support both variants. Add feature_bits to select the correct
SPI command, and default to EWSR.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@…>
Tested-by: Steven Rosario
Acked-by: Uwe Hermann <uwe@…>

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/chipdrivers.h

    r1083 r1115  
    4848int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len); 
    4949uint8_t spi_read_status_register(void); 
     50int spi_prettyprint_status_register_at25df(struct flashchip *flash); 
     51int spi_prettyprint_status_register_at25df_sec(struct flashchip *flash); 
     52int spi_prettyprint_status_register_at25f(struct flashchip *flash); 
     53int spi_prettyprint_status_register_at25fs010(struct flashchip *flash); 
     54int spi_prettyprint_status_register_at25fs040(struct flashchip *flash); 
    5055int spi_disable_blockprotect(struct flashchip *flash); 
     56int spi_disable_blockprotect_at25df(struct flashchip *flash); 
     57int spi_disable_blockprotect_at25df_sec(struct flashchip *flash); 
     58int spi_disable_blockprotect_at25f(struct flashchip *flash); 
     59int spi_disable_blockprotect_at25fs010(struct flashchip *flash); 
     60int spi_disable_blockprotect_at25fs040(struct flashchip *flash); 
    5161int spi_byte_program(int addr, uint8_t databyte); 
    5262int spi_nbyte_program(int addr, uint8_t *bytes, int len); 
  • trunk/flash.h

    r1112 r1115  
    7070/* 
    7171 * How many different erase functions do we have per chip? 
    72  */ 
    73 #define NUM_ERASEFUNCTIONS 5 
     72 * Atmel AT25FS010 has 6 different functions. 
     73 */ 
     74#define NUM_ERASEFUNCTIONS 6 
    7475 
    7576#define FEATURE_REGISTERMAP     (1 << 0) 
     
    8384#define FEATURE_ADDR_AAA        (2 << 2) 
    8485#define FEATURE_ADDR_SHIFTED    (1 << 5) 
     86#define FEATURE_WRSR_EWSR       (1 << 6) 
     87#define FEATURE_WRSR_WREN       (1 << 7) 
     88#define FEATURE_WRSR_EITHER     (FEATURE_WRSR_EWSR | FEATURE_WRSR_WREN) 
    8589 
    8690struct flashchip { 
  • trunk/flashchips.c

    r1114 r1115  
    790790                .total_size     = 256, 
    791791                .page_size      = 256, 
     792                .feature_bits   = FEATURE_WRSR_WREN, 
    792793                .tested         = TEST_UNTESTED, 
    793794                .probe          = probe_spi_rdid, 
     
    812813                        } 
    813814                }, 
    814                 .unlock         = spi_disable_blockprotect, 
     815                .printlock      = spi_prettyprint_status_register_at25df, 
     816                .unlock         = spi_disable_blockprotect_at25df, 
    815817                .write          = spi_chip_write_256, 
    816818                .read           = spi_chip_read, 
     
    825827                .total_size     = 512, 
    826828                .page_size      = 256, 
     829                .feature_bits   = FEATURE_WRSR_WREN, 
    827830                .tested         = TEST_UNTESTED, 
    828831                .probe          = probe_spi_rdid, 
     
    847850                        } 
    848851                }, 
    849                 .unlock         = spi_disable_blockprotect, 
     852                .printlock      = spi_prettyprint_status_register_at25df, 
     853                .unlock         = spi_disable_blockprotect_at25df, 
    850854                .write          = spi_chip_write_256, 
    851855                .read           = spi_chip_read, 
     
    860864                .total_size     = 1024, 
    861865                .page_size      = 256, 
     866                .feature_bits   = FEATURE_WRSR_WREN, 
    862867                .tested         = TEST_UNTESTED, 
    863868                .probe          = probe_spi_rdid, 
     
    882887                        } 
    883888                }, 
    884                 .unlock         = spi_disable_blockprotect, 
     889                .printlock      = spi_prettyprint_status_register_at25df, 
     890                .unlock         = spi_disable_blockprotect_at25df, 
     891                .write          = spi_chip_write_256, 
     892                .read           = spi_chip_read, 
     893        }, 
     894 
     895        { 
     896                .vendor         = "Atmel", 
     897                .name           = "AT25DF081A", 
     898                .bustype        = CHIP_BUSTYPE_SPI, 
     899                .manufacture_id = ATMEL_ID, 
     900                .model_id       = AT_25DF081A, 
     901                .total_size     = 1024, 
     902                .page_size      = 256, 
     903                .feature_bits   = FEATURE_WRSR_WREN, 
     904                .tested         = TEST_UNTESTED, 
     905                .probe          = probe_spi_rdid, 
     906                .probe_timing   = TIMING_ZERO, 
     907                .block_erasers  = 
     908                { 
     909                        { 
     910                                .eraseblocks = { {4 * 1024, 256} }, 
     911                                .block_erase = spi_block_erase_20, 
     912                        }, { 
     913                                .eraseblocks = { {32 * 1024, 32} }, 
     914                                .block_erase = spi_block_erase_52, 
     915                        }, { 
     916                                .eraseblocks = { {64 * 1024, 16} }, 
     917                                .block_erase = spi_block_erase_d8, 
     918                        }, { 
     919                                .eraseblocks = { {1024 * 1024, 1} }, 
     920                                .block_erase = spi_block_erase_60, 
     921                        }, { 
     922                                .eraseblocks = { {1024 * 1024, 1} }, 
     923                                .block_erase = spi_block_erase_c7, 
     924                        } 
     925                }, 
     926                .printlock      = spi_prettyprint_status_register_at25df_sec, 
     927                .unlock         = spi_disable_blockprotect_at25df_sec, 
    885928                .write          = spi_chip_write_256, 
    886929                .read           = spi_chip_read, 
     
    895938                .total_size     = 2048, 
    896939                .page_size      = 256, 
     940                .feature_bits   = FEATURE_WRSR_WREN, 
    897941                .tested         = TEST_UNTESTED, 
    898942                .probe          = probe_spi_rdid, 
     
    917961                        } 
    918962                }, 
    919                 .unlock         = spi_disable_blockprotect, 
     963                .printlock      = spi_prettyprint_status_register_at25df_sec, 
     964                .unlock         = spi_disable_blockprotect_at25df_sec, 
    920965                .write          = spi_chip_write_256, 
    921966                .read           = spi_chip_read, 
     
    930975                .total_size     = 4096, 
    931976                .page_size      = 256, 
     977                .feature_bits   = FEATURE_WRSR_WREN, 
    932978                .tested         = TEST_OK_PRW, 
    933979                .probe          = probe_spi_rdid, 
     
    952998                        } 
    953999                }, 
    954                 .unlock         = spi_disable_blockprotect, 
     1000                .printlock      = spi_prettyprint_status_register_at25df, 
     1001                .unlock         = spi_disable_blockprotect_at25df, 
    9551002                .write          = spi_chip_write_256, 
    9561003                .read           = spi_chip_read, 
     
    9651012                .total_size     = 4096, 
    9661013                .page_size      = 256, 
     1014                .feature_bits   = FEATURE_WRSR_WREN, 
    9671015                .tested         = TEST_UNTESTED, 
    9681016                .probe          = probe_spi_rdid, 
     
    9871035                        } 
    9881036                }, 
    989                 .unlock         = spi_disable_blockprotect, 
     1037                .printlock      = spi_prettyprint_status_register_at25df_sec, 
     1038                .unlock         = spi_disable_blockprotect_at25df_sec, 
    9901039                .write          = spi_chip_write_256, 
    9911040                .read           = spi_chip_read, 
     
    10001049                .total_size     = 8192, 
    10011050                .page_size      = 256, 
     1051                .feature_bits   = FEATURE_WRSR_WREN, 
    10021052                .tested         = TEST_UNTESTED, 
    10031053                .probe          = probe_spi_rdid, 
     
    10221072                        } 
    10231073                }, 
    1024                 .unlock         = spi_disable_blockprotect, 
     1074                .printlock      = spi_prettyprint_status_register_at25df_sec, 
     1075                .unlock         = spi_disable_blockprotect_at25df_sec, 
     1076                .write          = spi_chip_write_256, 
     1077                .read           = spi_chip_read, 
     1078        }, 
     1079 
     1080        { 
     1081                .vendor         = "Atmel", 
     1082                .name           = "AT25DQ161", 
     1083                .bustype        = CHIP_BUSTYPE_SPI, 
     1084                .manufacture_id = ATMEL_ID, 
     1085                .model_id       = AT_25DQ161, 
     1086                .total_size     = 2048, 
     1087                .page_size      = 256, 
     1088                .feature_bits   = FEATURE_WRSR_WREN, 
     1089                .tested         = TEST_UNTESTED, 
     1090                .probe          = probe_spi_rdid, 
     1091                .probe_timing   = TIMING_ZERO, 
     1092                .block_erasers  = 
     1093                { 
     1094                        { 
     1095                                .eraseblocks = { {4 * 1024, 512} }, 
     1096                                .block_erase = spi_block_erase_20, 
     1097                        }, { 
     1098                                .eraseblocks = { {32 * 1024, 64} }, 
     1099                                .block_erase = spi_block_erase_52, 
     1100                        }, { 
     1101                                .eraseblocks = { {64 * 1024, 32} }, 
     1102                                .block_erase = spi_block_erase_d8, 
     1103                        }, { 
     1104                                .eraseblocks = { {2 * 1024 * 1024, 1} }, 
     1105                                .block_erase = spi_block_erase_60, 
     1106                        }, { 
     1107                                .eraseblocks = { {2 * 1024 * 1024, 1} }, 
     1108                                .block_erase = spi_block_erase_c7, 
     1109                        } 
     1110                }, 
     1111                .printlock      = spi_prettyprint_status_register_at25df_sec, 
     1112                .unlock         = spi_disable_blockprotect_at25df_sec, 
    10251113                .write          = spi_chip_write_256, 
    10261114                .read           = spi_chip_read, 
     
    10351123                .total_size     = 64, 
    10361124                .page_size      = 256, 
     1125                .feature_bits   = FEATURE_WRSR_WREN, 
    10371126                .tested         = TEST_UNTESTED, 
    10381127                .probe          = probe_spi_rdid, 
     
    10571146                        } 
    10581147                }, 
    1059                 .unlock         = spi_disable_blockprotect, 
     1148                .printlock      = spi_prettyprint_status_register_at25f, 
     1149                .unlock         = spi_disable_blockprotect_at25f, 
    10601150                .write          = spi_chip_write_256, 
    10611151                .read           = spi_chip_read, 
     
    10791169                                .block_erase = spi_block_erase_20, 
    10801170                        }, { 
     1171                                .eraseblocks = { {4 * 1024, 32} }, 
     1172                                .block_erase = spi_block_erase_d7, 
     1173                        }, { 
    10811174                                .eraseblocks = { {32 * 1024, 4} }, 
    10821175                                .block_erase = spi_block_erase_52, 
     
    10921185                        } 
    10931186                }, 
    1094                 .unlock         = spi_disable_blockprotect, 
     1187                .printlock      = spi_prettyprint_status_register_at25fs010, 
     1188                .unlock         = spi_disable_blockprotect_at25fs010, 
    10951189                .write          = spi_chip_write_256, 
    10961190                .read           = spi_chip_read, 
     
    11271221                        } 
    11281222                }, 
    1129                 .unlock         = spi_disable_blockprotect, 
     1223                .printlock      = spi_prettyprint_status_register_at25fs040, 
     1224                .unlock         = spi_disable_blockprotect_at25fs040, 
    11301225                .write          = spi_chip_write_256, 
    11311226                .read           = spi_chip_read, 
  • trunk/flashchips.h

    r1097 r1115  
    111111#define AT_25DF041A             0x4401 
    112112#define AT_25DF081              0x4502 
     113#define AT_25DF081A             0x4501  /* Yes, 81A has a lower number than 81 */ 
    113114#define AT_25DF161              0x4602 
    114115#define AT_25DF321              0x4700  /* Same as 26DF321 */ 
    115116#define AT_25DF321A             0x4701 
    116117#define AT_25DF641              0x4800 
    117 #define AT_25F512A              0x65 /* Needs special RDID. AT25F512A_RDID 15 1d */ 
     118#define AT_25DQ161              0x8600 
     119#define AT25F512                /* No device ID found in datasheet. Vendor ID 
     120                                 * can be read with AT25F512A_RDID */ 
     121#define AT_25F512A              0x65 /* Needs AT25F512A_RDID */ 
    118122#define AT_25F512B              0x6500 
     123#define AT25F1024               /* No device ID found in datasheet. Vendor ID 
     124                                 * can be read with AT25F512A_RDID */ 
     125#define AT_25F1024A             0x60 /* Needs AT25F512A_RDID */ 
    119126#define AT_25FS010              0x6601 
    120127#define AT_25FS040              0x6604 
  • trunk/spi.c

    r1113 r1115  
    3030 
    3131enum spi_controller spi_controller = SPI_CONTROLLER_NONE; 
    32  
    33 void spi_prettyprint_status_register(struct flashchip *flash); 
    3432 
    3533const struct spi_programmer spi_programmer[] = { 
  • trunk/spi.h

    r1052 r1115  
    3232 
    3333/* AT25F512A has bit 3 as don't care bit in commands */ 
    34 #define AT25F512A_RDID          0x15 
     34#define AT25F512A_RDID          0x15    /* 0x15 or 0x1d */ 
    3535#define AT25F512A_RDID_OUTSIZE  0x01 
    3636#define AT25F512A_RDID_INSIZE   0x02 
     
    124124#define SPI_INVALID_ADDRESS     -3 
    125125#define SPI_INVALID_LENGTH      -4 
     126#define SPI_FLASHROM_BUG        -5 
    126127 
    127128#endif          /* !__SPI_H__ */ 
  • trunk/spi25.c

    r1112 r1115  
    313313 
    314314/* Prettyprint the status register. Common definitions. */ 
    315 void spi_prettyprint_status_register_common(uint8_t status) 
     315static 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. */ 
     324static void spi_prettyprint_status_register_common(uint8_t status) 
    316325{ 
    317326        msg_cdbg("Chip status register: Bit 5 / Block Protect 3 (BP3) is " 
     
    323332        msg_cdbg("Chip status register: Bit 2 / Block Protect 0 (BP0) is " 
    324333                     "%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); 
    329335} 
    330336 
     
    337343                     "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not "); 
    338344        spi_prettyprint_status_register_common(status); 
     345} 
     346 
     347/* Prettyprint the status register. Common definitions. */ 
     348static 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 
     360int 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 
     388int 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 
     396int 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 
     414int 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 
     438int 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; 
    339460} 
    340461 
     
    733854 * generic that this... 
    734855 */ 
    735 int spi_write_status_register(int status) 
     856static int spi_write_status_register_ewsr(struct flashchip *flash, int status) 
    736857{ 
    737858        int result; 
    738859        struct spi_command cmds[] = { 
    739860        { 
    740         /* FIXME: WRSR requires either EWSR or WREN depending on chip type. */ 
     861        /* WRSR requires either EWSR or WREN depending on chip type. */ 
    741862                .writecnt       = JEDEC_EWSR_OUTSIZE, 
    742863                .writearr       = (const unsigned char[]){ JEDEC_EWSR }, 
     
    760881                        __func__); 
    761882        } 
     883        /* WRSR performs a self-timed erase before the changes take effect. */ 
     884        programmer_delay(100 * 1000); 
    762885        return result; 
     886} 
     887 
     888static 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 
     920static 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; 
    763934} 
    764935 
     
    8451016} 
    8461017 
     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 */ 
    8471022int spi_disable_blockprotect(struct flashchip *flash) 
    8481023{ 
     
    8511026 
    8521027        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(); 
    8541039        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 
     1046int 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)); 
    8571066                if (result) { 
    8581067                        msg_cerr("spi_write_status_register failed\n"); 
    8591068                        return result; 
    8601069                } 
    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 
     1086int 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 
     1093int 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 
     1101int 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; 
    8651119                } 
     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} 
     1134int 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; 
    8661164        } 
    8671165        return 0; 
Note: See TracChangeset for help on using the changeset viewer.