Skip to content

Commit

Permalink
mtd: spinand: Create direct mapping descriptors for ECC operations
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Miquel Raynal committed Feb 10, 2022
1 parent dc4c2cb commit f9d7c72
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
35 changes: 33 additions & 2 deletions drivers/mtd/nand/spi/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions include/linux/mtd/spinand.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/**
Expand Down

0 comments on commit f9d7c72

Please sign in to comment.