lede/target/linux/ramips/patches-5.4/0300-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch
lovehackintosh 6fc2d00f25
kernel: bump 5.4 to 5.4.214 (#10170)
Manually rebased:
 generic/hack-5.4/953-net-patch-linux-kernel-to-support-shortcut-fe.patch
 ipq806x/patches-5.4/0063-2-tsens-support-configurable-interrupts.patch
 layerscape/patches-5.4/301-arch-0008-arm-add-new-non-shareable-ioremap.patch
 layerscape/patches-5.4/820-usb-0009-usb-dwc3-Add-workaround-for-host-mode-VBUS-glitch-wh.patch
 layerscape/patches-5.4/801-audio-0008-Revert-ASoC-Remove-dev_err-usage-after-platform_get_.patch
 octeon/patches-5.4/700-allocate_interface_by_label.patch

All other patches automatically rebased.

Signed-off-by: Liu Linhui <liulinhui36@gmail.com>

Signed-off-by: Liu Linhui <liulinhui36@gmail.com>
2022-09-24 12:09:08 +08:00

182 lines
6.2 KiB
Diff

From e84e2430ee0e483842b4ff013ae8a6e7e2fa2734 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Wed, 1 Apr 2020 02:07:58 +0800
Subject: [PATCH 1/2] mtd: rawnand: add driver support for MT7621 nand
flash controller
This patch adds NAND flash controller driver for MediaTek MT7621 SoC.
The NAND flash controller is similar with controllers described in
mtk_nand.c, except that the controller from MT7621 doesn't support DMA
transmission, and some registers' offset and fields are different.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
drivers/mtd/nand/raw/Kconfig | 8 +
drivers/mtd/nand/raw/Makefile | 1 +
drivers/mtd/nand/raw/mt7621_nand.c | 1348 ++++++++++++++++++++++++++++++++++++
3 files changed, 1357 insertions(+)
create mode 100644 drivers/mtd/nand/raw/mt7621_nand.c
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -391,6 +391,14 @@ config MTD_NAND_QCOM
Enables support for NAND flash chips on SoCs containing the EBI2 NAND
controller. This controller is found on IPQ806x SoC.
+config MTD_NAND_MT7621
+ tristate "MT7621 NAND controller"
+ depends on SOC_MT7621 || COMPILE_TEST
+ depends on HAS_IOMEM
+ help
+ Enables support for NAND controller on MT7621 SoC.
+ This driver uses PIO mode for data transmission instead of DMA mode.
+
config MTD_NAND_MTK
tristate "MTK NAND controller"
depends on ARCH_MEDIATEK || COMPILE_TEST
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n
obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o
+obj-$(CONFIG_MTD_NAND_MT7621) += mt7621_nand.o
obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o
obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o
obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
--- a/drivers/mtd/nand/raw/mt7621_nand.c
+++ b/drivers/mtd/nand/raw/mt7621_nand.c
@@ -18,7 +18,6 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
-#include <linux/mtd/mtk_bmt.h>
#include <linux/platform_device.h>
#include <asm/addrspace.h>
@@ -215,7 +214,6 @@ struct mt7621_nfc {
struct clk *nfi_clk;
struct device *dev;
- u32 nfi_base;
void __iomem *nfi_regs;
void __iomem *ecc_regs;
@@ -686,8 +684,8 @@ static int mt7621_nfc_exec_op(struct nan
return 0;
}
-static int mt7621_nfc_setup_interface(struct nand_chip *nand, int csline,
- const struct nand_interface_config *conf)
+static int mt7621_nfc_setup_data_interface(struct nand_chip *nand, int csline,
+ const struct nand_data_interface *conf)
{
struct mt7621_nfc *nfc = nand_get_controller_data(nand);
const struct nand_sdr_timings *timings;
@@ -761,7 +759,7 @@ static int mt7621_nfc_setup_interface(st
acccon = ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt);
- dev_dbg(nfc->dev, "Using programmed access timing: %08x\n", acccon);
+ dev_info(nfc->dev, "Using programmed access timing: %08x\n", acccon);
nfi_write32(nfc, NFI_ACCCON, acccon);
@@ -835,7 +833,7 @@ static int mt7621_nfc_ecc_init(struct mt
int ecc_cap;
/* Only hardware ECC mode is supported */
- if (nand->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) {
+ if (nand->ecc.mode != NAND_ECC_HW_SYNDROME) {
dev_err(nfc->dev, "Only hardware ECC mode is supported\n");
return -EINVAL;
}
@@ -862,8 +860,6 @@ static int mt7621_nfc_ecc_init(struct mt
(decode_block_size << DEC_CS_S) |
(DEC_CON_EL << DEC_CON_S) | DEC_EMPTY_EN;
- ecc_write32(nfc, ECC_FDMADDR, nfc->nfi_base + NFI_FDML(0));
-
mt7621_ecc_encoder_op(nfc, false);
ecc_write32(nfc, ECC_ENCCNFG, ecc_enccfg);
@@ -924,7 +920,7 @@ static int mt7621_nfc_attach_chip(struct
static const struct nand_controller_ops mt7621_nfc_controller_ops = {
.attach_chip = mt7621_nfc_attach_chip,
.exec_op = mt7621_nfc_exec_op,
- .setup_interface = mt7621_nfc_setup_interface,
+ .setup_data_interface = mt7621_nfc_setup_data_interface,
};
static int mt7621_nfc_ooblayout_free(struct mtd_info *mtd, int section,
@@ -976,7 +972,7 @@ static void mt7621_nfc_write_fdm(struct
vall |= (u32)oobptr[j] << (j * 8);
for (j = 0; j < 4; j++)
- valm |= (u32)oobptr[j + 4] << (j * 8);
+ valm |= (u32)oobptr[j + 4] << ((j - 4) * 8);
nfi_write32(nfc, NFI_FDML(i), vall);
nfi_write32(nfc, NFI_FDMM(i), valm);
@@ -1040,7 +1036,7 @@ static int mt7621_nfc_read_page_hwecc(st
oob_fdm_ptr(nand, i), i);
if (rc < 0) {
- dev_dbg(nfc->dev,
+ dev_warn(nfc->dev,
"Uncorrectable ECC error at page %d.%d\n",
page, i);
bitflips = -EBADMSG;
@@ -1229,11 +1225,11 @@ static int mt7621_nfc_init_chip(struct m
nand_set_controller_data(nand, (void *)nfc);
nand_set_flash_node(nand, nfc->dev->of_node);
- nand->options |= NAND_USES_DMA | NAND_NO_SUBPAGE_WRITE | NAND_SKIP_BBTSCAN;
+ nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_NO_SUBPAGE_WRITE;
if (!nfc->nfi_clk)
nand->options |= NAND_KEEP_TIMINGS;
- nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
+ nand->ecc.mode = NAND_ECC_HW_SYNDROME;
nand->ecc.read_page = mt7621_nfc_read_page_hwecc;
nand->ecc.read_page_raw = mt7621_nfc_read_page_raw;
nand->ecc.write_page = mt7621_nfc_write_page_hwecc;
@@ -1255,13 +1251,10 @@ static int mt7621_nfc_init_chip(struct m
if (ret)
return ret;
- mtk_bmt_attach(mtd);
-
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(nfc->dev, "Failed to register MTD: %d\n", ret);
- mtk_bmt_detach(mtd);
- nand_cleanup(nand);
+ nand_release(nand);
return ret;
}
@@ -1284,7 +1277,6 @@ static int mt7621_nfc_probe(struct platf
nfc->dev = dev;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nfi");
- nfc->nfi_base = res->start;
nfc->nfi_regs = devm_ioremap_resource(dev, res);
if (IS_ERR(nfc->nfi_regs)) {
ret = PTR_ERR(nfc->nfi_regs);
@@ -1329,12 +1321,8 @@ clk_disable:
static int mt7621_nfc_remove(struct platform_device *pdev)
{
struct mt7621_nfc *nfc = platform_get_drvdata(pdev);
- struct nand_chip *nand = &nfc->nand;
- struct mtd_info *mtd = nand_to_mtd(nand);
- mtk_bmt_detach(mtd);
- mtd_device_unregister(mtd);
- nand_cleanup(nand);
+ nand_release(&nfc->nand);
clk_disable_unprepare(nfc->nfi_clk);
return 0;