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

// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2009-2015 Freescale Semiconductor, Inc. and others
 *
 * Description: MPC5125, VF610, MCF54418 and Kinetis K70 Nand driver.
 * Jason ported to M54418TWR and MVFA5 (VF610).
 * Authors: Stefan Agner <[email protected]>
 *          Bill Pringlemeir <[email protected]>
 *          Shaohui Xie <[email protected]>
 *          Jason Jin <[email protected]>
 *
 * Based on original driver mpc5121_nfc.c.
 *
 * Limitations:
 * - Untested on MPC5125 and M54418.
 * - DMA and pipelining not used.
 * - 2K pages or less.
 * - HW ECC: Only 2K page with 64+ OOB.
 * - HW ECC: Only 24 and 32-bit error correction implemented.
 */

#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/swab.h>

#define DRV_NAME

/* Register Offsets */
#define NFC_FLASH_CMD1
#define NFC_FLASH_CMD2
#define NFC_COL_ADDR
#define NFC_ROW_ADDR
#define NFC_ROW_ADDR_INC
#define NFC_FLASH_STATUS1
#define NFC_FLASH_STATUS2
#define NFC_CACHE_SWAP
#define NFC_SECTOR_SIZE
#define NFC_FLASH_CONFIG
#define NFC_IRQ_STATUS

/* Addresses for NFC MAIN RAM BUFFER areas */
#define NFC_MAIN_AREA(n)

#define PAGE_2K
#define OOB_64
#define OOB_MAX

/* NFC_CMD2[CODE] controller cycle bit masks */
#define COMMAND_CMD_BYTE1
#define COMMAND_CAR_BYTE1
#define COMMAND_CAR_BYTE2
#define COMMAND_RAR_BYTE1
#define COMMAND_RAR_BYTE2
#define COMMAND_RAR_BYTE3
#define COMMAND_NADDR_BYTES(x)
#define COMMAND_WRITE_DATA
#define COMMAND_CMD_BYTE2
#define COMMAND_RB_HANDSHAKE
#define COMMAND_READ_DATA
#define COMMAND_CMD_BYTE3
#define COMMAND_READ_STATUS
#define COMMAND_READ_ID

/* NFC ECC mode define */
#define ECC_BYPASS
#define ECC_45_BYTE
#define ECC_60_BYTE

/*** Register Mask and bit definitions */

/* NFC_FLASH_CMD1 Field */
#define CMD_BYTE2_MASK
#define CMD_BYTE2_SHIFT

/* NFC_FLASH_CM2 Field */
#define CMD_BYTE1_MASK
#define CMD_BYTE1_SHIFT
#define CMD_CODE_MASK
#define CMD_CODE_SHIFT
#define BUFNO_MASK
#define BUFNO_SHIFT
#define START_BIT

/* NFC_COL_ADDR Field */
#define COL_ADDR_MASK
#define COL_ADDR_SHIFT
#define COL_ADDR(pos, val)

/* NFC_ROW_ADDR Field */
#define ROW_ADDR_MASK
#define ROW_ADDR_SHIFT
#define ROW_ADDR(pos, val)

#define ROW_ADDR_CHIP_SEL_RB_MASK
#define ROW_ADDR_CHIP_SEL_RB_SHIFT
#define ROW_ADDR_CHIP_SEL_MASK
#define ROW_ADDR_CHIP_SEL_SHIFT

/* NFC_FLASH_STATUS2 Field */
#define STATUS_BYTE1_MASK

/* NFC_FLASH_CONFIG Field */
#define CONFIG_ECC_SRAM_ADDR_MASK
#define CONFIG_ECC_SRAM_ADDR_SHIFT
#define CONFIG_ECC_SRAM_REQ_BIT
#define CONFIG_DMA_REQ_BIT
#define CONFIG_ECC_MODE_MASK
#define CONFIG_ECC_MODE_SHIFT
#define CONFIG_FAST_FLASH_BIT
#define CONFIG_16BIT
#define CONFIG_BOOT_MODE_BIT
#define CONFIG_ADDR_AUTO_INCR_BIT
#define CONFIG_BUFNO_AUTO_INCR_BIT
#define CONFIG_PAGE_CNT_MASK
#define CONFIG_PAGE_CNT_SHIFT

/* NFC_IRQ_STATUS Field */
#define IDLE_IRQ_BIT
#define IDLE_EN_BIT
#define CMD_DONE_CLEAR_BIT
#define IDLE_CLEAR_BIT

/*
 * ECC status - seems to consume 8 bytes (double word). The documented
 * status byte is located in the lowest byte of the second word (which is
 * the 4th or 7th byte depending on endianness).
 * Calculate an offset to store the ECC status at the end of the buffer.
 */
#define ECC_SRAM_ADDR

#define ECC_STATUS
#define ECC_STATUS_MASK
#define ECC_STATUS_ERR_COUNT

