mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 18:11:05 +00:00
Modified the SPI NOR flash driver to implement and expose a read JEDEC ID command as well as support block (64KiB) erase operations. BUG=None BRANCH=None TEST=Built all targets. Tested on two different EEPROMs. Before: ------------------------------------------- $ ~/haven_updater$ ./read_jedec_ftdi [+] JEDEC_ID=0x1940ef $ ~/haven_updater$ time ./chip_erase_ftdi [+] Success! real 4m0.440s user 0m6.674s sys 0m11.998s ------------------------------------------- $ ~/haven_updater$ ./read_jedec_ftdi [+] JEDEC_ID=0xc21a20c2 $ ~/haven_updater$ time ./chip_erase_ftdi [+] Success! real 5m57.291s user 0m9.964s sys 0m18.363s ------------------------------------------- After: ------------------------------------------- $ ~/haven_updater$ ./read_jedec_ftdi [+] JEDEC_ID=0x1940ef $ ~/haven_updater$ time ./chip_erase_ftdi [+] Success! real 1m33.176s user 0m2.327s sys 0m5.050s ------------------------------------------- $ ~/haven_updater$ ./read_jedec_ftdi [+] JEDEC_ID=0xc21a20c2 $ ~/haven_updater$ time ./chip_erase_ftdi [+] Success! real 2m41.923s user 0m4.191s sys 0m8.576s ------------------------------------------- Change-Id: Ic20372ca9966499977a52a700d6492d3f648d7b2 Signed-off-by: Nadim Taha <ntaha@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/416903 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-by: Shawn N <shawnn@chromium.org>
172 lines
6.9 KiB
C
172 lines
6.9 KiB
C
/* Copyright 2015 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
/* SPI Serial NOR Flash driver module for Chrome EC */
|
|
|
|
#ifndef __CROS_EC_SPI_NOR_H
|
|
#define __CROS_EC_SPI_NOR_H
|
|
|
|
#include "common.h"
|
|
#include "console.h"
|
|
#include "shared_mem.h"
|
|
#include "task.h"
|
|
#include "util.h"
|
|
|
|
/* Driver compatibility requirements based on JEDEC SFDP support:
|
|
*
|
|
* Parameter | SFDP v1.(5+) | SFDP v1.0 | All others
|
|
* ============================================================================
|
|
* Capacity | N/A | N/A | Uses instantiated default
|
|
* --------------------------------------------------------------
|
|
* | The capacity must be less than 4GiB for compatibility.
|
|
* ----------------------------------------------------------------------------
|
|
* Page Size | N/A | 1B or 64B | Uses instantiated default
|
|
* ----------------------------------------------------------------------------
|
|
* Erase Opcodes | 4KiB Erase with an opcode of 0x20 is always required.
|
|
* ----------------------------------------------------------------------------
|
|
* 4B Addressing | 4B addressing mode must be supported if the part is larger
|
|
* | than 16MiB. 4B mode entry will be attempted through opcode
|
|
* | 0xB7 and exit through 0xE9 where writes are enabled for both
|
|
* | in case it is required
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
/* Boards which use SPI NOR devices must provide enum spi_device indexing all
|
|
* spi_device_t's in the board.h file. */
|
|
enum spi_device;
|
|
|
|
struct spi_nor_device_t {
|
|
/* Name of the Serial NOR Flash device. */
|
|
const char *name;
|
|
|
|
/* Index of the SPI master which this device is connected through. */
|
|
const enum spi_device spi_master;
|
|
|
|
/* Maximum timeout per command in microseconds. */
|
|
const uint32_t timeout_usec;
|
|
|
|
/* when instantiating this device, the initialization values for the
|
|
* following fields will be the default values. Note that the values
|
|
* below may change on the fly based on device state and SFDP
|
|
* discovery. */
|
|
uint32_t capacity;
|
|
size_t page_size;
|
|
int in_4b_addressing_mode;
|
|
};
|
|
|
|
extern struct spi_nor_device_t spi_nor_devices[];
|
|
extern const unsigned int spi_nor_devices_used;
|
|
|
|
/* Industry standard Serial NOR Flash opcodes. All other opcodes are part
|
|
* specific and require SFDP discovery. */
|
|
#define SPI_NOR_OPCODE_WRITE_STATUS 0x01 /* Write Status Register (1 Byte) */
|
|
#define SPI_NOR_OPCODE_PAGE_PROGRAM 0x02 /* Page program */
|
|
#define SPI_NOR_OPCODE_SLOW_READ 0x03 /* Read data (low frequency) */
|
|
#define SPI_NOR_OPCODE_WRITE_DISABLE 0x04
|
|
#define SPI_NOR_OPCODE_READ_STATUS 0x05 /* Read Status Register */
|
|
#define SPI_NOR_OPCODE_WRITE_ENABLE 0x06
|
|
#define SPI_NOR_OPCODE_FAST_READ 0x0b /* Read data (high frequency) */
|
|
#define SPI_NOR_OPCODE_SFDP 0x5a /* Read JEDEC SFDP */
|
|
#define SPI_NOR_OPCODE_JEDEC_ID 0x9f /* Read JEDEC ID */
|
|
#define SPI_NOR_OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */
|
|
|
|
/* Flags for SPI_NOR_OPCODE_READ_STATUS */
|
|
#define SPI_NOR_STATUS_REGISTER_WIP (1 << 0) /* Write in progres */
|
|
#define SPI_NOR_STATUS_REGISTER_WEL (1 << 1) /* Write enabled latch */
|
|
|
|
/* If needed in the future this driver can be extended to discover SFDP
|
|
* advertised erase sizes and opcodes for SFDP v1.0+. */
|
|
#define SPI_NOR_DRIVER_SPECIFIED_OPCODE_4KIB_ERASE 0x20
|
|
#define SPI_NOR_DRIVER_SPECIFIED_OPCODE_64KIB_ERASE 0xd8
|
|
|
|
/* If needed in the future this driver can be extended to discover 4B entry and
|
|
* exit methods for SFDP v1.5+. */
|
|
#define SPI_NOR_DRIVER_SPECIFIED_OPCODE_ENTER_4B 0xb7
|
|
#define SPI_NOR_DRIVER_SPECIFIED_OPCODE_EXIT_4B 0xe9
|
|
|
|
/* JEDEC JEP106AR specifies 9 Manufacturer ID banks, read 12 to be sure. */
|
|
#define SPI_NOR_JEDEC_ID_BANKS 12
|
|
|
|
/**
|
|
* Initialize the module, assumes the Serial NOR Flash devices are currently
|
|
* all available for initialization. As part of the initialization the driver
|
|
* will check if the part has a compatible SFDP Basic Flash Parameter table
|
|
* and update the part's page_size, capacity, and forces the addressing mode.
|
|
* Parts with more than 16MiB of capacity are initialized into 4B addressing
|
|
* and parts with less are initialized into 3B addressing mode.
|
|
*
|
|
* WARNING: This must successfully return before invoking any other Serial NOR
|
|
* Flash APIs.
|
|
*/
|
|
int spi_nor_init(void);
|
|
|
|
/**
|
|
* Forces the Serial NOR Flash device to enter (or exit) 4 Byte addressing mode.
|
|
*
|
|
* WARNING:
|
|
* 1) In 3 Byte addressing mode only 16MiB of Serial NOR Flash is accessible.
|
|
* 2) If there's a second SPI master communicating with this Serial NOR Flash
|
|
* part on the board, the user is responsible for ensuring addressing mode
|
|
* compatibility and cooperation.
|
|
* 3) The user must ensure that multiple users do not trample on each other
|
|
* by having multiple parties changing the device's addressing mode.
|
|
*
|
|
* @param spi_nor_device The Serial NOR Flash device to use.
|
|
* @param enter_4b_addressing_mode Whether to enter (1) or exit (0) 4B mode.
|
|
* @return ec_error_list (non-zero on error and timeout).
|
|
*/
|
|
int spi_nor_set_4b_mode(struct spi_nor_device_t *spi_nor_device,
|
|
int enter_4b_addressing_mode);
|
|
|
|
/**
|
|
* Read JEDEC Identifier.
|
|
*
|
|
* @param spi_nor_device The Serial NOR Flash device to use.
|
|
* @param size Number of Bytes to read.
|
|
* @param data Destination buffer for data.
|
|
* @return ec_error_list (non-zero on error and timeout).
|
|
*/
|
|
int spi_nor_read_jedec_id(const struct spi_nor_device_t *spi_nor_device,
|
|
size_t size, uint8_t *data);
|
|
|
|
/**
|
|
* Read from the Serial NOR Flash device.
|
|
*
|
|
* @param spi_nor_device The Serial NOR Flash device to use.
|
|
* @param offset Flash offset to read.
|
|
* @param size Number of Bytes to read.
|
|
* @param data Destination buffer for data.
|
|
* @return ec_error_list (non-zero on error and timeout).
|
|
*/
|
|
int spi_nor_read(const struct spi_nor_device_t *spi_nor_device,
|
|
uint32_t offset, size_t size, uint8_t *data);
|
|
|
|
/**
|
|
* Erase flash on the Serial Flash Device.
|
|
*
|
|
* @param spi_nor_device The Serial NOR Flash device to use.
|
|
* @param offset Flash offset to erase, must be aligned to the minimum physical
|
|
* erase size.
|
|
* @param size Number of Bytes to erase, must be a multiple of the the minimum
|
|
* physical erase size.
|
|
* @return ec_error_list (non-zero on error and timeout).
|
|
*/
|
|
int spi_nor_erase(const struct spi_nor_device_t *spi_nor_device,
|
|
uint32_t offset, size_t size);
|
|
|
|
/**
|
|
* Write to the Serial NOR Flash device. Assumes already erased.
|
|
*
|
|
* @param spi_nor_device The Serial NOR Flash device to use.
|
|
* @param offset Flash offset to write.
|
|
* @param size Number of Bytes to write.
|
|
* @param data Data to write to flash.
|
|
* @return ec_error_list (non-zero on error and timeout).
|
|
*/
|
|
int spi_nor_write(const struct spi_nor_device_t *spi_nor_device,
|
|
uint32_t offset, size_t size, const uint8_t *data);
|
|
|
|
#endif /* __CROS_EC_SPI_NOR_H */
|