From f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 31 Jan 2024 01:04:47 +0000 Subject: [PATCH] add driver 5G --- kernel/include/linux/mtd/spi-nor.h | 292 ++++++++++++++++++++++++++++++--------------------------- 1 files changed, 153 insertions(+), 139 deletions(-) diff --git a/kernel/include/linux/mtd/spi-nor.h b/kernel/include/linux/mtd/spi-nor.h index c922e97..36d354a 100644 --- a/kernel/include/linux/mtd/spi-nor.h +++ b/kernel/include/linux/mtd/spi-nor.h @@ -1,10 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2014 Freescale Semiconductor, Inc. - * - * 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. */ #ifndef __LINUX_MTD_SPI_NOR_H @@ -13,21 +9,7 @@ #include <linux/bitops.h> #include <linux/mtd/cfi.h> #include <linux/mtd/mtd.h> - -/* - * Manufacturer IDs - * - * The first byte returned from the flash after sending opcode SPINOR_OP_RDID. - * Sometimes these are the same as CFI IDs, but sometimes they aren't. - */ -#define SNOR_MFR_ATMEL CFI_MFR_ATMEL -#define SNOR_MFR_GIGADEVICE 0xc8 -#define SNOR_MFR_INTEL CFI_MFR_INTEL -#define SNOR_MFR_MICRON CFI_MFR_ST /* ST Micro <--> Micron */ -#define SNOR_MFR_MACRONIX CFI_MFR_MACRONIX -#define SNOR_MFR_SPANSION CFI_MFR_AMD -#define SNOR_MFR_SST CFI_MFR_SST -#define SNOR_MFR_WINBOND 0xef /* Also used by some Spansion */ +#include <linux/spi/spi-mem.h> /* * Note on opcode nomenclature: some opcodes have a format like @@ -38,6 +20,7 @@ */ /* Flash opcodes. */ +#define SPINOR_OP_WRDI 0x04 /* Write disable */ #define SPINOR_OP_WREN 0x06 /* Write enable */ #define SPINOR_OP_RDSR 0x05 /* Read status register */ #define SPINOR_OP_WRSR 0x01 /* Write status register 1 byte */ @@ -49,9 +32,13 @@ #define SPINOR_OP_READ_1_2_2 0xbb /* Read data bytes (Dual I/O SPI) */ #define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad Output SPI) */ #define SPINOR_OP_READ_1_4_4 0xeb /* Read data bytes (Quad I/O SPI) */ +#define SPINOR_OP_READ_1_1_8 0x8b /* Read data bytes (Octal Output SPI) */ +#define SPINOR_OP_READ_1_8_8 0xcb /* Read data bytes (Octal I/O SPI) */ #define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */ #define SPINOR_OP_PP_1_1_4 0x32 /* Quad page program */ #define SPINOR_OP_PP_1_4_4 0x38 /* Quad page program */ +#define SPINOR_OP_PP_1_1_8 0x82 /* Octal page program */ +#define SPINOR_OP_PP_1_8_8 0xc2 /* Octal page program */ #define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */ #define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ #define SPINOR_OP_BE_32K 0x52 /* Erase 32KiB block */ @@ -60,6 +47,7 @@ #define SPINOR_OP_RDID 0x9f /* Read JEDEC ID */ #define SPINOR_OP_RDSFDP 0x5a /* Read SFDP */ #define SPINOR_OP_RDCR 0x35 /* Read configuration register */ +#define SPINOR_OP_WRCR 0x31 /* Write configure register */ #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ #define SPINOR_OP_RDEAR 0xc8 /* Read Extended Address Register */ @@ -72,9 +60,13 @@ #define SPINOR_OP_READ_1_2_2_4B 0xbc /* Read data bytes (Dual I/O SPI) */ #define SPINOR_OP_READ_1_1_4_4B 0x6c /* Read data bytes (Quad Output SPI) */ #define SPINOR_OP_READ_1_4_4_4B 0xec /* Read data bytes (Quad I/O SPI) */ +#define SPINOR_OP_READ_1_1_8_4B 0x7c /* Read data bytes (Octal Output SPI) */ +#define SPINOR_OP_READ_1_8_8_4B 0xcc /* Read data bytes (Octal I/O SPI) */ #define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */ #define SPINOR_OP_PP_1_1_4_4B 0x34 /* Quad page program */ #define SPINOR_OP_PP_1_4_4_4B 0x3e /* Quad page program */ +#define SPINOR_OP_PP_1_1_8_4B 0x84 /* Octal page program */ +#define SPINOR_OP_PP_1_8_8_4B 0x8e /* Octal page program */ #define SPINOR_OP_BE_4K_4B 0x21 /* Erase 4KiB block */ #define SPINOR_OP_BE_32K_4B 0x5c /* Erase 32KiB block */ #define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */ @@ -90,7 +82,6 @@ /* Used for SST flashes only. */ #define SPINOR_OP_BP 0x02 /* Byte program */ -#define SPINOR_OP_WRDI 0x04 /* Write disable */ #define SPINOR_OP_AAI_WP 0xad /* Auto address increment word program */ /* Used for S3AN flashes only */ @@ -121,13 +112,18 @@ #define SR_BP0 BIT(2) /* Block protect 0 */ #define SR_BP1 BIT(3) /* Block protect 1 */ #define SR_BP2 BIT(4) /* Block protect 2 */ -#define SR_TB BIT(5) /* Top/Bottom protect */ +#define SR_BP3 BIT(5) /* Block protect 3 */ +#define SR_TB_BIT5 BIT(5) /* Top/Bottom protect */ +#define SR_BP3_BIT6 BIT(6) /* Block protect 3 */ +#define SR_TB_BIT6 BIT(6) /* Top/Bottom protect */ #define SR_SRWD BIT(7) /* SR write protect */ /* Spansion/Cypress specific status bits */ #define SR_E_ERR BIT(5) #define SR_P_ERR BIT(6) -#define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */ +#define SR1_QUAD_EN_BIT6 BIT(6) + +#define SR_BP_SHIFT 2 /* Enhanced Volatile Configuration Register bits */ #define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */ @@ -138,10 +134,9 @@ #define FSR_P_ERR BIT(4) /* Program operation status */ #define FSR_PT_ERR BIT(1) /* Protection error bit */ -/* Configuration Register bits. */ -#define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */ - /* Status Register 2 bits. */ +#define SR2_QUAD_EN_BIT1 BIT(1) +#define SR2_QUAD_EN_BIT2 BIT(2) #define SR2_QUAD_EN_BIT7 BIT(7) /* Supported SPI protocols */ @@ -219,115 +214,6 @@ return spi_nor_get_protocol_data_nbits(proto); } -#define SPI_NOR_MAX_CMD_SIZE 8 -enum spi_nor_ops { - SPI_NOR_OPS_READ = 0, - SPI_NOR_OPS_WRITE, - SPI_NOR_OPS_ERASE, - SPI_NOR_OPS_LOCK, - SPI_NOR_OPS_UNLOCK, -}; - -enum spi_nor_option_flags { - SNOR_F_USE_FSR = BIT(0), - SNOR_F_HAS_SR_TB = BIT(1), - SNOR_F_NO_OP_CHIP_ERASE = BIT(2), - SNOR_F_S3AN_ADDR_DEFAULT = BIT(3), - SNOR_F_READY_XSR_RDY = BIT(4), - SNOR_F_USE_CLSR = BIT(5), - SNOR_F_BROKEN_RESET = BIT(6), -}; - -/** - * struct flash_info - Forward declaration of a structure used internally by - * spi_nor_scan() - */ -struct flash_info; - -/** - * struct spi_nor - Structure for defining a the SPI NOR layer - * @mtd: point to a mtd_info structure - * @lock: the lock for the read/write/erase/lock/unlock operations - * @dev: point to a spi device, or a spi nor controller device. - * @info: spi-nor part JDEC MFR id and other info - * @page_size: the page size of the SPI NOR - * @addr_width: number of address bytes - * @erase_opcode: the opcode for erasing a sector - * @read_opcode: the read opcode - * @read_dummy: the dummy needed by the read operation - * @program_opcode: the program opcode - * @sst_write_second: used by the SST write operation - * @flags: flag options for the current SPI-NOR (SNOR_F_*) - * @read_proto: the SPI protocol for read operations - * @write_proto: the SPI protocol for write operations - * @reg_proto the SPI protocol for read_reg/write_reg/erase operations - * @cmd_buf: used by the write_reg - * @prepare: [OPTIONAL] do some preparations for the - * read/write/erase/lock/unlock operations - * @unprepare: [OPTIONAL] do some post work after the - * read/write/erase/lock/unlock operations - * @read_reg: [DRIVER-SPECIFIC] read out the register - * @write_reg: [DRIVER-SPECIFIC] write data to the register - * @read: [DRIVER-SPECIFIC] read data from the SPI NOR - * @write: [DRIVER-SPECIFIC] write data to the SPI NOR - * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR - * at the offset @offs; if not provided by the driver, - * spi-nor will send the erase opcode via write_reg() - * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR - * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR - * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is - * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode - * completely locked - * @priv: the private data - */ -struct spi_nor { - struct mtd_info mtd; - struct mutex lock; - struct device *dev; - const struct flash_info *info; - u32 page_size; - u8 addr_width; - u8 erase_opcode; - u8 read_opcode; - u8 read_dummy; - u8 program_opcode; - enum spi_nor_protocol read_proto; - enum spi_nor_protocol write_proto; - enum spi_nor_protocol reg_proto; - bool sst_write_second; - u32 flags; - u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; - - int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops); - void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops); - int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len); - int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len); - - ssize_t (*read)(struct spi_nor *nor, loff_t from, - size_t len, u_char *read_buf); - ssize_t (*write)(struct spi_nor *nor, loff_t to, - size_t len, const u_char *write_buf); - int (*erase)(struct spi_nor *nor, loff_t offs); - - int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); - int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); - int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); - int (*quad_enable)(struct spi_nor *nor); - - void *priv; -}; - -static inline void spi_nor_set_flash_node(struct spi_nor *nor, - struct device_node *np) -{ - mtd_set_of_node(&nor->mtd, np); -} - -static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) -{ - return mtd_get_of_node(&nor->mtd); -} - /** * struct spi_nor_hwcaps - Structure for describing the hardware capabilies * supported by the SPI controller (bus master). @@ -340,7 +226,7 @@ /* *(Fast) Read capabilities. * MUST be ordered by priority: the higher bit position, the higher priority. - * As a matter of performances, it is relevant to use Octo SPI protocols first, + * As a matter of performances, it is relevant to use Octal SPI protocols first, * then Quad SPI protocols before Dual SPI protocols, Fast Read and lastly * (Slow) Read. */ @@ -361,7 +247,7 @@ #define SNOR_HWCAPS_READ_4_4_4 BIT(9) #define SNOR_HWCAPS_READ_1_4_4_DTR BIT(10) -#define SNOR_HWCPAS_READ_OCTO GENMASK(14, 11) +#define SNOR_HWCAPS_READ_OCTAL GENMASK(14, 11) #define SNOR_HWCAPS_READ_1_1_8 BIT(11) #define SNOR_HWCAPS_READ_1_8_8 BIT(12) #define SNOR_HWCAPS_READ_8_8_8 BIT(13) @@ -370,7 +256,7 @@ /* * Page Program capabilities. * MUST be ordered by priority: the higher bit position, the higher priority. - * Like (Fast) Read capabilities, Octo/Quad SPI protocols are preferred to the + * Like (Fast) Read capabilities, Octal/Quad SPI protocols are preferred to the * legacy SPI 1-1-1 protocol. * Note that Dual Page Programs are not supported because there is no existing * JEDEC/SFDP standard to define them. Also at this moment no SPI flash memory @@ -384,11 +270,139 @@ #define SNOR_HWCAPS_PP_1_4_4 BIT(18) #define SNOR_HWCAPS_PP_4_4_4 BIT(19) -#define SNOR_HWCAPS_PP_OCTO GENMASK(22, 20) +#define SNOR_HWCAPS_PP_OCTAL GENMASK(22, 20) #define SNOR_HWCAPS_PP_1_1_8 BIT(20) #define SNOR_HWCAPS_PP_1_8_8 BIT(21) #define SNOR_HWCAPS_PP_8_8_8 BIT(22) +#define SNOR_HWCAPS_X_X_X (SNOR_HWCAPS_READ_2_2_2 | \ + SNOR_HWCAPS_READ_4_4_4 | \ + SNOR_HWCAPS_READ_8_8_8 | \ + SNOR_HWCAPS_PP_4_4_4 | \ + SNOR_HWCAPS_PP_8_8_8) + +#define SNOR_HWCAPS_DTR (SNOR_HWCAPS_READ_1_1_1_DTR | \ + SNOR_HWCAPS_READ_1_2_2_DTR | \ + SNOR_HWCAPS_READ_1_4_4_DTR | \ + SNOR_HWCAPS_READ_1_8_8_DTR) + +#define SNOR_HWCAPS_ALL (SNOR_HWCAPS_READ_MASK | \ + SNOR_HWCAPS_PP_MASK) + +/* Forward declaration that is used in 'struct spi_nor_controller_ops' */ +struct spi_nor; + +/** + * struct spi_nor_controller_ops - SPI NOR controller driver specific + * operations. + * @prepare: [OPTIONAL] do some preparations for the + * read/write/erase/lock/unlock operations. + * @unprepare: [OPTIONAL] do some post work after the + * read/write/erase/lock/unlock operations. + * @read_reg: read out the register. + * @write_reg: write data to the register. + * @read: read data from the SPI NOR. + * @write: write data to the SPI NOR. + * @erase: erase a sector of the SPI NOR at the offset @offs; if + * not provided by the driver, SPI NOR will send the erase + * opcode via write_reg(). + */ +struct spi_nor_controller_ops { + int (*prepare)(struct spi_nor *nor); + void (*unprepare)(struct spi_nor *nor); + int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, size_t len); + int (*write_reg)(struct spi_nor *nor, u8 opcode, const u8 *buf, + size_t len); + + ssize_t (*read)(struct spi_nor *nor, loff_t from, size_t len, u8 *buf); + ssize_t (*write)(struct spi_nor *nor, loff_t to, size_t len, + const u8 *buf); + int (*erase)(struct spi_nor *nor, loff_t offs); +}; + +/* + * Forward declarations that are used internally by the core and manufacturer + * drivers. + */ +struct flash_info; +struct spi_nor_manufacturer; +struct spi_nor_flash_parameter; + +/** + * struct spi_nor - Structure for defining the SPI NOR layer + * @mtd: an mtd_info structure + * @lock: the lock for the read/write/erase/lock/unlock operations + * @dev: pointer to an SPI device or an SPI NOR controller device + * @spimem: pointer to the SPI memory device + * @bouncebuf: bounce buffer used when the buffer passed by the MTD + * layer is not DMA-able + * @bouncebuf_size: size of the bounce buffer + * @info: SPI NOR part JEDEC MFR ID and other info + * @manufacturer: SPI NOR manufacturer + * @page_size: the page size of the SPI NOR + * @addr_width: number of address bytes + * @erase_opcode: the opcode for erasing a sector + * @read_opcode: the read opcode + * @read_dummy: the dummy needed by the read operation + * @program_opcode: the program opcode + * @sst_write_second: used by the SST write operation + * @flags: flag options for the current SPI NOR (SNOR_F_*) + * @read_proto: the SPI protocol for read operations + * @write_proto: the SPI protocol for write operations + * @reg_proto: the SPI protocol for read_reg/write_reg/erase operations + * @controller_ops: SPI NOR controller driver specific operations. + * @params: [FLASH-SPECIFIC] SPI NOR flash parameters and settings. + * The structure includes legacy flash parameters and + * settings that can be overwritten by the spi_nor_fixups + * hooks, or dynamically when parsing the SFDP tables. + * @dirmap: pointers to struct spi_mem_dirmap_desc for reads/writes. + * @priv: pointer to the private data + */ +struct spi_nor { + struct mtd_info mtd; + struct mutex lock; + struct device *dev; + struct spi_mem *spimem; + u8 *bouncebuf; + size_t bouncebuf_size; + const struct flash_info *info; + const struct spi_nor_manufacturer *manufacturer; + u32 page_size; + u8 addr_width; + u8 erase_opcode; + u8 read_opcode; + u8 read_dummy; + u8 program_opcode; + enum spi_nor_protocol read_proto; + enum spi_nor_protocol write_proto; + enum spi_nor_protocol reg_proto; + bool sst_write_second; + u32 flags; + + const struct spi_nor_controller_ops *controller_ops; + + struct spi_nor_flash_parameter *params; + + struct { + struct spi_mem_dirmap_desc *rdesc; + struct spi_mem_dirmap_desc *wdesc; + } dirmap; + + struct miscdevice *misc_dev; + void *priv; +}; + +static inline void spi_nor_set_flash_node(struct spi_nor *nor, + struct device_node *np) +{ + mtd_set_of_node(&nor->mtd, np); +} + +static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) +{ + return mtd_get_of_node(&nor->mtd); +} + /** * spi_nor_scan() - scan the SPI NOR * @nor: the spi_nor structure -- Gitblit v1.6.2