linux/drivers/mtd/nand/raw/stm32_fmc2_nand.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) STMicroelectronics 2018
 * Author: Christophe Kerello <[email protected]>
 */

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/mtd/rawnand.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>

/* Bad block marker length */
#define FMC2_BBM_LEN

/* ECC step size */
#define FMC2_ECC_STEP_SIZE

/* BCHDSRx registers length */
#define FMC2_BCHDSRS_LEN

/* HECCR length */
#define FMC2_HECCR_LEN

/* Max requests done for a 8k nand page size */
#define FMC2_MAX_SG

/* Max chip enable */
#define FMC2_MAX_CE

/* Max ECC buffer length */
#define FMC2_MAX_ECC_BUF_LEN

#define FMC2_TIMEOUT_MS

/* Timings */
#define FMC2_THIZ
#define FMC2_TIO
#define FMC2_TSYNC
#define FMC2_PCR_TIMING_MASK
#define FMC2_PMEM_PATT_TIMING_MASK

/* FMC2 Controller Registers */
#define FMC2_BCR1
#define FMC2_PCR
#define FMC2_SR
#define FMC2_PMEM
#define FMC2_PATT
#define FMC2_HECCR
#define FMC2_ISR
#define FMC2_ICR
#define FMC2_CSQCR
#define FMC2_CSQCFGR1
#define FMC2_CSQCFGR2
#define FMC2_CSQCFGR3
#define FMC2_CSQAR1
#define FMC2_CSQAR2
#define FMC2_CSQIER
#define FMC2_CSQISR
#define FMC2_CSQICR
#define FMC2_CSQEMSR
#define FMC2_BCHIER
#define FMC2_BCHISR
#define FMC2_BCHICR
#define FMC2_BCHPBR1
#define FMC2_BCHPBR2
#define FMC2_BCHPBR3
#define FMC2_BCHPBR4
#define FMC2_BCHDSR0
#define FMC2_BCHDSR1
#define FMC2_BCHDSR2
#define FMC2_BCHDSR3
#define FMC2_BCHDSR4

/* Register: FMC2_BCR1 */
#define FMC2_BCR1_FMC2EN

/* Register: FMC2_PCR */
#define FMC2_PCR_PWAITEN
#define FMC2_PCR_PBKEN
#define FMC2_PCR_PWID
#define FMC2_PCR_PWID_BUSWIDTH_8
#define FMC2_PCR_PWID_BUSWIDTH_16
#define FMC2_PCR_ECCEN
#define FMC2_PCR_ECCALG
#define FMC2_PCR_TCLR
#define FMC2_PCR_TCLR_DEFAULT
#define FMC2_PCR_TAR
#define FMC2_PCR_TAR_DEFAULT
#define FMC2_PCR_ECCSS
#define FMC2_PCR_ECCSS_512
#define FMC2_PCR_ECCSS_2048
#define FMC2_PCR_BCHECC
#define FMC2_PCR_WEN

/* Register: FMC2_SR */
#define FMC2_SR_NWRF

/* Register: FMC2_PMEM */
#define FMC2_PMEM_MEMSET
#define FMC2_PMEM_MEMWAIT
#define FMC2_PMEM_MEMHOLD
#define FMC2_PMEM_MEMHIZ
#define FMC2_PMEM_DEFAULT

/* Register: FMC2_PATT */
#define FMC2_PATT_ATTSET
#define FMC2_PATT_ATTWAIT
#define FMC2_PATT_ATTHOLD
#define FMC2_PATT_ATTHIZ
#define FMC2_PATT_DEFAULT

/* Register: FMC2_ISR */
#define FMC2_ISR_IHLF

/* Register: FMC2_ICR */
#define FMC2_ICR_CIHLF

/* Register: FMC2_CSQCR */
#define FMC2_CSQCR_CSQSTART

/* Register: FMC2_CSQCFGR1 */
#define FMC2_CSQCFGR1_CMD2EN
#define FMC2_CSQCFGR1_DMADEN
#define FMC2_CSQCFGR1_ACYNBR
#define FMC2_CSQCFGR1_CMD1
#define FMC2_CSQCFGR1_CMD2
#define FMC2_CSQCFGR1_CMD1T
#define FMC2_CSQCFGR1_CMD2T

/* Register: FMC2_CSQCFGR2 */
#define FMC2_CSQCFGR2_SQSDTEN
#define FMC2_CSQCFGR2_RCMD2EN
#define FMC2_CSQCFGR2_DMASEN
#define FMC2_CSQCFGR2_RCMD1
#define FMC2_CSQCFGR2_RCMD2
#define FMC2_CSQCFGR2_RCMD1T
#define FMC2_CSQCFGR2_RCMD2T

