drivers/mtd/nand/raw/marvell_nand.c

Source file repositories/reference/linux-study-clean/drivers/mtd/nand/raw/marvell_nand.c

File Facts

System
Linux kernel
Corpus path
drivers/mtd/nand/raw/marvell_nand.c
Extension
.c
Size
92644 bytes
Lines
3195
Domain
Driver Families
Bucket
drivers/mtd
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct marvell_hw_ecc_layout {
	/* Constraints */
	int writesize;
	int chunk;
	int strength;
	/* Corresponding layout */
	int nchunks;
	int full_chunk_cnt;
	int data_bytes;
	int spare_bytes;
	int ecc_bytes;
	int last_data_bytes;
	int last_spare_bytes;
	int last_ecc_bytes;
};

#define MARVELL_LAYOUT(ws, dc, ds, nc, fcc, db, sb, eb, ldb, lsb, leb)	\
	{								\
		.writesize = ws,					\
		.chunk = dc,						\
		.strength = ds,						\
		.nchunks = nc,						\
		.full_chunk_cnt = fcc,					\
		.data_bytes = db,					\
		.spare_bytes = sb,					\
		.ecc_bytes = eb,					\
		.last_data_bytes = ldb,					\
		.last_spare_bytes = lsb,				\
		.last_ecc_bytes = leb,					\
	}

/* Layouts explained in AN-379_Marvell_SoC_NFC_ECC */
static const struct marvell_hw_ecc_layout marvell_nfc_layouts[] = {
	MARVELL_LAYOUT(  512,   512,  1,  1,  1,  512,  8,  8,  0,  0,  0),
	MARVELL_LAYOUT( 2048,   512,  1,  1,  1, 2048, 40, 24,  0,  0,  0),
	MARVELL_LAYOUT( 2048,   512,  4,  1,  1, 2048, 32, 30,  0,  0,  0),
	MARVELL_LAYOUT( 2048,   512,  8,  2,  1, 1024,  0, 30,1024,32, 30),
	MARVELL_LAYOUT( 2048,   512,  8,  2,  1, 1024,  0, 30,1024,64, 30),
	MARVELL_LAYOUT( 2048,   512,  12, 3,  2, 704,   0, 30,640,  0, 30),
	MARVELL_LAYOUT( 2048,   512,  16, 5,  4, 512,   0, 30,  0, 32, 30),
	MARVELL_LAYOUT( 4096,   512,  4,  2,  2, 2048, 32, 30,  0,  0,  0),
	MARVELL_LAYOUT( 4096,   512,  8,  5,  4, 1024,  0, 30,  0, 64, 30),
	MARVELL_LAYOUT( 4096,   512,  12, 6,  5, 704,   0, 30,576, 32, 30),
	MARVELL_LAYOUT( 4096,   512,  16, 9,  8, 512,   0, 30,  0, 32, 30),
	MARVELL_LAYOUT( 8192,   512,  4,  4,  4, 2048,  0, 30,  0,  0,  0),
	MARVELL_LAYOUT( 8192,   512,  8,  9,  8, 1024,  0, 30,  0, 160, 30),
	MARVELL_LAYOUT( 8192,   512,  12, 12, 11, 704,  0, 30,448,  64, 30),
	MARVELL_LAYOUT( 8192,   512,  16, 17, 16, 512,  0, 30,  0,  32, 30),
};

/**
 * struct marvell_nand_chip_sel - CS line description
 *
 * The Nand Flash Controller has up to 4 CE and 2 RB pins. The CE selection
 * is made by a field in NDCB0 register, and in another field in NDCB2 register.
 * The datasheet describes the logic with an error: ADDR5 field is once
 * declared at the beginning of NDCB2, and another time at its end. Because the
 * ADDR5 field of NDCB2 may be used by other bytes, it would be more logical
 * to use the last bit of this field instead of the first ones.
 *
 * @cs:			Wanted CE lane.
 * @ndcb0_csel:		Value of the NDCB0 register with or without the flag
 *			selecting the wanted CE lane. This is set once when
 *			the Device Tree is probed.
 * @rb:			Ready/Busy pin for the flash chip
 */
struct marvell_nand_chip_sel {
	unsigned int cs;
	u32 ndcb0_csel;
	unsigned int rb;
};

/**
 * struct marvell_nand_chip - stores NAND chip device related information
 *
 * @chip:		Base NAND chip structure
 * @node:		Used to store NAND chips into a list
 * @layout:		NAND layout when using hardware ECC
 * @ndcr:		Controller register value for this NAND chip
 * @ndtr0:		Timing registers 0 value for this NAND chip
 * @ndtr1:		Timing registers 1 value for this NAND chip
 * @addr_cyc:		Amount of cycles needed to pass column address
 * @selected_die:	Current active CS
 * @nsels:		Number of CS lines required by the NAND chip
 * @sels:		Array of CS lines descriptions
 */
struct marvell_nand_chip {
	struct nand_chip chip;
	struct list_head node;
	const struct marvell_hw_ecc_layout *layout;

Annotation

Implementation Notes