drivers/mtd/nand/raw/stm32_fmc2_nand.c

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

File Facts

System
Linux kernel
Corpus path
drivers/mtd/nand/raw/stm32_fmc2_nand.c
Extension
.c
Size
56644 bytes
Lines
2164
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 stm32_fmc2_timings {
	u8 tclr;
	u8 tar;
	u8 thiz;
	u8 twait;
	u8 thold_mem;
	u8 tset_mem;
	u8 thold_att;
	u8 tset_att;
};

struct stm32_fmc2_nand {
	struct nand_chip chip;
	struct gpio_desc *wp_gpio;
	struct stm32_fmc2_timings timings;
	int ncs;
	int cs_used[FMC2_MAX_CE];
};

static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip)
{
	return container_of(chip, struct stm32_fmc2_nand, chip);
}

struct stm32_fmc2_nfc;

struct stm32_fmc2_nfc_data {
	int max_ncs;
	int (*set_cdev)(struct stm32_fmc2_nfc *nfc);
};

struct stm32_fmc2_nfc {
	struct nand_controller base;
	struct stm32_fmc2_nand nand;
	struct device *dev;
	struct device *cdev;
	struct regmap *regmap;
	void __iomem *data_base[FMC2_MAX_CE];
	void __iomem *cmd_base[FMC2_MAX_CE];
	void __iomem *addr_base[FMC2_MAX_CE];
	phys_addr_t io_phys_addr;
	phys_addr_t data_phys_addr[FMC2_MAX_CE];
	struct clk *clk;
	u8 irq_state;
	const struct stm32_fmc2_nfc_data *data;

	struct dma_chan *dma_tx_ch;
	struct dma_chan *dma_rx_ch;
	struct dma_chan *dma_ecc_ch;
	struct sg_table dma_data_sg;
	struct sg_table dma_ecc_sg;
	u8 *ecc_buf;
	dma_addr_t dma_ecc_addr;
	int dma_ecc_len;
	u32 tx_dma_max_burst;
	u32 rx_dma_max_burst;

	struct completion complete;
	struct completion dma_data_complete;
	struct completion dma_ecc_complete;

	u8 cs_assigned;
	int cs_sel;
};

static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct nand_controller *base)
{
	return container_of(base, struct stm32_fmc2_nfc, base);
}

static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip)
{
	struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
	struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
	struct stm32_fmc2_timings *timings = &nand->timings;
	u32 pmem, patt;

	/* Set tclr/tar timings */
	regmap_update_bits(nfc->regmap, FMC2_PCR,
			   FMC2_PCR_TCLR | FMC2_PCR_TAR,
			   FIELD_PREP(FMC2_PCR_TCLR, timings->tclr) |
			   FIELD_PREP(FMC2_PCR_TAR, timings->tar));

	/* Set tset/twait/thold/thiz timings in common bank */
	pmem = FIELD_PREP(FMC2_PMEM_MEMSET, timings->tset_mem);
	pmem |= FIELD_PREP(FMC2_PMEM_MEMWAIT, timings->twait);
	pmem |= FIELD_PREP(FMC2_PMEM_MEMHOLD, timings->thold_mem);
	pmem |= FIELD_PREP(FMC2_PMEM_MEMHIZ, timings->thiz);
	regmap_write(nfc->regmap, FMC2_PMEM, pmem);

Annotation

Implementation Notes