14a725a41SJon Lin // SPDX-License-Identifier: GPL-2.0
24a725a41SJon Lin /*
34a725a41SJon Lin * Copyright (c) 2023 Rockchip Electronics Co., Ltd
44a725a41SJon Lin *
54a725a41SJon Lin * Authors:
64a725a41SJon Lin * Dingqiang Lin <jon.lin@rock-chips.com>
74a725a41SJon Lin */
84a725a41SJon Lin
94a725a41SJon Lin #ifndef __UBOOT__
104a725a41SJon Lin #include <linux/device.h>
114a725a41SJon Lin #include <linux/kernel.h>
124a725a41SJon Lin #endif
134a725a41SJon Lin #include <linux/mtd/spinand.h>
144a725a41SJon Lin
154a725a41SJon Lin #define SPINAND_MFR_GSTO 0x52
164a725a41SJon Lin
174a725a41SJon Lin static SPINAND_OP_VARIANTS(read_cache_variants,
184a725a41SJon Lin SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
194a725a41SJon Lin SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
204a725a41SJon Lin SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
214a725a41SJon Lin SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
224a725a41SJon Lin SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
234a725a41SJon Lin SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
244a725a41SJon Lin
254a725a41SJon Lin static SPINAND_OP_VARIANTS(write_cache_variants,
264a725a41SJon Lin SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
274a725a41SJon Lin SPINAND_PROG_LOAD(true, 0, NULL, 0));
284a725a41SJon Lin
294a725a41SJon Lin static SPINAND_OP_VARIANTS(update_cache_variants,
304a725a41SJon Lin SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
314a725a41SJon Lin SPINAND_PROG_LOAD(false, 0, NULL, 0));
324a725a41SJon Lin
gss0xgsak1_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)334a725a41SJon Lin static int gss0xgsak1_ooblayout_ecc(struct mtd_info *mtd, int section,
344a725a41SJon Lin struct mtd_oob_region *region)
354a725a41SJon Lin {
364a725a41SJon Lin if (section)
374a725a41SJon Lin return -ERANGE;
384a725a41SJon Lin
394a725a41SJon Lin region->offset = 32;
404a725a41SJon Lin region->length = 32;
414a725a41SJon Lin
424a725a41SJon Lin return 0;
434a725a41SJon Lin }
444a725a41SJon Lin
gss0xgsak1_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)454a725a41SJon Lin static int gss0xgsak1_ooblayout_free(struct mtd_info *mtd, int section,
464a725a41SJon Lin struct mtd_oob_region *region)
474a725a41SJon Lin {
484a725a41SJon Lin if (section)
494a725a41SJon Lin return -ERANGE;
504a725a41SJon Lin
514a725a41SJon Lin region->offset = 2;
524a725a41SJon Lin region->length = 30;
534a725a41SJon Lin
544a725a41SJon Lin return 0;
554a725a41SJon Lin }
564a725a41SJon Lin
574a725a41SJon Lin static const struct mtd_ooblayout_ops gss0xgsak1_ooblayout = {
584a725a41SJon Lin .ecc = gss0xgsak1_ooblayout_ecc,
594a725a41SJon Lin .rfree = gss0xgsak1_ooblayout_free,
604a725a41SJon Lin };
614a725a41SJon Lin
gss0xgsax1_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)6211dada4eSJon Lin static int gss0xgsax1_ooblayout_ecc(struct mtd_info *mtd, int section,
6311dada4eSJon Lin struct mtd_oob_region *region)
6411dada4eSJon Lin {
6511dada4eSJon Lin if (section)
6611dada4eSJon Lin return -ERANGE;
6711dada4eSJon Lin
6811dada4eSJon Lin region->offset = 64;
6911dada4eSJon Lin region->length = 64;
7011dada4eSJon Lin
7111dada4eSJon Lin return 0;
7211dada4eSJon Lin }
7311dada4eSJon Lin
gss0xgsax1_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)7411dada4eSJon Lin static int gss0xgsax1_ooblayout_free(struct mtd_info *mtd, int section,
7511dada4eSJon Lin struct mtd_oob_region *region)
7611dada4eSJon Lin {
7711dada4eSJon Lin if (section)
7811dada4eSJon Lin return -ERANGE;
7911dada4eSJon Lin
8011dada4eSJon Lin region->offset = 2;
8111dada4eSJon Lin region->length = 62;
8211dada4eSJon Lin
8311dada4eSJon Lin return 0;
8411dada4eSJon Lin }
8511dada4eSJon Lin
8611dada4eSJon Lin static const struct mtd_ooblayout_ops gss0xgsax1_ooblayout = {
8711dada4eSJon Lin .ecc = gss0xgsax1_ooblayout_ecc,
8811dada4eSJon Lin .rfree = gss0xgsax1_ooblayout_free,
8911dada4eSJon Lin };
9011dada4eSJon Lin
914a725a41SJon Lin static const struct spinand_info gsto_spinand_table[] = {
924a725a41SJon Lin SPINAND_INFO("GSS01GSAK1",
934a725a41SJon Lin SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBA, 0x13),
944a725a41SJon Lin NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
954a725a41SJon Lin NAND_ECCREQ(4, 512),
964a725a41SJon Lin SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
974a725a41SJon Lin &write_cache_variants,
984a725a41SJon Lin &update_cache_variants),
994a725a41SJon Lin 0,
1004a725a41SJon Lin SPINAND_ECCINFO(&gss0xgsak1_ooblayout, NULL)),
1014a725a41SJon Lin SPINAND_INFO("GSS02GSAK1",
1024a725a41SJon Lin SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBA, 0x23),
1034a725a41SJon Lin NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
1044a725a41SJon Lin NAND_ECCREQ(4, 512),
1054a725a41SJon Lin SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
1064a725a41SJon Lin &write_cache_variants,
1074a725a41SJon Lin &update_cache_variants),
1084a725a41SJon Lin 0,
1095d41499fSJon Lin SPINAND_ECCINFO(&gss0xgsax1_ooblayout, NULL)),
11011dada4eSJon Lin SPINAND_INFO("GSS02GSAX1",
1115d41499fSJon Lin SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCA, 0x23),
11211dada4eSJon Lin NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
11311dada4eSJon Lin NAND_ECCREQ(8, 512),
11411dada4eSJon Lin SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
11511dada4eSJon Lin &write_cache_variants,
11611dada4eSJon Lin &update_cache_variants),
11711dada4eSJon Lin 0,
11811dada4eSJon Lin SPINAND_ECCINFO(&gss0xgsax1_ooblayout, NULL)),
11911dada4eSJon Lin SPINAND_INFO("GSS01GSAX1",
1205d41499fSJon Lin SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCA, 0x13),
12111dada4eSJon Lin NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
12211dada4eSJon Lin NAND_ECCREQ(8, 512),
12311dada4eSJon Lin SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
12411dada4eSJon Lin &write_cache_variants,
12511dada4eSJon Lin &update_cache_variants),
12611dada4eSJon Lin 0,
12711dada4eSJon Lin SPINAND_ECCINFO(&gss0xgsax1_ooblayout, NULL)),
128*aac263efSJon Lin SPINAND_INFO("GSS01GSBX1",
129*aac263efSJon Lin SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB, 0x13),
130*aac263efSJon Lin NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
131*aac263efSJon Lin NAND_ECCREQ(8, 512),
132*aac263efSJon Lin SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
133*aac263efSJon Lin &write_cache_variants,
134*aac263efSJon Lin &update_cache_variants),
135*aac263efSJon Lin 0,
136*aac263efSJon Lin SPINAND_ECCINFO(&gss0xgsax1_ooblayout, NULL)),
1374a725a41SJon Lin };
1384a725a41SJon Lin
1394a725a41SJon Lin static const struct spinand_manufacturer_ops gsto_spinand_manuf_ops = {
1404a725a41SJon Lin };
1414a725a41SJon Lin
1424a725a41SJon Lin const struct spinand_manufacturer gsto_spinand_manufacturer = {
1434a725a41SJon Lin .id = SPINAND_MFR_GSTO,
1444a725a41SJon Lin .name = "GSTO",
1454a725a41SJon Lin .chips = gsto_spinand_table,
1464a725a41SJon Lin .nchips = ARRAY_SIZE(gsto_spinand_table),
1474a725a41SJon Lin .ops = &gsto_spinand_manuf_ops,
1484a725a41SJon Lin };
149