linux/drivers/mtd/nand/raw/atmel/nand-controller.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2017 ATMEL
 * Copyright 2017 Free Electrons
 *
 * Author: Boris Brezillon <[email protected]>
 *
 * Derived from the atmel_nand.c driver which contained the following
 * copyrights:
 *
 *   Copyright 2003 Rick Bronson
 *
 *   Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8)
 *	Copyright 2001 Thomas Gleixner ([email protected])
 *
 *   Derived from drivers/mtd/spia.c (removed in v3.8)
 *	Copyright 2000 Steven J. Hill ([email protected])
 *
 *
 *   Add Hardware ECC support for AT91SAM9260 / AT91SAM9263
 *	Richard Genoud ([email protected]), Adeneo Copyright 2007
 *
 *   Derived from Das U-Boot source code
 *	(u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c)
 *	Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas
 *
 *   Add Programmable Multibit ECC support for various AT91 SoC
 *	Copyright 2012 ATMEL, Hong Xu
 *
 *   Add Nand Flash Controller support for SAMA5 SoC
 *	Copyright 2013 ATMEL, Josh Wu ([email protected])
 *
 * A few words about the naming convention in this file. This convention
 * applies to structure and function names.
 *
 * Prefixes:
 *
 * - atmel_nand_: all generic structures/functions
 * - atmel_smc_nand_: all structures/functions specific to the SMC interface
 *		      (at91sam9 and avr32 SoCs)
 * - atmel_hsmc_nand_: all structures/functions specific to the HSMC interface
 *		       (sama5 SoCs and later)
 * - atmel_nfc_: all structures/functions used to manipulate the NFC sub-block
 *		 that is available in the HSMC block
 * - <soc>_nand_: all SoC specific structures/functions
 */

#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/genalloc.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/atmel-matrix.h>
#include <linux/mfd/syscon/atmel-smc.h>
#include <linux/module.h>
#include <linux/mtd/rawnand.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/iopoll.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <soc/at91/atmel-sfr.h>

#include "pmecc.h"

#define ATMEL_HSMC_NFC_CFG
#define ATMEL_HSMC_NFC_CFG_SPARESIZE(x)
#define ATMEL_HSMC_NFC_CFG_SPARESIZE_MASK
#define ATMEL_HSMC_NFC_CFG_DTO(cyc, mul)
#define ATMEL_HSMC_NFC_CFG_DTO_MAX
#define ATMEL_HSMC_NFC_CFG_RBEDGE
#define ATMEL_HSMC_NFC_CFG_FALLING_EDGE
#define ATMEL_HSMC_NFC_CFG_RSPARE
#define ATMEL_HSMC_NFC_CFG_WSPARE
#define ATMEL_HSMC_NFC_CFG_PAGESIZE_MASK
#define ATMEL_HSMC_NFC_CFG_PAGESIZE(x)

#define ATMEL_HSMC_NFC_CTRL
#define ATMEL_HSMC_NFC_CTRL_EN
#define ATMEL_HSMC_NFC_CTRL_DIS

#define ATMEL_HSMC_NFC_SR
#define ATMEL_HSMC_NFC_IER
#define ATMEL_HSMC_NFC_IDR
#define ATMEL_HSMC_NFC_IMR
#define ATMEL_HSMC_NFC_SR_ENABLED
#define ATMEL_HSMC_NFC_SR_RB_RISE
#define ATMEL_HSMC_NFC_SR_RB_FALL
#define ATMEL_HSMC_NFC_SR_BUSY
#define ATMEL_HSMC_NFC_SR_WR
#define ATMEL_HSMC_NFC_SR_CSID
#define ATMEL_HSMC_NFC_SR_XFRDONE
#define ATMEL_HSMC_NFC_SR_CMDDONE
#define ATMEL_HSMC_NFC_SR_DTOE
#define ATMEL_HSMC_NFC_SR_UNDEF
#define ATMEL_HSMC_NFC_SR_AWB
#define ATMEL_HSMC_NFC_SR_NFCASE
#define ATMEL_HSMC_NFC_SR_ERRORS
#define ATMEL_HSMC_NFC_SR_RBEDGE(x)

#define ATMEL_HSMC_NFC_ADDR
#define ATMEL_HSMC_NFC_BANK

#define ATMEL_NFC_MAX_RB_ID

#define ATMEL_NFC_SRAM_SIZE

#define ATMEL_NFC_CMD(pos, cmd)
#define ATMEL_NFC_VCMD2
#define ATMEL_NFC_ACYCLE(naddrs)
#define ATMEL_NFC_CSID(cs)
#define ATMEL_NFC_DATAEN
#define ATMEL_NFC_NFCWR

#define ATMEL_NFC_MAX_ADDR_CYCLES

#define ATMEL_NAND_ALE_OFFSET
#define ATMEL_NAND_CLE_OFFSET

#define DEFAULT_TIMEOUT_MS
#define MIN_DMA_LEN

