aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/patches-5.15/120-09-v5.18-mtd-spinand-Create-direct-mapping-descriptors-for-EC.patch
diff options
context:
space:
mode:
authorChuanhong Guo <gch981213@gmail.com>2022-04-07 10:05:25 +0800
committerChuanhong Guo <gch981213@gmail.com>2022-04-28 18:06:00 +0800
commit861efe158ac56da2e00637aed704a77994bec54c (patch)
tree539836b2d4f7ec33792b2dda0b6ab7f45455c35f /target/linux/mediatek/patches-5.15/120-09-v5.18-mtd-spinand-Create-direct-mapping-descriptors-for-EC.patch
parent3e5925225ec27519f1eccc1605fe9a76303d539b (diff)
downloadupstream-861efe158ac56da2e00637aed704a77994bec54c.tar.gz
upstream-861efe158ac56da2e00637aed704a77994bec54c.tar.bz2
upstream-861efe158ac56da2e00637aed704a77994bec54c.zip
mediatek: v5.15: backport spi-mem ecc support
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
Diffstat (limited to 'target/linux/mediatek/patches-5.15/120-09-v5.18-mtd-spinand-Create-direct-mapping-descriptors-for-EC.patch')
-rw-r--r--target/linux/mediatek/patches-5.15/120-09-v5.18-mtd-spinand-Create-direct-mapping-descriptors-for-EC.patch105
1 files changed, 105 insertions, 0 deletions
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@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@bootlin.com>
+Reviewed-by: Boris Brezillon <boris.brezillon@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
+