- Backport upstream Winbond W25N04KV Flash support. - Backport upstream GigaDevice series Flash support. - Backport pending Airoha AN8855 switch TPID value fix. - Backport Mediatek UART baudrate accuracy compensation support. - Pull mtk patchset from MTK SDK mtksoc-20250711 branch: Remove mt7622_rfb changes. The MTK SDK already dropped them. Replace Airoha ethernet PHY driver with new version. Split downstream snfi changes into independent patches. Add new Marvell CUX3410 PHY driver. Add new MediaTek built-in 2.5Gbps PHY driver. Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
296 lines
9.5 KiB
Diff
296 lines
9.5 KiB
Diff
From 001ce4e53f197a358b4307d36cc6d5048fc59158 Mon Sep 17 00:00:00 2001
|
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
|
Date: Wed, 27 Jul 2022 16:36:13 +0800
|
|
Subject: [PATCH 19/30] mtd: spi-nand: add more spi-nand chips
|
|
|
|
Support more spi-nand chips
|
|
|
|
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
|
|
---
|
|
drivers/mtd/nand/spi/Makefile | 1 +
|
|
drivers/mtd/nand/spi/core.c | 1 +
|
|
drivers/mtd/nand/spi/etron.c | 181 ++++++++++++++++++++++++++++++
|
|
drivers/mtd/nand/spi/gigadevice.c | 38 +++++++
|
|
drivers/mtd/nand/spi/winbond.c | 9 ++
|
|
include/linux/mtd/spinand.h | 1 +
|
|
6 files changed, 231 insertions(+)
|
|
create mode 100644 drivers/mtd/nand/spi/etron.c
|
|
|
|
--- a/drivers/mtd/nand/spi/Makefile
|
|
+++ b/drivers/mtd/nand/spi/Makefile
|
|
@@ -2,4 +2,5 @@
|
|
|
|
spinand-objs := core.o esmt.o gigadevice.o macronix.o micron.o paragon.o
|
|
spinand-objs += toshiba.o winbond.o xtx.o
|
|
+spinand-objs += etron.o
|
|
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
|
|
--- a/drivers/mtd/nand/spi/core.c
|
|
+++ b/drivers/mtd/nand/spi/core.c
|
|
@@ -826,6 +826,7 @@ static const struct nand_ops spinand_ops
|
|
};
|
|
|
|
static const struct spinand_manufacturer *spinand_manufacturers[] = {
|
|
+ &etron_spinand_manufacturer,
|
|
&gigadevice_spinand_manufacturer,
|
|
¯onix_spinand_manufacturer,
|
|
µn_spinand_manufacturer,
|
|
--- /dev/null
|
|
+++ b/drivers/mtd/nand/spi/etron.c
|
|
@@ -0,0 +1,181 @@
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
+/*
|
|
+ * Copyright (c) 2020 Etron Technology, Inc.
|
|
+ *
|
|
+ */
|
|
+#ifndef __UBOOT__
|
|
+#include <malloc.h>
|
|
+#include <linux/device.h>
|
|
+#include <linux/kernel.h>
|
|
+#endif
|
|
+#include <linux/bug.h>
|
|
+#include <linux/mtd/spinand.h>
|
|
+
|
|
+#define SPINAND_MFR_ETRON 0xD5
|
|
+
|
|
+#define STATUS_ECC_LIMIT_BITFLIPS (3 << 4)
|
|
+
|
|
+static SPINAND_OP_VARIANTS(read_cache_variants,
|
|
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, 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 etron_ooblayout_ecc(struct mtd_info *mtd, int section,
|
|
+ struct mtd_oob_region *region)
|
|
+{
|
|
+ if (section > 3)
|
|
+ return -ERANGE;
|
|
+
|
|
+ region->offset = (14 * section) + 72;
|
|
+ region->length = 14;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int etron_ooblayout_free(struct mtd_info *mtd, int section,
|
|
+ struct mtd_oob_region *region)
|
|
+{
|
|
+ if (section > 3)
|
|
+ return -ERANGE;
|
|
+
|
|
+ if (section) {
|
|
+ region->offset = 18 * section;
|
|
+ region->length = 18;
|
|
+ } else {
|
|
+ /* section 0 has one byte reserved for bad block mark */
|
|
+ region->offset = 2;
|
|
+ region->length = 16;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static const struct mtd_ooblayout_ops etron_ooblayout = {
|
|
+ .ecc = etron_ooblayout_ecc,
|
|
+ .rfree = etron_ooblayout_free,
|
|
+};
|
|
+
|
|
+static int etron_ecc_get_status(struct spinand_device *spinand,
|
|
+ u8 status)
|
|
+{
|
|
+ struct nand_device *nand = spinand_to_nand(spinand);
|
|
+
|
|
+ switch (status & STATUS_ECC_MASK) {
|
|
+ case STATUS_ECC_NO_BITFLIPS:
|
|
+ return 0;
|
|
+
|
|
+ case STATUS_ECC_UNCOR_ERROR:
|
|
+ return -EBADMSG;
|
|
+
|
|
+ case STATUS_ECC_HAS_BITFLIPS:
|
|
+ return nand->eccreq.strength >> 1;
|
|
+
|
|
+ case STATUS_ECC_LIMIT_BITFLIPS:
|
|
+ return nand->eccreq.strength;
|
|
+
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return -EINVAL;
|
|
+}
|
|
+
|
|
+static const struct spinand_info etron_spinand_table[] = {
|
|
+ /* EM73C 1Gb 3.3V */
|
|
+ SPINAND_INFO("EM73C044VCF",
|
|
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x25),
|
|
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
|
+ NAND_ECCREQ(4, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ SPINAND_HAS_QE_BIT,
|
|
+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
|
|
+ /* EM7xD 2Gb */
|
|
+ SPINAND_INFO("EM73D044VCR",
|
|
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x41),
|
|
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
|
|
+ NAND_ECCREQ(4, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ SPINAND_HAS_QE_BIT,
|
|
+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
|
|
+ SPINAND_INFO("EM73D044VCO",
|
|
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x3A),
|
|
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
|
+ NAND_ECCREQ(8, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ SPINAND_HAS_QE_BIT,
|
|
+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
|
|
+ SPINAND_INFO("EM78D044VCM",
|
|
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x8E),
|
|
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
|
+ NAND_ECCREQ(8, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ SPINAND_HAS_QE_BIT,
|
|
+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
|
|
+ /* EM7xE 4Gb */
|
|
+ SPINAND_INFO("EM73E044VCE",
|
|
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x3B),
|
|
+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
|
|
+ NAND_ECCREQ(8, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ SPINAND_HAS_QE_BIT,
|
|
+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
|
|
+ SPINAND_INFO("EM78E044VCD",
|
|
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x8F),
|
|
+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
|
|
+ NAND_ECCREQ(8, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ SPINAND_HAS_QE_BIT,
|
|
+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
|
|
+ /* EM7xF044VCA 8Gb */
|
|
+ SPINAND_INFO("EM73F044VCA",
|
|
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
|
|
+ NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
|
|
+ NAND_ECCREQ(8, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ SPINAND_HAS_QE_BIT,
|
|
+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
|
|
+ SPINAND_INFO("EM78F044VCA",
|
|
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x8D),
|
|
+ NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
|
|
+ NAND_ECCREQ(8, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ SPINAND_HAS_QE_BIT,
|
|
+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
|
|
+};
|
|
+
|
|
+static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = {
|
|
+};
|
|
+
|
|
+const struct spinand_manufacturer etron_spinand_manufacturer = {
|
|
+ .id = SPINAND_MFR_ETRON,
|
|
+ .name = "Etron",
|
|
+ .chips = etron_spinand_table,
|
|
+ .nchips = ARRAY_SIZE(etron_spinand_table),
|
|
+ .ops = &etron_spinand_manuf_ops,
|
|
+};
|
|
--- a/drivers/mtd/nand/spi/gigadevice.c
|
|
+++ b/drivers/mtd/nand/spi/gigadevice.c
|
|
@@ -284,7 +284,45 @@ static int gd5fxgq4ufxxg_ecc_get_status(
|
|
return -EINVAL;
|
|
}
|
|
|
|
+static int esmt_1_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 esmt_1_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 esmt_1_ooblayout = {
|
|
+ .ecc = esmt_1_ooblayout_ecc,
|
|
+ .rfree = esmt_1_ooblayout_free,
|
|
+};
|
|
+
|
|
static const struct spinand_info gigadevice_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(8, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ 0,
|
|
+ SPINAND_ECCINFO(&esmt_1_ooblayout, NULL)),
|
|
SPINAND_INFO("GD5F1GQ4xA",
|
|
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
|
|
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
|
--- a/drivers/mtd/nand/spi/winbond.c
|
|
+++ b/drivers/mtd/nand/spi/winbond.c
|
|
@@ -167,6 +167,15 @@ static const struct spinand_info winbond
|
|
&update_cache_variants),
|
|
0,
|
|
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
|
|
+ SPINAND_INFO("W25N01KV",
|
|
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
|
|
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
|
+ NAND_ECCREQ(4, 512),
|
|
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
|
+ &write_cache_variants,
|
|
+ &update_cache_variants),
|
|
+ 0,
|
|
+ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
|
|
SPINAND_INFO("W25N02KV",
|
|
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
|
|
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
|
--- a/include/linux/mtd/spinand.h
|
|
+++ b/include/linux/mtd/spinand.h
|
|
@@ -244,6 +244,7 @@ struct spinand_manufacturer {
|
|
};
|
|
|
|
/* SPI NAND manufacturers */
|
|
+extern const struct spinand_manufacturer etron_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;
|