[openwrt/openwrt] mediatek: v5.15: backport spi-mem ecc support

LEDE Commits lede-commits at lists.infradead.org
Thu Apr 28 07:01:40 PDT 2022


981213 pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/861efe158ac56da2e00637aed704a77994bec54c

commit 861efe158ac56da2e00637aed704a77994bec54c
Author: Chuanhong Guo <gch981213 at gmail.com>
AuthorDate: Thu Apr 7 10:05:25 2022 +0800

    mediatek: v5.15: backport spi-mem ecc support
    
    Signed-off-by: Chuanhong Guo <gch981213 at gmail.com>
---
 ...c-Add-infrastructure-to-support-hardware-.patch | 224 +++++++++++++++++++++
 ...d-a-new-helper-to-retrieve-the-ECC-contex.patch |  36 ++++
 ...c-Provide-a-helper-to-retrieve-a-pileline.patch |  80 ++++++++
 ...-spi-mem-Introduce-a-capability-structure.patch |  78 +++++++
 ...m-Check-the-controller-extra-capabilities.patch |  56 ++++++
 ...m-Kill-the-spi_mem_dtr_supports_op-helper.patch | 122 +++++++++++
 ...-Add-an-ecc-parameter-to-the-spi_mem_op-s.patch |  79 ++++++++
 ...nd-Delay-a-little-bit-the-dirmap-creation.patch |  55 +++++
 ...-Create-direct-mapping-descriptors-for-EC.patch | 105 ++++++++++
 ...18-mtd-nand-fix-ecc-parameters-for-mt7622.patch |  93 +++++++++
 10 files changed, 928 insertions(+)

diff --git a/target/linux/mediatek/patches-5.15/120-01-v5.18-mtd-nand-ecc-Add-infrastructure-to-support-hardware-.patch b/target/linux/mediatek/patches-5.15/120-01-v5.18-mtd-nand-ecc-Add-infrastructure-to-support-hardware-.patch
new file mode 100644
index 0000000000..b6b069d234
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-01-v5.18-mtd-nand-ecc-Add-infrastructure-to-support-hardware-.patch
@@ -0,0 +1,224 @@
+From ad4944aa0b02cb043afe20bc2a018c161e65c992 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal at bootlin.com>
+Date: Thu, 16 Dec 2021 12:16:38 +0100
+Subject: [PATCH 01/15] mtd: nand: ecc: Add infrastructure to support hardware
+ engines
+
+Add the necessary helpers to register/unregister hardware ECC engines
+that will be called from ECC engine drivers.
+
+Also add helpers to get the right engine from the user
+perspective. Keep a reference of the in use ECC engine in order to
+prevent modules to be unloaded. Put the reference when the engine gets
+retired.
+
+A static list of hardware (only) ECC engines is setup to keep track of
+the registered engines.
+
+Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-13-miquel.raynal@bootlin.com
+(cherry picked from commit 96489c1c0b53131b0e1ec33e2060538379ad6152)
+---
+ drivers/mtd/nand/core.c  | 10 +++--
+ drivers/mtd/nand/ecc.c   | 88 ++++++++++++++++++++++++++++++++++++++++
+ include/linux/mtd/nand.h | 28 +++++++++++++
+ 3 files changed, 123 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
+index 5e13a03d2b32..b228b4d13b7a 100644
+--- a/drivers/mtd/nand/core.c
++++ b/drivers/mtd/nand/core.c
+@@ -232,7 +232,9 @@ static int nanddev_get_ecc_engine(struct nand_device *nand)
+ 		nand->ecc.engine = nand_ecc_get_on_die_hw_engine(nand);
+ 		break;
+ 	case NAND_ECC_ENGINE_TYPE_ON_HOST:
+-		pr_err("On-host hardware ECC engines not supported yet\n");
++		nand->ecc.engine = nand_ecc_get_on_host_hw_engine(nand);
++		if (PTR_ERR(nand->ecc.engine) == -EPROBE_DEFER)
++			return -EPROBE_DEFER;
+ 		break;
+ 	default:
+ 		pr_err("Missing ECC engine type\n");
+@@ -252,7 +254,7 @@ static int nanddev_put_ecc_engine(struct nand_device *nand)
+ {
+ 	switch (nand->ecc.ctx.conf.engine_type) {
+ 	case NAND_ECC_ENGINE_TYPE_ON_HOST:
+-		pr_err("On-host hardware ECC engines not supported yet\n");
++		nand_ecc_put_on_host_hw_engine(nand);
+ 		break;
+ 	case NAND_ECC_ENGINE_TYPE_NONE:
+ 	case NAND_ECC_ENGINE_TYPE_SOFT:
+@@ -297,7 +299,9 @@ int nanddev_ecc_engine_init(struct nand_device *nand)
+ 	/* Look for the ECC engine to use */
+ 	ret = nanddev_get_ecc_engine(nand);
+ 	if (ret) {
+-		pr_err("No ECC engine found\n");
++		if (ret != -EPROBE_DEFER)
++			pr_err("No ECC engine found\n");
++
+ 		return ret;
+ 	}
+ 
+diff --git a/drivers/mtd/nand/ecc.c b/drivers/mtd/nand/ecc.c
+index 6c43dfda01d4..078f5ec38de3 100644
+--- a/drivers/mtd/nand/ecc.c
++++ b/drivers/mtd/nand/ecc.c
+@@ -96,6 +96,12 @@
+ #include <linux/module.h>
+ #include <linux/mtd/nand.h>
+ #include <linux/slab.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_platform.h>
++
++static LIST_HEAD(on_host_hw_engines);
++static DEFINE_MUTEX(on_host_hw_engines_mutex);
+ 
+ /**
+  * nand_ecc_init_ctx - Init the ECC engine context
+@@ -611,6 +617,88 @@ struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand)
+ }
+ EXPORT_SYMBOL(nand_ecc_get_on_die_hw_engine);
+ 
++int nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine)
++{
++	struct nand_ecc_engine *item;
++
++	if (!engine)
++		return -EINVAL;
++
++	/* Prevent multiple registrations of one engine */
++	list_for_each_entry(item, &on_host_hw_engines, node)
++		if (item == engine)
++			return 0;
++
++	mutex_lock(&on_host_hw_engines_mutex);
++	list_add_tail(&engine->node, &on_host_hw_engines);
++	mutex_unlock(&on_host_hw_engines_mutex);
++
++	return 0;
++}
++EXPORT_SYMBOL(nand_ecc_register_on_host_hw_engine);
++
++int nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine)
++{
++	if (!engine)
++		return -EINVAL;
++
++	mutex_lock(&on_host_hw_engines_mutex);
++	list_del(&engine->node);
++	mutex_unlock(&on_host_hw_engines_mutex);
++
++	return 0;
++}
++EXPORT_SYMBOL(nand_ecc_unregister_on_host_hw_engine);
++
++static struct nand_ecc_engine *nand_ecc_match_on_host_hw_engine(struct device *dev)
++{
++	struct nand_ecc_engine *item;
++
++	list_for_each_entry(item, &on_host_hw_engines, node)
++		if (item->dev == dev)
++			return item;
++
++	return NULL;
++}
++
++struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand)
++{
++	struct nand_ecc_engine *engine = NULL;
++	struct device *dev = &nand->mtd.dev;
++	struct platform_device *pdev;
++	struct device_node *np;
++
++	if (list_empty(&on_host_hw_engines))
++		return NULL;
++
++	/* Check for an explicit nand-ecc-engine property */
++	np = of_parse_phandle(dev->of_node, "nand-ecc-engine", 0);
++	if (np) {
++		pdev = of_find_device_by_node(np);
++		if (!pdev)
++			return ERR_PTR(-EPROBE_DEFER);
++
++		engine = nand_ecc_match_on_host_hw_engine(&pdev->dev);
++		platform_device_put(pdev);
++		of_node_put(np);
++
++		if (!engine)
++			return ERR_PTR(-EPROBE_DEFER);
++	}
++
++	if (engine)
++		get_device(engine->dev);
++
++	return engine;
++}
++EXPORT_SYMBOL(nand_ecc_get_on_host_hw_engine);
++
++void nand_ecc_put_on_host_hw_engine(struct nand_device *nand)
++{
++	put_device(nand->ecc.engine->dev);
++}
++EXPORT_SYMBOL(nand_ecc_put_on_host_hw_engine);
++
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Miquel Raynal <miquel.raynal at bootlin.com>");
+ MODULE_DESCRIPTION("Generic ECC engine");
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index 32fc7edf65b3..4ddd20fe9c9e 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -263,12 +263,36 @@ struct nand_ecc_engine_ops {
+ 			     struct nand_page_io_req *req);
+ };
+ 
++/**
++ * enum nand_ecc_engine_integration - How the NAND ECC engine is integrated
++ * @NAND_ECC_ENGINE_INTEGRATION_INVALID: Invalid value
++ * @NAND_ECC_ENGINE_INTEGRATION_PIPELINED: Pipelined engine, performs on-the-fly
++ *                                         correction, does not need to copy
++ *                                         data around
++ * @NAND_ECC_ENGINE_INTEGRATION_EXTERNAL: External engine, needs to bring the
++ *                                        data into its own area before use
++ */
++enum nand_ecc_engine_integration {
++	NAND_ECC_ENGINE_INTEGRATION_INVALID,
++	NAND_ECC_ENGINE_INTEGRATION_PIPELINED,
++	NAND_ECC_ENGINE_INTEGRATION_EXTERNAL,
++};
++
+ /**
+  * struct nand_ecc_engine - ECC engine abstraction for NAND devices
++ * @dev: Host device
++ * @node: Private field for registration time
+  * @ops: ECC engine operations
++ * @integration: How the engine is integrated with the host
++ *               (only relevant on %NAND_ECC_ENGINE_TYPE_ON_HOST engines)
++ * @priv: Private data
+  */
+ struct nand_ecc_engine {
++	struct device *dev;
++	struct list_head node;
+ 	struct nand_ecc_engine_ops *ops;
++	enum nand_ecc_engine_integration integration;
++	void *priv;
+ };
+ 
+ void of_get_nand_ecc_user_config(struct nand_device *nand);
+@@ -279,8 +303,12 @@ int nand_ecc_prepare_io_req(struct nand_device *nand,
+ int nand_ecc_finish_io_req(struct nand_device *nand,
+ 			   struct nand_page_io_req *req);
+ bool nand_ecc_is_strong_enough(struct nand_device *nand);
++int nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine);
++int nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine);
+ struct nand_ecc_engine *nand_ecc_get_sw_engine(struct nand_device *nand);
+ struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand);
++struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand);
++void nand_ecc_put_on_host_hw_engine(struct nand_device *nand);
+ 
+ #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING)
+ struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void);
+-- 
+2.35.1
+
diff --git a/target/linux/mediatek/patches-5.15/120-02-v5.18-mtd-nand-Add-a-new-helper-to-retrieve-the-ECC-contex.patch b/target/linux/mediatek/patches-5.15/120-02-v5.18-mtd-nand-Add-a-new-helper-to-retrieve-the-ECC-contex.patch
new file mode 100644
index 0000000000..6522507786
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-02-v5.18-mtd-nand-Add-a-new-helper-to-retrieve-the-ECC-contex.patch
@@ -0,0 +1,36 @@
+From 840b2f8dd2d0579e517140e1f9bbc482eaf4ed07 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal at bootlin.com>
+Date: Thu, 16 Dec 2021 12:16:39 +0100
+Subject: [PATCH 02/15] mtd: nand: Add a new helper to retrieve the ECC context
+
+Introduce nand_to_ecc_ctx() which will allow to easily jump to the
+private pointer of an ECC context given a NAND device. This is very
+handy, from the prepare or finish ECC hook, to get the internal context
+out of the NAND device object.
+
+Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-14-miquel.raynal@bootlin.com
+(cherry picked from commit cda32a618debd3fad8e42757b198719ae180f8f4)
+---
+ include/linux/mtd/nand.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index 4ddd20fe9c9e..b617efa0a881 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -990,6 +990,11 @@ int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos);
+ int nanddev_ecc_engine_init(struct nand_device *nand);
+ void nanddev_ecc_engine_cleanup(struct nand_device *nand);
+ 
++static inline void *nand_to_ecc_ctx(struct nand_device *nand)
++{
++	return nand->ecc.ctx.priv;
++}
++
+ /* BBT related functions */
+ enum nand_bbt_block_status {
+ 	NAND_BBT_BLOCK_STATUS_UNKNOWN,
+-- 
+2.35.1
+
diff --git a/target/linux/mediatek/patches-5.15/120-03-v5.18-mtd-nand-ecc-Provide-a-helper-to-retrieve-a-pileline.patch b/target/linux/mediatek/patches-5.15/120-03-v5.18-mtd-nand-ecc-Provide-a-helper-to-retrieve-a-pileline.patch
new file mode 100644
index 0000000000..ce353a9226
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-03-v5.18-mtd-nand-ecc-Provide-a-helper-to-retrieve-a-pileline.patch
@@ -0,0 +1,80 @@
+From 784866bc4f9f25e0494b77750f95af2a2619e498 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal at bootlin.com>
+Date: Thu, 16 Dec 2021 12:16:41 +0100
+Subject: [PATCH 03/15] mtd: nand: ecc: Provide a helper to retrieve a
+ pilelined engine device
+
+In a pipelined engine situation, we might either have the host which
+internally has support for error correction, or have it using an
+external hardware block for this purpose. In the former case, the host
+is also the ECC engine. In the latter case, it is not. In order to get
+the right pointers on the right devices (for example: in order to devm_*
+allocate variables), let's introduce this helper which can safely be
+called by pipelined ECC engines in order to retrieve the right device
+structure.
+
+Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
+Link: https://lore.kernel.org/linux-mtd/20211216111654.238086-16-miquel.raynal@bootlin.com
+(cherry picked from commit 5145abeb0649acf810a32e63bd762e617a9b3309)
+---
+ drivers/mtd/nand/ecc.c   | 31 +++++++++++++++++++++++++++++++
+ include/linux/mtd/nand.h |  1 +
+ 2 files changed, 32 insertions(+)
+
+diff --git a/drivers/mtd/nand/ecc.c b/drivers/mtd/nand/ecc.c
+index 078f5ec38de3..5250764cedee 100644
+--- a/drivers/mtd/nand/ecc.c
++++ b/drivers/mtd/nand/ecc.c
+@@ -699,6 +699,37 @@ void nand_ecc_put_on_host_hw_engine(struct nand_device *nand)
+ }
+ EXPORT_SYMBOL(nand_ecc_put_on_host_hw_engine);
+ 
++/*
++ * In the case of a pipelined engine, the device registering the ECC
++ * engine is not necessarily the ECC engine itself but may be a host controller.
++ * It is then useful to provide a helper to retrieve the right device object
++ * which actually represents the ECC engine.
++ */
++struct device *nand_ecc_get_engine_dev(struct device *host)
++{
++	struct platform_device *ecc_pdev;
++	struct device_node *np;
++
++	/*
++	 * If the device node contains this property, it means we need to follow
++	 * it in order to get the right ECC engine device we are looking for.
++	 */
++	np = of_parse_phandle(host->of_node, "nand-ecc-engine", 0);
++	if (!np)
++		return host;
++
++	ecc_pdev = of_find_device_by_node(np);
++	if (!ecc_pdev) {
++		of_node_put(np);
++		return NULL;
++	}
++
++	platform_device_put(ecc_pdev);
++	of_node_put(np);
++
++	return &ecc_pdev->dev;
++}
++
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Miquel Raynal <miquel.raynal at bootlin.com>");
+ MODULE_DESCRIPTION("Generic ECC engine");
+diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
+index b617efa0a881..615b3e3a3920 100644
+--- a/include/linux/mtd/nand.h
++++ b/include/linux/mtd/nand.h
+@@ -309,6 +309,7 @@ struct nand_ecc_engine *nand_ecc_get_sw_engine(struct nand_device *nand);
+ struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand);
+ struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand);
+ void nand_ecc_put_on_host_hw_engine(struct nand_device *nand);
++struct device *nand_ecc_get_engine_dev(struct device *host);
+ 
+ #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING)
+ struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void);
+-- 
+2.35.1
+
diff --git a/target/linux/mediatek/patches-5.15/120-04-v5.18-spi-spi-mem-Introduce-a-capability-structure.patch b/target/linux/mediatek/patches-5.15/120-04-v5.18-spi-spi-mem-Introduce-a-capability-structure.patch
new file mode 100644
index 0000000000..bcd2ee8004
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-04-v5.18-spi-spi-mem-Introduce-a-capability-structure.patch
@@ -0,0 +1,78 @@
+From 3e45577e70cbf8fdc5c13033114989794a3797d5 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal at bootlin.com>
+Date: Thu, 27 Jan 2022 10:17:56 +0100
+Subject: [PATCH 04/15] spi: spi-mem: Introduce a capability structure
+
+Create a spi_controller_mem_caps structure and put it within the
+spi_controller structure close to the spi_controller_mem_ops
+strucure. So far the only field in this structure is the support for dtr
+operations, but soon we will add another parameter.
+
+Also create a helper to parse the capabilities and check if the
+requested capability has been set or not.
+
+Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
+Reviewed-by: Pratyush Yadav <p.yadav at ti.com>
+Reviewed-by: Boris Brezillon <boris.brezillon at collabora.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus at microchip.com>
+Reviewed-by: Mark Brown <broonie at kernel.org>
+Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-2-miquel.raynal@bootlin.com
+(cherry picked from commit 4a3cc7fb6e63bcfdedec25364738f1493345bd20)
+---
+ include/linux/spi/spi-mem.h | 11 +++++++++++
+ include/linux/spi/spi.h     |  3 +++
+ 2 files changed, 14 insertions(+)
+
+diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
+index 85e2ff7b840d..38e5d45c9842 100644
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -285,6 +285,17 @@ struct spi_controller_mem_ops {
+ 			   unsigned long timeout_ms);
+ };
+ 
++/**
++ * struct spi_controller_mem_caps - SPI memory controller capabilities
++ * @dtr: Supports DTR operations
++ */
++struct spi_controller_mem_caps {
++	bool dtr;
++};
++
++#define spi_mem_controller_is_capable(ctlr, cap)	\
++	((ctlr)->mem_caps && (ctlr)->mem_caps->cap)
++
+ /**
+  * struct spi_mem_driver - SPI memory driver
+  * @spidrv: inherit from a SPI driver
+diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
+index 6b0b686f6f90..8ac58b1a2a9f 100644
+--- a/include/linux/spi/spi.h
++++ b/include/linux/spi/spi.h
+@@ -23,6 +23,7 @@ struct software_node;
+ struct spi_controller;
+ struct spi_transfer;
+ struct spi_controller_mem_ops;
++struct spi_controller_mem_caps;
+ 
+ /*
+  * INTERFACES between SPI master-side drivers and SPI slave protocol handlers,
+@@ -419,6 +420,7 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch
+  * @mem_ops: optimized/dedicated operations for interactions with SPI memory.
+  *	     This field is optional and should only be implemented if the
+  *	     controller has native support for memory like operations.
++ * @mem_caps: controller capabilities for the handling of memory operations.
+  * @unprepare_message: undo any work done by prepare_message().
+  * @slave_abort: abort the ongoing transfer request on an SPI slave controller
+  * @cs_gpios: LEGACY: array of GPIO descs to use as chip select lines; one per
+@@ -643,6 +645,7 @@ struct spi_controller {
+ 
+ 	/* Optimized handlers for SPI memory-like operations. */
+ 	const struct spi_controller_mem_ops *mem_ops;
++	const struct spi_controller_mem_caps *mem_caps;
+ 
+ 	/* gpio chip select */
+ 	int			*cs_gpios;
+-- 
+2.35.1
+
diff --git a/target/linux/mediatek/patches-5.15/120-05-v5.18-spi-spi-mem-Check-the-controller-extra-capabilities.patch b/target/linux/mediatek/patches-5.15/120-05-v5.18-spi-spi-mem-Check-the-controller-extra-capabilities.patch
new file mode 100644
index 0000000000..20e7bac651
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-05-v5.18-spi-spi-mem-Check-the-controller-extra-capabilities.patch
@@ -0,0 +1,56 @@
+From c9cae7e1e5c87d0aa76b7bededa5191a0c8cf25a Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal at bootlin.com>
+Date: Thu, 27 Jan 2022 10:17:57 +0100
+Subject: [PATCH 05/15] spi: spi-mem: Check the controller extra capabilities
+
+Controllers can now provide a spi-mem capabilities structure. Let's make
+use of it in spi_mem_controller_default_supports_op(). As we want to
+check for DTR operations as well as normal operations in a single
+helper, let's pull the necessary checks from spi_mem_dtr_supports_op()
+for now.
+
+However, because no controller provide these extra capabilities, this
+change has no effect so far.
+
+Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
+Reviewed-by: Pratyush Yadav <p.yadav at ti.com>
+Reviewed-by: Boris Brezillon <boris.brezillon at collabora.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus at microchip.com>
+Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-3-miquel.raynal@bootlin.com
+(cherry picked from commit cb7e96ee81edaa48c67d84c14df2cbe464391c37)
+---
+ drivers/spi/spi-mem.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index 37f4443ce9a0..86e6597bc3dc 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -173,11 +173,20 @@ EXPORT_SYMBOL_GPL(spi_mem_dtr_supports_op);
+ bool spi_mem_default_supports_op(struct spi_mem *mem,
+ 				 const struct spi_mem_op *op)
+ {
+-	if (op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr)
+-		return false;
++	struct spi_controller *ctlr = mem->spi->controller;
++	bool op_is_dtr =
++		op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr;
+ 
+-	if (op->cmd.nbytes != 1)
+-		return false;
++	if (op_is_dtr) {
++		if (!spi_mem_controller_is_capable(ctlr, dtr))
++			return false;
++
++		if (op->cmd.nbytes != 2)
++			return false;
++	} else {
++		if (op->cmd.nbytes != 1)
++			return false;
++	}
+ 
+ 	return spi_mem_check_buswidth(mem, op);
+ }
+-- 
+2.35.1
+
diff --git a/target/linux/mediatek/patches-5.15/120-06-v5.18-spi-spi-mem-Kill-the-spi_mem_dtr_supports_op-helper.patch b/target/linux/mediatek/patches-5.15/120-06-v5.18-spi-spi-mem-Kill-the-spi_mem_dtr_supports_op-helper.patch
new file mode 100644
index 0000000000..efc0ed526c
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-06-v5.18-spi-spi-mem-Kill-the-spi_mem_dtr_supports_op-helper.patch
@@ -0,0 +1,122 @@
+From 2e5fba82e4aeb72d71230eef2541881615aaf7cf Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal at bootlin.com>
+Date: Thu, 27 Jan 2022 10:18:00 +0100
+Subject: [PATCH 06/15] spi: spi-mem: Kill the spi_mem_dtr_supports_op() helper
+
+Now that spi_mem_default_supports_op() has access to the static
+controller capabilities (relating to memory operations), and now that
+these capabilities have been filled by the relevant controllers, there
+is no need for a specific helper checking only DTR operations, so let's
+just kill spi_mem_dtr_supports_op() and simply use
+spi_mem_default_supports_op() instead.
+
+Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
+Reviewed-by: Pratyush Yadav <p.yadav at ti.com>
+Reviewed-by: Boris Brezillon <boris.brezillon at collabora.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus at microchip.com>
+Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-6-miquel.raynal@bootlin.com
+(cherry picked from commit 9a15efc5d5e6b5beaed0883e5bdcd0b1384c1b20)
+---
+ drivers/spi/spi-cadence-quadspi.c |  5 +----
+ drivers/spi/spi-mem.c             | 10 ----------
+ drivers/spi/spi-mxic.c            | 10 +---------
+ include/linux/spi/spi-mem.h       | 11 -----------
+ 4 files changed, 2 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
+index 101cc71bffa7..2c98d6a9a2aa 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -1252,10 +1252,7 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem,
+ 	if (!(all_true || all_false))
+ 		return false;
+ 
+-	if (all_true)
+-		return spi_mem_dtr_supports_op(mem, op);
+-	else
+-		return spi_mem_default_supports_op(mem, op);
++	return spi_mem_default_supports_op(mem, op);
+ }
+ 
+ static int cqspi_of_get_flash_pdata(struct platform_device *pdev,
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index 86e6597bc3dc..ed966d8129eb 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -160,16 +160,6 @@ static bool spi_mem_check_buswidth(struct spi_mem *mem,
+ 	return true;
+ }
+ 
+-bool spi_mem_dtr_supports_op(struct spi_mem *mem,
+-			     const struct spi_mem_op *op)
+-{
+-	if (op->cmd.nbytes != 2)
+-		return false;
+-
+-	return spi_mem_check_buswidth(mem, op);
+-}
+-EXPORT_SYMBOL_GPL(spi_mem_dtr_supports_op);
+-
+ bool spi_mem_default_supports_op(struct spi_mem *mem,
+ 				 const struct spi_mem_op *op)
+ {
+diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c
+index 45889947afed..e895df09896a 100644
+--- a/drivers/spi/spi-mxic.c
++++ b/drivers/spi/spi-mxic.c
+@@ -335,8 +335,6 @@ static int mxic_spi_data_xfer(struct mxic_spi *mxic, const void *txbuf,
+ static bool mxic_spi_mem_supports_op(struct spi_mem *mem,
+ 				     const struct spi_mem_op *op)
+ {
+-	bool all_false;
+-
+ 	if (op->data.buswidth > 8 || op->addr.buswidth > 8 ||
+ 	    op->dummy.buswidth > 8 || op->cmd.buswidth > 8)
+ 		return false;
+@@ -348,13 +346,7 @@ static bool mxic_spi_mem_supports_op(struct spi_mem *mem,
+ 	if (op->addr.nbytes > 7)
+ 		return false;
+ 
+-	all_false = !op->cmd.dtr && !op->addr.dtr && !op->dummy.dtr &&
+-		    !op->data.dtr;
+-
+-	if (all_false)
+-		return spi_mem_default_supports_op(mem, op);
+-	else
+-		return spi_mem_dtr_supports_op(mem, op);
++	return spi_mem_default_supports_op(mem, op);
+ }
+ 
+ static int mxic_spi_mem_exec_op(struct spi_mem *mem,
+diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
+index 38e5d45c9842..4a1bfe689872 100644
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -330,10 +330,6 @@ void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr,
+ 
+ bool spi_mem_default_supports_op(struct spi_mem *mem,
+ 				 const struct spi_mem_op *op);
+-
+-bool spi_mem_dtr_supports_op(struct spi_mem *mem,
+-			     const struct spi_mem_op *op);
+-
+ #else
+ static inline int
+ spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr,
+@@ -356,13 +352,6 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+ {
+ 	return false;
+ }
+-
+-static inline
+-bool spi_mem_dtr_supports_op(struct spi_mem *mem,
+-			     const struct spi_mem_op *op)
+-{
+-	return false;
+-}
+ #endif /* CONFIG_SPI_MEM */
+ 
+ int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op);
+-- 
+2.35.1
+
diff --git a/target/linux/mediatek/patches-5.15/120-07-v5.18-spi-spi-mem-Add-an-ecc-parameter-to-the-spi_mem_op-s.patch b/target/linux/mediatek/patches-5.15/120-07-v5.18-spi-spi-mem-Add-an-ecc-parameter-to-the-spi_mem_op-s.patch
new file mode 100644
index 0000000000..fd9e9e2c48
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-07-v5.18-spi-spi-mem-Add-an-ecc-parameter-to-the-spi_mem_op-s.patch
@@ -0,0 +1,79 @@
+From 9e7eb0ea442ecb1c3fe443289e288694f10c5148 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal at bootlin.com>
+Date: Thu, 27 Jan 2022 10:18:01 +0100
+Subject: [PATCH 07/15] spi: spi-mem: Add an ecc parameter to the spi_mem_op
+ structure
+
+Soon the SPI-NAND core will need a way to request a SPI controller to
+enable ECC support for a given operation. This is because of the
+pipelined integration of certain ECC engines, which are directly managed
+by the SPI controller itself.
+
+Introduce a spi_mem_op additional field for this purpose: ecc.
+
+So far this field is left unset and checked to be false by all
+the SPI controller drivers in their ->supports_op() hook, as they all
+call spi_mem_default_supports_op().
+
+Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
+Acked-by: Pratyush Yadav <p.yadav at ti.com>
+Reviewed-by: Boris Brezillon <boris.brezillon at collabora.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus at microchip.com>
+Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-7-miquel.raynal@bootlin.com
+(cherry picked from commit a433c2cbd75ab76f277364f44e76f32c7df306e7)
+---
+ drivers/spi/spi-mem.c       | 5 +++++
+ include/linux/spi/spi-mem.h | 4 ++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
+index ed966d8129eb..f38ac31961c9 100644
+--- a/drivers/spi/spi-mem.c
++++ b/drivers/spi/spi-mem.c
+@@ -178,6 +178,11 @@ bool spi_mem_default_supports_op(struct spi_mem *mem,
+ 			return false;
+ 	}
+ 
++	if (op->data.ecc) {
++		if (!spi_mem_controller_is_capable(ctlr, ecc))
++			return false;
++	}
++
+ 	return spi_mem_check_buswidth(mem, op);
+ }
+ EXPORT_SYMBOL_GPL(spi_mem_default_supports_op);
+diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
+index 4a1bfe689872..2ba044d0d5e5 100644
+--- a/include/linux/spi/spi-mem.h
++++ b/include/linux/spi/spi-mem.h
+@@ -89,6 +89,7 @@ enum spi_mem_data_dir {
+  * @dummy.dtr: whether the dummy bytes should be sent in DTR mode or not
+  * @data.buswidth: number of IO lanes used to send/receive the data
+  * @data.dtr: whether the data should be sent in DTR mode or not
++ * @data.ecc: whether error correction is required or not
+  * @data.dir: direction of the transfer
+  * @data.nbytes: number of data bytes to send/receive. Can be zero if the
+  *		 operation does not involve transferring data
+@@ -119,6 +120,7 @@ struct spi_mem_op {
+ 	struct {
+ 		u8 buswidth;
+ 		u8 dtr : 1;
++		u8 ecc : 1;
+ 		enum spi_mem_data_dir dir;
+ 		unsigned int nbytes;
+ 		union {
+@@ -288,9 +290,11 @@ struct spi_controller_mem_ops {
+ /**
+  * struct spi_controller_mem_caps - SPI memory controller capabilities
+  * @dtr: Supports DTR operations
++ * @ecc: Supports operations with error correction
+  */
+ struct spi_controller_mem_caps {
+ 	bool dtr;
++	bool ecc;
+ };
+ 
+ #define spi_mem_controller_is_capable(ctlr, cap)	\
+-- 
+2.35.1
+
diff --git a/target/linux/mediatek/patches-5.15/120-08-v5.18-mtd-spinand-Delay-a-little-bit-the-dirmap-creation.patch b/target/linux/mediatek/patches-5.15/120-08-v5.18-mtd-spinand-Delay-a-little-bit-the-dirmap-creation.patch
new file mode 100644
index 0000000000..d8c0e1bcd8
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-08-v5.18-mtd-spinand-Delay-a-little-bit-the-dirmap-creation.patch
@@ -0,0 +1,55 @@
+From 94ef3c35b935a63f6c156957c92f6cf33c9a8dae Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal at bootlin.com>
+Date: Thu, 27 Jan 2022 10:18:02 +0100
+Subject: [PATCH 08/15] mtd: spinand: Delay a little bit the dirmap creation
+
+As we will soon tweak the dirmap creation to act a little bit
+differently depending on the picked ECC engine, we need to initialize
+dirmaps after ECC engines. This should not have any effect as dirmaps
+are not yet used at this point.
+
+Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
+Reviewed-by: Boris Brezillon <boris.brezillon at collabora.com>
+Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-8-miquel.raynal@bootlin.com
+(cherry picked from commit dc4c2cbf0be2d4a8e2a65013ea2815bb2c8ba949)
+---
+ drivers/mtd/nand/spi/core.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
+index 2c8685f1f2fa..bb6b026b558b 100644
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1208,14 +1208,6 @@ static int spinand_init(struct spinand_device *spinand)
+ 	if (ret)
+ 		goto err_free_bufs;
+ 
+-	ret = spinand_create_dirmaps(spinand);
+-	if (ret) {
+-		dev_err(dev,
+-			"Failed to create direct mappings for read/write operations (err = %d)\n",
+-			ret);
+-		goto err_manuf_cleanup;
+-	}
+-
+ 	ret = nanddev_init(nand, &spinand_ops, THIS_MODULE);
+ 	if (ret)
+ 		goto err_manuf_cleanup;
+@@ -1250,6 +1242,14 @@ static int spinand_init(struct spinand_device *spinand)
+ 	mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength;
+ 	mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size;
+ 
++	ret = spinand_create_dirmaps(spinand);
++	if (ret) {
++		dev_err(dev,
++			"Failed to create direct mappings for read/write operations (err = %d)\n",
++			ret);
++		goto err_cleanup_ecc_engine;
++	}
++
+ 	return 0;
+ 
+ err_cleanup_ecc_engine:
+-- 
+2.35.1
+
diff --git a/target/linux/mediatek/patches-5.15/120-09-v5.18-mtd-spinand-Create-direct-mapping-descriptors-for-EC.patch b/target/linux/mediatek/patches-5.15/120-09-v5.18-mtd-spinand-Create-direct-mapping-descriptors-for-EC.patch
new file mode 100644
index 0000000000..ee3a6d384f
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-09-v5.18-mtd-spinand-Create-direct-mapping-descriptors-for-EC.patch
@@ -0,0 +1,105 @@
+From eb4a2d282c3c5752211d69be6dff2674119e5583 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal at bootlin.com>
+Date: Thu, 27 Jan 2022 10:18:03 +0100
+Subject: [PATCH 09/15] mtd: spinand: Create direct mapping descriptors for ECC
+ operations
+
+In order for pipelined ECC engines to be able to enable/disable the ECC
+engine only when needed and avoid races when future parallel-operations
+will be supported, we need to provide the information about the use of
+the ECC engine in the direct mapping hooks. As direct mapping
+configurations are meant to be static, it is best to create two new
+mappings: one for regular 'raw' accesses and one for accesses involving
+correction. It is up to the driver to use or not the new ECC enable
+boolean contained in the spi-mem operation.
+
+As dirmaps are not free (they consume a few pages of MMIO address space)
+and because these extra entries are only meant to be used by pipelined
+engines, let's limit their use to this specific type of engine and save
+a bit of memory with all the other setups.
+
+Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
+Reviewed-by: Boris Brezillon <boris.brezillon at collabora.com>
+Link: https://lore.kernel.org/linux-mtd/20220127091808.1043392-9-miquel.raynal@bootlin.com
+(cherry picked from commit f9d7c7265bcff7d9a17425a8cddf702e8fe159c2)
+---
+ drivers/mtd/nand/spi/core.c | 35 +++++++++++++++++++++++++++++++++--
+ include/linux/mtd/spinand.h |  2 ++
+ 2 files changed, 35 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
+index bb6b026b558b..ff8336870bc0 100644
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -381,7 +381,10 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
+ 		}
+ 	}
+ 
+-	rdesc = spinand->dirmaps[req->pos.plane].rdesc;
++	if (req->mode == MTD_OPS_RAW)
++		rdesc = spinand->dirmaps[req->pos.plane].rdesc;
++	else
++		rdesc = spinand->dirmaps[req->pos.plane].rdesc_ecc;
+ 
+ 	while (nbytes) {
+ 		ret = spi_mem_dirmap_read(rdesc, column, nbytes, buf);
+@@ -452,7 +455,10 @@ static int spinand_write_to_cache_op(struct spinand_device *spinand,
+ 			       req->ooblen);
+ 	}
+ 
+-	wdesc = spinand->dirmaps[req->pos.plane].wdesc;
++	if (req->mode == MTD_OPS_RAW)
++		wdesc = spinand->dirmaps[req->pos.plane].wdesc;
++	else
++		wdesc = spinand->dirmaps[req->pos.plane].wdesc_ecc;
+ 
+ 	while (nbytes) {
+ 		ret = spi_mem_dirmap_write(wdesc, column, nbytes, buf);
+@@ -865,6 +871,31 @@ static int spinand_create_dirmap(struct spinand_device *spinand,
+ 
+ 	spinand->dirmaps[plane].rdesc = desc;
+ 
++	if (nand->ecc.engine->integration != NAND_ECC_ENGINE_INTEGRATION_PIPELINED) {
++		spinand->dirmaps[plane].wdesc_ecc = spinand->dirmaps[plane].wdesc;
++		spinand->dirmaps[plane].rdesc_ecc = spinand->dirmaps[plane].rdesc;
++
++		return 0;
++	}
++
++	info.op_tmpl = *spinand->op_templates.update_cache;
++	info.op_tmpl.data.ecc = true;
++	desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
++					  spinand->spimem, &info);
++	if (IS_ERR(desc))
++		return PTR_ERR(desc);
++
++	spinand->dirmaps[plane].wdesc_ecc = desc;
++
++	info.op_tmpl = *spinand->op_templates.read_cache;
++	info.op_tmpl.data.ecc = true;
++	desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev,
++					  spinand->spimem, &info);
++	if (IS_ERR(desc))
++		return PTR_ERR(desc);
++
++	spinand->dirmaps[plane].rdesc_ecc = desc;
++
+ 	return 0;
+ }
+ 
+diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
+index 6988956b8492..3aa28240a77f 100644
+--- a/include/linux/mtd/spinand.h
++++ b/include/linux/mtd/spinand.h
+@@ -389,6 +389,8 @@ struct spinand_info {
+ struct spinand_dirmap {
+ 	struct spi_mem_dirmap_desc *wdesc;
+ 	struct spi_mem_dirmap_desc *rdesc;
++	struct spi_mem_dirmap_desc *wdesc_ecc;
++	struct spi_mem_dirmap_desc *rdesc_ecc;
+ };
+ 
+ /**
+-- 
+2.35.1
+
diff --git a/target/linux/mediatek/patches-5.15/120-10-v5.18-mtd-nand-fix-ecc-parameters-for-mt7622.patch b/target/linux/mediatek/patches-5.15/120-10-v5.18-mtd-nand-fix-ecc-parameters-for-mt7622.patch
new file mode 100644
index 0000000000..7dbcf2fcda
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/120-10-v5.18-mtd-nand-fix-ecc-parameters-for-mt7622.patch
@@ -0,0 +1,93 @@
+From 41825166744c6e5664281611f5e6d9a2e9333c2b Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213 at gmail.com>
+Date: Sat, 2 Apr 2022 22:31:20 +0800
+Subject: [PATCH 10/15] mtd: nand: fix ecc parameters for mt7622
+
+According to the datasheet, mt7622 only has 5 ECC capabilities instead
+of 7, and the decoding error register is arranged  as follows:
++------+---------+---------+---------+---------+
+| Bits |  19:15  |  14:10  |   9:5   |   4:0   |
++------+---------+---------+---------+---------+
+| Name | ERRNUM3 | ERRNUM2 | ERRNUM1 | ERRNUM0 |
++------+---------+---------+---------+---------+
+This means err_mask should be 0x1f instead of 0x3f and the number of
+bits shifted in mtk_ecc_get_stats should be 5 instead of 8.
+
+This commit introduces err_shift for the difference in this register
+and fix other existing parameters.
+
+Public MT7622 reference manual can be found on [0] and the info this
+commit is based on is from page 656 and page 660.
+
+[0]: https://wiki.banana-pi.org/Banana_Pi_BPI-R64#Documents
+
+Fixes: 98dea8d71931 ("mtd: nand: mtk: Support MT7622 NAND flash controller.")
+Signed-off-by: Chuanhong Guo <gch981213 at gmail.com>
+(cherry picked from commit 088b769abd1bd21753002b17b696ae1778b16e8c)
+---
+ drivers/mtd/nand/raw/mtk_ecc.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/raw/mtk_ecc.c b/drivers/mtd/nand/raw/mtk_ecc.c
+index c437d97debb8..ec9d1fb07006 100644
+--- a/drivers/mtd/nand/raw/mtk_ecc.c
++++ b/drivers/mtd/nand/raw/mtk_ecc.c
+@@ -43,6 +43,7 @@
+ 
+ struct mtk_ecc_caps {
+ 	u32 err_mask;
++	u32 err_shift;
+ 	const u8 *ecc_strength;
+ 	const u32 *ecc_regs;
+ 	u8 num_ecc_strength;
+@@ -76,7 +77,7 @@ static const u8 ecc_strength_mt2712[] = {
+ };
+ 
+ static const u8 ecc_strength_mt7622[] = {
+-	4, 6, 8, 10, 12, 14, 16
++	4, 6, 8, 10, 12
+ };
+ 
+ enum mtk_ecc_regs {
+@@ -221,7 +222,7 @@ void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
+ 	for (i = 0; i < sectors; i++) {
+ 		offset = (i >> 2) << 2;
+ 		err = readl(ecc->regs + ECC_DECENUM0 + offset);
+-		err = err >> ((i % 4) * 8);
++		err = err >> ((i % 4) * ecc->caps->err_shift);
+ 		err &= ecc->caps->err_mask;
+ 		if (err == ecc->caps->err_mask) {
+ 			/* uncorrectable errors */
+@@ -449,6 +450,7 @@ EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
+ 
+ static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
+ 	.err_mask = 0x3f,
++	.err_shift = 8,
+ 	.ecc_strength = ecc_strength_mt2701,
+ 	.ecc_regs = mt2701_ecc_regs,
+ 	.num_ecc_strength = 20,
+@@ -459,6 +461,7 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
+ 
+ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
+ 	.err_mask = 0x7f,
++	.err_shift = 8,
+ 	.ecc_strength = ecc_strength_mt2712,
+ 	.ecc_regs = mt2712_ecc_regs,
+ 	.num_ecc_strength = 23,
+@@ -468,10 +471,11 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
+ };
+ 
+ static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
+-	.err_mask = 0x3f,
++	.err_mask = 0x1f,
++	.err_shift = 5,
+ 	.ecc_strength = ecc_strength_mt7622,
+ 	.ecc_regs = mt7622_ecc_regs,
+-	.num_ecc_strength = 7,
++	.num_ecc_strength = 5,
+ 	.ecc_mode_shift = 4,
+ 	.parity_bits = 13,
+ 	.pg_irq_sel = 0,
+-- 
+2.35.1
+




More information about the lede-commits mailing list