mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 15:12:36 +02:00

This may seem too big just to support yet another flash chip, but in reality it brings support for whole new family of S25FS Spansion/Cypress flash chips. These chips require handling of some special status registers for erasing or writing, with very specific timing checks in place. For example, WIP status bit will remain being set to 1 if erase or programming errors occur, and in that case chip 'software reset' has to be performed otherwise the chip will remain unresponsive to all further commands. Also, special CR3NV register (Configuration Register 3 Nonvolatile) status bits needs to be read and set by using RDAR (ReaD Any Register) and WRAR (WRite Any Register) OP commands, and these states are needed to determine which type of reset feature is enabled at the time (legacy or S25FS type) in the first place, determine whether Uniform or Hybrid sector architecture is used at the time, or set programming buffer address wrap point (256 or 512 bytes). Furthermore, S25FS chip status register has to be restored to its original state (hence that ugly CHIP_RESTORE_CALLBACK) following erasing or writing, failing to do so may result in host being unable to access data on the chip at all. Finally, although this brings support for the whole family of chips, I only have one such chip to do the actual testing, S25FS128S (Small Sectors), which I had fully tested on ch341a and FT4232H programmers, with confirmed working probe, read, erase and write. Full summary of changes are here: flashchips: add new flashchip sctructure property: .reset add chip definitions: S25FS128S Large Sectors S25FS128S Small Sectors flash: add macro (chip_restore_func_data call-back): CHIP_RESTORE_CALLBACK flashrom: add struct: chip_restore_func_data add call-back function: register_chip_restore spi: add OP codes: CMD_RDAR, CMD_WRAR, CMD_WRAR_LEN, CMD_RSTEN, CMD_RST add register bit function definitions: CR3NV_ADDR, CR3NV_20H_NV add timers: T_W, T_RPH, T_SE spi25: refactor (based on chromiumos implementation) function: spi_poll_wip port these functions from chromiumos: probe_spi_big_spansion s25fs_software_reset s25f_legacy_software_reset s25fs_block_erase_d8 spi25_statusreg: port these functions from chromiumos: spi_restore_status s25fs_read_cr s25fs_write_cr s25fs_restore_cr3nv Most of the ported functions are originally from s25f.c found at https://chromium.googlesource.com/chromiumos/third_party/flashrom with exception of spi_restore_status which is defined in spi25_statusreg.c. The rest of macros and OP codes are defined in same files as in this commit. Change-Id: If659290874a4b9db6e71256bdef382d31b288e72 Signed-off-by: Samir Ibradzic <sibradzic@gmail.com> Reviewed-on: https://review.coreboot.org/c/flashrom/+/39822 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
209 lines
5.9 KiB
C
209 lines
5.9 KiB
C
/*
|
|
* This file is part of the flashrom project.
|
|
*
|
|
* Copyright (C) 2007, 2008 Carl-Daniel Hailfinger
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef __SPI_H__
|
|
#define __SPI_H__ 1
|
|
|
|
/*
|
|
* Contains the generic SPI headers
|
|
*/
|
|
|
|
#define JEDEC_MAX_ADDR_LEN 0x04
|
|
|
|
/* Read Electronic ID */
|
|
#define JEDEC_RDID 0x9f
|
|
#define JEDEC_RDID_OUTSIZE 0x01
|
|
/* INSIZE may be 0x04 for some chips*/
|
|
#define JEDEC_RDID_INSIZE 0x03
|
|
|
|
/* Some ST M95X model */
|
|
#define ST_M95_RDID 0x83
|
|
#define ST_M95_RDID_3BA_OUTSIZE 0x04 /* 8b op, 24bit addr where size >64KiB */
|
|
#define ST_M95_RDID_2BA_OUTSIZE 0x03 /* 8b op, 16bit addr where size <=64KiB */
|
|
#define ST_M95_RDID_OUTSIZE_MAX 0x04 /* ST_M95_RDID_3BA_OUTSIZE */
|
|
#define ST_M95_RDID_INSIZE 0x03
|
|
|
|
/* Some Atmel AT25F* models have bit 3 as don't care bit in commands */
|
|
#define AT25F_RDID 0x15 /* 0x15 or 0x1d */
|
|
#define AT25F_RDID_OUTSIZE 0x01
|
|
#define AT25F_RDID_INSIZE 0x02
|
|
|
|
/* Read Electronic Manufacturer Signature */
|
|
#define JEDEC_REMS 0x90
|
|
#define JEDEC_REMS_OUTSIZE 0x04
|
|
#define JEDEC_REMS_INSIZE 0x02
|
|
|
|
/* Read Serial Flash Discoverable Parameters (SFDP) */
|
|
#define JEDEC_SFDP 0x5a
|
|
#define JEDEC_SFDP_OUTSIZE 0x05 /* 8b op, 24b addr, 8b dummy */
|
|
/* JEDEC_SFDP_INSIZE : any length */
|
|
|
|
/* Read Electronic Signature */
|
|
#define JEDEC_RES 0xab
|
|
#define JEDEC_RES_OUTSIZE 0x04
|
|
/* INSIZE may be 0x02 for some chips*/
|
|
#define JEDEC_RES_INSIZE 0x01
|
|
|
|
/* Write Enable */
|
|
#define JEDEC_WREN 0x06
|
|
#define JEDEC_WREN_OUTSIZE 0x01
|
|
#define JEDEC_WREN_INSIZE 0x00
|
|
|
|
/* Write Disable */
|
|
#define JEDEC_WRDI 0x04
|
|
#define JEDEC_WRDI_OUTSIZE 0x01
|
|
#define JEDEC_WRDI_INSIZE 0x00
|
|
|
|
/* Chip Erase 0x60 is supported by Macronix/SST chips. */
|
|
#define JEDEC_CE_60 0x60
|
|
#define JEDEC_CE_60_OUTSIZE 0x01
|
|
#define JEDEC_CE_60_INSIZE 0x00
|
|
|
|
/* Chip Erase 0x62 is supported by Atmel AT25F chips. */
|
|
#define JEDEC_CE_62 0x62
|
|
#define JEDEC_CE_62_OUTSIZE 0x01
|
|
#define JEDEC_CE_62_INSIZE 0x00
|
|
|
|
/* Chip Erase 0xc7 is supported by SST/ST/EON/Macronix chips. */
|
|
#define JEDEC_CE_C7 0xc7
|
|
#define JEDEC_CE_C7_OUTSIZE 0x01
|
|
#define JEDEC_CE_C7_INSIZE 0x00
|
|
|
|
/* Block Erase 0x50 is supported by Atmel AT26DF chips. */
|
|
#define JEDEC_BE_50 0x50
|
|
#define JEDEC_BE_50_OUTSIZE 0x04
|
|
#define JEDEC_BE_50_INSIZE 0x00
|
|
|
|
/* Block Erase 0x52 is supported by SST and old Atmel chips. */
|
|
#define JEDEC_BE_52 0x52
|
|
#define JEDEC_BE_52_OUTSIZE 0x04
|
|
#define JEDEC_BE_52_INSIZE 0x00
|
|
|
|
/* Block Erase 0x81 is supported by Atmel AT26DF chips. */
|
|
#define JEDEC_BE_81 0x81
|
|
#define JEDEC_BE_81_OUTSIZE 0x04
|
|
#define JEDEC_BE_81_INSIZE 0x00
|
|
|
|
/* Block Erase 0xc4 is supported by Micron chips. */
|
|
#define JEDEC_BE_C4 0xc4
|
|
#define JEDEC_BE_C4_OUTSIZE 0x04
|
|
#define JEDEC_BE_C4_INSIZE 0x00
|
|
|
|
/* Block Erase 0xd8 is supported by EON/Macronix/Spansion chips. */
|
|
#define JEDEC_BE_D8 0xd8
|
|
#define JEDEC_BE_D8_OUTSIZE 0x04
|
|
#define JEDEC_BE_D8_INSIZE 0x00
|
|
|
|
/* Block Erase 0xd7 is supported by PMC chips. */
|
|
#define JEDEC_BE_D7 0xd7
|
|
#define JEDEC_BE_D7_OUTSIZE 0x04
|
|
#define JEDEC_BE_D7_INSIZE 0x00
|
|
|
|
/* Sector Erase 0x20 is supported by Macronix/SST chips. */
|
|
#define JEDEC_SE 0x20
|
|
#define JEDEC_SE_OUTSIZE 0x04
|
|
#define JEDEC_SE_INSIZE 0x00
|
|
|
|
/* RADR, WRAR, RSTEN, RST & CR3NV OPs and timers on Spansion S25FS chips */
|
|
#define CMD_RDAR 0x65
|
|
#define CMD_WRAR 0x71
|
|
#define CMD_WRAR_LEN 5
|
|
#define CMD_RSTEN 0x66
|
|
#define CMD_RST 0x99
|
|
#define CR3NV_ADDR 0x000004
|
|
#define CR3NV_20H_NV (1 << 3)
|
|
#define T_W 145 * 1000 /* NV register write time */
|
|
#define T_RPH 35 /* Reset pulse hold time */
|
|
#define T_SE 145 * 1000 /* Sector Erase Time */
|
|
|
|
/* Page Erase 0xDB */
|
|
#define JEDEC_PE 0xDB
|
|
#define JEDEC_PE_OUTSIZE 0x04
|
|
#define JEDEC_PE_INSIZE 0x00
|
|
|
|
/* Read Status Register */
|
|
#define JEDEC_RDSR 0x05
|
|
#define JEDEC_RDSR_OUTSIZE 0x01
|
|
#define JEDEC_RDSR_INSIZE 0x01
|
|
|
|
/* Status Register Bits */
|
|
#define SPI_SR_WIP (0x01 << 0)
|
|
#define SPI_SR_WEL (0x01 << 1)
|
|
#define SPI_SR_ERA_ERR (0x01 << 5)
|
|
#define SPI_SR_AAI (0x01 << 6)
|
|
|
|
/* Write Status Enable */
|
|
#define JEDEC_EWSR 0x50
|
|
#define JEDEC_EWSR_OUTSIZE 0x01
|
|
#define JEDEC_EWSR_INSIZE 0x00
|
|
|
|
/* Write Status Register */
|
|
#define JEDEC_WRSR 0x01
|
|
#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
|
|
/* JEDEC_READ_INSIZE : any length */
|
|
|
|
/* Read the memory (with delay after sending address) */
|
|
#define JEDEC_READ_FAST 0x0b
|
|
|
|
/* Write memory byte */
|
|
#define JEDEC_BYTE_PROGRAM 0x02
|
|
#define JEDEC_BYTE_PROGRAM_OUTSIZE 0x05
|
|
#define JEDEC_BYTE_PROGRAM_INSIZE 0x00
|
|
|
|
/* Write AAI word (SST25VF080B) */
|
|
#define JEDEC_AAI_WORD_PROGRAM 0xad
|
|
#define JEDEC_AAI_WORD_PROGRAM_OUTSIZE 0x06
|
|
#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
|
|
|
|
/* Read the memory with 4-byte address (and delay after sending address)
|
|
From ANY mode (3-bytes or 4-bytes) it works with 4-byte address */
|
|
#define JEDEC_READ_4BA_FAST 0x0c
|
|
|
|
/* 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
|
|
#define SPI_INVALID_ADDRESS -3
|
|
#define SPI_INVALID_LENGTH -4
|
|
#define SPI_FLASHROM_BUG -5
|
|
#define SPI_PROGRAMMER_ERROR -6
|
|
|
|
#endif /* !__SPI_H__ */
|