15e3003c6SJon Lin // SPDX-License-Identifier: GPL-2.0
25e3003c6SJon Lin /*
35e3003c6SJon Lin * Copyright (c) 2024 Rockchip Electronics Co., Ltd
45e3003c6SJon Lin *
55e3003c6SJon Lin * Authors:
65e3003c6SJon Lin * Dingqiang Lin <jon.lin@rock-chips.com>
75e3003c6SJon Lin */
85e3003c6SJon Lin
95e3003c6SJon Lin #ifndef __UBOOT__
105e3003c6SJon Lin #include <linux/device.h>
115e3003c6SJon Lin #include <linux/kernel.h>
125e3003c6SJon Lin #endif
135e3003c6SJon Lin #include <linux/mtd/spinand.h>
145e3003c6SJon Lin
155e3003c6SJon Lin #define SPINAND_MFR_HIKSEMI 0x3C
165e3003c6SJon Lin
175e3003c6SJon Lin static SPINAND_OP_VARIANTS(read_cache_variants,
185e3003c6SJon Lin SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
195e3003c6SJon Lin SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
205e3003c6SJon Lin SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
215e3003c6SJon Lin SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
225e3003c6SJon Lin SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
235e3003c6SJon Lin SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
245e3003c6SJon Lin
255e3003c6SJon Lin static SPINAND_OP_VARIANTS(write_cache_variants,
265e3003c6SJon Lin SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
275e3003c6SJon Lin SPINAND_PROG_LOAD(true, 0, NULL, 0));
285e3003c6SJon Lin
295e3003c6SJon Lin static SPINAND_OP_VARIANTS(update_cache_variants,
305e3003c6SJon Lin SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
315e3003c6SJon Lin SPINAND_PROG_LOAD(false, 0, NULL, 0));
325e3003c6SJon Lin
hsesyhdswxg_ooblayout_ecc(struct mtd_info * mtd,int section,struct mtd_oob_region * region)335e3003c6SJon Lin static int hsesyhdswxg_ooblayout_ecc(struct mtd_info *mtd, int section,
345e3003c6SJon Lin struct mtd_oob_region *region)
355e3003c6SJon Lin {
365e3003c6SJon Lin if (section)
375e3003c6SJon Lin return -ERANGE;
385e3003c6SJon Lin
395e3003c6SJon Lin region->offset = 64;
405e3003c6SJon Lin region->length = 64;
415e3003c6SJon Lin
425e3003c6SJon Lin return 0;
435e3003c6SJon Lin }
445e3003c6SJon Lin
hsesyhdswxg_ooblayout_free(struct mtd_info * mtd,int section,struct mtd_oob_region * region)455e3003c6SJon Lin static int hsesyhdswxg_ooblayout_free(struct mtd_info *mtd, int section,
465e3003c6SJon Lin struct mtd_oob_region *region)
475e3003c6SJon Lin {
485e3003c6SJon Lin if (section)
495e3003c6SJon Lin return -ERANGE;
505e3003c6SJon Lin
515e3003c6SJon Lin region->offset = 2;
525e3003c6SJon Lin region->length = 62;
535e3003c6SJon Lin
545e3003c6SJon Lin return 0;
555e3003c6SJon Lin }
565e3003c6SJon Lin
575e3003c6SJon Lin static const struct mtd_ooblayout_ops hsesyhdswxg_ooblayout = {
585e3003c6SJon Lin .ecc = hsesyhdswxg_ooblayout_ecc,
595e3003c6SJon Lin .rfree = hsesyhdswxg_ooblayout_free,
605e3003c6SJon Lin };
615e3003c6SJon Lin
625e3003c6SJon Lin static const struct spinand_info hiksemi_spinand_table[] = {
635e3003c6SJon Lin SPINAND_INFO("HSESYHDSW2G",
645e3003c6SJon Lin SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
655e3003c6SJon Lin NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
665e3003c6SJon Lin NAND_ECCREQ(4, 512),
675e3003c6SJon Lin SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
685e3003c6SJon Lin &write_cache_variants,
695e3003c6SJon Lin &update_cache_variants),
705e3003c6SJon Lin 0,
715e3003c6SJon Lin SPINAND_ECCINFO(&hsesyhdswxg_ooblayout, NULL)),
72*0233d049SJon Lin SPINAND_INFO("HSESDFDSW4G",
73*0233d049SJon Lin SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
74*0233d049SJon Lin NAND_MEMORG(1, 2048, 128, 64, 4096, 1, 1, 1),
75*0233d049SJon Lin NAND_ECCREQ(4, 512),
76*0233d049SJon Lin SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
77*0233d049SJon Lin &write_cache_variants,
78*0233d049SJon Lin &update_cache_variants),
79*0233d049SJon Lin 0,
80*0233d049SJon Lin SPINAND_ECCINFO(&hsesyhdswxg_ooblayout, NULL)),
815e3003c6SJon Lin };
825e3003c6SJon Lin
835e3003c6SJon Lin static const struct spinand_manufacturer_ops hiksemi_spinand_manuf_ops = {
845e3003c6SJon Lin };
855e3003c6SJon Lin
865e3003c6SJon Lin const struct spinand_manufacturer hiksemi_spinand_manufacturer = {
875e3003c6SJon Lin .id = SPINAND_MFR_HIKSEMI,
885e3003c6SJon Lin .name = "HIKSEMI",
895e3003c6SJon Lin .chips = hiksemi_spinand_table,
905e3003c6SJon Lin .nchips = ARRAY_SIZE(hiksemi_spinand_table),
915e3003c6SJon Lin .ops = &hiksemi_spinand_manuf_ops,
925e3003c6SJon Lin };
93