summaryrefslogtreecommitdiff
path: root/include/linux/mtd
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2022-02-18 17:11:12 +0300
committerMiquel Raynal <miquel.raynal@bootlin.com>2022-02-18 17:11:12 +0300
commitd71dac3b897f51d7d1fcf28d2a2ab29e541a6cda (patch)
treec39637eb678816ccb481293edcc4208cdfe3b0ac /include/linux/mtd
parentad5e35f58384179bbd3cdb349904e150f364c4f3 (diff)
parent00360ebae483e603d55ec9a7231b787cb80ffe13 (diff)
downloadlinux-d71dac3b897f51d7d1fcf28d2a2ab29e541a6cda.tar.xz
Merge tag 'mtd/spi-mem-ecc-for-5.18' into mtd/next
Topic branch bringing-in changes related to the support of ECC engines that can be used by SPI controllers to manage SPI NANDs as well as possibly by parallel NAND controllers. In particular, it brings support for Macronix ECC engine that can be used with Macronix SPI controller. The changes touch the NAND core, the NAND ECC core, the spi-mem layer, a SPI controller driver and add a new NAND ECC driver, as well as a number of binding updates. Binding changes: * Vendor prefixes: Clarify Macronix prefix * SPI NAND: Convert spi-nand description file to yaml * Raw NAND chip: Create a NAND chip description * Raw NAND controller: - Harmonize the property types - Fix a comment in the examples - Fix the reg property description * Describe Macronix NAND ECC engine * Macronix SPI controller: - Document the nand-ecc-engine property - Convert to yaml - The interrupt property is not mandatory NAND core changes: * ECC: - Add infrastructure to support hardware engines - Add a new helper to retrieve the ECC context - Provide a helper to retrieve a pilelined engine device NAND-ECC changes: * Macronix ECC engine: - Add Macronix external ECC engine support - Support SPI pipelined mode SPI-NAND core changes: * Delay a little bit the dirmap creation * Create direct mapping descriptors for ECC operations SPI-NAND driver changes: * macronix: Use random program load SPI changes: * Macronix SPI controller: - Fix the transmit path - Create a helper to configure the controller before an operation - Create a helper to ease the start of an operation - Add support for direct mapping - Add support for pipelined ECC operations * spi-mem: - Introduce a capability structure - Check the controller extra capabilities - cadence-quadspi/mxic: Provide capability structures - Kill the spi_mem_dtr_supports_op() helper - Add an ecc parameter to the spi_mem_op structure
Diffstat (limited to 'include/linux/mtd')
-rw-r--r--include/linux/mtd/nand-ecc-mxic.h49
-rw-r--r--include/linux/mtd/nand.h49
-rw-r--r--include/linux/mtd/spinand.h2
3 files changed, 100 insertions, 0 deletions
diff --git a/include/linux/mtd/nand-ecc-mxic.h b/include/linux/mtd/nand-ecc-mxic.h
new file mode 100644
index 000000000000..b125926e458c
--- /dev/null
+++ b/include/linux/mtd/nand-ecc-mxic.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright © 2019 Macronix
+ * Author: Miquèl Raynal <miquel.raynal@bootlin.com>
+ *
+ * Header for the Macronix external ECC engine.
+ */
+
+#ifndef __MTD_NAND_ECC_MXIC_H__
+#define __MTD_NAND_ECC_MXIC_H__
+
+#include <linux/platform_device.h>
+#include <linux/device.h>
+
+struct mxic_ecc_engine;
+
+#if IS_ENABLED(CONFIG_MTD_NAND_ECC_MXIC) && IS_REACHABLE(CONFIG_MTD_NAND_CORE)
+
+struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void);
+struct nand_ecc_engine *mxic_ecc_get_pipelined_engine(struct platform_device *spi_pdev);
+void mxic_ecc_put_pipelined_engine(struct nand_ecc_engine *eng);
+int mxic_ecc_process_data_pipelined(struct nand_ecc_engine *eng,
+ unsigned int direction, dma_addr_t dirmap);
+
+#else /* !CONFIG_MTD_NAND_ECC_MXIC */
+
+static inline struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void)
+{
+ return NULL;
+}
+
+static inline struct nand_ecc_engine *
+mxic_ecc_get_pipelined_engine(struct platform_device *spi_pdev)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline void mxic_ecc_put_pipelined_engine(struct nand_ecc_engine *eng) {}
+
+static inline int mxic_ecc_process_data_pipelined(struct nand_ecc_engine *eng,
+ unsigned int direction,
+ dma_addr_t dirmap)
+{
+ return -EOPNOTSUPP;
+}
+
+#endif /* CONFIG_MTD_NAND_ECC_MXIC */
+
+#endif /* __MTD_NAND_ECC_MXIC_H__ */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 32fc7edf65b3..c3693bb87b4c 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -264,11 +264,35 @@ struct nand_ecc_engine_ops {
};
/**
+ * 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,28 @@ 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);
+
+#if IS_REACHABLE(CONFIG_MTD_NAND_CORE)
+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);
+#else
+static inline int
+nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine)
+{
+ return -ENOTSUPP;
+}
+static inline int
+nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine)
+{
+ return -ENOTSUPP;
+}
+#endif
+
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);
@@ -962,6 +1006,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,
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;
};
/**