enum vf610_nfc_variant {};

struct vf610_nfc {};

static inline struct vf610_nfc *chip_to_nfc(struct nand_chip *chip)
{}

static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
{}

static inline void vf610_nfc_write(struct vf610_nfc *nfc, uint reg, u32 val)
{}

static inline void vf610_nfc_set(struct vf610_nfc *nfc, uint reg, u32 bits)
{}

static inline void vf610_nfc_clear(struct vf610_nfc *nfc, uint reg, u32 bits)
{}

static inline void vf610_nfc_set_field(struct vf610_nfc *nfc, u32 reg,
				       u32 mask, u32 shift, u32 val)
{}

static inline bool vf610_nfc_kernel_is_little_endian(void)
{}

/*
 * Read accessor for internal SRAM buffer
 * @dst: destination address in regular memory
 * @src: source address in SRAM buffer
 * @len: bytes to copy
 * @fix_endian: Fix endianness if required
 *
 * Use this accessor for the internal SRAM buffers. On the ARM
 * Freescale Vybrid SoC it's known that the driver can treat
 * the SRAM buffer as if it's memory. Other platform might need
 * to treat the buffers differently.
 *
 * The controller stores bytes from the NAND chip internally in big
 * endianness. On little endian platforms such as Vybrid this leads
 * to reversed byte order.
 * For performance reason (and earlier probably due to unawareness)
 * the driver avoids correcting endianness where it has control over
 * write and read side (e.g. page wise data access).
 */
static inline void vf610_nfc_rd_from_sram(void *dst, const void __iomem *src,
					  size_t len, bool fix_endian)
{}

/*
 * Write accessor for internal SRAM buffer
 * @dst: destination address in SRAM buffer
 * @src: source address in regular memory
 * @len: bytes to copy
 * @fix_endian: Fix endianness if required
 *
 * Use this accessor for the internal SRAM buffers. On the ARM
 * Freescale Vybrid SoC it's known that the driver can treat
 * the SRAM buffer as if it's memory. Other platform might need
 * to treat the buffers differently.
 *
 * The controller stores bytes from the NAND chip internally in big
 * endianness. On little endian platforms such as Vybrid this leads
 * to reversed byte order.
 * For performance reason (and earlier probably due to unawareness)
 * the driver avoids correcting endianness where it has control over
 * write and read side (e.g. page wise data access).
 */
static inline void vf610_nfc_wr_to_sram(void __iomem *dst, const void *src,
					size_t len, bool fix_endian)
{}

/* Clear flags for upcoming command */
static inline void vf610_nfc_clear_status(struct vf610_nfc *nfc)
{}

static void vf610_nfc_done(struct vf610_nfc *nfc)
{}

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

static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode)
{}

static inline void vf610_nfc_run(struct vf610_nfc *nfc, u32 col, u32 row,
				 u32 cmd1, u32 cmd2, u32 trfr_sz)
{}

static inline const struct nand_op_instr *
vf610_get_next_instr(const struct nand_subop *subop, int *op_id)
{}

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

static const struct nand_op_parser vf610_nfc_op_parser =;

/*
 * This function supports Vybrid only (MPC5125 would have full RB and four CS)
 */
static void vf610_nfc_select_target(struct nand_chip *chip, unsigned int cs)
{}

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

static inline int vf610_nfc_correct_data(struct nand_chip *chip, uint8_t *dat,
					 uint8_t *oob, int page)
{}

static void vf610_nfc_fill_row(struct nand_chip *chip, int page, u32 *code,
			       u32 *row)
{}

static int vf610_nfc_read_page(struct nand_chip *chip, uint8_t *buf,
			       int oob_required, int page)
{}

static int vf610_nfc_write_page(struct nand_chip *chip, const uint8_t *buf,
				int oob_required, int page)
{}

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

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

static int vf610_nfc_read_oob(struct nand_chip *chip, int page)
{}

static int vf610_nfc_write_oob(struct nand_chip *chip, int page)
{}

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

static void vf610_nfc_preinit_controller(struct vf610_nfc *nfc)
{}

static void vf610_nfc_init_controller(struct vf610_nfc *nfc)
{}

static int vf610_nfc_attach_chip(struct nand_chip *chip)
{}

static const struct nand_controller_ops vf610_nfc_controller_ops =;

static int vf610_nfc_probe(struct platform_device *pdev)
{}

static void vf610_nfc_remove(struct platform_device *pdev)
{}

#ifdef CONFIG_PM_SLEEP
static int vf610_nfc_suspend(struct device *dev)
{}

static int vf610_nfc_resume(struct device *dev)
{}
#endif

static SIMPLE_DEV_PM_OPS(vf610_nfc_pm_ops, vf610_nfc_suspend, vf610_nfc_resume);

static struct platform_driver vf610_nfc_driver =;

module_platform_driver();

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