2020-03-13 19:42:37 +00:00
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright ( C ) 2005 , Intec Automation Inc .
* Copyright ( C ) 2014 , Freescale Semiconductor , Inc .
*/
# ifndef __LINUX_MTD_SPI_NOR_INTERNAL_H
# define __LINUX_MTD_SPI_NOR_INTERNAL_H
# include "sfdp.h"
2020-03-13 19:42:38 +00:00
# define SPI_NOR_MAX_ID_LEN 6
/**
* struct spi_nor_fixups - SPI NOR fixup hooks
* @ default_init : called after default flash parameters init . Used to tweak
* flash parameters when information provided by the flash_info
* table is incomplete or wrong .
* @ post_bfpt : called after the BFPT table has been parsed
* @ post_sfdp : called after SFDP has been parsed ( is also called for SPI NORs
* that do not support RDSFDP ) . Typically used to tweak various
* parameters that could not be extracted by other means ( i . e .
* when information provided by the SFDP / flash_info tables are
* incomplete or wrong ) .
*
* Those hooks can be used to tweak the SPI NOR configuration when the SFDP
* table is broken or not available .
*/
struct spi_nor_fixups {
void ( * default_init ) ( struct spi_nor * nor ) ;
int ( * post_bfpt ) ( struct spi_nor * nor ,
const struct sfdp_parameter_header * bfpt_header ,
const struct sfdp_bfpt * bfpt ,
struct spi_nor_flash_parameter * params ) ;
void ( * post_sfdp ) ( struct spi_nor * nor ) ;
} ;
struct flash_info {
char * name ;
/*
* This array stores the ID bytes .
* The first three bytes are the JEDIC ID .
* JEDEC ID zero means " no ID " ( mostly older chips ) .
*/
u8 id [ SPI_NOR_MAX_ID_LEN ] ;
u8 id_len ;
/* The size listed here is what works with SPINOR_OP_SE, which isn't
* necessarily called a " sector " by the vendor .
*/
unsigned sector_size ;
u16 n_sectors ;
u16 page_size ;
u16 addr_width ;
u32 flags ;
# define SECT_4K BIT(0) /* SPINOR_OP_BE_4K works uniformly */
# define SPI_NOR_NO_ERASE BIT(1) /* No erase command needed */
# define SST_WRITE BIT(2) /* use SST byte programming */
# define SPI_NOR_NO_FR BIT(3) /* Can't do fastread */
# define SECT_4K_PMC BIT(4) /* SPINOR_OP_BE_4K_PMC works uniformly */
# define SPI_NOR_DUAL_READ BIT(5) /* Flash supports Dual Read */
# define SPI_NOR_QUAD_READ BIT(6) /* Flash supports Quad Read */
# define USE_FSR BIT(7) /* use flag status register */
# define SPI_NOR_HAS_LOCK BIT(8) /* Flash supports lock/unlock via SR */
# define SPI_NOR_HAS_TB BIT(9) / *
* Flash SR has Top / Bottom ( TB ) protect
* bit . Must be used with
* SPI_NOR_HAS_LOCK .
*/
# define SPI_NOR_XSR_RDY BIT(10) / *
* S3AN flashes have specific opcode to
* read the status register .
* Flags SPI_NOR_XSR_RDY and SPI_S3AN
* use the same bit as one implies the
* other , but we will get rid of
* SPI_S3AN soon .
*/
# define SPI_S3AN BIT(10) / *
* Xilinx Spartan 3 AN In - System Flash
* ( MFR cannot be used for probing
* because it has the same value as
* ATMEL flashes )
*/
# define SPI_NOR_4B_OPCODES BIT(11) / *
* Use dedicated 4 byte address op codes
* to support memory size above 128 Mib .
*/
# define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */
# define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */
# define USE_CLSR BIT(14) /* use CLSR command */
# define SPI_NOR_OCTAL_READ BIT(15) /* Flash supports Octal Read */
# define SPI_NOR_TB_SR_BIT6 BIT(16) / *
* Top / Bottom ( TB ) is bit 6 of
* status register . Must be used with
* SPI_NOR_HAS_TB .
*/
/* Part specific fixup hooks. */
const struct spi_nor_fixups * fixups ;
} ;
/* Used when the "_ext_id" is two bytes at most */
# define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
. id = { \
( ( _jedec_id ) > > 16 ) & 0xff , \
( ( _jedec_id ) > > 8 ) & 0xff , \
( _jedec_id ) & 0xff , \
( ( _ext_id ) > > 8 ) & 0xff , \
( _ext_id ) & 0xff , \
} , \
. id_len = ( ! ( _jedec_id ) ? 0 : ( 3 + ( ( _ext_id ) ? 2 : 0 ) ) ) , \
. sector_size = ( _sector_size ) , \
. n_sectors = ( _n_sectors ) , \
. page_size = 256 , \
. flags = ( _flags ) ,
# define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
. id = { \
( ( _jedec_id ) > > 16 ) & 0xff , \
( ( _jedec_id ) > > 8 ) & 0xff , \
( _jedec_id ) & 0xff , \
( ( _ext_id ) > > 16 ) & 0xff , \
( ( _ext_id ) > > 8 ) & 0xff , \
( _ext_id ) & 0xff , \
} , \
. id_len = 6 , \
. sector_size = ( _sector_size ) , \
. n_sectors = ( _n_sectors ) , \
. page_size = 256 , \
. flags = ( _flags ) ,
# define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \
. sector_size = ( _sector_size ) , \
. n_sectors = ( _n_sectors ) , \
. page_size = ( _page_size ) , \
. addr_width = ( _addr_width ) , \
. flags = ( _flags ) ,
# define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \
. id = { \
( ( _jedec_id ) > > 16 ) & 0xff , \
( ( _jedec_id ) > > 8 ) & 0xff , \
( _jedec_id ) & 0xff \
} , \
. id_len = 3 , \
. sector_size = ( 8 * _page_size ) , \
. n_sectors = ( _n_sectors ) , \
. page_size = _page_size , \
. addr_width = 3 , \
. flags = SPI_NOR_NO_FR | SPI_S3AN ,
2020-03-13 19:42:39 +00:00
/**
* struct spi_nor_manufacturer - SPI NOR manufacturer object
* @ name : manufacturer name
* @ parts : array of parts supported by this manufacturer
* @ nparts : number of entries in the parts array
* @ fixups : hooks called at various points in time during spi_nor_scan ( )
*/
struct spi_nor_manufacturer {
const char * name ;
const struct flash_info * parts ;
unsigned int nparts ;
const struct spi_nor_fixups * fixups ;
} ;
2020-03-13 19:42:39 +00:00
/* Manufacturer drivers. */
extern const struct spi_nor_manufacturer spi_nor_atmel ;
2020-03-13 19:42:40 +00:00
extern const struct spi_nor_manufacturer spi_nor_eon ;
2020-03-13 19:42:41 +00:00
extern const struct spi_nor_manufacturer spi_nor_esmt ;
2020-03-13 19:42:41 +00:00
extern const struct spi_nor_manufacturer spi_nor_everspin ;
2020-03-13 19:42:42 +00:00
extern const struct spi_nor_manufacturer spi_nor_fujitsu ;
2020-03-13 19:42:43 +00:00
extern const struct spi_nor_manufacturer spi_nor_gigadevice ;
2020-03-13 19:42:43 +00:00
extern const struct spi_nor_manufacturer spi_nor_intel ;
2020-03-13 19:42:44 +00:00
extern const struct spi_nor_manufacturer spi_nor_issi ;
2020-03-13 19:42:45 +00:00
extern const struct spi_nor_manufacturer spi_nor_macronix ;
2020-03-13 19:42:46 +00:00
extern const struct spi_nor_manufacturer spi_nor_micron ;
extern const struct spi_nor_manufacturer spi_nor_st ;
2020-03-13 19:42:39 +00:00
2020-03-13 19:42:38 +00:00
int spi_nor_write_enable ( struct spi_nor * nor ) ;
int spi_nor_write_disable ( struct spi_nor * nor ) ;
int spi_nor_set_4byte_addr_mode ( struct spi_nor * nor , bool enable ) ;
int spi_nor_write_ear ( struct spi_nor * nor , u8 ear ) ;
int spi_nor_wait_till_ready ( struct spi_nor * nor ) ;
int spi_nor_lock_and_prep ( struct spi_nor * nor ) ;
void spi_nor_unlock_and_unprep ( struct spi_nor * nor ) ;
2020-03-13 19:42:37 +00:00
int spi_nor_sr1_bit6_quad_enable ( struct spi_nor * nor ) ;
int spi_nor_sr2_bit1_quad_enable ( struct spi_nor * nor ) ;
int spi_nor_sr2_bit7_quad_enable ( struct spi_nor * nor ) ;
2020-03-13 19:42:38 +00:00
int spi_nor_xread_sr ( struct spi_nor * nor , u8 * sr ) ;
2020-03-13 19:42:37 +00:00
ssize_t spi_nor_read_data ( struct spi_nor * nor , loff_t from , size_t len ,
u8 * buf ) ;
2020-03-13 19:42:38 +00:00
ssize_t spi_nor_write_data ( struct spi_nor * nor , loff_t to , size_t len ,
const u8 * buf ) ;
2020-03-13 19:42:37 +00:00
int spi_nor_hwcaps_read2cmd ( u32 hwcaps ) ;
u8 spi_nor_convert_3to4_read ( u8 opcode ) ;
void spi_nor_set_pp_settings ( struct spi_nor_pp_command * pp , u8 opcode ,
enum spi_nor_protocol proto ) ;
void spi_nor_set_erase_type ( struct spi_nor_erase_type * erase , u32 size ,
u8 opcode ) ;
struct spi_nor_erase_region *
spi_nor_region_next ( struct spi_nor_erase_region * region ) ;
void spi_nor_init_uniform_erase_map ( struct spi_nor_erase_map * map ,
u8 erase_mask , u64 flash_size ) ;
int spi_nor_post_bfpt_fixups ( struct spi_nor * nor ,
const struct sfdp_parameter_header * bfpt_header ,
const struct sfdp_bfpt * bfpt ,
struct spi_nor_flash_parameter * params ) ;
2020-03-13 19:42:38 +00:00
static struct spi_nor __maybe_unused * mtd_to_spi_nor ( struct mtd_info * mtd )
{
return mtd - > priv ;
}
2020-03-13 19:42:37 +00:00
# endif /* __LINUX_MTD_SPI_NOR_INTERNAL_H */