1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- From eb4a2d282c3c5752211d69be6dff2674119e5583 Mon Sep 17 00:00:00 2001
- From: Miquel Raynal <[email protected]>
- 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 <[email protected]>
- Reviewed-by: Boris Brezillon <[email protected]>
- Link: https://lore.kernel.org/linux-mtd/[email protected]
- (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(-)
- --- 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(st
- }
- }
-
- - 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(str
- 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);
- @@ -875,6 +881,31 @@ static int spinand_create_dirmap(struct
-
- 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;
- }
-
- --- a/include/linux/mtd/spinand.h
- +++ b/include/linux/mtd/spinand.h
- @@ -392,6 +392,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;
- };
-
- /**
|