static bool atmel_nand_avoid_dma __read_mostly;

MODULE_PARM_DESC();
module_param_named(avoiddma, atmel_nand_avoid_dma, bool, 0400);

enum atmel_nand_rb_type {};

struct atmel_nand_rb {};

struct atmel_nand_cs {};

struct atmel_nand {};

static inline struct atmel_nand *to_atmel_nand(struct nand_chip *chip)
{}

enum atmel_nfc_data_xfer {};

struct atmel_nfc_op {};

struct atmel_nand_controller;
struct atmel_nand_controller_caps;

struct atmel_nand_controller_ops {};

struct atmel_nand_controller_caps {};

struct atmel_nand_controller {};

static inline struct atmel_nand_controller *
to_nand_controller(struct nand_controller *ctl)
{}

struct atmel_smc_nand_ebi_csa_cfg {};

struct atmel_smc_nand_controller {};

static inline struct atmel_smc_nand_controller *
to_smc_nand_controller(struct nand_controller *ctl)
{}

struct atmel_hsmc_nand_controller {};

static inline struct atmel_hsmc_nand_controller *
to_hsmc_nand_controller(struct nand_controller *ctl)
{}

static bool atmel_nfc_op_done(struct atmel_nfc_op *op, u32 status)
{}

static irqreturn_t atmel_nfc_interrupt(int irq, void *data)
{}

static int atmel_nfc_wait(struct atmel_hsmc_nand_controller *nc, bool poll,
			  unsigned int timeout_ms)
{}

static void atmel_nand_dma_transfer_finished(void *data)
{}

static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc,
				   void *buf, dma_addr_t dev_dma, size_t len,
				   enum dma_data_direction dir)
{}

static int atmel_nfc_exec_op(struct atmel_hsmc_nand_controller *nc, bool poll)
{}

static void atmel_nand_data_in(struct atmel_nand *nand, void *buf,
			       unsigned int len, bool force_8bit)
{}

static void atmel_nand_data_out(struct atmel_nand *nand, const void *buf,
				unsigned int len, bool force_8bit)
{}

static int atmel_nand_waitrdy(struct atmel_nand *nand, unsigned int timeout_ms)
{}

static int atmel_hsmc_nand_waitrdy(struct atmel_nand *nand,
				   unsigned int timeout_ms)
{}

static void atmel_nand_select_target(struct atmel_nand *nand,
				     unsigned int cs)
{}

static void atmel_hsmc_nand_select_target(struct atmel_nand *nand,
					  unsigned int cs)
{}

static int atmel_smc_nand_exec_instr(struct atmel_nand *nand,
				     const struct nand_op_instr *instr)
{}

static int atmel_smc_nand_exec_op(struct atmel_nand *nand,
				  const struct nand_operation *op,
				  bool check_only)
{}

static int atmel_hsmc_exec_cmd_addr(struct nand_chip *chip,
				    const struct nand_subop *subop)
{}

static int atmel_hsmc_exec_rw(struct nand_chip *chip,
			      const struct nand_subop *subop)
{}

static int atmel_hsmc_exec_waitrdy(struct nand_chip *chip,
				   const struct nand_subop *subop)
{}

static const struct nand_op_parser atmel_hsmc_op_parser =;

static int atmel_hsmc_nand_exec_op(struct atmel_nand *nand,
				   const struct nand_operation *op,
				   bool check_only)
{}

static void atmel_nfc_copy_to_sram(struct nand_chip *chip, const u8 *buf,
				   bool oob_required)
{}

static void atmel_nfc_copy_from_sram(struct nand_chip *chip, u8 *buf,
				     bool oob_required)
{}

static void atmel_nfc_set_op_addr(struct nand_chip *chip, int page, int column)
{}

static int atmel_nand_pmecc_enable(struct nand_chip *chip, int op, bool raw)
{}

static void atmel_nand_pmecc_disable(struct nand_chip *chip, bool raw)
{}

static int atmel_nand_pmecc_generate_eccbytes(struct nand_chip *chip, bool raw)
{}

static int atmel_nand_pmecc_correct_data(struct nand_chip *chip, void *buf,
					 bool raw)
{}

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

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

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

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

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

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

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

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

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

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

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

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

static int atmel_nand_pmecc_init(struct nand_chip *chip)
{}

static int atmel_nand_ecc_init(struct nand_chip *chip)
{}

static int atmel_hsmc_nand_ecc_init(struct nand_chip *chip)
{}

static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand,
					const struct nand_interface_config *conf,
					struct atmel_smc_cs_conf *smcconf)
{}

static int atmel_smc_nand_setup_interface(struct atmel_nand *nand,
					int csline,
					const struct nand_interface_config *conf)
{}

static int atmel_hsmc_nand_setup_interface(struct atmel_nand *nand,
					int csline,
					const struct nand_interface_config *conf)
{}