/* Register: FMC2_CSQCFGR3 */
#define FMC2_CSQCFGR3_SNBR
#define FMC2_CSQCFGR3_AC1T
#define FMC2_CSQCFGR3_AC2T
#define FMC2_CSQCFGR3_AC3T
#define FMC2_CSQCFGR3_AC4T
#define FMC2_CSQCFGR3_AC5T
#define FMC2_CSQCFGR3_SDT
#define FMC2_CSQCFGR3_RAC1T
#define FMC2_CSQCFGR3_RAC2T

/* Register: FMC2_CSQCAR1 */
#define FMC2_CSQCAR1_ADDC1
#define FMC2_CSQCAR1_ADDC2
#define FMC2_CSQCAR1_ADDC3
#define FMC2_CSQCAR1_ADDC4

/* Register: FMC2_CSQCAR2 */
#define FMC2_CSQCAR2_ADDC5
#define FMC2_CSQCAR2_NANDCEN
#define FMC2_CSQCAR2_SAO

/* Register: FMC2_CSQIER */
#define FMC2_CSQIER_TCIE

/* Register: FMC2_CSQICR */
#define FMC2_CSQICR_CLEAR_IRQ

/* Register: FMC2_CSQEMSR */
#define FMC2_CSQEMSR_SEM

/* Register: FMC2_BCHIER */
#define FMC2_BCHIER_DERIE
#define FMC2_BCHIER_EPBRIE

/* Register: FMC2_BCHICR */
#define FMC2_BCHICR_CLEAR_IRQ

/* Register: FMC2_BCHDSR0 */
#define FMC2_BCHDSR0_DUE
#define FMC2_BCHDSR0_DEF
#define FMC2_BCHDSR0_DEN

/* Register: FMC2_BCHDSR1 */
#define FMC2_BCHDSR1_EBP1
#define FMC2_BCHDSR1_EBP2

/* Register: FMC2_BCHDSR2 */
#define FMC2_BCHDSR2_EBP3
#define FMC2_BCHDSR2_EBP4

/* Register: FMC2_BCHDSR3 */
#define FMC2_BCHDSR3_EBP5
#define FMC2_BCHDSR3_EBP6

/* Register: FMC2_BCHDSR4 */
#define FMC2_BCHDSR4_EBP7
#define FMC2_BCHDSR4_EBP8

enum stm32_fmc2_ecc {};

enum stm32_fmc2_irq_state {};

struct stm32_fmc2_timings {};

struct stm32_fmc2_nand {};

static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip)
{}

struct stm32_fmc2_nfc;

struct stm32_fmc2_nfc_data {};

struct stm32_fmc2_nfc {};

static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct nand_controller *base)
{}

static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip)
{}

static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
{}

static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr)
{}

static void stm32_fmc2_nfc_set_buswidth_16(struct stm32_fmc2_nfc *nfc, bool set)
{}

static void stm32_fmc2_nfc_set_ecc(struct stm32_fmc2_nfc *nfc, bool enable)
{}

static void stm32_fmc2_nfc_enable_seq_irq(struct stm32_fmc2_nfc *nfc)
{}

static void stm32_fmc2_nfc_disable_seq_irq(struct stm32_fmc2_nfc *nfc)
{}

static void stm32_fmc2_nfc_clear_seq_irq(struct stm32_fmc2_nfc *nfc)
{}

static void stm32_fmc2_nfc_enable_bch_irq(struct stm32_fmc2_nfc *nfc, int mode)
{}

static void stm32_fmc2_nfc_disable_bch_irq(struct stm32_fmc2_nfc *nfc)
{}

static void stm32_fmc2_nfc_clear_bch_irq(struct stm32_fmc2_nfc *nfc)
{}

/*
 * Enable ECC logic and reset syndrome/parity bits previously calculated
 * Syndrome/parity bits is cleared by setting the ECCEN bit to 0
 */
static void stm32_fmc2_nfc_hwctl(struct nand_chip *chip, int mode)
{}

/*
 * ECC Hamming calculation
 * ECC is 3 bytes for 512 bytes of data (supports error correction up to
 * max of 1-bit)
 */
static void stm32_fmc2_nfc_ham_set_ecc(const u32 ecc_sta, u8 *ecc)
{}

static int stm32_fmc2_nfc_ham_calculate(struct nand_chip *chip, const u8 *data,
					u8 *ecc)
{}

static int stm32_fmc2_nfc_ham_correct(struct nand_chip *chip, u8 *dat,
				      u8 *read_ecc, u8 *calc_ecc)
{}

/*
 * ECC BCH calculation and correction
 * ECC is 7/13 bytes for 512 bytes of data (supports error correction up to
 * max of 4-bit/8-bit)
 */
static int stm32_fmc2_nfc_bch_calculate(struct nand_chip *chip, const u8 *data,
					u8 *ecc)
{}

static int stm32_fmc2_nfc_bch_decode(int eccsize, u8 *dat, u32 *ecc_sta)
{}

