cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gigadevice.c (16696B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Author:
      4 *	Chuanhong Guo <gch981213@gmail.com>
      5 */
      6
      7#include <linux/device.h>
      8#include <linux/kernel.h>
      9#include <linux/mtd/spinand.h>
     10
     11#define SPINAND_MFR_GIGADEVICE			0xC8
     12
     13#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS	(1 << 4)
     14#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS	(3 << 4)
     15
     16#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS	(1 << 4)
     17#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS	(3 << 4)
     18
     19#define GD5FXGQXXEXXG_REG_STATUS2		0xf0
     20
     21#define GD5FXGQ4UXFXXG_STATUS_ECC_MASK		(7 << 4)
     22#define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS	(0 << 4)
     23#define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS	(1 << 4)
     24#define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR	(7 << 4)
     25
     26static SPINAND_OP_VARIANTS(read_cache_variants,
     27		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
     28		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
     29		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
     30		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
     31		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
     32		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
     33
     34static SPINAND_OP_VARIANTS(read_cache_variants_f,
     35		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
     36		SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0),
     37		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
     38		SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0),
     39		SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
     40		SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
     41
     42static SPINAND_OP_VARIANTS(read_cache_variants_1gq5,
     43		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
     44		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
     45		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
     46		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
     47		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
     48		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
     49
     50static SPINAND_OP_VARIANTS(read_cache_variants_2gq5,
     51		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0),
     52		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
     53		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0),
     54		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
     55		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
     56		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
     57
     58static SPINAND_OP_VARIANTS(write_cache_variants,
     59		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
     60		SPINAND_PROG_LOAD(true, 0, NULL, 0));
     61
     62static SPINAND_OP_VARIANTS(update_cache_variants,
     63		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
     64		SPINAND_PROG_LOAD(false, 0, NULL, 0));
     65
     66static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
     67				  struct mtd_oob_region *region)
     68{
     69	if (section > 3)
     70		return -ERANGE;
     71
     72	region->offset = (16 * section) + 8;
     73	region->length = 8;
     74
     75	return 0;
     76}
     77
     78static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
     79				   struct mtd_oob_region *region)
     80{
     81	if (section > 3)
     82		return -ERANGE;
     83
     84	if (section) {
     85		region->offset = 16 * section;
     86		region->length = 8;
     87	} else {
     88		/* section 0 has one byte reserved for bad block mark */
     89		region->offset = 1;
     90		region->length = 7;
     91	}
     92	return 0;
     93}
     94
     95static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
     96	.ecc = gd5fxgq4xa_ooblayout_ecc,
     97	.free = gd5fxgq4xa_ooblayout_free,
     98};
     99
    100static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
    101					 u8 status)
    102{
    103	switch (status & STATUS_ECC_MASK) {
    104	case STATUS_ECC_NO_BITFLIPS:
    105		return 0;
    106
    107	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
    108		/* 1-7 bits are flipped. return the maximum. */
    109		return 7;
    110
    111	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
    112		return 8;
    113
    114	case STATUS_ECC_UNCOR_ERROR:
    115		return -EBADMSG;
    116
    117	default:
    118		break;
    119	}
    120
    121	return -EINVAL;
    122}
    123
    124static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
    125				       struct mtd_oob_region *region)
    126{
    127	if (section)
    128		return -ERANGE;
    129
    130	region->offset = 64;
    131	region->length = 64;
    132
    133	return 0;
    134}
    135
    136static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
    137					struct mtd_oob_region *region)
    138{
    139	if (section)
    140		return -ERANGE;
    141
    142	/* Reserve 1 bytes for the BBM. */
    143	region->offset = 1;
    144	region->length = 63;
    145
    146	return 0;
    147}
    148
    149/* Valid for Q4/Q5 and Q6 (untested) devices */
    150static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
    151	.ecc = gd5fxgqx_variant2_ooblayout_ecc,
    152	.free = gd5fxgqx_variant2_ooblayout_free,
    153};
    154
    155static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
    156					struct mtd_oob_region *oobregion)
    157{
    158	if (section)
    159		return -ERANGE;
    160
    161	oobregion->offset = 128;
    162	oobregion->length = 128;
    163
    164	return 0;
    165}
    166
    167static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
    168					 struct mtd_oob_region *oobregion)
    169{
    170	if (section)
    171		return -ERANGE;
    172
    173	oobregion->offset = 1;
    174	oobregion->length = 127;
    175
    176	return 0;
    177}
    178
    179static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
    180	.ecc = gd5fxgq4xc_ooblayout_256_ecc,
    181	.free = gd5fxgq4xc_ooblayout_256_free,
    182};
    183
    184static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
    185					u8 status)
    186{
    187	u8 status2;
    188	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
    189						      &status2);
    190	int ret;
    191
    192	switch (status & STATUS_ECC_MASK) {
    193	case STATUS_ECC_NO_BITFLIPS:
    194		return 0;
    195
    196	case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
    197		/*
    198		 * Read status2 register to determine a more fine grained
    199		 * bit error status
    200		 */
    201		ret = spi_mem_exec_op(spinand->spimem, &op);
    202		if (ret)
    203			return ret;
    204
    205		/*
    206		 * 4 ... 7 bits are flipped (1..4 can't be detected, so
    207		 * report the maximum of 4 in this case
    208		 */
    209		/* bits sorted this way (3...0): ECCS1,ECCS0,ECCSE1,ECCSE0 */
    210		return ((status & STATUS_ECC_MASK) >> 2) |
    211			((status2 & STATUS_ECC_MASK) >> 4);
    212
    213	case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
    214		return 8;
    215
    216	case STATUS_ECC_UNCOR_ERROR:
    217		return -EBADMSG;
    218
    219	default:
    220		break;
    221	}
    222
    223	return -EINVAL;
    224}
    225
    226static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
    227					u8 status)
    228{
    229	u8 status2;
    230	struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
    231						      &status2);
    232	int ret;
    233
    234	switch (status & STATUS_ECC_MASK) {
    235	case STATUS_ECC_NO_BITFLIPS:
    236		return 0;
    237
    238	case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
    239		/*
    240		 * Read status2 register to determine a more fine grained
    241		 * bit error status
    242		 */
    243		ret = spi_mem_exec_op(spinand->spimem, &op);
    244		if (ret)
    245			return ret;
    246
    247		/*
    248		 * 1 ... 4 bits are flipped (and corrected)
    249		 */
    250		/* bits sorted this way (1...0): ECCSE1, ECCSE0 */
    251		return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
    252
    253	case STATUS_ECC_UNCOR_ERROR:
    254		return -EBADMSG;
    255
    256	default:
    257		break;
    258	}
    259
    260	return -EINVAL;
    261}
    262
    263static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
    264					u8 status)
    265{
    266	switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
    267	case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
    268		return 0;
    269
    270	case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
    271		return 3;
    272
    273	case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
    274		return -EBADMSG;
    275
    276	default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
    277		return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
    278	}
    279
    280	return -EINVAL;
    281}
    282
    283static const struct spinand_info gigadevice_spinand_table[] = {
    284	SPINAND_INFO("GD5F1GQ4xA",
    285		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
    286		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
    287		     NAND_ECCREQ(8, 512),
    288		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    289					      &write_cache_variants,
    290					      &update_cache_variants),
    291		     SPINAND_HAS_QE_BIT,
    292		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
    293				     gd5fxgq4xa_ecc_get_status)),
    294	SPINAND_INFO("GD5F2GQ4xA",
    295		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
    296		     NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
    297		     NAND_ECCREQ(8, 512),
    298		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    299					      &write_cache_variants,
    300					      &update_cache_variants),
    301		     SPINAND_HAS_QE_BIT,
    302		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
    303				     gd5fxgq4xa_ecc_get_status)),
    304	SPINAND_INFO("GD5F4GQ4xA",
    305		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
    306		     NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
    307		     NAND_ECCREQ(8, 512),
    308		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    309					      &write_cache_variants,
    310					      &update_cache_variants),
    311		     SPINAND_HAS_QE_BIT,
    312		     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
    313				     gd5fxgq4xa_ecc_get_status)),
    314	SPINAND_INFO("GD5F4GQ4RC",
    315		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
    316		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
    317		     NAND_ECCREQ(8, 512),
    318		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
    319					      &write_cache_variants,
    320					      &update_cache_variants),
    321		     SPINAND_HAS_QE_BIT,
    322		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
    323				     gd5fxgq4ufxxg_ecc_get_status)),
    324	SPINAND_INFO("GD5F4GQ4UC",
    325		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
    326		     NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
    327		     NAND_ECCREQ(8, 512),
    328		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
    329					      &write_cache_variants,
    330					      &update_cache_variants),
    331		     SPINAND_HAS_QE_BIT,
    332		     SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
    333				     gd5fxgq4ufxxg_ecc_get_status)),
    334	SPINAND_INFO("GD5F1GQ4UExxG",
    335		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
    336		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    337		     NAND_ECCREQ(8, 512),
    338		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    339					      &write_cache_variants,
    340					      &update_cache_variants),
    341		     SPINAND_HAS_QE_BIT,
    342		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    343				     gd5fxgq4uexxg_ecc_get_status)),
    344	SPINAND_INFO("GD5F1GQ4RExxG",
    345		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1),
    346		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    347		     NAND_ECCREQ(8, 512),
    348		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    349					      &write_cache_variants,
    350					      &update_cache_variants),
    351		     SPINAND_HAS_QE_BIT,
    352		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    353				     gd5fxgq4uexxg_ecc_get_status)),
    354	SPINAND_INFO("GD5F2GQ4UExxG",
    355		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2),
    356		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
    357		     NAND_ECCREQ(8, 512),
    358		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    359					      &write_cache_variants,
    360					      &update_cache_variants),
    361		     SPINAND_HAS_QE_BIT,
    362		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    363				     gd5fxgq4uexxg_ecc_get_status)),
    364	SPINAND_INFO("GD5F2GQ4RExxG",
    365		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2),
    366		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
    367		     NAND_ECCREQ(8, 512),
    368		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
    369					      &write_cache_variants,
    370					      &update_cache_variants),
    371		     SPINAND_HAS_QE_BIT,
    372		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    373				     gd5fxgq4uexxg_ecc_get_status)),
    374	SPINAND_INFO("GD5F1GQ4UFxxG",
    375		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
    376		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    377		     NAND_ECCREQ(8, 512),
    378		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
    379					      &write_cache_variants,
    380					      &update_cache_variants),
    381		     SPINAND_HAS_QE_BIT,
    382		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    383				     gd5fxgq4ufxxg_ecc_get_status)),
    384	SPINAND_INFO("GD5F1GQ5UExxG",
    385		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
    386		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    387		     NAND_ECCREQ(4, 512),
    388		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
    389					      &write_cache_variants,
    390					      &update_cache_variants),
    391		     SPINAND_HAS_QE_BIT,
    392		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    393				     gd5fxgq5xexxg_ecc_get_status)),
    394	SPINAND_INFO("GD5F1GQ5RExxG",
    395		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41),
    396		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    397		     NAND_ECCREQ(4, 512),
    398		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
    399					      &write_cache_variants,
    400					      &update_cache_variants),
    401		     SPINAND_HAS_QE_BIT,
    402		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    403				     gd5fxgq5xexxg_ecc_get_status)),
    404	SPINAND_INFO("GD5F2GQ5UExxG",
    405		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52),
    406		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
    407		     NAND_ECCREQ(4, 512),
    408		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
    409					      &write_cache_variants,
    410					      &update_cache_variants),
    411		     SPINAND_HAS_QE_BIT,
    412		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    413				     gd5fxgq5xexxg_ecc_get_status)),
    414	SPINAND_INFO("GD5F2GQ5RExxG",
    415		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42),
    416		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
    417		     NAND_ECCREQ(4, 512),
    418		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
    419					      &write_cache_variants,
    420					      &update_cache_variants),
    421		     SPINAND_HAS_QE_BIT,
    422		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    423				     gd5fxgq5xexxg_ecc_get_status)),
    424	SPINAND_INFO("GD5F4GQ6UExxG",
    425		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55),
    426		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
    427		     NAND_ECCREQ(4, 512),
    428		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
    429					      &write_cache_variants,
    430					      &update_cache_variants),
    431		     SPINAND_HAS_QE_BIT,
    432		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    433				     gd5fxgq5xexxg_ecc_get_status)),
    434	SPINAND_INFO("GD5F4GQ6RExxG",
    435		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45),
    436		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1),
    437		     NAND_ECCREQ(4, 512),
    438		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5,
    439					      &write_cache_variants,
    440					      &update_cache_variants),
    441		     SPINAND_HAS_QE_BIT,
    442		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    443				     gd5fxgq5xexxg_ecc_get_status)),
    444	SPINAND_INFO("GD5F1GM7UExxG",
    445		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91),
    446		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    447		     NAND_ECCREQ(8, 512),
    448		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
    449					      &write_cache_variants,
    450					      &update_cache_variants),
    451		     SPINAND_HAS_QE_BIT,
    452		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    453				     gd5fxgq4uexxg_ecc_get_status)),
    454	SPINAND_INFO("GD5F1GM7RExxG",
    455		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81),
    456		     NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
    457		     NAND_ECCREQ(8, 512),
    458		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
    459					      &write_cache_variants,
    460					      &update_cache_variants),
    461		     SPINAND_HAS_QE_BIT,
    462		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    463				     gd5fxgq4uexxg_ecc_get_status)),
    464	SPINAND_INFO("GD5F2GM7UExxG",
    465		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
    466		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
    467		     NAND_ECCREQ(8, 512),
    468		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
    469					      &write_cache_variants,
    470					      &update_cache_variants),
    471		     SPINAND_HAS_QE_BIT,
    472		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    473				     gd5fxgq4uexxg_ecc_get_status)),
    474	SPINAND_INFO("GD5F2GM7RExxG",
    475		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82),
    476		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
    477		     NAND_ECCREQ(8, 512),
    478		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
    479					      &write_cache_variants,
    480					      &update_cache_variants),
    481		     SPINAND_HAS_QE_BIT,
    482		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    483				     gd5fxgq4uexxg_ecc_get_status)),
    484	SPINAND_INFO("GD5F4GM8UExxG",
    485		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95),
    486		     NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
    487		     NAND_ECCREQ(8, 512),
    488		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
    489					      &write_cache_variants,
    490					      &update_cache_variants),
    491		     SPINAND_HAS_QE_BIT,
    492		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    493				     gd5fxgq4uexxg_ecc_get_status)),
    494	SPINAND_INFO("GD5F4GM8RExxG",
    495		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85),
    496		     NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
    497		     NAND_ECCREQ(8, 512),
    498		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
    499					      &write_cache_variants,
    500					      &update_cache_variants),
    501		     SPINAND_HAS_QE_BIT,
    502		     SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
    503				     gd5fxgq4uexxg_ecc_get_status)),
    504};
    505
    506static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
    507};
    508
    509const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
    510	.id = SPINAND_MFR_GIGADEVICE,
    511	.name = "GigaDevice",
    512	.chips = gigadevice_spinand_table,
    513	.nchips = ARRAY_SIZE(gigadevice_spinand_table),
    514	.ops = &gigadevice_spinand_manuf_ops,
    515};