#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/rawnand.h>
#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
#define MAX_ADDRESS_CYC …
#define MAX_ERASE_ADDRESS_CYC …
#define MAX_DATA_SIZE …
#define DMA_DATA_SIZE_ALIGN …
#define CMD_REG0 …
#define CMD_REG0_CT …
#define CMD_REG0_CT_CDMA …
#define CMD_REG0_CT_GEN …
#define CMD_REG0_TN …
#define CMD_REG2 …
#define CMD_REG3 …
#define CMD_STATUS_PTR …
#define CMD_STATUS …
#define INTR_STATUS …
#define INTR_STATUS_SDMA_ERR …
#define INTR_STATUS_SDMA_TRIGG …
#define INTR_STATUS_UNSUPP_CMD …
#define INTR_STATUS_DDMA_TERR …
#define INTR_STATUS_CDMA_TERR …
#define INTR_STATUS_CDMA_IDL …
#define INTR_ENABLE …
#define INTR_ENABLE_INTR_EN …
#define INTR_ENABLE_SDMA_ERR_EN …
#define INTR_ENABLE_SDMA_TRIGG_EN …
#define INTR_ENABLE_UNSUPP_CMD_EN …
#define INTR_ENABLE_DDMA_TERR_EN …
#define INTR_ENABLE_CDMA_TERR_EN …
#define INTR_ENABLE_CDMA_IDLE_EN …
#define CTRL_STATUS …
#define CTRL_STATUS_INIT_COMP …
#define CTRL_STATUS_CTRL_BUSY …
#define TRD_STATUS …
#define TRD_ERR_INT_STATUS …
#define TRD_ERR_INT_STATUS_EN …
#define TRD_COMP_INT_STATUS …
#define TRAN_CFG_0 …
#define TRAN_CFG_0_OFFSET …
#define TRAN_CFG_0_SEC_CNT …
#define TRAN_CFG_1 …
#define TRAN_CFG_1_LAST_SEC_SIZE …
#define TRAN_CFG_1_SECTOR_SIZE …
#define ECC_CONFIG_0 …
#define ECC_CONFIG_0_CORR_STR …
#define ECC_CONFIG_0_ERASE_DET_EN …
#define ECC_CONFIG_0_ECC_EN …
#define ECC_CONFIG_1 …
#define MULTIPLANE_CFG …
#define CACHE_CFG …
#define DMA_SETINGS …
#define DMA_SETINGS_SDMA_ERR_RSP …
#define SDMA_SIZE …
#define SDMA_TRD_NUM …
#define SDMA_TRD_NUM_SDMA_TRD …
#define CONTROL_DATA_CTRL …
#define CONTROL_DATA_CTRL_SIZE …
#define CTRL_VERSION …
#define CTRL_VERSION_REV …
#define CTRL_FEATURES …
#define CTRL_FEATURES_NVDDR_2_3 …
#define CTRL_FEATURES_NVDDR …
#define CTRL_FEATURES_ASYNC …
#define CTRL_FEATURES_N_BANKS …
#define CTRL_FEATURES_DMA_DWITH64 …
#define CTRL_FEATURES_CONTROL_DATA …
#define BCH_CFG_0 …
#define BCH_CFG_0_CORR_CAP_0 …
#define BCH_CFG_0_CORR_CAP_1 …
#define BCH_CFG_0_CORR_CAP_2 …
#define BCH_CFG_0_CORR_CAP_3 …
#define BCH_CFG_1 …
#define BCH_CFG_1_CORR_CAP_4 …
#define BCH_CFG_1_CORR_CAP_5 …
#define BCH_CFG_1_CORR_CAP_6 …
#define BCH_CFG_1_CORR_CAP_7 …
#define BCH_CFG_2 …
#define BCH_CFG_2_SECT_0 …
#define BCH_CFG_2_SECT_1 …
#define BCH_CFG_3 …
#define BCH_CFG_3_METADATA_SIZE …
#define RBN_SETINGS …
#define COMMON_SET …
#define COMMON_SET_DEVICE_16BIT …
#define SKIP_BYTES_CONF …
#define SKIP_BYTES_MARKER_VALUE …
#define SKIP_BYTES_NUM_OF_BYTES …
#define SKIP_BYTES_OFFSET …
#define SKIP_BYTES_OFFSET_VALUE …
#define ASYNC_TOGGLE_TIMINGS …
#define ASYNC_TOGGLE_TIMINGS_TRH …
#define ASYNC_TOGGLE_TIMINGS_TRP …
#define ASYNC_TOGGLE_TIMINGS_TWH …
#define ASYNC_TOGGLE_TIMINGS_TWP …
#define TIMINGS0 …
#define TIMINGS0_TADL …
#define TIMINGS0_TCCS …
#define TIMINGS0_TWHR …
#define TIMINGS0_TRHW …
#define TIMINGS1 …
#define TIMINGS1_TRHZ …
#define TIMINGS1_TWB …
#define TIMINGS1_TVDLY …
#define TIMINGS2 …
#define TIMINGS2_TFEAT …
#define TIMINGS2_CS_HOLD_TIME …
#define TIMINGS2_CS_SETUP_TIME …
#define DLL_PHY_CTRL …
#define DLL_PHY_CTRL_DLL_RST_N …
#define DLL_PHY_CTRL_EXTENDED_WR_MODE …
#define DLL_PHY_CTRL_EXTENDED_RD_MODE …
#define DLL_PHY_CTRL_RS_HIGH_WAIT_CNT …
#define DLL_PHY_CTRL_RS_IDLE_CNT …
#define PHY_DQ_TIMING …
#define PHY_DQS_TIMING …
#define PHY_DQS_TIMING_DQS_SEL_OE_END …
#define PHY_DQS_TIMING_PHONY_DQS_SEL …
#define PHY_DQS_TIMING_USE_PHONY_DQS …
#define PHY_GATE_LPBK_CTRL …
#define PHY_GATE_LPBK_CTRL_RDS …
#define PHY_DLL_MASTER_CTRL …
#define PHY_DLL_MASTER_CTRL_BYPASS_MODE …
#define PHY_DLL_SLAVE_CTRL …
#define PHY_CTRL …
#define PHY_CTRL_SDR_DQS …
#define PHY_CTRL_PHONY_DQS …
#define PHY_TSEL …
#define GCMD_LAY_CS …
#define GCMD_LAY_TWB …
#define GCMD_LAY_INSTR …
#define GCMD_LAY_INSTR_CMD …
#define GCMD_LAY_INSTR_ADDR …
#define GCMD_LAY_INSTR_DATA …
#define GCMD_LAY_INPUT_CMD …
#define GCMD_LAY_INPUT_ADDR …
#define GCMD_LAY_INPUT_ADDR_SIZE …
#define GCMD_DIR …
#define GCMD_DIR_READ …
#define GCMD_DIR_WRITE …
#define GCMD_ECC_EN …
#define GCMD_SECT_SIZE …
#define GCMD_SECT_CNT …
#define GCMD_LAST_SIZE …
#define CDMA_CT_ERASE …
#define CDMA_CT_WR …
#define CDMA_CT_RD …
#define CDMA_CFPTR_MEM_SHIFT …
#define CDMA_CFPTR_MEM …
#define CDMA_CF_INT …
#define CDMA_CF_CONT …
#define CDMA_CF_DMA_MASTER …
#define CDMA_CS_COMP …
#define CDMA_CS_FAIL …
#define CDMA_CS_ERP …
#define CDMA_CS_TOUT …
#define CDMA_CS_MAXERR …
#define CDMA_CS_UNCE …
#define CDMA_CS_ERR …
#define STAT_OK …
#define STAT_FAIL …
#define STAT_ECC_UNCORR …
#define STAT_ERASED …
#define STAT_ECC_CORR …
#define STAT_UNKNOWN …
#define STAT_BUSY …
#define BCH_MAX_NUM_CORR_CAPS …
#define BCH_MAX_NUM_SECTOR_SIZES …
struct cadence_nand_timings { … };
struct cadence_nand_cdma_desc { … };
struct cadence_nand_irq_status { … };
struct cadence_nand_dt_devdata { … };
struct cdns_nand_caps { … };
struct cdns_nand_ctrl { … };
struct cdns_nand_chip { … };
static inline struct
cdns_nand_chip *to_cdns_nand_chip(struct nand_chip *chip)
{ … }
static inline struct
cdns_nand_ctrl *to_cdns_nand_ctrl(struct nand_controller *controller)
{ … }
static bool
cadence_nand_dma_buf_ok(struct cdns_nand_ctrl *cdns_ctrl, const void *buf,
u32 buf_len)
{ … }
static int cadence_nand_wait_for_value(struct cdns_nand_ctrl *cdns_ctrl,
u32 reg_offset, u32 timeout_us,
u32 mask, bool is_clear)
{ … }
static int cadence_nand_set_ecc_enable(struct cdns_nand_ctrl *cdns_ctrl,
bool enable)
{ … }
static void cadence_nand_set_ecc_strength(struct cdns_nand_ctrl *cdns_ctrl,
u8 corr_str_idx)
{ … }
static int cadence_nand_get_ecc_strength_idx(struct cdns_nand_ctrl *cdns_ctrl,
u8 strength)
{ … }
static int cadence_nand_set_skip_marker_val(struct cdns_nand_ctrl *cdns_ctrl,
u16 marker_value)
{ … }
static int cadence_nand_set_skip_bytes_conf(struct cdns_nand_ctrl *cdns_ctrl,
u8 num_of_bytes,
u32 offset_value,
int enable)
{ … }
static void cadence_nand_set_erase_detection(struct cdns_nand_ctrl *cdns_ctrl,
bool enable,
u8 bitflips_threshold)
{ … }
static int cadence_nand_set_access_width16(struct cdns_nand_ctrl *cdns_ctrl,
bool bit_bus16)
{ … }
static void
cadence_nand_clear_interrupt(struct cdns_nand_ctrl *cdns_ctrl,
struct cadence_nand_irq_status *irq_status)
{ … }
static void
cadence_nand_read_int_status(struct cdns_nand_ctrl *cdns_ctrl,
struct cadence_nand_irq_status *irq_status)
{ … }
static u32 irq_detected(struct cdns_nand_ctrl *cdns_ctrl,
struct cadence_nand_irq_status *irq_status)
{ … }
static void cadence_nand_reset_irq(struct cdns_nand_ctrl *cdns_ctrl)
{ … }
static irqreturn_t cadence_nand_isr(int irq, void *dev_id)
{ … }
static void cadence_nand_set_irq_mask(struct cdns_nand_ctrl *cdns_ctrl,
struct cadence_nand_irq_status *irq_mask)
{ … }
static void
cadence_nand_wait_for_irq(struct cdns_nand_ctrl *cdns_ctrl,
struct cadence_nand_irq_status *irq_mask,
struct cadence_nand_irq_status *irq_status)
{ … }
static int cadence_nand_generic_cmd_send(struct cdns_nand_ctrl *cdns_ctrl,
u8 chip_nr,
u64 mini_ctrl_cmd)
{ … }
static int cadence_nand_wait_on_sdma(struct cdns_nand_ctrl *cdns_ctrl,
u8 *out_sdma_trd,
u32 *out_sdma_size)
{ … }
static void cadence_nand_get_caps(struct cdns_nand_ctrl *cdns_ctrl)
{ … }
static void
cadence_nand_cdma_desc_prepare(struct cdns_nand_ctrl *cdns_ctrl,
char nf_mem, u32 flash_ptr, dma_addr_t mem_ptr,
dma_addr_t ctrl_data_ptr, u16 ctype)
{ … }
static u8 cadence_nand_check_desc_error(struct cdns_nand_ctrl *cdns_ctrl,
u32 desc_status)
{ … }
static int cadence_nand_cdma_finish(struct cdns_nand_ctrl *cdns_ctrl)
{ … }
static int cadence_nand_cdma_send(struct cdns_nand_ctrl *cdns_ctrl,
u8 thread)
{ … }
static u32
cadence_nand_cdma_send_and_wait(struct cdns_nand_ctrl *cdns_ctrl,
u8 thread)
{ … }
static int cadence_nand_calc_ecc_bytes(int max_step_size, int strength)
{ … }
#define CADENCE_NAND_CALC_ECC_BYTES(max_step_size) …
CADENCE_NAND_CALC_ECC_BYTES(…)
CADENCE_NAND_CALC_ECC_BYTES(…)
CADENCE_NAND_CALC_ECC_BYTES(…)
CADENCE_NAND_CALC_ECC_BYTES(…)
CADENCE_NAND_CALC_ECC_BYTES(…)
static int cadence_nand_read_bch_caps(struct cdns_nand_ctrl *cdns_ctrl)
{ … }
static int cadence_nand_hw_init(struct cdns_nand_ctrl *cdns_ctrl)
{ … }
#define TT_MAIN_OOB_AREAS …
#define TT_RAW_PAGE …
#define TT_BBM …
#define TT_MAIN_OOB_AREA_EXT …
static void
cadence_nand_prepare_data_size(struct nand_chip *chip,
int transfer_type)
{ … }
static int
cadence_nand_cdma_transfer(struct cdns_nand_ctrl *cdns_ctrl, u8 chip_nr,
int page, void *buf, void *ctrl_dat, u32 buf_size,
u32 ctrl_dat_size, enum dma_data_direction dir,
bool with_ecc)
{ … }
static void cadence_nand_set_timings(struct cdns_nand_ctrl *cdns_ctrl,
struct cadence_nand_timings *t)
{ … }
static int cadence_nand_select_target(struct nand_chip *chip)
{ … }
static int cadence_nand_erase(struct nand_chip *chip, u32 page)
{ … }
static int cadence_nand_read_bbm(struct nand_chip *chip, int page, u8 *buf)
{ … }
static int cadence_nand_write_page(struct nand_chip *chip,
const u8 *buf, int oob_required,
int page)
{ … }
static int cadence_nand_write_oob(struct nand_chip *chip, int page)
{ … }
static int cadence_nand_write_page_raw(struct nand_chip *chip,
const u8 *buf, int oob_required,
int page)
{ … }
static int cadence_nand_write_oob_raw(struct nand_chip *chip,
int page)
{ … }
static int cadence_nand_read_page(struct nand_chip *chip,
u8 *buf, int oob_required, int page)
{ … }
static int cadence_nand_read_oob(struct nand_chip *chip, int page)
{ … }
static int cadence_nand_read_page_raw(struct nand_chip *chip,
u8 *buf, int oob_required, int page)
{ … }
static int cadence_nand_read_oob_raw(struct nand_chip *chip,
int page)
{ … }
static void cadence_nand_slave_dma_transfer_finished(void *data)
{ … }
static int cadence_nand_slave_dma_transfer(struct cdns_nand_ctrl *cdns_ctrl,
void *buf,
dma_addr_t dev_dma, size_t len,
enum dma_data_direction dir)
{ … }
static int cadence_nand_read_buf(struct cdns_nand_ctrl *cdns_ctrl,
u8 *buf, int len)
{ … }
static int cadence_nand_write_buf(struct cdns_nand_ctrl *cdns_ctrl,
const u8 *buf, int len)
{ … }
static int cadence_nand_force_byte_access(struct nand_chip *chip,
bool force_8bit)
{ … }
static int cadence_nand_cmd_opcode(struct nand_chip *chip,
const struct nand_subop *subop)
{ … }
static int cadence_nand_cmd_address(struct nand_chip *chip,
const struct nand_subop *subop)
{ … }
static int cadence_nand_cmd_erase(struct nand_chip *chip,
const struct nand_subop *subop)
{ … }
static int cadence_nand_cmd_data(struct nand_chip *chip,
const struct nand_subop *subop)
{ … }
static int cadence_nand_cmd_waitrdy(struct nand_chip *chip,
const struct nand_subop *subop)
{ … }
static const struct nand_op_parser cadence_nand_op_parser = …;
static int cadence_nand_exec_op(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only)
{ … }
static int cadence_nand_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{ … }
static int cadence_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{ … }
static const struct mtd_ooblayout_ops cadence_nand_ooblayout_ops = …;
static int calc_cycl(u32 timing, u32 clock)
{ … }
static inline u32 calc_tdvw_max(u32 trp_cnt, u32 clk_period, u32 trhoh_min,
u32 board_delay_skew_min, u32 ext_mode)
{ … }
static inline u32 calc_tdvw(u32 trp_cnt, u32 clk_period, u32 trhoh_min,
u32 trea_max, u32 ext_mode)
{ … }
static int
cadence_nand_setup_interface(struct nand_chip *chip, int chipnr,
const struct nand_interface_config *conf)
{ … }
static int cadence_nand_attach_chip(struct nand_chip *chip)
{ … }
static const struct nand_controller_ops cadence_nand_controller_ops = …;
static int cadence_nand_chip_init(struct cdns_nand_ctrl *cdns_ctrl,
struct device_node *np)
{ … }
static void cadence_nand_chips_cleanup(struct cdns_nand_ctrl *cdns_ctrl)
{ … }
static int cadence_nand_chips_init(struct cdns_nand_ctrl *cdns_ctrl)
{ … }
static void
cadence_nand_irq_cleanup(int irqnum, struct cdns_nand_ctrl *cdns_ctrl)
{ … }
static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
{ … }
static void cadence_nand_remove(struct cdns_nand_ctrl *cdns_ctrl)
{ … }
struct cadence_nand_dt { … };
static const struct cadence_nand_dt_devdata cadence_nand_default = …;
static const struct of_device_id cadence_nand_dt_ids[] = …;
MODULE_DEVICE_TABLE(of, cadence_nand_dt_ids);
static int cadence_nand_dt_probe(struct platform_device *ofdev)
{ … }
static void cadence_nand_dt_remove(struct platform_device *ofdev)
{ … }
static struct platform_driver cadence_nand_dt_driver = …;
module_platform_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;