static int stm32_fmc2_nfc_bch_correct(struct nand_chip *chip, u8 *dat,
				      u8 *read_ecc, u8 *calc_ecc)
{}

static int stm32_fmc2_nfc_read_page(struct nand_chip *chip, u8 *buf,
				    int oob_required, int page)
{}

/* Sequencer read/write configuration */
static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page,
					int raw, bool write_data)
{}

static void stm32_fmc2_nfc_dma_callback(void *arg)
{}

/* Read/write data from/to a page */
static int stm32_fmc2_nfc_xfer(struct nand_chip *chip, const u8 *buf,
			       int raw, bool write_data)
{}

static int stm32_fmc2_nfc_seq_write(struct nand_chip *chip, const u8 *buf,
				    int oob_required, int page, int raw)
{}

static int stm32_fmc2_nfc_seq_write_page(struct nand_chip *chip, const u8 *buf,
					 int oob_required, int page)
{}

static int stm32_fmc2_nfc_seq_write_page_raw(struct nand_chip *chip,
					     const u8 *buf, int oob_required,
					     int page)
{}

/* Get a status indicating which sectors have errors */
static u16 stm32_fmc2_nfc_get_mapping_status(struct stm32_fmc2_nfc *nfc)
{}

static int stm32_fmc2_nfc_seq_correct(struct nand_chip *chip, u8 *dat,
				      u8 *read_ecc, u8 *calc_ecc)
{}

static int stm32_fmc2_nfc_seq_read_page(struct nand_chip *chip, u8 *buf,
					int oob_required, int page)
{}

static int stm32_fmc2_nfc_seq_read_page_raw(struct nand_chip *chip, u8 *buf,
					    int oob_required, int page)
{}

static irqreturn_t stm32_fmc2_nfc_irq(int irq, void *dev_id)
{}

static void stm32_fmc2_nfc_read_data(struct nand_chip *chip, void *buf,
				     unsigned int len, bool force_8bit)
{}

static void stm32_fmc2_nfc_write_data(struct nand_chip *chip, const void *buf,
				      unsigned int len, bool force_8bit)
{}

static int stm32_fmc2_nfc_waitrdy(struct nand_chip *chip,
				  unsigned long timeout_ms)
{}

static int stm32_fmc2_nfc_exec_op(struct nand_chip *chip,
				  const struct nand_operation *op,
				  bool check_only)
{}

static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc)
{}

static void stm32_fmc2_nfc_calc_timings(struct nand_chip *chip,
					const struct nand_sdr_timings *sdrt)
{}

static int stm32_fmc2_nfc_setup_interface(struct nand_chip *chip, int chipnr,
					  const struct nand_interface_config *conf)
{}

static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc *nfc)
{}

static void stm32_fmc2_nfc_nand_callbacks_setup(struct nand_chip *chip)
{}

static int stm32_fmc2_nfc_ooblayout_ecc(struct mtd_info *mtd, int section,
					struct mtd_oob_region *oobregion)
{}

static int stm32_fmc2_nfc_ooblayout_free(struct mtd_info *mtd, int section,
					 struct mtd_oob_region *oobregion)
{}

static const struct mtd_ooblayout_ops stm32_fmc2_nfc_ooblayout_ops =;

static int stm32_fmc2_nfc_calc_ecc_bytes(int step_size, int strength)
{}

NAND_ECC_CAPS_SINGLE();

static int stm32_fmc2_nfc_attach_chip(struct nand_chip *chip)
{}

static const struct nand_controller_ops stm32_fmc2_nfc_controller_ops =;

static void stm32_fmc2_nfc_wp_enable(struct stm32_fmc2_nand *nand)
{}

static void stm32_fmc2_nfc_wp_disable(struct stm32_fmc2_nand *nand)
{}

static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc,
				      struct device_node *dn)
{}

static int stm32_fmc2_nfc_parse_dt(struct stm32_fmc2_nfc *nfc)
{}

static int stm32_fmc2_nfc_set_cdev(struct stm32_fmc2_nfc *nfc)
{}

static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
{}

static void stm32_fmc2_nfc_remove(struct platform_device *pdev)
{}

static int __maybe_unused stm32_fmc2_nfc_suspend(struct device *dev)
{}

static int __maybe_unused stm32_fmc2_nfc_resume(struct device *dev)
{}

static SIMPLE_DEV_PM_OPS(stm32_fmc2_nfc_pm_ops, stm32_fmc2_nfc_suspend,
			 stm32_fmc2_nfc_resume);

static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp1_data =;

static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp25_data =;

static const struct of_device_id stm32_fmc2_nfc_match[] =;
MODULE_DEVICE_TABLE(of, stm32_fmc2_nfc_match);

static struct platform_driver stm32_fmc2_nfc_driver =;
module_platform_driver();

MODULE_ALIAS();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();