18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2014 Freescale Semiconductor, Inc. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef __LINUX_MTD_SPI_NOR_H 78c2ecf20Sopenharmony_ci#define __LINUX_MTD_SPI_NOR_H 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/bitops.h> 108c2ecf20Sopenharmony_ci#include <linux/mtd/cfi.h> 118c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h> 128c2ecf20Sopenharmony_ci#include <linux/spi/spi-mem.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* 158c2ecf20Sopenharmony_ci * Note on opcode nomenclature: some opcodes have a format like 168c2ecf20Sopenharmony_ci * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number 178c2ecf20Sopenharmony_ci * of I/O lines used for the opcode, address, and data (respectively). The 188c2ecf20Sopenharmony_ci * FUNCTION has an optional suffix of '4', to represent an opcode which 198c2ecf20Sopenharmony_ci * requires a 4-byte (32-bit) address. 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* Flash opcodes. */ 238c2ecf20Sopenharmony_ci#define SPINOR_OP_WRDI 0x04 /* Write disable */ 248c2ecf20Sopenharmony_ci#define SPINOR_OP_WREN 0x06 /* Write enable */ 258c2ecf20Sopenharmony_ci#define SPINOR_OP_RDSR 0x05 /* Read status register */ 268c2ecf20Sopenharmony_ci#define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */ 278c2ecf20Sopenharmony_ci#define SPINOR_OP_RDSR2 0x3f /* Read status register 2 */ 288c2ecf20Sopenharmony_ci#define SPINOR_OP_WRSR2 0x3e /* Write status register 2 */ 298c2ecf20Sopenharmony_ci#define SPINOR_OP_READ 0x03 /* Read data bytes (low frequency) */ 308c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */ 318c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual Output SPI) */ 328c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_2_2 0xbb /* Read data bytes (Dual I/O SPI) */ 338c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad Output SPI) */ 348c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_4_4 0xeb /* Read data bytes (Quad I/O SPI) */ 358c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_1_8 0x8b /* Read data bytes (Octal Output SPI) */ 368c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_8_8 0xcb /* Read data bytes (Octal I/O SPI) */ 378c2ecf20Sopenharmony_ci#define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */ 388c2ecf20Sopenharmony_ci#define SPINOR_OP_PP_1_1_4 0x32 /* Quad page program */ 398c2ecf20Sopenharmony_ci#define SPINOR_OP_PP_1_4_4 0x38 /* Quad page program */ 408c2ecf20Sopenharmony_ci#define SPINOR_OP_PP_1_1_8 0x82 /* Octal page program */ 418c2ecf20Sopenharmony_ci#define SPINOR_OP_PP_1_8_8 0xc2 /* Octal page program */ 428c2ecf20Sopenharmony_ci#define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */ 438c2ecf20Sopenharmony_ci#define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ 448c2ecf20Sopenharmony_ci#define SPINOR_OP_BE_32K 0x52 /* Erase 32KiB block */ 458c2ecf20Sopenharmony_ci#define SPINOR_OP_CHIP_ERASE 0xc7 /* Erase whole flash chip */ 468c2ecf20Sopenharmony_ci#define SPINOR_OP_SE 0xd8 /* Sector erase (usually 64KiB) */ 478c2ecf20Sopenharmony_ci#define SPINOR_OP_RDID 0x9f /* Read JEDEC ID */ 488c2ecf20Sopenharmony_ci#define SPINOR_OP_RDSFDP 0x5a /* Read SFDP */ 498c2ecf20Sopenharmony_ci#define SPINOR_OP_RDCR 0x35 /* Read configuration register */ 508c2ecf20Sopenharmony_ci#define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ 518c2ecf20Sopenharmony_ci#define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ 528c2ecf20Sopenharmony_ci#define SPINOR_OP_RDEAR 0xc8 /* Read Extended Address Register */ 538c2ecf20Sopenharmony_ci#define SPINOR_OP_WREAR 0xc5 /* Write Extended Address Register */ 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ 568c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */ 578c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_FAST_4B 0x0c /* Read data bytes (high frequency) */ 588c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_1_2_4B 0x3c /* Read data bytes (Dual Output SPI) */ 598c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_2_2_4B 0xbc /* Read data bytes (Dual I/O SPI) */ 608c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_1_4_4B 0x6c /* Read data bytes (Quad Output SPI) */ 618c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_4_4_4B 0xec /* Read data bytes (Quad I/O SPI) */ 628c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_1_8_4B 0x7c /* Read data bytes (Octal Output SPI) */ 638c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_8_8_4B 0xcc /* Read data bytes (Octal I/O SPI) */ 648c2ecf20Sopenharmony_ci#define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */ 658c2ecf20Sopenharmony_ci#define SPINOR_OP_PP_1_1_4_4B 0x34 /* Quad page program */ 668c2ecf20Sopenharmony_ci#define SPINOR_OP_PP_1_4_4_4B 0x3e /* Quad page program */ 678c2ecf20Sopenharmony_ci#define SPINOR_OP_PP_1_1_8_4B 0x84 /* Octal page program */ 688c2ecf20Sopenharmony_ci#define SPINOR_OP_PP_1_8_8_4B 0x8e /* Octal page program */ 698c2ecf20Sopenharmony_ci#define SPINOR_OP_BE_4K_4B 0x21 /* Erase 4KiB block */ 708c2ecf20Sopenharmony_ci#define SPINOR_OP_BE_32K_4B 0x5c /* Erase 32KiB block */ 718c2ecf20Sopenharmony_ci#define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */ 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci/* Double Transfer Rate opcodes - defined in JEDEC JESD216B. */ 748c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_1_1_DTR 0x0d 758c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_2_2_DTR 0xbd 768c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_4_4_DTR 0xed 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_1_1_DTR_4B 0x0e 798c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_2_2_DTR_4B 0xbe 808c2ecf20Sopenharmony_ci#define SPINOR_OP_READ_1_4_4_DTR_4B 0xee 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/* Used for SST flashes only. */ 838c2ecf20Sopenharmony_ci#define SPINOR_OP_BP 0x02 /* Byte program */ 848c2ecf20Sopenharmony_ci#define SPINOR_OP_AAI_WP 0xad /* Auto address increment word program */ 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* Used for S3AN flashes only */ 878c2ecf20Sopenharmony_ci#define SPINOR_OP_XSE 0x50 /* Sector erase */ 888c2ecf20Sopenharmony_ci#define SPINOR_OP_XPP 0x82 /* Page program */ 898c2ecf20Sopenharmony_ci#define SPINOR_OP_XRDSR 0xd7 /* Read status register */ 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci#define XSR_PAGESIZE BIT(0) /* Page size in Po2 or Linear */ 928c2ecf20Sopenharmony_ci#define XSR_RDY BIT(7) /* Ready */ 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* Used for Macronix and Winbond flashes. */ 968c2ecf20Sopenharmony_ci#define SPINOR_OP_EN4B 0xb7 /* Enter 4-byte mode */ 978c2ecf20Sopenharmony_ci#define SPINOR_OP_EX4B 0xe9 /* Exit 4-byte mode */ 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci/* Used for Spansion flashes only. */ 1008c2ecf20Sopenharmony_ci#define SPINOR_OP_BRWR 0x17 /* Bank register write */ 1018c2ecf20Sopenharmony_ci#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci/* Used for Micron flashes only. */ 1048c2ecf20Sopenharmony_ci#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ 1058c2ecf20Sopenharmony_ci#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */ 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci/* Status Register bits. */ 1088c2ecf20Sopenharmony_ci#define SR_WIP BIT(0) /* Write in progress */ 1098c2ecf20Sopenharmony_ci#define SR_WEL BIT(1) /* Write enable latch */ 1108c2ecf20Sopenharmony_ci/* meaning of other SR_* bits may differ between vendors */ 1118c2ecf20Sopenharmony_ci#define SR_BP0 BIT(2) /* Block protect 0 */ 1128c2ecf20Sopenharmony_ci#define SR_BP1 BIT(3) /* Block protect 1 */ 1138c2ecf20Sopenharmony_ci#define SR_BP2 BIT(4) /* Block protect 2 */ 1148c2ecf20Sopenharmony_ci#define SR_BP3 BIT(5) /* Block protect 3 */ 1158c2ecf20Sopenharmony_ci#define SR_TB_BIT5 BIT(5) /* Top/Bottom protect */ 1168c2ecf20Sopenharmony_ci#define SR_BP3_BIT6 BIT(6) /* Block protect 3 */ 1178c2ecf20Sopenharmony_ci#define SR_TB_BIT6 BIT(6) /* Top/Bottom protect */ 1188c2ecf20Sopenharmony_ci#define SR_SRWD BIT(7) /* SR write protect */ 1198c2ecf20Sopenharmony_ci/* Spansion/Cypress specific status bits */ 1208c2ecf20Sopenharmony_ci#define SR_E_ERR BIT(5) 1218c2ecf20Sopenharmony_ci#define SR_P_ERR BIT(6) 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci#define SR1_QUAD_EN_BIT6 BIT(6) 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci#define SR_BP_SHIFT 2 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci/* Enhanced Volatile Configuration Register bits */ 1288c2ecf20Sopenharmony_ci#define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */ 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/* Flag Status Register bits */ 1318c2ecf20Sopenharmony_ci#define FSR_READY BIT(7) /* Device status, 0 = Busy, 1 = Ready */ 1328c2ecf20Sopenharmony_ci#define FSR_E_ERR BIT(5) /* Erase operation status */ 1338c2ecf20Sopenharmony_ci#define FSR_P_ERR BIT(4) /* Program operation status */ 1348c2ecf20Sopenharmony_ci#define FSR_PT_ERR BIT(1) /* Protection error bit */ 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci/* Status Register 2 bits. */ 1378c2ecf20Sopenharmony_ci#define SR2_QUAD_EN_BIT1 BIT(1) 1388c2ecf20Sopenharmony_ci#define SR2_QUAD_EN_BIT7 BIT(7) 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci/* Supported SPI protocols */ 1418c2ecf20Sopenharmony_ci#define SNOR_PROTO_INST_MASK GENMASK(23, 16) 1428c2ecf20Sopenharmony_ci#define SNOR_PROTO_INST_SHIFT 16 1438c2ecf20Sopenharmony_ci#define SNOR_PROTO_INST(_nbits) \ 1448c2ecf20Sopenharmony_ci ((((unsigned long)(_nbits)) << SNOR_PROTO_INST_SHIFT) & \ 1458c2ecf20Sopenharmony_ci SNOR_PROTO_INST_MASK) 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci#define SNOR_PROTO_ADDR_MASK GENMASK(15, 8) 1488c2ecf20Sopenharmony_ci#define SNOR_PROTO_ADDR_SHIFT 8 1498c2ecf20Sopenharmony_ci#define SNOR_PROTO_ADDR(_nbits) \ 1508c2ecf20Sopenharmony_ci ((((unsigned long)(_nbits)) << SNOR_PROTO_ADDR_SHIFT) & \ 1518c2ecf20Sopenharmony_ci SNOR_PROTO_ADDR_MASK) 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci#define SNOR_PROTO_DATA_MASK GENMASK(7, 0) 1548c2ecf20Sopenharmony_ci#define SNOR_PROTO_DATA_SHIFT 0 1558c2ecf20Sopenharmony_ci#define SNOR_PROTO_DATA(_nbits) \ 1568c2ecf20Sopenharmony_ci ((((unsigned long)(_nbits)) << SNOR_PROTO_DATA_SHIFT) & \ 1578c2ecf20Sopenharmony_ci SNOR_PROTO_DATA_MASK) 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci#define SNOR_PROTO_IS_DTR BIT(24) /* Double Transfer Rate */ 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci#define SNOR_PROTO_STR(_inst_nbits, _addr_nbits, _data_nbits) \ 1628c2ecf20Sopenharmony_ci (SNOR_PROTO_INST(_inst_nbits) | \ 1638c2ecf20Sopenharmony_ci SNOR_PROTO_ADDR(_addr_nbits) | \ 1648c2ecf20Sopenharmony_ci SNOR_PROTO_DATA(_data_nbits)) 1658c2ecf20Sopenharmony_ci#define SNOR_PROTO_DTR(_inst_nbits, _addr_nbits, _data_nbits) \ 1668c2ecf20Sopenharmony_ci (SNOR_PROTO_IS_DTR | \ 1678c2ecf20Sopenharmony_ci SNOR_PROTO_STR(_inst_nbits, _addr_nbits, _data_nbits)) 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cienum spi_nor_protocol { 1708c2ecf20Sopenharmony_ci SNOR_PROTO_1_1_1 = SNOR_PROTO_STR(1, 1, 1), 1718c2ecf20Sopenharmony_ci SNOR_PROTO_1_1_2 = SNOR_PROTO_STR(1, 1, 2), 1728c2ecf20Sopenharmony_ci SNOR_PROTO_1_1_4 = SNOR_PROTO_STR(1, 1, 4), 1738c2ecf20Sopenharmony_ci SNOR_PROTO_1_1_8 = SNOR_PROTO_STR(1, 1, 8), 1748c2ecf20Sopenharmony_ci SNOR_PROTO_1_2_2 = SNOR_PROTO_STR(1, 2, 2), 1758c2ecf20Sopenharmony_ci SNOR_PROTO_1_4_4 = SNOR_PROTO_STR(1, 4, 4), 1768c2ecf20Sopenharmony_ci SNOR_PROTO_1_8_8 = SNOR_PROTO_STR(1, 8, 8), 1778c2ecf20Sopenharmony_ci SNOR_PROTO_2_2_2 = SNOR_PROTO_STR(2, 2, 2), 1788c2ecf20Sopenharmony_ci SNOR_PROTO_4_4_4 = SNOR_PROTO_STR(4, 4, 4), 1798c2ecf20Sopenharmony_ci SNOR_PROTO_8_8_8 = SNOR_PROTO_STR(8, 8, 8), 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci SNOR_PROTO_1_1_1_DTR = SNOR_PROTO_DTR(1, 1, 1), 1828c2ecf20Sopenharmony_ci SNOR_PROTO_1_2_2_DTR = SNOR_PROTO_DTR(1, 2, 2), 1838c2ecf20Sopenharmony_ci SNOR_PROTO_1_4_4_DTR = SNOR_PROTO_DTR(1, 4, 4), 1848c2ecf20Sopenharmony_ci SNOR_PROTO_1_8_8_DTR = SNOR_PROTO_DTR(1, 8, 8), 1858c2ecf20Sopenharmony_ci}; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistatic inline bool spi_nor_protocol_is_dtr(enum spi_nor_protocol proto) 1888c2ecf20Sopenharmony_ci{ 1898c2ecf20Sopenharmony_ci return !!(proto & SNOR_PROTO_IS_DTR); 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic inline u8 spi_nor_get_protocol_inst_nbits(enum spi_nor_protocol proto) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci return ((unsigned long)(proto & SNOR_PROTO_INST_MASK)) >> 1958c2ecf20Sopenharmony_ci SNOR_PROTO_INST_SHIFT; 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic inline u8 spi_nor_get_protocol_addr_nbits(enum spi_nor_protocol proto) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci return ((unsigned long)(proto & SNOR_PROTO_ADDR_MASK)) >> 2018c2ecf20Sopenharmony_ci SNOR_PROTO_ADDR_SHIFT; 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistatic inline u8 spi_nor_get_protocol_data_nbits(enum spi_nor_protocol proto) 2058c2ecf20Sopenharmony_ci{ 2068c2ecf20Sopenharmony_ci return ((unsigned long)(proto & SNOR_PROTO_DATA_MASK)) >> 2078c2ecf20Sopenharmony_ci SNOR_PROTO_DATA_SHIFT; 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistatic inline u8 spi_nor_get_protocol_width(enum spi_nor_protocol proto) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci return spi_nor_get_protocol_data_nbits(proto); 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci/** 2168c2ecf20Sopenharmony_ci * struct spi_nor_hwcaps - Structure for describing the hardware capabilies 2178c2ecf20Sopenharmony_ci * supported by the SPI controller (bus master). 2188c2ecf20Sopenharmony_ci * @mask: the bitmask listing all the supported hw capabilies 2198c2ecf20Sopenharmony_ci */ 2208c2ecf20Sopenharmony_cistruct spi_nor_hwcaps { 2218c2ecf20Sopenharmony_ci u32 mask; 2228c2ecf20Sopenharmony_ci}; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci/* 2258c2ecf20Sopenharmony_ci *(Fast) Read capabilities. 2268c2ecf20Sopenharmony_ci * MUST be ordered by priority: the higher bit position, the higher priority. 2278c2ecf20Sopenharmony_ci * As a matter of performances, it is relevant to use Octal SPI protocols first, 2288c2ecf20Sopenharmony_ci * then Quad SPI protocols before Dual SPI protocols, Fast Read and lastly 2298c2ecf20Sopenharmony_ci * (Slow) Read. 2308c2ecf20Sopenharmony_ci */ 2318c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_MASK GENMASK(14, 0) 2328c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ BIT(0) 2338c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_FAST BIT(1) 2348c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_1_1_DTR BIT(2) 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_DUAL GENMASK(6, 3) 2378c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_1_2 BIT(3) 2388c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_2_2 BIT(4) 2398c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_2_2_2 BIT(5) 2408c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_2_2_DTR BIT(6) 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_QUAD GENMASK(10, 7) 2438c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_1_4 BIT(7) 2448c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_4_4 BIT(8) 2458c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_4_4_4 BIT(9) 2468c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_4_4_DTR BIT(10) 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_OCTAL GENMASK(14, 11) 2498c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_1_8 BIT(11) 2508c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_8_8 BIT(12) 2518c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_8_8_8 BIT(13) 2528c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_READ_1_8_8_DTR BIT(14) 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci/* 2558c2ecf20Sopenharmony_ci * Page Program capabilities. 2568c2ecf20Sopenharmony_ci * MUST be ordered by priority: the higher bit position, the higher priority. 2578c2ecf20Sopenharmony_ci * Like (Fast) Read capabilities, Octal/Quad SPI protocols are preferred to the 2588c2ecf20Sopenharmony_ci * legacy SPI 1-1-1 protocol. 2598c2ecf20Sopenharmony_ci * Note that Dual Page Programs are not supported because there is no existing 2608c2ecf20Sopenharmony_ci * JEDEC/SFDP standard to define them. Also at this moment no SPI flash memory 2618c2ecf20Sopenharmony_ci * implements such commands. 2628c2ecf20Sopenharmony_ci */ 2638c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP_MASK GENMASK(22, 16) 2648c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP BIT(16) 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP_QUAD GENMASK(19, 17) 2678c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP_1_1_4 BIT(17) 2688c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP_1_4_4 BIT(18) 2698c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP_4_4_4 BIT(19) 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP_OCTAL GENMASK(22, 20) 2728c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP_1_1_8 BIT(20) 2738c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP_1_8_8 BIT(21) 2748c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_PP_8_8_8 BIT(22) 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_X_X_X (SNOR_HWCAPS_READ_2_2_2 | \ 2778c2ecf20Sopenharmony_ci SNOR_HWCAPS_READ_4_4_4 | \ 2788c2ecf20Sopenharmony_ci SNOR_HWCAPS_READ_8_8_8 | \ 2798c2ecf20Sopenharmony_ci SNOR_HWCAPS_PP_4_4_4 | \ 2808c2ecf20Sopenharmony_ci SNOR_HWCAPS_PP_8_8_8) 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_DTR (SNOR_HWCAPS_READ_1_1_1_DTR | \ 2838c2ecf20Sopenharmony_ci SNOR_HWCAPS_READ_1_2_2_DTR | \ 2848c2ecf20Sopenharmony_ci SNOR_HWCAPS_READ_1_4_4_DTR | \ 2858c2ecf20Sopenharmony_ci SNOR_HWCAPS_READ_1_8_8_DTR) 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci#define SNOR_HWCAPS_ALL (SNOR_HWCAPS_READ_MASK | \ 2888c2ecf20Sopenharmony_ci SNOR_HWCAPS_PP_MASK) 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci/* Forward declaration that is used in 'struct spi_nor_controller_ops' */ 2918c2ecf20Sopenharmony_cistruct spi_nor; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci/** 2948c2ecf20Sopenharmony_ci * struct spi_nor_controller_ops - SPI NOR controller driver specific 2958c2ecf20Sopenharmony_ci * operations. 2968c2ecf20Sopenharmony_ci * @prepare: [OPTIONAL] do some preparations for the 2978c2ecf20Sopenharmony_ci * read/write/erase/lock/unlock operations. 2988c2ecf20Sopenharmony_ci * @unprepare: [OPTIONAL] do some post work after the 2998c2ecf20Sopenharmony_ci * read/write/erase/lock/unlock operations. 3008c2ecf20Sopenharmony_ci * @read_reg: read out the register. 3018c2ecf20Sopenharmony_ci * @write_reg: write data to the register. 3028c2ecf20Sopenharmony_ci * @read: read data from the SPI NOR. 3038c2ecf20Sopenharmony_ci * @write: write data to the SPI NOR. 3048c2ecf20Sopenharmony_ci * @erase: erase a sector of the SPI NOR at the offset @offs; if 3058c2ecf20Sopenharmony_ci * not provided by the driver, SPI NOR will send the erase 3068c2ecf20Sopenharmony_ci * opcode via write_reg(). 3078c2ecf20Sopenharmony_ci */ 3088c2ecf20Sopenharmony_cistruct spi_nor_controller_ops { 3098c2ecf20Sopenharmony_ci int (*prepare)(struct spi_nor *nor); 3108c2ecf20Sopenharmony_ci void (*unprepare)(struct spi_nor *nor); 3118c2ecf20Sopenharmony_ci int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, size_t len); 3128c2ecf20Sopenharmony_ci int (*write_reg)(struct spi_nor *nor, u8 opcode, const u8 *buf, 3138c2ecf20Sopenharmony_ci size_t len); 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci ssize_t (*read)(struct spi_nor *nor, loff_t from, size_t len, u8 *buf); 3168c2ecf20Sopenharmony_ci ssize_t (*write)(struct spi_nor *nor, loff_t to, size_t len, 3178c2ecf20Sopenharmony_ci const u8 *buf); 3188c2ecf20Sopenharmony_ci int (*erase)(struct spi_nor *nor, loff_t offs); 3198c2ecf20Sopenharmony_ci}; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* 3228c2ecf20Sopenharmony_ci * Forward declarations that are used internally by the core and manufacturer 3238c2ecf20Sopenharmony_ci * drivers. 3248c2ecf20Sopenharmony_ci */ 3258c2ecf20Sopenharmony_cistruct flash_info; 3268c2ecf20Sopenharmony_cistruct spi_nor_manufacturer; 3278c2ecf20Sopenharmony_cistruct spi_nor_flash_parameter; 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci/** 3308c2ecf20Sopenharmony_ci * struct spi_nor - Structure for defining the SPI NOR layer 3318c2ecf20Sopenharmony_ci * @mtd: an mtd_info structure 3328c2ecf20Sopenharmony_ci * @lock: the lock for the read/write/erase/lock/unlock operations 3338c2ecf20Sopenharmony_ci * @dev: pointer to an SPI device or an SPI NOR controller device 3348c2ecf20Sopenharmony_ci * @spimem: pointer to the SPI memory device 3358c2ecf20Sopenharmony_ci * @bouncebuf: bounce buffer used when the buffer passed by the MTD 3368c2ecf20Sopenharmony_ci * layer is not DMA-able 3378c2ecf20Sopenharmony_ci * @bouncebuf_size: size of the bounce buffer 3388c2ecf20Sopenharmony_ci * @info: SPI NOR part JEDEC MFR ID and other info 3398c2ecf20Sopenharmony_ci * @manufacturer: SPI NOR manufacturer 3408c2ecf20Sopenharmony_ci * @page_size: the page size of the SPI NOR 3418c2ecf20Sopenharmony_ci * @addr_width: number of address bytes 3428c2ecf20Sopenharmony_ci * @erase_opcode: the opcode for erasing a sector 3438c2ecf20Sopenharmony_ci * @read_opcode: the read opcode 3448c2ecf20Sopenharmony_ci * @read_dummy: the dummy needed by the read operation 3458c2ecf20Sopenharmony_ci * @program_opcode: the program opcode 3468c2ecf20Sopenharmony_ci * @sst_write_second: used by the SST write operation 3478c2ecf20Sopenharmony_ci * @flags: flag options for the current SPI NOR (SNOR_F_*) 3488c2ecf20Sopenharmony_ci * @read_proto: the SPI protocol for read operations 3498c2ecf20Sopenharmony_ci * @write_proto: the SPI protocol for write operations 3508c2ecf20Sopenharmony_ci * @reg_proto: the SPI protocol for read_reg/write_reg/erase operations 3518c2ecf20Sopenharmony_ci * @controller_ops: SPI NOR controller driver specific operations. 3528c2ecf20Sopenharmony_ci * @params: [FLASH-SPECIFIC] SPI NOR flash parameters and settings. 3538c2ecf20Sopenharmony_ci * The structure includes legacy flash parameters and 3548c2ecf20Sopenharmony_ci * settings that can be overwritten by the spi_nor_fixups 3558c2ecf20Sopenharmony_ci * hooks, or dynamically when parsing the SFDP tables. 3568c2ecf20Sopenharmony_ci * @dirmap: pointers to struct spi_mem_dirmap_desc for reads/writes. 3578c2ecf20Sopenharmony_ci * @priv: pointer to the private data 3588c2ecf20Sopenharmony_ci */ 3598c2ecf20Sopenharmony_cistruct spi_nor { 3608c2ecf20Sopenharmony_ci struct mtd_info mtd; 3618c2ecf20Sopenharmony_ci struct mutex lock; 3628c2ecf20Sopenharmony_ci struct device *dev; 3638c2ecf20Sopenharmony_ci struct spi_mem *spimem; 3648c2ecf20Sopenharmony_ci u8 *bouncebuf; 3658c2ecf20Sopenharmony_ci size_t bouncebuf_size; 3668c2ecf20Sopenharmony_ci const struct flash_info *info; 3678c2ecf20Sopenharmony_ci const struct spi_nor_manufacturer *manufacturer; 3688c2ecf20Sopenharmony_ci u32 page_size; 3698c2ecf20Sopenharmony_ci u8 addr_width; 3708c2ecf20Sopenharmony_ci u8 erase_opcode; 3718c2ecf20Sopenharmony_ci u8 read_opcode; 3728c2ecf20Sopenharmony_ci u8 read_dummy; 3738c2ecf20Sopenharmony_ci u8 program_opcode; 3748c2ecf20Sopenharmony_ci enum spi_nor_protocol read_proto; 3758c2ecf20Sopenharmony_ci enum spi_nor_protocol write_proto; 3768c2ecf20Sopenharmony_ci enum spi_nor_protocol reg_proto; 3778c2ecf20Sopenharmony_ci bool sst_write_second; 3788c2ecf20Sopenharmony_ci u32 flags; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci const struct spi_nor_controller_ops *controller_ops; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci struct spi_nor_flash_parameter *params; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci struct { 3858c2ecf20Sopenharmony_ci struct spi_mem_dirmap_desc *rdesc; 3868c2ecf20Sopenharmony_ci struct spi_mem_dirmap_desc *wdesc; 3878c2ecf20Sopenharmony_ci } dirmap; 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci void *priv; 3908c2ecf20Sopenharmony_ci}; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_cistatic inline void spi_nor_set_flash_node(struct spi_nor *nor, 3938c2ecf20Sopenharmony_ci struct device_node *np) 3948c2ecf20Sopenharmony_ci{ 3958c2ecf20Sopenharmony_ci mtd_set_of_node(&nor->mtd, np); 3968c2ecf20Sopenharmony_ci} 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_cistatic inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) 3998c2ecf20Sopenharmony_ci{ 4008c2ecf20Sopenharmony_ci return mtd_get_of_node(&nor->mtd); 4018c2ecf20Sopenharmony_ci} 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci/** 4048c2ecf20Sopenharmony_ci * spi_nor_scan() - scan the SPI NOR 4058c2ecf20Sopenharmony_ci * @nor: the spi_nor structure 4068c2ecf20Sopenharmony_ci * @name: the chip type name 4078c2ecf20Sopenharmony_ci * @hwcaps: the hardware capabilities supported by the controller driver 4088c2ecf20Sopenharmony_ci * 4098c2ecf20Sopenharmony_ci * The drivers can use this fuction to scan the SPI NOR. 4108c2ecf20Sopenharmony_ci * In the scanning, it will try to get all the necessary information to 4118c2ecf20Sopenharmony_ci * fill the mtd_info{} and the spi_nor{}. 4128c2ecf20Sopenharmony_ci * 4138c2ecf20Sopenharmony_ci * The chip type name can be provided through the @name parameter. 4148c2ecf20Sopenharmony_ci * 4158c2ecf20Sopenharmony_ci * Return: 0 for success, others for failure. 4168c2ecf20Sopenharmony_ci */ 4178c2ecf20Sopenharmony_ciint spi_nor_scan(struct spi_nor *nor, const char *name, 4188c2ecf20Sopenharmony_ci const struct spi_nor_hwcaps *hwcaps); 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci/** 4218c2ecf20Sopenharmony_ci * spi_nor_restore_addr_mode() - restore the status of SPI NOR 4228c2ecf20Sopenharmony_ci * @nor: the spi_nor structure 4238c2ecf20Sopenharmony_ci */ 4248c2ecf20Sopenharmony_civoid spi_nor_restore(struct spi_nor *nor); 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci#endif 427