| /* 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 0x00 |
| #define NAND_ADDR0 0x04 |
| #define NAND_ADDR1 0x08 |
| #define NAND_FLASH_CHIP_SELECT 0x0c |
| #define NAND_EXEC_CMD 0x10 |
| #define NAND_FLASH_STATUS 0x14 |
| #define NAND_BUFFER_STATUS 0x18 |
| #define NAND_DEV0_CFG0 0x20 |
| #define NAND_DEV0_CFG1 0x24 |
| #define NAND_DEV0_ECC_CFG 0x28 |
| #define NAND_AUTO_STATUS_EN 0x2c |
| #define NAND_DEV1_CFG0 0x30 |
| #define NAND_DEV1_CFG1 0x34 |
| #define NAND_READ_ID 0x40 |
| #define NAND_READ_STATUS 0x44 |
| #define NAND_DEV_CMD0 0xa0 |
| #define NAND_DEV_CMD1 0xa4 |
| #define NAND_DEV_CMD2 0xa8 |
| #define NAND_DEV_CMD_VLD 0xac |
| #define SFLASHC_BURST_CFG 0xe0 |
| #define NAND_ERASED_CW_DETECT_CFG 0xe8 |
| #define NAND_ERASED_CW_DETECT_STATUS 0xec |
| #define NAND_EBI2_ECC_BUF_CFG 0xf0 |
| #define FLASH_BUF_ACC 0x100 |
| |
| #define NAND_CTRL 0xf00 |
| #define NAND_VERSION 0xf08 |
| #define NAND_READ_LOCATION_0 0xf20 |
| #define NAND_READ_LOCATION_1 0xf24 |
| #define NAND_READ_LOCATION_2 0xf28 |
| #define NAND_READ_LOCATION_3 0xf2c |
| #define NAND_READ_LOCATION_LAST_CW_0 0xf40 |
| #define NAND_READ_LOCATION_LAST_CW_1 0xf44 |
| #define NAND_READ_LOCATION_LAST_CW_2 0xf48 |
| #define NAND_READ_LOCATION_LAST_CW_3 0xf4c |
| |
| /* dummy register offsets, used by qcom_write_reg_dma */ |
| #define NAND_DEV_CMD1_RESTORE 0xdead |
| #define NAND_DEV_CMD_VLD_RESTORE 0xbeef |
| |
| /* 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 0x1f |
| |
| /* NAND_DEVn_CFG0 bits */ |
| #define DISABLE_STATUS_AFTER_WRITE BIT(4) |
| #define CW_PER_PAGE_MASK GENMASK(8, 6) |
| #define UD_SIZE_BYTES_MASK GENMASK(18, 9) |
| #define ECC_PARITY_SIZE_BYTES_RS GENMASK(22, 19) |
| #define SPARE_SIZE_BYTES_MASK GENMASK(26, 23) |
| #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_MASK GENMASK(4, 2) |
| #define CS_ACTIVE_BSY BIT(5) |
| #define BAD_BLOCK_BYTE_NUM_MASK GENMASK(15, 6) |
| #define BAD_BLOCK_IN_SPARE_AREA BIT(16) |
| #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_MASK GENMASK(5, 4) |
| #define ECC_MODE_4BIT 0 |
| #define ECC_MODE_8BIT 1 |
| #define ECC_PARITY_SIZE_BYTES_BCH_MASK GENMASK(12, 8) |
| #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_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_MASK GENMASK(9, 0) |
| #define READ_LOCATION_SIZE_MASK GENMASK(25, 16) |
| #define READ_LOCATION_LAST_MASK BIT(31) |
| |
| /* Version Mask */ |
| #define NAND_VERSION_MAJOR_MASK 0xf0000000 |
| #define NAND_VERSION_MAJOR_SHIFT 28 |
| #define NAND_VERSION_MINOR_MASK 0x0fff0000 |
| #define NAND_VERSION_MINOR_SHIFT 16 |
| |
| /* NAND OP_CMDs */ |
| #define OP_PAGE_READ 0x2 |
| #define OP_PAGE_READ_WITH_ECC 0x3 |
| #define OP_PAGE_READ_WITH_ECC_SPARE 0x4 |
| #define OP_PAGE_READ_ONFI_READ 0x5 |
| #define OP_PROGRAM_PAGE 0x6 |
| #define OP_PAGE_PROGRAM_WITH_ECC 0x7 |
| #define OP_PROGRAM_PAGE_SPARE 0x9 |
| #define OP_BLOCK_ERASE 0xa |
| #define OP_CHECK_STATUS 0xc |
| #define OP_FETCH_ID 0xb |
| #define OP_RESET_DEVICE 0xd |
| |
| /* 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 8K, 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 |
| |