xref: /rk3399_rockchip-uboot/drivers/mtd/nand/spi/silicongo.c (revision 81afcfe1f95ac45ca73ae8b8dd7c330fb6ed9d81)
168df10e3SJon Lin // SPDX-License-Identifier: GPL-2.0
268df10e3SJon Lin /*
368df10e3SJon Lin  * Copyright (c) 2020 Grandstream Networks, Inc
468df10e3SJon Lin  *
568df10e3SJon Lin  * Authors:
668df10e3SJon Lin  *	Carl <xjxia@grandstream.cn>
768df10e3SJon Lin  */
868df10e3SJon Lin 
968df10e3SJon Lin #ifndef __UBOOT__
1068df10e3SJon Lin #include <linux/device.h>
1168df10e3SJon Lin #include <linux/kernel.h>
1268df10e3SJon Lin #endif
1368df10e3SJon Lin #include <linux/mtd/spinand.h>
1468df10e3SJon Lin 
1568df10e3SJon Lin #define SPINAND_MFR_SILICONGO		0xEA
1668df10e3SJon Lin 
1768df10e3SJon Lin static SPINAND_OP_VARIANTS(read_cache_variants,
1868df10e3SJon Lin 		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
1968df10e3SJon Lin 		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
2068df10e3SJon Lin 		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
2168df10e3SJon Lin 		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
2268df10e3SJon Lin 		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
2368df10e3SJon Lin 		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
2468df10e3SJon Lin 
2568df10e3SJon Lin static SPINAND_OP_VARIANTS(write_cache_variants,
2668df10e3SJon Lin 		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
2768df10e3SJon Lin 		SPINAND_PROG_LOAD(true, 0, NULL, 0));
2868df10e3SJon Lin 
2968df10e3SJon Lin static SPINAND_OP_VARIANTS(update_cache_variants,
3068df10e3SJon Lin 		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
3168df10e3SJon Lin 		SPINAND_PROG_LOAD(false, 0, NULL, 0));
3268df10e3SJon Lin 
sgm7000i_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)3368df10e3SJon Lin static int sgm7000i_ooblayout_ecc(struct mtd_info *mtd, int section,
3468df10e3SJon Lin 				  struct mtd_oob_region *region)
3568df10e3SJon Lin {
3668df10e3SJon Lin 	return -ERANGE;
3768df10e3SJon Lin }
3868df10e3SJon Lin 
sgm7000i_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)3968df10e3SJon Lin static int sgm7000i_ooblayout_free(struct mtd_info *mtd, int section,
4068df10e3SJon Lin 				   struct mtd_oob_region *region)
4168df10e3SJon Lin {
4268df10e3SJon Lin 	if (section)
4368df10e3SJon Lin 		return -ERANGE;
4468df10e3SJon Lin 
4568df10e3SJon Lin 	region->offset = 2;
4668df10e3SJon Lin 	region->length = mtd->oobsize - 2;
4768df10e3SJon Lin 
4868df10e3SJon Lin 	return 0;
4968df10e3SJon Lin }
5068df10e3SJon Lin 
5168df10e3SJon Lin static const struct mtd_ooblayout_ops sgm7000i_ooblayout = {
5268df10e3SJon Lin 	.ecc = sgm7000i_ooblayout_ecc,
5368df10e3SJon Lin 	.rfree = sgm7000i_ooblayout_free,
5468df10e3SJon Lin };
5568df10e3SJon Lin 
5668df10e3SJon Lin static const struct spinand_info silicongo_spinand_table[] = {
57*81afcfe1SJon Lin 	SPINAND_INFO("SGM7000I-S24W1GH",
58*81afcfe1SJon Lin 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC1),
5968df10e3SJon Lin 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
6068df10e3SJon Lin 		     NAND_ECCREQ(4, 512),
6168df10e3SJon Lin 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
6268df10e3SJon Lin 					      &write_cache_variants,
6368df10e3SJon Lin 					      &update_cache_variants),
6468df10e3SJon Lin 		     SPINAND_HAS_QE_BIT,
6568df10e3SJon Lin 		     SPINAND_ECCINFO(&sgm7000i_ooblayout, NULL)),
6668df10e3SJon Lin };
6768df10e3SJon Lin 
6868df10e3SJon Lin static const struct spinand_manufacturer_ops silicongo_spinand_manuf_ops = {
6968df10e3SJon Lin };
7068df10e3SJon Lin 
7168df10e3SJon Lin const struct spinand_manufacturer silicongo_spinand_manufacturer = {
7268df10e3SJon Lin 	.id = SPINAND_MFR_SILICONGO,
7368df10e3SJon Lin 	.name = "silicongo",
74*81afcfe1SJon Lin 	.chips = silicongo_spinand_table,
75*81afcfe1SJon Lin 	.nchips = ARRAY_SIZE(silicongo_spinand_table),
7668df10e3SJon Lin 	.ops = &silicongo_spinand_manuf_ops,
7768df10e3SJon Lin };
78