mtd: spinand: Add support for GigaDevice GD5F1GQ4UFxxG
Subsystems (2)
v3 cover mtd: spinand: Add support for GigaDevice GD5F1GQ4UFxxG
Thanks for the time and suggestions in review.
Commit-message wording revised as suggested.
No changes in patch content.
Supersedes series:
[v2,1/3] mtd: spinand: Add #define-s for page-read ops with three-byte addresses
https://patchwork.ozlabs.org/project/linux-mtd/list/?series=107874
Jeff
PATCH v3 1/3 mtd: spinand: Define macros for page-read ops with three-byte addresses
From: Jeff Kletsky <[email protected]>
The GigaDevice GD5F1GQ4UFxxG SPI NAND utilizes three-byte addresses for its page-read ops.
http://www.gigadevice.com/datasheet/gd5f1gq4xfxxg/
--- include/linux/mtd/spinand.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
include/linux/mtd/spinand.h +30 -0
@@ -68,30 +68,60 @@ SPI_MEM_OP_DUMMY(ndummy, 1), \ SPI_MEM_OP_DATA_IN(len, buf, 1)) +#define SPINAND_PAGE_READ_FROM_CACHE_OP_3A (fast, addr, ndummy, buf, len) \ + SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1), \ + SPI_MEM_OP_ADDR(3, addr, 1), \ + SPI_MEM_OP_DUMMY(ndummy, 1), \ + SPI_MEM_OP_DATA_IN(len, buf, 1)) +#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP (addr, ndummy, buf, len) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \ SPI_MEM_OP_ADDR(2, addr, 1), \ SPI_MEM_OP_DUMMY(ndummy, 1), \ SPI_MEM_OP_DATA_IN(len, buf, 2)) +#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A (addr, ndummy, buf, len) \ + SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \ + SPI_MEM_OP_ADDR(3, addr, 1), \ + SPI_MEM_OP_DUMMY(ndummy, 1), \ + SPI_MEM_OP_DATA_IN(len, buf, 2)) +#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP (addr, ndummy, buf, len) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \ SPI_MEM_OP_ADDR(2, addr, 1), \ SPI_MEM_OP_DUMMY(ndummy, 1), \ SPI_MEM_OP_DATA_IN(len, buf, 4)) +#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A (addr, ndummy, buf, len) \ + SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \ + SPI_MEM_OP_ADDR(3, addr, 1), \ + SPI_MEM_OP_DUMMY(ndummy, 1), \ + SPI_MEM_OP_DATA_IN(len, buf, 4)) +#define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP (addr, ndummy, buf, len) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \ SPI_MEM_OP_ADDR(2, addr, 2), \ SPI_MEM_OP_DUMMY(ndummy, 2), \ SPI_MEM_OP_DATA_IN(len, buf, 2)) +#define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP_3A (addr, ndummy, buf, len) \ + SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \ + SPI_MEM_OP_ADDR(3, addr, 2), \ + SPI_MEM_OP_DUMMY(ndummy, 2), \ + SPI_MEM_OP_DATA_IN(len, buf, 2)) +#define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP (addr, ndummy, buf, len) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \ SPI_MEM_OP_ADDR(2, addr, 4), \ SPI_MEM_OP_DUMMY(ndummy, 4), \ SPI_MEM_OP_DATA_IN(len, buf, 4)) +#define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP_3A (addr, ndummy, buf, len) \ + SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \ + SPI_MEM_OP_ADDR(3, addr, 4), \ + SPI_MEM_OP_DUMMY(ndummy, 4), \ + SPI_MEM_OP_DATA_IN(len, buf, 4)) +#define SPINAND_PROG_EXEC_OP (addr) \ SPI_MEM_OP(SPI_MEM_OP_CMD(0x10, 1), \ SPI_MEM_OP_ADDR(3, addr, 1), \
Signature · 1 line
2.20.1
PATCH v3 2/3 mtd: spinand: Add support for two-byte device IDs
In reply to Jeff KletskyFrom: Jeff Kletsky <[email protected]>
The GigaDevice GD5F1GQ4UFxxG SPI NAND utilizes two-byte device IDs.
http://www.gigadevice.com/datasheet/gd5f1gq4xfxxg/
--- drivers/mtd/nand/spi/core.c | 2 +- include/linux/mtd/spinand.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/mtd/nand/spi/core.c +1 -1
@@ -853,7 +853,7 @@ spinand_select_op_variant(struct spinand_device *spinand,*/ int spinand_match_and_init (struct spinand_device *spinand,const struct spinand_info *table, -unsigned int table_size,u8 devid) +unsigned int table_size,u16 devid) {struct nand_device *nand =spinand_to_nand (spinand);unsigned int i;
include/linux/mtd/spinand.h +2 -2
@@ -290,7 +290,7 @@ struct spinand_ecc_info {*/ struct spinand_info {const char *model; -u8 devid; +u16 devid;u32 flags;struct nand_memory_organization memorg;struct nand_ecc_req eccreq;
@@ -445,7 +445,7 @@ static inline void spinand_set_of_node(struct spinand_device *spinand,int spinand_match_and_init (struct spinand_device *dev,const struct spinand_info *table, -unsigned int table_size,u8 devid); +unsigned int table_size,u16 devid);int spinand_upd_cfg (struct spinand_device *spinand,u8 mask,u8 val);int spinand_select_target (struct spinand_device *spinand,unsigned int target);
Signature · 1 line
2.20.1
PATCH v3 3/3 mtd: spinand: Add support for GigaDevice GD5F1GQ4UFxxG
In reply to Jeff KletskyFrom: Jeff Kletsky <[email protected]>
The GigaDevice GD5F1GQ4UFxxG SPI NAND is in current production devices and, while it has the same logical layout as the E-series devices, it differs in the SPI interfacing in significant ways.
This support is contingent on previous commits to:
* Add support for two-byte device IDs
* Define macros for page-read ops with three-byte addresses
http://www.gigadevice.com/datasheet/gd5f1gq4xfxxg/
--- drivers/mtd/nand/spi/gigadevice.c | 79 +++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 15 deletions(-)
drivers/mtd/nand/spi/gigadevice.c +64 -15
@@ -9,11 +9,17 @@#include <linux/mtd/spinand.h> #define SPINAND_MFR_GIGADEVICE 0xC8 +#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)#define GD5FXGQ4UEXXG_REG_STATUS2 0xf0 +#define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4) +#define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4) +#define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS (1 << 4) +#define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4) + static SPINAND_OP_VARIANTS(read_cache_variants, SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
@@ -22,6 +28,14 @@ static SPINAND_OP_VARIANTS(read_cache_variants,SPINAND_PAGE_READ_FROM_CACHE_OP (true,0 ,1 ,NULL ,0 ), SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); +static SPINAND_OP_VARIANTS(read_cache_variants_f, + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), +SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A (0 ,1 ,NULL ,0 ), +SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP (0 ,1 ,NULL ,0 ), +SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A (0 ,1 ,NULL ,0 ), +SPINAND_PAGE_READ_FROM_CACHE_OP_3A (true,0 ,1 ,NULL ,0 ), + SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0)); + static SPINAND_OP_VARIANTS(write_cache_variants, SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), SPINAND_PROG_LOAD(true, 0, NULL, 0));
@@ -59,6 +73,11 @@ static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,return 0 ; } +static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = { + .ecc = gd5fxgq4xa_ooblayout_ecc, + .free = gd5fxgq4xa_ooblayout_free, +}; +static int gd5fxgq4xa_ecc_get_status (struct spinand_device *spinand,u8 status) {
@@ -83,7 +102,7 @@ static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,return -EINVAL ; } -static int gd5fxgq4uexxg_ooblayout_ecc (struct mtd_info *mtd,int section, +static int gd5fxgq4_variant2_ooblayout_ecc (struct mtd_info *mtd,int section,struct mtd_oob_region *region) {if (section)
@@ -95,7 +114,7 @@ static int gd5fxgq4uexxg_ooblayout_ecc(struct mtd_info *mtd, int section,return 0 ; } -static int gd5fxgq4uexxg_ooblayout_free (struct mtd_info *mtd,int section, +static int gd5fxgq4_variant2_ooblayout_free (struct mtd_info *mtd,int section,struct mtd_oob_region *region) {if (section)
@@ -108,6 +127,11 @@ static int gd5fxgq4uexxg_ooblayout_free(struct mtd_info *mtd, int section,return 0 ; } +static const struct mtd_ooblayout_ops gd5fxgq4_variant2_ooblayout = { + .ecc = gd5fxgq4_variant2_ooblayout_ecc, + .free = gd5fxgq4_variant2_ooblayout_free, +}; +static int gd5fxgq4uexxg_ecc_get_status (struct spinand_device *spinand,u8 status) {
@@ -150,15 +174,25 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,return -EINVAL ; } -static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = { - .ecc = gd5fxgq4xa_ooblayout_ecc, - .free = gd5fxgq4xa_ooblayout_free, -}; +static int gd5fxgq4ufxxg_ecc_get_status (struct spinand_device *spinand, +u8 status) +{ +switch (status &GD5FXGQ4UXFXXG_STATUS_ECC_MASK ) { +case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS : +return 0 ; -static const struct mtd_ooblayout_ops gd5fxgq4uexxg_ooblayout = { - .ecc = gd5fxgq4uexxg_ooblayout_ecc, - .free = gd5fxgq4uexxg_ooblayout_free, -}; +case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS : +return 3 ; + +case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR : +return -EBADMSG ; + +default :/* (2 << 4) through (6 << 4) are 4-8 corrected errors */ +return ((status &GD5FXGQ4UXFXXG_STATUS_ECC_MASK ) >>4 ) +2 ; + } + +return -EINVAL ; +}static const struct spinand_info gigadevice_spinand_table[] = { SPINAND_INFO("GD5F1GQ4xA", 0xF1,
@@ -195,25 +229,40 @@ static const struct spinand_info gigadevice_spinand_table[] = { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&gd5fxgq4uexxg_ooblayout, + SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout, gd5fxgq4uexxg_ecc_get_status)), +SPINAND_INFO ("GD5F1GQ4UFxxG" ,0xb148 , +NAND_MEMORG (1 ,2048 ,128 ,64 ,1024 ,1 ,1 ,1 ), +NAND_ECCREQ (8 ,512 ), +SPINAND_INFO_OP_VARIANTS (&read_cache_variants_f, + &write_cache_variants, + &update_cache_variants), +0 , +SPINAND_ECCINFO (&gd5fxgq4_variant2_ooblayout, + gd5fxgq4ufxxg_ecc_get_status)), };static int gigadevice_spinand_detect (struct spinand_device *spinand) {u8 *id = spinand->id.data; +u16 did;int ret;/* -* For GD NANDs, There is an address byte needed to shift in before IDs -* are read out, so the first byte in raw_id is dummy. +* Earlier GDF5-series devices (A,E) return [0][MID][DID] +* Later (F) devices return [MID][DID1][DID2] */ -if (id[1 ] !=SPINAND_MFR_GIGADEVICE ) + +if (id[0 ] ==SPINAND_MFR_GIGADEVICE ) + did = (id[1 ] <<8 ) + id[2 ]; +else if (id[0 ] ==0 && id[1 ] ==SPINAND_MFR_GIGADEVICE ) + did = id[2 ]; +else return 0 ; ret =spinand_match_and_init (spinand, gigadevice_spinand_table,ARRAY_SIZE (gigadevice_spinand_table), - id[2 ]); + did);if (ret)return ret;
Signature · 1 line
2.20.1
Superseded by v4
https://patchwork.ozlabs.org/project/linux-mtd/list/?series=109337
which
Addresses changes in macros and related data structures introduced by
commit 377e517b5fa5
mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
Resolves issue detected by kbuild test robot
Tue, 21 May 2019 17:28:09 +0800
Tue, 21 May 2019 18:17:28 +0800
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/