Quelle nand-qpic-common.h
Sprache: C
/* SPDX-License-Identifier: GPL-2.0 */
/*
* QCOM QPIC common APIs header file
*
* Copyright ( c ) 2023 Qualcomm Inc .
* Authors : Md sadre Alam < quic_mdalam @ quicinc . com >
*
*/
#ifndef __MTD_NAND_QPIC_COMMON_H__
#define __MTD_NAND_QPIC_COMMON_H__
/* NANDc reg offsets */
#define NAND_FLASH_CMD 0 x00
#define NAND_ADDR0 0 x04
#define NAND_ADDR1 0 x08
#define NAND_FLASH_CHIP_SELECT 0 x0c
#define NAND_EXEC_CMD 0 x10
#define NAND_FLASH_STATUS 0 x14
#define NAND_BUFFER_STATUS 0 x18
#define NAND_DEV0_CFG0 0 x20
#define NAND_DEV0_CFG1 0 x24
#define NAND_DEV0_ECC_CFG 0 x28
#define NAND_AUTO_STATUS_EN 0 x2c
#define NAND_DEV1_CFG0 0 x30
#define NAND_DEV1_CFG1 0 x34
#define NAND_READ_ID 0 x40
#define NAND_READ_STATUS 0 x44
#define NAND_DEV_CMD0 0 xa0
#define NAND_DEV_CMD1 0 xa4
#define NAND_DEV_CMD2 0 xa8
#define NAND_DEV_CMD_VLD 0 xac
#define SFLASHC_BURST_CFG 0 xe0
#define NAND_ERASED_CW_DETECT_CFG 0 xe8
#define NAND_ERASED_CW_DETECT_STATUS 0 xec
#define NAND_EBI2_ECC_BUF_CFG 0 xf0
#define FLASH_BUF_ACC 0 x100
#define NAND_CTRL 0 xf00
#define NAND_VERSION 0 xf08
#define NAND_READ_LOCATION_0 0 xf20
#define NAND_READ_LOCATION_1 0 xf24
#define NAND_READ_LOCATION_2 0 xf28
#define NAND_READ_LOCATION_3 0 xf2c
#define NAND_READ_LOCATION_LAST_CW_0 0 xf40
#define NAND_READ_LOCATION_LAST_CW_1 0 xf44
#define NAND_READ_LOCATION_LAST_CW_2 0 xf48
#define NAND_READ_LOCATION_LAST_CW_3 0 xf4c
/* dummy register offsets, used by qcom_write_reg_dma */
#define NAND_DEV_CMD1_RESTORE 0 xdead
#define NAND_DEV_CMD_VLD_RESTORE 0 xbeef
/* NAND_FLASH_CMD bits */
#define PAGE_ACC BIT(4 )
#define LAST_PAGE BIT(5 )
/* NAND_FLASH_CHIP_SELECT bits */
#define NAND_DEV_SEL 0
#define DM_EN BIT(2 )
/* NAND_FLASH_STATUS bits */
#define FS_OP_ERR BIT(4 )
#define FS_READY_BSY_N BIT(5 )
#define FS_MPU_ERR BIT(8 )
#define FS_DEVICE_STS_ERR BIT(16 )
#define FS_DEVICE_WP BIT(23 )
/* NAND_BUFFER_STATUS bits */
#define BS_UNCORRECTABLE_BIT BIT(8 )
#define BS_CORRECTABLE_ERR_MSK 0 x1f
/* NAND_DEVn_CFG0 bits */
#define DISABLE_STATUS_AFTER_WRITE BIT(4 )
#define CW_PER_PAGE 6
#define CW_PER_PAGE_MASK GENMASK(8 , 6 )
#define UD_SIZE_BYTES 9
#define UD_SIZE_BYTES_MASK GENMASK(18 , 9 )
#define ECC_PARITY_SIZE_BYTES_RS GENMASK(22 , 19 )
#define SPARE_SIZE_BYTES 23
#define SPARE_SIZE_BYTES_MASK GENMASK(26 , 23 )
#define NUM_ADDR_CYCLES 27
#define NUM_ADDR_CYCLES_MASK GENMASK(29 , 27 )
#define STATUS_BFR_READ BIT(30 )
#define SET_RD_MODE_AFTER_STATUS BIT(31 )
/* NAND_DEVn_CFG0 bits */
#define DEV0_CFG1_ECC_DISABLE BIT(0 )
#define WIDE_FLASH BIT(1 )
#define NAND_RECOVERY_CYCLES 2
#define NAND_RECOVERY_CYCLES_MASK GENMASK(4 , 2 )
#define CS_ACTIVE_BSY BIT(5 )
#define BAD_BLOCK_BYTE_NUM 6
#define BAD_BLOCK_BYTE_NUM_MASK GENMASK(15 , 6 )
#define BAD_BLOCK_IN_SPARE_AREA BIT(16 )
#define WR_RD_BSY_GAP 17
#define WR_RD_BSY_GAP_MASK GENMASK(22 , 17 )
#define ENABLE_BCH_ECC BIT(27 )
/* NAND_DEV0_ECC_CFG bits */
#define ECC_CFG_ECC_DISABLE BIT(0 )
#define ECC_SW_RESET BIT(1 )
#define ECC_MODE 4
#define ECC_MODE_MASK GENMASK(5 , 4 )
#define ECC_MODE_4BIT 0
#define ECC_MODE_8BIT 1
#define ECC_PARITY_SIZE_BYTES_BCH 8
#define ECC_PARITY_SIZE_BYTES_BCH_MASK GENMASK(12 , 8 )
#define ECC_NUM_DATA_BYTES 16
#define ECC_NUM_DATA_BYTES_MASK GENMASK(25 , 16 )
#define ECC_FORCE_CLK_OPEN BIT(30 )
/* NAND_DEV_CMD1 bits */
#define READ_ADDR_MASK GENMASK(7 , 0 )
/* NAND_DEV_CMD_VLD bits */
#define READ_START_VLD BIT(0 )
#define READ_STOP_VLD BIT(1 )
#define WRITE_START_VLD BIT(2 )
#define ERASE_START_VLD BIT(3 )
#define SEQ_READ_START_VLD BIT(4 )
/* NAND_EBI2_ECC_BUF_CFG bits */
#define NUM_STEPS 0
#define NUM_STEPS_MASK GENMASK(9 , 0 )
/* NAND_ERASED_CW_DETECT_CFG bits */
#define ERASED_CW_ECC_MASK 1
#define AUTO_DETECT_RES 0
#define MASK_ECC BIT(ERASED_CW_ECC_MASK)
#define RESET_ERASED_DET BIT(AUTO_DETECT_RES)
#define ACTIVE_ERASED_DET (0 << AUTO_DETECT_RES)
#define CLR_ERASED_PAGE_DET (RESET_ERASED_DET | MASK_ECC)
#define SET_ERASED_PAGE_DET (ACTIVE_ERASED_DET | MASK_ECC)
/* NAND_ERASED_CW_DETECT_STATUS bits */
#define PAGE_ALL_ERASED BIT(7 )
#define CODEWORD_ALL_ERASED BIT(6 )
#define PAGE_ERASED BIT(5 )
#define CODEWORD_ERASED BIT(4 )
#define ERASED_PAGE (PAGE_ALL_ERASED | PAGE_ERASED)
#define ERASED_CW (CODEWORD_ALL_ERASED | CODEWORD_ERASED)
/* NAND_READ_LOCATION_n bits */
#define READ_LOCATION_OFFSET 0
#define READ_LOCATION_OFFSET_MASK GENMASK(9 , 0 )
#define READ_LOCATION_SIZE 16
#define READ_LOCATION_SIZE_MASK GENMASK(25 , 16 )
#define READ_LOCATION_LAST 31
#define READ_LOCATION_LAST_MASK BIT(31 )
/* Version Mask */
#define NAND_VERSION_MAJOR_MASK 0 xf0000000
#define NAND_VERSION_MAJOR_SHIFT 28
#define NAND_VERSION_MINOR_MASK 0 x0fff0000
#define NAND_VERSION_MINOR_SHIFT 16
/* NAND OP_CMDs */
#define OP_PAGE_READ 0 x2
#define OP_PAGE_READ_WITH_ECC 0 x3
#define OP_PAGE_READ_WITH_ECC_SPARE 0 x4
#define OP_PAGE_READ_ONFI_READ 0 x5
#define OP_PROGRAM_PAGE 0 x6
#define OP_PAGE_PROGRAM_WITH_ECC 0 x7
#define OP_PROGRAM_PAGE_SPARE 0 x9
#define OP_BLOCK_ERASE 0 xa
#define OP_CHECK_STATUS 0 xc
#define OP_FETCH_ID 0 xb
#define OP_RESET_DEVICE 0 xd
/* Default Value for NAND_DEV_CMD_VLD */
#define NAND_DEV_CMD_VLD_VAL (READ_START_VLD | WRITE_START_VLD | \
ERASE_START_VLD | SEQ_READ_START_VLD)
/* NAND_CTRL bits */
#define BAM_MODE_EN BIT(0 )
/*
* the NAND controller performs reads / writes with ECC in 516 byte chunks .
* the driver calls the chunks ' step ' or ' codeword ' interchangeably
*/
#define NANDC_STEP_SIZE 512
/*
* the largest page size we support is 8 K , this will have 16 steps / codewords
* of 512 bytes each
*/
#define MAX_NUM_STEPS (SZ_8K / NANDC_STEP_SIZE)
/* we read at most 3 registers per codeword scan */
#define MAX_REG_RD (3 * MAX_NUM_STEPS)
/* ECC modes supported by the controller */
#define ECC_NONE BIT(0 )
#define ECC_RS_4BIT BIT(1 )
#define ECC_BCH_4BIT BIT(2 )
#define ECC_BCH_8BIT BIT(3 )
/*
* Returns the actual register address for all NAND_DEV_ registers
* ( i . e . NAND_DEV_CMD0 , NAND_DEV_CMD1 , NAND_DEV_CMD2 and NAND_DEV_CMD_VLD )
*/
#define dev_cmd_reg_addr(nandc, reg) ((nandc)->props->dev_cmd_reg_start + (reg))
/* Returns the dma address for reg read buffer */
#define reg_buf_dma_addr(chip, vaddr) \
((chip)->reg_read_dma + \
((u8 *)(vaddr) - (u8 *)(chip)->reg_read_buf))
#define QPIC_PER_CW_CMD_ELEMENTS 32
#define QPIC_PER_CW_CMD_SGL 32
#define QPIC_PER_CW_DATA_SGL 8
#define QPIC_NAND_COMPLETION_TIMEOUT msecs_to_jiffies(2000 )
/*
* Flags used in DMA descriptor preparation helper functions
* ( i . e . qcom_read_reg_dma / qcom_write_reg_dma / qcom_read_data_dma / qcom_write_data_dma )
*/
/* Don't set the EOT in current tx BAM sgl */
#define NAND_BAM_NO_EOT BIT(0 )
/* Set the NWD flag in current BAM sgl */
#define NAND_BAM_NWD BIT(1 )
/* Finish writing in the current BAM sgl and start writing in another BAM sgl */
#define NAND_BAM_NEXT_SGL BIT(2 )
/*
* Erased codeword status is being used two times in single transfer so this
* flag will determine the current value of erased codeword status register
*/
#define NAND_ERASED_CW_SET BIT(4 )
#define MAX_ADDRESS_CYCLE 5
/*
* This data type corresponds to the BAM transaction which will be used for all
* NAND transfers .
* @ bam_ce - the array of BAM command elements
* @ cmd_sgl - sgl for NAND BAM command pipe
* @ data_sgl - sgl for NAND BAM consumer / producer pipe
* @ last_data_desc - last DMA desc in data channel ( tx / rx ) .
* @ last_cmd_desc - last DMA desc in command channel .
* @ txn_done - completion for NAND transfer .
* @ bam_ce_nitems - the number of elements in the @ bam_ce array
* @ cmd_sgl_nitems - the number of elements in the @ cmd_sgl array
* @ data_sgl_nitems - the number of elements in the @ data_sgl array
* @ bam_ce_pos - the index in bam_ce which is available for next sgl
* @ bam_ce_start - the index in bam_ce which marks the start position ce
* for current sgl . It will be used for size calculation
* for current sgl
* @ cmd_sgl_pos - current index in command sgl .
* @ cmd_sgl_start - start index in command sgl .
* @ tx_sgl_pos - current index in data sgl for tx .
* @ tx_sgl_start - start index in data sgl for tx .
* @ rx_sgl_pos - current index in data sgl for rx .
* @ rx_sgl_start - start index in data sgl for rx .
*/
struct bam_transaction {
struct bam_cmd_element *bam_ce;
struct scatterlist *cmd_sgl;
struct scatterlist *data_sgl;
struct dma_async_tx_descriptor *last_data_desc;
struct dma_async_tx_descriptor *last_cmd_desc;
struct completion txn_done;
unsigned int bam_ce_nitems;
unsigned int cmd_sgl_nitems;
unsigned int data_sgl_nitems;
struct_group(bam_positions,
u32 bam_ce_pos;
u32 bam_ce_start;
u32 cmd_sgl_pos;
u32 cmd_sgl_start;
u32 tx_sgl_pos;
u32 tx_sgl_start;
u32 rx_sgl_pos;
u32 rx_sgl_start;
);
};
/*
* This data type corresponds to the nand dma descriptor
* @ dma_desc - low level DMA engine descriptor
* @ list - list for desc_info
*
* @ adm_sgl - sgl which will be used for single sgl dma descriptor . Only used by
* ADM
* @ bam_sgl - sgl which will be used for dma descriptor . Only used by BAM
* @ sgl_cnt - number of SGL in bam_sgl . Only used by BAM
* @ dir - DMA transfer direction
*/
struct desc_info {
struct dma_async_tx_descriptor *dma_desc;
struct list_head node;
union {
struct scatterlist adm_sgl;
struct {
struct scatterlist *bam_sgl;
int sgl_cnt;
};
};
enum dma_data_direction dir;
};
/*
* holds the current register values that we want to write . acts as a contiguous
* chunk of memory which we use to write the controller registers through DMA .
*/
struct nandc_regs {
__le32 cmd;
__le32 addr0;
__le32 addr1;
__le32 chip_sel;
__le32 exec;
__le32 cfg0;
__le32 cfg1;
__le32 ecc_bch_cfg;
__le32 clrflashstatus;
__le32 clrreadstatus;
__le32 cmd1;
__le32 vld;
__le32 orig_cmd1;
__le32 orig_vld;
__le32 ecc_buf_cfg;
__le32 read_location0;
__le32 read_location1;
__le32 read_location2;
__le32 read_location3;
__le32 read_location_last0;
__le32 read_location_last1;
__le32 read_location_last2;
__le32 read_location_last3;
__le32 spi_cfg;
__le32 num_addr_cycle;
__le32 busy_wait_cnt;
__le32 flash_feature;
__le32 erased_cw_detect_cfg_clr;
__le32 erased_cw_detect_cfg_set;
};
/*
* NAND controller data struct
*
* @ dev : parent device
*
* @ base : MMIO base
*
* @ core_clk : controller clock
* @ aon_clk : another controller clock
* @ iomacro_clk : io macro clock
*
* @ regs : a contiguous chunk of memory for DMA register
* writes . contains the register values to be
* written to controller
*
* @ props : properties of current NAND controller ,
* initialized via DT match data
*
* @ controller : base controller structure
* @ qspi : qpic spi structure
* @ host_list : list containing all the chips attached to the
* controller
*
* @ chan : dma channel
* @ cmd_crci : ADM DMA CRCI for command flow control
* @ data_crci : ADM DMA CRCI for data flow control
*
* @ desc_list : DMA descriptor list ( list of desc_infos )
*
* @ data_buffer : our local DMA buffer for page read / writes ,
* used when we can ' t use the buffer provided
* by upper layers directly
* @ reg_read_buf : local buffer for reading back registers via DMA
*
* @ base_phys : physical base address of controller registers
* @ base_dma : dma base address of controller registers
* @ reg_read_dma : contains dma address for register read buffer
*
* @ buf_size / count / start : markers for chip - > legacy . read_buf / write_buf
* functions
* @ max_cwperpage : maximum QPIC codewords required . calculated
* from all connected NAND devices pagesize
*
* @ reg_read_pos : marker for data read in reg_read_buf
*
* @ cmd1 / vld : some fixed controller register values
*
* @ exec_opwrite : flag to select correct number of code word
* while reading status
*/
struct qcom_nand_controller {
struct device *dev;
void __iomem *base;
struct clk *core_clk;
struct clk *aon_clk;
struct nandc_regs *regs;
struct bam_transaction *bam_txn;
const struct qcom_nandc_props *props;
struct nand_controller *controller;
struct qpic_spi_nand *qspi;
struct list_head host_list;
union {
/* will be used only by QPIC for BAM DMA */
struct {
struct dma_chan *tx_chan;
struct dma_chan *rx_chan;
struct dma_chan *cmd_chan;
};
/* will be used only by EBI2 for ADM DMA */
struct {
struct dma_chan *chan;
unsigned int cmd_crci;
unsigned int data_crci;
};
};
struct list_head desc_list;
u8 *data_buffer;
__le32 *reg_read_buf;
phys_addr_t base_phys;
dma_addr_t base_dma;
dma_addr_t reg_read_dma;
int buf_size;
int buf_count;
int buf_start;
unsigned int max_cwperpage;
int reg_read_pos;
u32 cmd1, vld;
bool exec_opwrite;
};
/*
* This data type corresponds to the NAND controller properties which varies
* among different NAND controllers .
* @ ecc_modes - ecc mode for NAND
* @ dev_cmd_reg_start - NAND_DEV_CMD_ * registers starting offset
* @ supports_bam - whether NAND controller is using BAM
* @ nandc_part_of_qpic - whether NAND controller is part of qpic IP
* @ qpic_version2 - flag to indicate QPIC IP version 2
* @ use_codeword_fixup - whether NAND has different layout for boot partitions
*/
struct qcom_nandc_props {
u32 ecc_modes;
u32 dev_cmd_reg_start;
u32 bam_offset;
bool supports_bam;
bool nandc_part_of_qpic;
bool qpic_version2;
bool use_codeword_fixup;
};
void qcom_free_bam_transaction(struct qcom_nand_controller *nandc);
struct bam_transaction *qcom_alloc_bam_transaction(struct qcom_nand_controller *nandc);
void qcom_clear_bam_transaction(struct qcom_nand_controller *nandc);
void qcom_qpic_bam_dma_done(void *data);
void qcom_nandc_dev_to_mem(struct qcom_nand_controller *nandc, bool is_cpu);
int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc,
struct dma_chan *chan, unsigned long flags);
int qcom_prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
int reg_off, const void *vaddr, int size, unsigned int flags);
int qcom_prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
const void *vaddr, int size, unsigned int flags);
int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, int reg_off,
const void *vaddr, int size, bool flow_control);
int qcom_read_reg_dma(struct qcom_nand_controller *nandc, int first, int num_regs,
unsigned int flags);
int qcom_write_reg_dma(struct qcom_nand_controller *nandc, __le32 *vaddr, int first,
int num_regs, unsigned int flags);
int qcom_read_data_dma(struct qcom_nand_controller *nandc, int reg_off, const u8 *vaddr,
int size, unsigned int flags);
int qcom_write_data_dma(struct qcom_nand_controller *nandc, int reg_off, const u8 *vaddr,
int size, unsigned int flags);
int qcom_submit_descs(struct qcom_nand_controller *nandc);
void qcom_clear_read_regs(struct qcom_nand_controller *nandc);
void qcom_nandc_unalloc(struct qcom_nand_controller *nandc);
int qcom_nandc_alloc(struct qcom_nand_controller *nandc);
#endif
Messung V0.5 in Prozent C=89 H=98 G=93
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland
2026-10-10
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=1126438
#Domains=1897691