Nico Huber has uploaded this change for review. ( https://review.coreboot.org/22388
Change subject: spi25: Merge remainder of spi4ba in ......................................................................
spi25: Merge remainder of spi4ba in
Change-Id: If581e24347e45cbb27002ea99ffd70e334c110cf Signed-off-by: Nico Huber nico.h@gmx.de --- M Makefile M chipdrivers.h M flashchips.c M spi.h M spi25.c D spi4ba.c D spi4ba.h 7 files changed, 119 insertions(+), 466 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/88/22388/1
diff --git a/Makefile b/Makefile index 5bd7158..2f9a25f 100644 --- a/Makefile +++ b/Makefile @@ -514,7 +514,7 @@ CHIP_OBJS = jedec.o stm50.o w39.o w29ee011.o \ sst28sf040.o 82802ab.o \ sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o spi25_statusreg.o \ - spi4ba.o opaque.o sfdp.o en29lv640b.o at45db.o + opaque.o sfdp.o en29lv640b.o at45db.o
############################################################################### # Library code. diff --git a/chipdrivers.h b/chipdrivers.h index 12fc5a3..d7a4aa9 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -43,8 +43,10 @@ int spi_write_enable(struct flashctx *flash); int spi_write_disable(struct flashctx *flash); int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_21(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_5c(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int blocklen); @@ -53,11 +55,17 @@ int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int blocklen); int spi_block_erase_db(struct flashctx *flash, unsigned int addr, unsigned int blocklen); +int spi_block_erase_dc(struct flashctx *flash, unsigned int addr, unsigned int blocklen); erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode); int spi_chip_write_1(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int spi_nbyte_read(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len); int spi_read_chunked(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize); int spi_write_chunked(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len, unsigned int chunksize); +int spi_enter_4ba_b7(struct flashctx *flash); +int spi_enter_4ba_b7_we(struct flashctx *flash); +int spi_exit_4ba_e9(struct flashctx *flash); +int spi_exit_4ba_e9_we(struct flashctx *flash); +
/* spi25_statusreg.c */ uint8_t spi_read_status_register(struct flashctx *flash); @@ -192,29 +200,5 @@ /* en29lv640b.c */ int probe_en29lv640b(struct flashctx *flash); int write_en29lv640b(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); - -/* spi4ba.c */ -int spi_enter_4ba_b7(struct flashctx *flash); -int spi_enter_4ba_b7_we(struct flashctx *flash); -int spi_exit_4ba_e9(struct flashctx *flash); -int spi_exit_4ba_e9_we(struct flashctx *flash); -int spi_byte_program_4ba(struct flashctx *flash, unsigned int addr, uint8_t databyte); -int spi_nbyte_program_4ba(struct flashctx *flash, unsigned int addr, const uint8_t *bytes, unsigned int len); -int spi_nbyte_read_4ba(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len); -int spi_block_erase_20_4ba(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_52_4ba(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_d8_4ba(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_byte_program_4ba_ereg(struct flashctx *flash, unsigned int addr, uint8_t databyte); -int spi_nbyte_program_4ba_ereg(struct flashctx *flash, unsigned int addr, const uint8_t *bytes, unsigned int len); -int spi_nbyte_read_4ba_ereg(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len); -int spi_block_erase_20_4ba_ereg(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_52_4ba_ereg(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_d8_4ba_ereg(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_byte_program_4ba_direct(struct flashctx *flash, unsigned int addr, uint8_t databyte); -int spi_nbyte_program_4ba_direct(struct flashctx *flash, unsigned int addr, const uint8_t *bytes, unsigned int len); -int spi_nbyte_read_4ba_direct(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len); -int spi_block_erase_21_4ba_direct(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_5c_4ba_direct(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_dc_4ba_direct(struct flashctx *flash, unsigned int addr, unsigned int blocklen);
#endif /* !__CHIPDRIVERS_H__ */ diff --git a/flashchips.c b/flashchips.c index 34bce06..a14d514 100644 --- a/flashchips.c +++ b/flashchips.c @@ -9853,10 +9853,10 @@ .block_erasers = { { .eraseblocks = { {4 * 1024, 8192} }, - .block_erase = spi_block_erase_21_4ba_direct, + .block_erase = spi_block_erase_21, }, { .eraseblocks = { {64 * 1024, 512} }, - .block_erase = spi_block_erase_dc_4ba_direct, + .block_erase = spi_block_erase_dc, }, { .eraseblocks = { {32768 * 1024, 1} }, .block_erase = spi_block_erase_c7, @@ -9886,10 +9886,10 @@ .block_erasers = { { .eraseblocks = { {4 * 1024, 16384} }, - .block_erase = spi_block_erase_21_4ba_direct, + .block_erase = spi_block_erase_21, }, { .eraseblocks = { {64 * 1024, 1024} }, - .block_erase = spi_block_erase_dc_4ba_direct, + .block_erase = spi_block_erase_dc, }, { .eraseblocks = { {65536 * 1024, 1} }, .block_erase = spi_block_erase_c7, diff --git a/spi.h b/spi.h index 41b0245..4da7b73 100644 --- a/spi.h +++ b/spi.h @@ -138,6 +138,18 @@ #define JEDEC_WRSR_OUTSIZE 0x02 #define JEDEC_WRSR_INSIZE 0x00
+/* Enter 4-byte Address Mode */ +#define JEDEC_ENTER_4_BYTE_ADDR_MODE 0xB7 + +/* Exit 4-byte Address Mode */ +#define JEDEC_EXIT_4_BYTE_ADDR_MODE 0xE9 + +/* Write Extended Address Register */ +#define JEDEC_WRITE_EXT_ADDR_REG 0xC5 + +/* Read Extended Address Register */ +#define JEDEC_READ_EXT_ADDR_REG 0xC8 + /* Read the memory */ #define JEDEC_READ 0x03 #define JEDEC_READ_OUTSIZE 0x04 @@ -154,6 +166,14 @@ #define JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE 0x03 #define JEDEC_AAI_WORD_PROGRAM_INSIZE 0x00
+/* Read the memory with 4-byte address + From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ +#define JEDEC_READ_4BA 0x13 + +/* Write memory byte with 4-byte address + From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ +#define JEDEC_BYTE_PROGRAM_4BA 0x12 + /* Error codes */ #define SPI_GENERIC_ERROR -1 #define SPI_INVALID_OPCODE -2 diff --git a/spi25.c b/spi25.c index 41e3429..df0ebbe 100644 --- a/spi25.c +++ b/spi25.c @@ -30,7 +30,6 @@ #include "chipdrivers.h" #include "programmer.h" #include "spi.h" -#include "spi4ba.h"
static int spi_rdid(struct flashctx *flash, unsigned char *readarr, int bytes) { @@ -364,6 +363,25 @@ return result ? result : status; }
+static int spi_write_extended_address_register(struct flashctx *const flash, const uint8_t regdata) +{ + struct spi_command cmds[] = { + { + .writecnt = 1, + .writearr = (const unsigned char[]){ JEDEC_WREN }, + }, { + .writecnt = 2, + .writearr = (const unsigned char[]){ JEDEC_WRITE_EXT_ADDR_REG, regdata }, + }, + NULL_SPI_CMD, + }; + + const int result = spi_send_multicommand(flash, cmds); + if (result) + msg_cerr("%s failed during command execution\n", __func__); + return result; +} + static int spi_set_extended_address(struct flashctx *const flash, const uint8_t addr_high) { if (flash->address_high_byte != addr_high && @@ -565,6 +583,27 @@ return spi_chip_erase_c7(flash); }
+/* Erase 4 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) */ +int spi_block_erase_21(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +{ + /* This usually takes 15-800ms, so wait in 10ms steps. */ + return spi_write_cmd(flash, 0x21, true, addr, NULL, 0, 10 * 1000); +} + +/* Erase 32 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) */ +int spi_block_erase_5c(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +{ + /* This usually takes 100-4000ms, so wait in 100ms steps. */ + return spi_write_cmd(flash, 0x5c, true, addr, NULL, 0, 100 * 1000); +} + +/* Erase 64 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) */ +int spi_block_erase_dc(struct flashctx *flash, unsigned int addr, unsigned int blocklen) +{ + /* This usually takes 100-4000ms, so wait in 100ms steps. */ + return spi_write_cmd(flash, 0xdc, true, addr, NULL, 0, 100 * 1000); +} + erasefunc_t *spi_get_erasefn_from_opcode(uint8_t opcode) { switch(opcode){ @@ -574,10 +613,14 @@ return NULL; case 0x20: return &spi_block_erase_20; + case 0x21: + return &spi_block_erase_21; case 0x50: return &spi_block_erase_50; case 0x52: return &spi_block_erase_52; + case 0x5c: + return &spi_block_erase_5c; case 0x60: return &spi_block_erase_60; case 0x62: @@ -594,6 +637,8 @@ return &spi_block_erase_d8; case 0xdb: return &spi_block_erase_db; + case 0xdc: + return &spi_block_erase_dc; default: msg_cinfo("%s: unknown erase opcode (0x%02x). Please report " "this at flashrom@flashrom.org\n", __func__, opcode); @@ -812,3 +857,43 @@ msg_cerr("%s failed to disable AAI mode.\n", __func__); return SPI_GENERIC_ERROR; } + +/* Enter 4-bytes addressing mode (without sending WREN before) */ +int spi_enter_4ba_b7(struct flashctx *flash) +{ + const unsigned char cmd = JEDEC_ENTER_4_BYTE_ADDR_MODE; + + const int ret = spi_send_command(flash, sizeof(cmd), 0, &cmd, NULL); + if (!ret) + flash->in_4ba_mode = true; + return ret; +} + +/* Enter 4-bytes addressing mode with sending WREN before */ +int spi_enter_4ba_b7_we(struct flashctx *flash) +{ + const int ret = spi_simple_write_cmd(flash, JEDEC_ENTER_4_BYTE_ADDR_MODE, 0); + if (!ret) + flash->in_4ba_mode = true; + return ret; +} + +/* Exit 4-bytes addressing mode (without sending WREN before) */ +int spi_exit_4ba_e9(struct flashctx *flash) +{ + const unsigned char cmd = JEDEC_EXIT_4_BYTE_ADDR_MODE; + + const int ret = spi_send_command(flash, sizeof(cmd), 0, &cmd, NULL); + if (!ret) + flash->in_4ba_mode = false; + return ret; +} + +/* Exit 4-bytes addressing mode with sending WREN before */ +int spi_exit_4ba_e9_we(struct flashctx *flash) +{ + const int ret = spi_simple_write_cmd(flash, JEDEC_EXIT_4_BYTE_ADDR_MODE, 0); + if (!ret) + flash->in_4ba_mode = false; + return ret; +} diff --git a/spi4ba.c b/spi4ba.c deleted file mode 100644 index 8cce3c6..0000000 --- a/spi4ba.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * This file is part of the flashrom project. - * - * Copyright (C) 2014 Boris Baykov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * SPI chip driver functions for 4-bytes addressing - */ - -#include <string.h> -#include "flash.h" -#include "chipdrivers.h" -#include "spi.h" -#include "programmer.h" -#include "spi4ba.h" - -/* #define MSG_TRACE_4BA_FUNCS 1 */ - -#ifdef MSG_TRACE_4BA_FUNCS -#define msg_trace(...) print(MSG_DEBUG, __VA_ARGS__) -#else -#define msg_trace(...) -#endif - -/* Enter 4-bytes addressing mode (without sending WREN before) */ -int spi_enter_4ba_b7(struct flashctx *flash) -{ - int result; - const unsigned char cmd[JEDEC_ENTER_4_BYTE_ADDR_MODE_OUTSIZE] = { JEDEC_ENTER_4_BYTE_ADDR_MODE }; - - msg_trace("-> %s\n", __func__); - - /* Switch to 4-bytes addressing mode */ - result = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL); - if (!result) - flash->in_4ba_mode = true; - - return result; -} - -/* Enter 4-bytes addressing mode with sending WREN before */ -int spi_enter_4ba_b7_we(struct flashctx *flash) -{ - int result; - struct spi_command cmds[] = { - { - .writecnt = JEDEC_WREN_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_WREN }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = JEDEC_ENTER_4_BYTE_ADDR_MODE_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_ENTER_4_BYTE_ADDR_MODE }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = 0, - .writearr = NULL, - .readcnt = 0, - .readarr = NULL, - }}; - - msg_trace("-> %s\n", __func__); - - /* Switch to 4-bytes addressing mode */ - result = spi_send_multicommand(flash, cmds); - if (result) - msg_cerr("%s failed during command execution\n", __func__); - else - flash->in_4ba_mode = true; - return result; -} - -/* Exit 4-bytes addressing mode (without sending WREN before) */ -int spi_exit_4ba_e9(struct flashctx *flash) -{ - int result; - const unsigned char cmd[JEDEC_EXIT_4_BYTE_ADDR_MODE_OUTSIZE] = { JEDEC_EXIT_4_BYTE_ADDR_MODE }; - - msg_trace("-> %s\n", __func__); - - /* Switch to 3-bytes addressing mode */ - result = spi_send_command(flash, sizeof(cmd), 0, cmd, NULL); - if (!result) - flash->in_4ba_mode = false; - - return result; -} - -/* Exit 4-bytes addressing mode with sending WREN before */ -int spi_exit_4ba_e9_we(struct flashctx *flash) -{ - int result; - struct spi_command cmds[] = { - { - .writecnt = JEDEC_WREN_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_WREN }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = JEDEC_EXIT_4_BYTE_ADDR_MODE_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_EXIT_4_BYTE_ADDR_MODE }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = 0, - .writearr = NULL, - .readcnt = 0, - .readarr = NULL, - }}; - - msg_trace("-> %s\n", __func__); - - /* Switch to 3-bytes addressing mode */ - result = spi_send_multicommand(flash, cmds); - if (result) - msg_cerr("%s failed during command execution\n", __func__); - else - flash->in_4ba_mode = false; - return result; -} - -/* Write Extended Address Register value */ -int spi_write_extended_address_register(struct flashctx *flash, uint8_t regdata) -{ - int result; - struct spi_command cmds[] = { - { - .writecnt = JEDEC_WREN_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_WREN }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = JEDEC_WRITE_EXT_ADDR_REG_OUTSIZE, - .writearr = (const unsigned char[]){ - JEDEC_WRITE_EXT_ADDR_REG, - regdata - }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = 0, - .writearr = NULL, - .readcnt = 0, - .readarr = NULL, - }}; - - msg_trace("-> %s (%02X)\n", __func__, regdata); - - result = spi_send_multicommand(flash, cmds); - if (result) { - msg_cerr("%s failed during command execution\n", __func__); - return result; - } - return 0; -} - -/* Erase 4 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) - JEDEC_SE_4BA (21h) instruction is new for 4-bytes addressing flash chips. - The presence of this instruction for an exact chip should be checked - by its datasheet or from SFDP 4-Bytes Address Instruction Table (JESD216B). */ -int spi_block_erase_21_4ba_direct(struct flashctx *flash, unsigned int addr, - unsigned int blocklen) -{ - int result; - struct spi_command cmds[] = { - { - .writecnt = JEDEC_WREN_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_WREN }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = JEDEC_SE_4BA_OUTSIZE, - .writearr = (const unsigned char[]){ - JEDEC_SE_4BA, - (addr >> 24) & 0xff, - (addr >> 16) & 0xff, - (addr >> 8) & 0xff, - (addr & 0xff) - }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = 0, - .writearr = NULL, - .readcnt = 0, - .readarr = NULL, - }}; - - msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1); - - result = spi_send_multicommand(flash, cmds); - if (result) { - msg_cerr("%s failed during command execution at address 0x%x\n", - __func__, addr); - return result; - } - /* Wait until the Write-In-Progress bit is cleared. - * This usually takes 15-800 ms, so wait in 10 ms steps. - */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(10 * 1000); - /* FIXME: Check the status register for errors. */ - return 0; -} - -/* Erase 32 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) - JEDEC_BE_5C_4BA (5Ch) instruction is new for 4-bytes addressing flash chips. - The presence of this instruction for an exact chip should be checked - by its datasheet or from SFDP 4-Bytes Address Instruction Table (JESD216B). */ -int spi_block_erase_5c_4ba_direct(struct flashctx *flash, unsigned int addr, - unsigned int blocklen) -{ - int result; - struct spi_command cmds[] = { - { - .writecnt = JEDEC_WREN_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_WREN }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = JEDEC_BE_5C_4BA_OUTSIZE, - .writearr = (const unsigned char[]){ - JEDEC_BE_5C_4BA, - (addr >> 24) & 0xff, - (addr >> 16) & 0xff, - (addr >> 8) & 0xff, - (addr & 0xff) - }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = 0, - .writearr = NULL, - .readcnt = 0, - .readarr = NULL, - }}; - - msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1); - - result = spi_send_multicommand(flash, cmds); - if (result) { - msg_cerr("%s failed during command execution at address 0x%x\n", - __func__, addr); - return result; - } - /* Wait until the Write-In-Progress bit is cleared. - * This usually takes 100-4000 ms, so wait in 100 ms steps. - */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(100 * 1000); - /* FIXME: Check the status register for errors. */ - return 0; -} - -/* Erase 64 KB of flash with 4-bytes address from ANY mode (3-bytes or 4-bytes) - JEDEC_BE_DC_4BA (DCh) instruction is new for 4-bytes addressing flash chips. - The presence of this instruction for an exact chip should be checked - by its datasheet or from SFDP 4-Bytes Address Instruction Table (JESD216B). */ -int spi_block_erase_dc_4ba_direct(struct flashctx *flash, unsigned int addr, - unsigned int blocklen) -{ - int result; - struct spi_command cmds[] = { - { - .writecnt = JEDEC_WREN_OUTSIZE, - .writearr = (const unsigned char[]){ JEDEC_WREN }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = JEDEC_BE_DC_4BA_OUTSIZE, - .writearr = (const unsigned char[]){ - JEDEC_BE_DC_4BA, - (addr >> 24) & 0xff, - (addr >> 16) & 0xff, - (addr >> 8) & 0xff, - (addr & 0xff) - }, - .readcnt = 0, - .readarr = NULL, - }, { - .writecnt = 0, - .writearr = NULL, - .readcnt = 0, - .readarr = NULL, - }}; - - msg_trace("-> %s (0x%08X-0x%08X)\n", __func__, addr, addr + blocklen - 1); - - result = spi_send_multicommand(flash, cmds); - if (result) { - msg_cerr("%s failed during command execution at address 0x%x\n", - __func__, addr); - return result; - } - /* Wait until the Write-In-Progress bit is cleared. - * This usually takes 100-4000 ms, so wait in 100 ms steps. - */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(100 * 1000); - /* FIXME: Check the status register for errors. */ - return 0; -} diff --git a/spi4ba.h b/spi4ba.h deleted file mode 100644 index a0316bc..0000000 --- a/spi4ba.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This file is part of the flashrom project. - * - * Copyright (C) 2014 Boris Baykov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* - * JEDEC flash chips instructions for 4-bytes addressing - * SPI chip driver functions for 4-bytes addressing - */ - -#ifndef __SPI_4BA_H__ -#define __SPI_4BA_H__ 1 - -/* Enter 4-byte Address Mode */ -#define JEDEC_ENTER_4_BYTE_ADDR_MODE 0xB7 -#define JEDEC_ENTER_4_BYTE_ADDR_MODE_OUTSIZE 0x01 -#define JEDEC_ENTER_4_BYTE_ADDR_MODE_INSIZE 0x00 - -/* Exit 4-byte Address Mode */ -#define JEDEC_EXIT_4_BYTE_ADDR_MODE 0xE9 -#define JEDEC_EXIT_4_BYTE_ADDR_MODE_OUTSIZE 0x01 -#define JEDEC_EXIT_4_BYTE_ADDR_MODE_INSIZE 0x00 - -/* Write Extended Address Register */ -#define JEDEC_WRITE_EXT_ADDR_REG 0xC5 -#define JEDEC_WRITE_EXT_ADDR_REG_OUTSIZE 0x02 -#define JEDEC_WRITE_EXT_ADDR_REG_INSIZE 0x00 - -/* Read Extended Address Register */ -#define JEDEC_READ_EXT_ADDR_REG 0xC8 -#define JEDEC_READ_EXT_ADDR_REG_OUTSIZE 0x01 -#define JEDEC_READ_EXT_ADDR_REG_INSIZE 0x01 - -/* Read the memory with 4-byte address - From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ -#define JEDEC_READ_4BA 0x13 -#define JEDEC_READ_4BA_OUTSIZE 0x05 -/* JEDEC_READ_4BA_INSIZE : any length */ - -/* Write memory byte with 4-byte address - From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ -#define JEDEC_BYTE_PROGRAM_4BA 0x12 -#define JEDEC_BYTE_PROGRAM_4BA_OUTSIZE 0x06 -#define JEDEC_BYTE_PROGRAM_4BA_INSIZE 0x00 - -/* Sector Erase 0x21 (with 4-byte address), usually 4k size. - From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ -#define JEDEC_SE_4BA 0x21 -#define JEDEC_SE_4BA_OUTSIZE 0x05 -#define JEDEC_SE_4BA_INSIZE 0x00 - -/* Block Erase 0x5C (with 4-byte address), usually 32k size. - From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ -#define JEDEC_BE_5C_4BA 0x5C -#define JEDEC_BE_5C_4BA_OUTSIZE 0x05 -#define JEDEC_BE_5C_4BA_INSIZE 0x00 - -/* Block Erase 0xDC (with 4-byte address), usually 64k size. - From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */ -#define JEDEC_BE_DC_4BA 0xdc -#define JEDEC_BE_DC_4BA_OUTSIZE 0x05 -#define JEDEC_BE_DC_4BA_INSIZE 0x00 - -/* enter 4-bytes addressing mode */ -int spi_enter_4ba_b7(struct flashctx *flash); -int spi_enter_4ba_b7_we(struct flashctx *flash); - -/* exit 4-bytes addressing mode */ -int spi_exit_4ba_e9(struct flashctx *flash); -int spi_exit_4ba_e9_we(struct flashctx *flash); - -/* read/write flash bytes in 4-bytes addressing mode */ -int spi_byte_program_4ba(struct flashctx *flash, unsigned int addr, uint8_t databyte); -int spi_nbyte_program_4ba(struct flashctx *flash, unsigned int addr, const uint8_t *bytes, unsigned int len); -int spi_nbyte_read_4ba(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len); - -/* erase flash bytes in 4-bytes addressing mode */ -int spi_block_erase_20_4ba(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_52_4ba(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_d8_4ba(struct flashctx *flash, unsigned int addr, unsigned int blocklen); - -/* read/write flash bytes from 3-bytes addressing mode using extended address register */ -int spi_byte_program_4ba_ereg(struct flashctx *flash, unsigned int addr, uint8_t databyte); -int spi_nbyte_program_4ba_ereg(struct flashctx *flash, unsigned int addr, const uint8_t *bytes, unsigned int len); -int spi_nbyte_read_4ba_ereg(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len); - -/* erase flash bytes from 3-bytes addressing mode using extended address register */ -int spi_block_erase_20_4ba_ereg(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_52_4ba_ereg(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_d8_4ba_ereg(struct flashctx *flash, unsigned int addr, unsigned int blocklen); - -/* read/write flash bytes with 4-bytes address from any mode (3-byte or 4-byte) */ -int spi_byte_program_4ba_direct(struct flashctx *flash, unsigned int addr, uint8_t databyte); -int spi_nbyte_program_4ba_direct(struct flashctx *flash, unsigned int addr, const uint8_t *bytes, unsigned int len); -int spi_nbyte_read_4ba_direct(struct flashctx *flash, unsigned int addr, uint8_t *bytes, unsigned int len); - -/* erase flash bytes with 4-bytes address from any mode (3-byte or 4-byte) */ -int spi_block_erase_21_4ba_direct(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_5c_4ba_direct(struct flashctx *flash, unsigned int addr, unsigned int blocklen); -int spi_block_erase_dc_4ba_direct(struct flashctx *flash, unsigned int addr, unsigned int blocklen); - -int spi_write_extended_address_register(struct flashctx *flash, uint8_t regdata); - -#endif /* __SPI_4BA_H__ */