static int atmel_nand_setup_interface(struct nand_chip *chip, int csline,
				      const struct nand_interface_config *conf)
{}

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

static void atmel_nand_init(struct atmel_nand_controller *nc,
			    struct atmel_nand *nand)
{}

static void atmel_smc_nand_init(struct atmel_nand_controller *nc,
				struct atmel_nand *nand)
{}

static int atmel_nand_controller_remove_nand(struct atmel_nand *nand)
{}

static struct atmel_nand *atmel_nand_create(struct atmel_nand_controller *nc,
					    struct device_node *np,
					    int reg_cells)
{}

static int
atmel_nand_controller_add_nand(struct atmel_nand_controller *nc,
			       struct atmel_nand *nand)
{}

static int
atmel_nand_controller_remove_nands(struct atmel_nand_controller *nc)
{}

static int
atmel_nand_controller_legacy_add_nands(struct atmel_nand_controller *nc)
{}

static int atmel_nand_controller_add_nands(struct atmel_nand_controller *nc)
{}

static void atmel_nand_controller_cleanup(struct atmel_nand_controller *nc)
{}

static const struct atmel_smc_nand_ebi_csa_cfg at91sam9260_ebi_csa =;

static const struct atmel_smc_nand_ebi_csa_cfg at91sam9261_ebi_csa =;

static const struct atmel_smc_nand_ebi_csa_cfg at91sam9263_ebi_csa =;

static const struct atmel_smc_nand_ebi_csa_cfg at91sam9rl_ebi_csa =;

static const struct atmel_smc_nand_ebi_csa_cfg at91sam9g45_ebi_csa =;

static const struct atmel_smc_nand_ebi_csa_cfg at91sam9n12_ebi_csa =;

static const struct atmel_smc_nand_ebi_csa_cfg at91sam9x5_ebi_csa =;

static const struct atmel_smc_nand_ebi_csa_cfg sam9x60_ebi_csa =;

static const struct of_device_id __maybe_unused atmel_ebi_csa_regmap_of_ids[] =;

static int atmel_nand_attach_chip(struct nand_chip *chip)
{}

static const struct nand_controller_ops atmel_nand_controller_ops =;

static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
				struct platform_device *pdev,
				const struct atmel_nand_controller_caps *caps)
{}

static int
atmel_smc_nand_controller_init(struct atmel_smc_nand_controller *nc)
{}

static int
atmel_hsmc_nand_controller_legacy_init(struct atmel_hsmc_nand_controller *nc)
{}

static int
atmel_hsmc_nand_controller_init(struct atmel_hsmc_nand_controller *nc)
{}

static int
atmel_hsmc_nand_controller_remove(struct atmel_nand_controller *nc)
{}

static int atmel_hsmc_nand_controller_probe(struct platform_device *pdev,
				const struct atmel_nand_controller_caps *caps)
{}

static const struct atmel_nand_controller_ops atmel_hsmc_nc_ops =;

static const struct atmel_nand_controller_caps atmel_sama5_nc_caps =;

/* Only used to parse old bindings. */
static const struct atmel_nand_controller_caps atmel_sama5_nand_caps =;

static int atmel_smc_nand_controller_probe(struct platform_device *pdev,
				const struct atmel_nand_controller_caps *caps)
{}

static int
atmel_smc_nand_controller_remove(struct atmel_nand_controller *nc)
{}

/*
 * The SMC reg layout of at91rm9200 is completely different which prevents us
 * from re-using atmel_smc_nand_setup_interface() for the
 * ->setup_interface() hook.
 * At this point, there's no support for the at91rm9200 SMC IP, so we leave
 * ->setup_interface() unassigned.
 */
static const struct atmel_nand_controller_ops at91rm9200_nc_ops =;

static const struct atmel_nand_controller_caps atmel_rm9200_nc_caps =;

static const struct atmel_nand_controller_ops atmel_smc_nc_ops =;

static const struct atmel_nand_controller_caps atmel_sam9260_nc_caps =;

static const struct atmel_nand_controller_caps atmel_sam9261_nc_caps =;

static const struct atmel_nand_controller_caps atmel_sam9g45_nc_caps =;

static const struct atmel_nand_controller_caps microchip_sam9x60_nc_caps =;

/* Only used to parse old bindings. */
static const struct atmel_nand_controller_caps atmel_rm9200_nand_caps =;

static const struct atmel_nand_controller_caps atmel_sam9261_nand_caps =;

static const struct atmel_nand_controller_caps atmel_sam9g45_nand_caps =;

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

static int atmel_nand_controller_probe(struct platform_device *pdev)
{}

static void atmel_nand_controller_remove(struct platform_device *pdev)
{}

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

static SIMPLE_DEV_PM_OPS(atmel_nand_controller_pm_ops, NULL,
			 atmel_nand_controller_resume);

static struct platform_driver atmel_nand_controller_driver =;
module_platform_driver();

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