forked from openwrt/openwrt
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
kernel: 5.15: add support for ESMT F50x1G41LB
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
- Loading branch information
Showing
1 changed file
with
143 additions
and
0 deletions.
There are no files selected for viewing
143 changes: 143 additions & 0 deletions
143
target/linux/generic/pending-5.15/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
From a43b844cb40bf1b783055fdc81b7f991e21e7e76 Mon Sep 17 00:00:00 2001 | ||
From: Chuanhong Guo <gch981213@gmail.com> | ||
Date: Wed, 13 Apr 2022 11:58:17 +0800 | ||
Subject: [PATCH] mtd: spinand: add support for ESMT F50x1G41LB | ||
|
||
This patch adds support for ESMT F50L1G41LB and F50D1G41LB. | ||
It seems that ESMT likes to use random JEDEC ID from other vendors. | ||
Their 1G chips uses 0xc8 from GigaDevice and 2G/4G chips uses 0x2c from | ||
Micron. For this reason, the ESMT entry is named esmt_c8 with explicit | ||
JEDEC ID in variable name. | ||
|
||
Datasheets: | ||
https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50L1G41LB(2M).pdf | ||
https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50D1G41LB(2M).pdf | ||
|
||
Signed-off-by: Chuanhong Guo <gch981213@gmail.com> | ||
--- | ||
drivers/mtd/nand/spi/Makefile | 2 +- | ||
drivers/mtd/nand/spi/core.c | 1 + | ||
drivers/mtd/nand/spi/esmt.c | 89 +++++++++++++++++++++++++++++++++++ | ||
include/linux/mtd/spinand.h | 1 + | ||
4 files changed, 92 insertions(+), 1 deletion(-) | ||
create mode 100644 drivers/mtd/nand/spi/esmt.c | ||
|
||
--- a/drivers/mtd/nand/spi/Makefile | ||
+++ b/drivers/mtd/nand/spi/Makefile | ||
@@ -1,3 +1,3 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
-spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o | ||
+spinand-objs := core.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o | ||
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o | ||
--- a/drivers/mtd/nand/spi/core.c | ||
+++ b/drivers/mtd/nand/spi/core.c | ||
@@ -896,6 +896,7 @@ static const struct nand_ops spinand_ops | ||
}; | ||
|
||
static const struct spinand_manufacturer *spinand_manufacturers[] = { | ||
+ &esmt_c8_spinand_manufacturer, | ||
&gigadevice_spinand_manufacturer, | ||
¯onix_spinand_manufacturer, | ||
µn_spinand_manufacturer, | ||
--- /dev/null | ||
+++ b/drivers/mtd/nand/spi/esmt.c | ||
@@ -0,0 +1,89 @@ | ||
+// SPDX-License-Identifier: GPL-2.0 | ||
+/* | ||
+ * Author: | ||
+ * Chuanhong Guo <gch981213@gmail.com> | ||
+ */ | ||
+ | ||
+#include <linux/device.h> | ||
+#include <linux/kernel.h> | ||
+#include <linux/mtd/spinand.h> | ||
+ | ||
+/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */ | ||
+#define SPINAND_MFR_ESMT_C8 0xc8 | ||
+ | ||
+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), | ||
+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), | ||
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), | ||
+ 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(write_cache_variants, | ||
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), | ||
+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); | ||
+ | ||
+static SPINAND_OP_VARIANTS(update_cache_variants, | ||
+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), | ||
+ SPINAND_PROG_LOAD(false, 0, NULL, 0)); | ||
+ | ||
+static int f50l1g41lb_ooblayout_ecc(struct mtd_info *mtd, int section, | ||
+ struct mtd_oob_region *region) | ||
+{ | ||
+ if (section > 3) | ||
+ return -ERANGE; | ||
+ | ||
+ region->offset = 16 * section + 8; | ||
+ region->length = 8; | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
+static int f50l1g41lb_ooblayout_free(struct mtd_info *mtd, int section, | ||
+ struct mtd_oob_region *region) | ||
+{ | ||
+ if (section > 3) | ||
+ return -ERANGE; | ||
+ | ||
+ region->offset = 16 * section + 2; | ||
+ region->length = 6; | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
+static const struct mtd_ooblayout_ops f50l1g41lb_ooblayout = { | ||
+ .ecc = f50l1g41lb_ooblayout_ecc, | ||
+ .free = f50l1g41lb_ooblayout_free, | ||
+}; | ||
+ | ||
+static const struct spinand_info esmt_c8_spinand_table[] = { | ||
+ SPINAND_INFO("F50L1G41LB", | ||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01), | ||
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), | ||
+ NAND_ECCREQ(1, 512), | ||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | ||
+ &write_cache_variants, | ||
+ &update_cache_variants), | ||
+ 0, | ||
+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), | ||
+ SPINAND_INFO("F50D1G41LB", | ||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11), | ||
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), | ||
+ NAND_ECCREQ(1, 512), | ||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | ||
+ &write_cache_variants, | ||
+ &update_cache_variants), | ||
+ 0, | ||
+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), | ||
+}; | ||
+ | ||
+static const struct spinand_manufacturer_ops esmt_spinand_manuf_ops = { | ||
+}; | ||
+ | ||
+const struct spinand_manufacturer esmt_c8_spinand_manufacturer = { | ||
+ .id = SPINAND_MFR_ESMT_C8, | ||
+ .name = "ESMT", | ||
+ .chips = esmt_c8_spinand_table, | ||
+ .nchips = ARRAY_SIZE(esmt_c8_spinand_table), | ||
+ .ops = &esmt_spinand_manuf_ops, | ||
+}; | ||
--- a/include/linux/mtd/spinand.h | ||
+++ b/include/linux/mtd/spinand.h | ||
@@ -260,6 +260,7 @@ struct spinand_manufacturer { | ||
}; | ||
|
||
/* SPI NAND manufacturers */ | ||
+extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; | ||
extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; | ||
extern const struct spinand_manufacturer macronix_spinand_manufacturer; | ||
extern const struct spinand_manufacturer micron_spinand_manufacturer; |