mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
mtd: nand: Introduce the ECC engine framework
Create a generic ECC engine framework. This is a base to instantiate ECC engine objects. If we really want to be generic, bindings must evolve, so here is the new logic. The following three properties are mutually exclusive: - The nand-no-ecc-engine boolean property is set and there is no ECC engine to retrieve. - The nand-use-soft-ecc-engine boolean property is set and the core will force using the use of software correction. - There is a nand-ecc-engine property pointing at a node which will act as ECC engine. It the later case, the property may reference: - The NAND chip node itself (for the on-die ECC case). - The parent node if the NAND controller embeds an ECC engine. - Any other node being an external ECC controller as well. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20200827085208.16276-9-miquel.raynal@bootlin.com
This commit is contained in:
parent
b440915af2
commit
a8c7ffdb5f
4 changed files with 608 additions and 0 deletions
|
@ -127,6 +127,40 @@ struct nand_page_io_req {
|
|||
int mode;
|
||||
};
|
||||
|
||||
const struct mtd_ooblayout_ops *nand_get_small_page_ooblayout(void);
|
||||
const struct mtd_ooblayout_ops *nand_get_large_page_ooblayout(void);
|
||||
const struct mtd_ooblayout_ops *nand_get_large_page_hamming_ooblayout(void);
|
||||
|
||||
/**
|
||||
* enum nand_ecc_engine_type - NAND ECC engine type
|
||||
* @NAND_ECC_ENGINE_TYPE_INVALID: Invalid value
|
||||
* @NAND_ECC_ENGINE_TYPE_NONE: No ECC correction
|
||||
* @NAND_ECC_ENGINE_TYPE_SOFT: Software ECC correction
|
||||
* @NAND_ECC_ENGINE_TYPE_ON_HOST: On host hardware ECC correction
|
||||
* @NAND_ECC_ENGINE_TYPE_ON_DIE: On chip hardware ECC correction
|
||||
*/
|
||||
enum nand_ecc_engine_type {
|
||||
NAND_ECC_ENGINE_TYPE_INVALID,
|
||||
NAND_ECC_ENGINE_TYPE_NONE,
|
||||
NAND_ECC_ENGINE_TYPE_SOFT,
|
||||
NAND_ECC_ENGINE_TYPE_ON_HOST,
|
||||
NAND_ECC_ENGINE_TYPE_ON_DIE,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nand_ecc_placement - NAND ECC bytes placement
|
||||
* @NAND_ECC_PLACEMENT_UNKNOWN: The actual position of the ECC bytes is unknown
|
||||
* @NAND_ECC_PLACEMENT_OOB: The ECC bytes are located in the OOB area
|
||||
* @NAND_ECC_PLACEMENT_INTERLEAVED: Syndrome layout, there are ECC bytes
|
||||
* interleaved with regular data in the main
|
||||
* area
|
||||
*/
|
||||
enum nand_ecc_placement {
|
||||
NAND_ECC_PLACEMENT_UNKNOWN,
|
||||
NAND_ECC_PLACEMENT_OOB,
|
||||
NAND_ECC_PLACEMENT_INTERLEAVED,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nand_ecc_algo - NAND ECC algorithm
|
||||
* @NAND_ECC_ALGO_UNKNOWN: Unknown algorithm
|
||||
|
@ -143,16 +177,27 @@ enum nand_ecc_algo {
|
|||
|
||||
/**
|
||||
* struct nand_ecc_props - NAND ECC properties
|
||||
* @engine_type: ECC engine type
|
||||
* @placement: OOB placement (if relevant)
|
||||
* @algo: ECC algorithm (if relevant)
|
||||
* @strength: ECC strength
|
||||
* @step_size: Number of bytes per step
|
||||
* @flags: Misc properties
|
||||
*/
|
||||
struct nand_ecc_props {
|
||||
enum nand_ecc_engine_type engine_type;
|
||||
enum nand_ecc_placement placement;
|
||||
enum nand_ecc_algo algo;
|
||||
unsigned int strength;
|
||||
unsigned int step_size;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
#define NAND_ECCREQ(str, stp) { .strength = (str), .step_size = (stp) }
|
||||
|
||||
/* NAND ECC misc flags */
|
||||
#define NAND_ECC_MAXIMIZE_STRENGTH BIT(0)
|
||||
|
||||
/**
|
||||
* struct nand_bbt - bad block table object
|
||||
* @cache: in memory BBT cache
|
||||
|
@ -183,6 +228,75 @@ struct nand_ops {
|
|||
bool (*isbad)(struct nand_device *nand, const struct nand_pos *pos);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_ecc_context - Context for the ECC engine
|
||||
* @conf: basic ECC engine parameters
|
||||
* @total: total number of bytes used for storing ECC codes, this is used by
|
||||
* generic OOB layouts
|
||||
* @priv: ECC engine driver private data
|
||||
*/
|
||||
struct nand_ecc_context {
|
||||
struct nand_ecc_props conf;
|
||||
unsigned int total;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_ecc_engine_ops - ECC engine operations
|
||||
* @init_ctx: given a desired user configuration for the pointed NAND device,
|
||||
* requests the ECC engine driver to setup a configuration with
|
||||
* values it supports.
|
||||
* @cleanup_ctx: clean the context initialized by @init_ctx.
|
||||
* @prepare_io_req: is called before reading/writing a page to prepare the I/O
|
||||
* request to be performed with ECC correction.
|
||||
* @finish_io_req: is called after reading/writing a page to terminate the I/O
|
||||
* request and ensure proper ECC correction.
|
||||
*/
|
||||
struct nand_ecc_engine_ops {
|
||||
int (*init_ctx)(struct nand_device *nand);
|
||||
void (*cleanup_ctx)(struct nand_device *nand);
|
||||
int (*prepare_io_req)(struct nand_device *nand,
|
||||
struct nand_page_io_req *req);
|
||||
int (*finish_io_req)(struct nand_device *nand,
|
||||
struct nand_page_io_req *req);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_ecc_engine - ECC engine abstraction for NAND devices
|
||||
* @ops: ECC engine operations
|
||||
*/
|
||||
struct nand_ecc_engine {
|
||||
struct nand_ecc_engine_ops *ops;
|
||||
};
|
||||
|
||||
void of_get_nand_ecc_user_config(struct nand_device *nand);
|
||||
int nand_ecc_init_ctx(struct nand_device *nand);
|
||||
void nand_ecc_cleanup_ctx(struct nand_device *nand);
|
||||
int nand_ecc_prepare_io_req(struct nand_device *nand,
|
||||
struct nand_page_io_req *req);
|
||||
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);
|
||||
|
||||
/**
|
||||
* struct nand_ecc - Information relative to the ECC
|
||||
* @defaults: Default values, depend on the underlying subsystem
|
||||
* @requirements: ECC requirements from the NAND chip perspective
|
||||
* @user_conf: User desires in terms of ECC parameters
|
||||
* @ctx: ECC context for the ECC engine, derived from the device @requirements
|
||||
* the @user_conf and the @defaults
|
||||
* @ondie_engine: On-die ECC engine reference, if any
|
||||
* @engine: ECC engine actually bound
|
||||
*/
|
||||
struct nand_ecc {
|
||||
struct nand_ecc_props defaults;
|
||||
struct nand_ecc_props requirements;
|
||||
struct nand_ecc_props user_conf;
|
||||
struct nand_ecc_context ctx;
|
||||
struct nand_ecc_engine *ondie_engine;
|
||||
struct nand_ecc_engine *engine;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_device - NAND device
|
||||
* @mtd: MTD instance attached to the NAND device
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue