* [PATCH 1/5] mtd: rawnand: qcom: Convert nandc to chip in Read/Write helper @ 2021-02-23 19:38 ` Md Sadre Alam 0 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:38 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan This change will convert nandc to chip in Read/Write helper, this change is needed because if we wnated to access number of steps in Read/Write helper then we need to get the chip->ecc.steps, currentlly its not possible.After this change we can directly acces chip->ecc.steps in Read/Write helper. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 153 ++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 73 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 667e4bf..4898d32 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -181,8 +181,8 @@ #define ECC_BCH_4BIT BIT(2) #define ECC_BCH_8BIT BIT(3) -#define nandc_set_read_loc(nandc, reg, offset, size, is_last) \ -nandc_set_reg(nandc, NAND_READ_LOCATION_##reg, \ +#define nandc_set_read_loc(chip, reg, offset, size, is_last) \ +nandc_set_reg(chip, NAND_READ_LOCATION_##reg, \ ((offset) << READ_LOCATION_OFFSET) | \ ((size) << READ_LOCATION_SIZE) | \ ((is_last) << READ_LOCATION_LAST)) @@ -649,9 +649,10 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset) } } -static void nandc_set_reg(struct qcom_nand_controller *nandc, int offset, +static void nandc_set_reg(struct nand_chip *chip, int offset, u32 val) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); struct nandc_regs *regs = nandc->regs; __le32 *reg; @@ -665,13 +666,12 @@ static void nandc_set_reg(struct qcom_nand_controller *nandc, int offset, static void set_address(struct qcom_nand_host *host, u16 column, int page) { struct nand_chip *chip = &host->chip; - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); if (chip->options & NAND_BUSWIDTH_16) column >>= 1; - nandc_set_reg(nandc, NAND_ADDR0, page << 16 | column); - nandc_set_reg(nandc, NAND_ADDR1, page >> 16 & 0xff); + nandc_set_reg(chip, NAND_ADDR0, page << 16 | column); + nandc_set_reg(chip, NAND_ADDR1, page >> 16 & 0xff); } /* @@ -684,7 +684,6 @@ static void set_address(struct qcom_nand_host *host, u16 column, int page) static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) { struct nand_chip *chip = &host->chip; - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); u32 cmd, cfg0, cfg1, ecc_bch_cfg; if (read) { @@ -710,17 +709,17 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE; } - nandc_set_reg(nandc, NAND_FLASH_CMD, cmd); - nandc_set_reg(nandc, NAND_DEV0_CFG0, cfg0); - nandc_set_reg(nandc, NAND_DEV0_CFG1, cfg1); - nandc_set_reg(nandc, NAND_DEV0_ECC_CFG, ecc_bch_cfg); - nandc_set_reg(nandc, NAND_EBI2_ECC_BUF_CFG, host->ecc_buf_cfg); - nandc_set_reg(nandc, NAND_FLASH_STATUS, host->clrflashstatus); - nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus); - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_FLASH_CMD, cmd); + nandc_set_reg(chip, NAND_DEV0_CFG0, cfg0); + nandc_set_reg(chip, NAND_DEV0_CFG1, cfg1); + nandc_set_reg(chip, NAND_DEV0_ECC_CFG, ecc_bch_cfg); + nandc_set_reg(chip, NAND_EBI2_ECC_BUF_CFG, host->ecc_buf_cfg); + nandc_set_reg(chip, NAND_FLASH_STATUS, host->clrflashstatus); + nandc_set_reg(chip, NAND_READ_STATUS, host->clrreadstatus); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); if (read) - nandc_set_read_loc(nandc, 0, 0, host->use_ecc ? + nandc_set_read_loc(chip, 0, 0, host->use_ecc ? host->cw_data : host->cw_size, 1); } @@ -1079,8 +1078,10 @@ static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off, * Helper to prepare DMA descriptors for configuring registers * before reading a NAND page. */ -static void config_nand_page_read(struct qcom_nand_controller *nandc) +static void config_nand_page_read(struct nand_chip *chip) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + write_reg_dma(nandc, NAND_ADDR0, 2, 0); write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0); write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0); @@ -1094,8 +1095,10 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc) * before reading each codeword in NAND page. */ static void -config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc) +config_nand_cw_read(struct nand_chip *chip, bool use_ecc) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + if (nandc->props->is_bam) write_reg_dma(nandc, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL); @@ -1117,19 +1120,21 @@ config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc) * single codeword in page */ static void -config_nand_single_cw_page_read(struct qcom_nand_controller *nandc, +config_nand_single_cw_page_read(struct nand_chip *chip, bool use_ecc) { - config_nand_page_read(nandc); - config_nand_cw_read(nandc, use_ecc); + config_nand_page_read(chip); + config_nand_cw_read(chip, use_ecc); } /* * Helper to prepare DMA descriptors used to configure registers needed for * before writing a NAND page. */ -static void config_nand_page_write(struct qcom_nand_controller *nandc) +static void config_nand_page_write(struct nand_chip *chip) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + write_reg_dma(nandc, NAND_ADDR0, 2, 0); write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0); write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, @@ -1140,8 +1145,10 @@ static void config_nand_page_write(struct qcom_nand_controller *nandc) * Helper to prepare DMA descriptors for configuring registers * before writing each codeword in NAND page. */ -static void config_nand_cw_write(struct qcom_nand_controller *nandc) +static void config_nand_cw_write(struct nand_chip *chip) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -1168,44 +1175,44 @@ static int nandc_param(struct qcom_nand_host *host) * bytes to read onfi params */ if (nandc->props->qpic_v2) - nandc_set_reg(nandc, NAND_FLASH_CMD, OP_PAGE_READ_ONFI_READ | + nandc_set_reg(chip, NAND_FLASH_CMD, OP_PAGE_READ_ONFI_READ | PAGE_ACC | LAST_PAGE); else - nandc_set_reg(nandc, NAND_FLASH_CMD, OP_PAGE_READ | + nandc_set_reg(chip, NAND_FLASH_CMD, OP_PAGE_READ | PAGE_ACC | LAST_PAGE); - nandc_set_reg(nandc, NAND_ADDR0, 0); - nandc_set_reg(nandc, NAND_ADDR1, 0); - nandc_set_reg(nandc, NAND_DEV0_CFG0, 0 << CW_PER_PAGE + nandc_set_reg(chip, NAND_ADDR0, 0); + nandc_set_reg(chip, NAND_ADDR1, 0); + nandc_set_reg(chip, NAND_DEV0_CFG0, 0 << CW_PER_PAGE | 512 << UD_SIZE_BYTES | 5 << NUM_ADDR_CYCLES | 0 << SPARE_SIZE_BYTES); - nandc_set_reg(nandc, NAND_DEV0_CFG1, 7 << NAND_RECOVERY_CYCLES + nandc_set_reg(chip, NAND_DEV0_CFG1, 7 << NAND_RECOVERY_CYCLES | 0 << CS_ACTIVE_BSY | 17 << BAD_BLOCK_BYTE_NUM | 1 << BAD_BLOCK_IN_SPARE_AREA | 2 << WR_RD_BSY_GAP | 0 << WIDE_FLASH | 1 << DEV0_CFG1_ECC_DISABLE); - nandc_set_reg(nandc, NAND_EBI2_ECC_BUF_CFG, 1 << ECC_CFG_ECC_DISABLE); + nandc_set_reg(chip, NAND_EBI2_ECC_BUF_CFG, 1 << ECC_CFG_ECC_DISABLE); /* configure CMD1 and VLD for ONFI param probing in QPIC v1 */ if (!nandc->props->qpic_v2) { - nandc_set_reg(nandc, NAND_DEV_CMD_VLD, + nandc_set_reg(chip, NAND_DEV_CMD_VLD, (nandc->vld & ~READ_START_VLD)); - nandc_set_reg(nandc, NAND_DEV_CMD1, + nandc_set_reg(chip, NAND_DEV_CMD1, (nandc->cmd1 & ~(0xFF << READ_ADDR)) | NAND_CMD_PARAM << READ_ADDR); } - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); if (!nandc->props->qpic_v2) { - nandc_set_reg(nandc, NAND_DEV_CMD1_RESTORE, nandc->cmd1); - nandc_set_reg(nandc, NAND_DEV_CMD_VLD_RESTORE, nandc->vld); + nandc_set_reg(chip, NAND_DEV_CMD1_RESTORE, nandc->cmd1); + nandc_set_reg(chip, NAND_DEV_CMD_VLD_RESTORE, nandc->vld); } - nandc_set_read_loc(nandc, 0, 0, 512, 1); + nandc_set_read_loc(chip, 0, 0, 512, 1); if (!nandc->props->qpic_v2) { write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0); @@ -1215,7 +1222,7 @@ static int nandc_param(struct qcom_nand_host *host) nandc->buf_count = 512; memset(nandc->data_buffer, 0xff, nandc->buf_count); - config_nand_single_cw_page_read(nandc, false); + config_nand_single_cw_page_read(chip, false); read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, nandc->buf_count, 0); @@ -1235,16 +1242,16 @@ static int erase_block(struct qcom_nand_host *host, int page_addr) struct nand_chip *chip = &host->chip; struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - nandc_set_reg(nandc, NAND_FLASH_CMD, + nandc_set_reg(chip, NAND_FLASH_CMD, OP_BLOCK_ERASE | PAGE_ACC | LAST_PAGE); - nandc_set_reg(nandc, NAND_ADDR0, page_addr); - nandc_set_reg(nandc, NAND_ADDR1, 0); - nandc_set_reg(nandc, NAND_DEV0_CFG0, + nandc_set_reg(chip, NAND_ADDR0, page_addr); + nandc_set_reg(chip, NAND_ADDR1, 0); + nandc_set_reg(chip, NAND_DEV0_CFG0, host->cfg0_raw & ~(7 << CW_PER_PAGE)); - nandc_set_reg(nandc, NAND_DEV0_CFG1, host->cfg1_raw); - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); - nandc_set_reg(nandc, NAND_FLASH_STATUS, host->clrflashstatus); - nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus); + nandc_set_reg(chip, NAND_DEV0_CFG1, host->cfg1_raw); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_FLASH_STATUS, host->clrflashstatus); + nandc_set_reg(chip, NAND_READ_STATUS, host->clrreadstatus); write_reg_dma(nandc, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL); @@ -1267,12 +1274,12 @@ static int read_id(struct qcom_nand_host *host, int column) if (column == -1) return 0; - nandc_set_reg(nandc, NAND_FLASH_CMD, OP_FETCH_ID); - nandc_set_reg(nandc, NAND_ADDR0, column); - nandc_set_reg(nandc, NAND_ADDR1, 0); - nandc_set_reg(nandc, NAND_FLASH_CHIP_SELECT, + nandc_set_reg(chip, NAND_FLASH_CMD, OP_FETCH_ID); + nandc_set_reg(chip, NAND_ADDR0, column); + nandc_set_reg(chip, NAND_ADDR1, 0); + nandc_set_reg(chip, NAND_FLASH_CHIP_SELECT, nandc->props->is_bam ? 0 : DM_EN); - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); write_reg_dma(nandc, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -1288,8 +1295,8 @@ static int reset(struct qcom_nand_host *host) struct nand_chip *chip = &host->chip; struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - nandc_set_reg(nandc, NAND_FLASH_CMD, OP_RESET_DEVICE); - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_FLASH_CMD, OP_RESET_DEVICE); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -1617,7 +1624,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, clear_bam_transaction(nandc); set_address(host, host->cw_size * cw, page); update_rw_regs(host, 1, true); - config_nand_page_read(nandc); + config_nand_page_read(chip); data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; @@ -1633,19 +1640,19 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, } if (nandc->props->is_bam) { - nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0); + nandc_set_read_loc(chip, 0, read_loc, data_size1, 0); read_loc += data_size1; - nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0); + nandc_set_read_loc(chip, 1, read_loc, oob_size1, 0); read_loc += oob_size1; - nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0); + nandc_set_read_loc(chip, 2, read_loc, data_size2, 0); read_loc += data_size2; - nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1); + nandc_set_read_loc(chip, 3, read_loc, oob_size2, 1); } - config_nand_cw_read(nandc, false); + config_nand_cw_read(chip, false); read_data_dma(nandc, reg_off, data_buf, data_size1, 0); reg_off += data_size1; @@ -1856,7 +1863,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, u8 *data_buf_start = data_buf, *oob_buf_start = oob_buf; int i, ret; - config_nand_page_read(nandc); + config_nand_page_read(chip); /* queue cmd descs for each codeword */ for (i = 0; i < ecc->steps; i++) { @@ -1873,18 +1880,18 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, if (nandc->props->is_bam) { if (data_buf && oob_buf) { - nandc_set_read_loc(nandc, 0, 0, data_size, 0); - nandc_set_read_loc(nandc, 1, data_size, + nandc_set_read_loc(chip, 0, 0, data_size, 0); + nandc_set_read_loc(chip, 1, data_size, oob_size, 1); } else if (data_buf) { - nandc_set_read_loc(nandc, 0, 0, data_size, 1); + nandc_set_read_loc(chip, 0, 0, data_size, 1); } else { - nandc_set_read_loc(nandc, 0, data_size, + nandc_set_read_loc(chip, 0, data_size, oob_size, 1); } } - config_nand_cw_read(nandc, true); + config_nand_cw_read(chip, true); if (data_buf) read_data_dma(nandc, FLASH_BUF_ACC, data_buf, @@ -1946,7 +1953,7 @@ static int copy_last_cw(struct qcom_nand_host *host, int page) set_address(host, host->cw_size * (ecc->steps - 1), page); update_rw_regs(host, 1, true); - config_nand_single_cw_page_read(nandc, host->use_ecc); + config_nand_single_cw_page_read(chip, host->use_ecc); read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0); @@ -2036,7 +2043,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, host->use_ecc = true; update_rw_regs(host, ecc->steps, false); - config_nand_page_write(nandc); + config_nand_page_write(chip); for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; @@ -2068,7 +2075,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, oob_buf, oob_size, 0); } - config_nand_cw_write(nandc); + config_nand_cw_write(chip); data_buf += data_size; oob_buf += oob_size; @@ -2107,7 +2114,7 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, host->use_ecc = false; update_rw_regs(host, ecc->steps, false); - config_nand_page_write(nandc); + config_nand_page_write(chip); for (i = 0; i < ecc->steps; i++) { int data_size1, data_size2, oob_size1, oob_size2; @@ -2144,7 +2151,7 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0); oob_buf += oob_size2; - config_nand_cw_write(nandc); + config_nand_cw_write(chip); } ret = submit_descs(nandc); @@ -2191,10 +2198,10 @@ static int qcom_nandc_write_oob(struct nand_chip *chip, int page) set_address(host, host->cw_size * (ecc->steps - 1), page); update_rw_regs(host, 1, false); - config_nand_page_write(nandc); + config_nand_page_write(chip); write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, data_size + oob_size, 0); - config_nand_cw_write(nandc); + config_nand_cw_write(chip); ret = submit_descs(nandc); @@ -2270,10 +2277,10 @@ static int qcom_nandc_block_markbad(struct nand_chip *chip, loff_t ofs) set_address(host, host->cw_size * (ecc->steps - 1), page); update_rw_regs(host, 1, false); - config_nand_page_write(nandc); + config_nand_page_write(chip); write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, host->cw_size, 0); - config_nand_cw_write(nandc); + config_nand_cw_write(chip); ret = submit_descs(nandc); -- 2.7.4 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 1/5] mtd: rawnand: qcom: Convert nandc to chip in Read/Write helper @ 2021-02-23 19:38 ` Md Sadre Alam 0 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:38 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan This change will convert nandc to chip in Read/Write helper, this change is needed because if we wnated to access number of steps in Read/Write helper then we need to get the chip->ecc.steps, currentlly its not possible.After this change we can directly acces chip->ecc.steps in Read/Write helper. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 153 ++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 73 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 667e4bf..4898d32 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -181,8 +181,8 @@ #define ECC_BCH_4BIT BIT(2) #define ECC_BCH_8BIT BIT(3) -#define nandc_set_read_loc(nandc, reg, offset, size, is_last) \ -nandc_set_reg(nandc, NAND_READ_LOCATION_##reg, \ +#define nandc_set_read_loc(chip, reg, offset, size, is_last) \ +nandc_set_reg(chip, NAND_READ_LOCATION_##reg, \ ((offset) << READ_LOCATION_OFFSET) | \ ((size) << READ_LOCATION_SIZE) | \ ((is_last) << READ_LOCATION_LAST)) @@ -649,9 +649,10 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset) } } -static void nandc_set_reg(struct qcom_nand_controller *nandc, int offset, +static void nandc_set_reg(struct nand_chip *chip, int offset, u32 val) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); struct nandc_regs *regs = nandc->regs; __le32 *reg; @@ -665,13 +666,12 @@ static void nandc_set_reg(struct qcom_nand_controller *nandc, int offset, static void set_address(struct qcom_nand_host *host, u16 column, int page) { struct nand_chip *chip = &host->chip; - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); if (chip->options & NAND_BUSWIDTH_16) column >>= 1; - nandc_set_reg(nandc, NAND_ADDR0, page << 16 | column); - nandc_set_reg(nandc, NAND_ADDR1, page >> 16 & 0xff); + nandc_set_reg(chip, NAND_ADDR0, page << 16 | column); + nandc_set_reg(chip, NAND_ADDR1, page >> 16 & 0xff); } /* @@ -684,7 +684,6 @@ static void set_address(struct qcom_nand_host *host, u16 column, int page) static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) { struct nand_chip *chip = &host->chip; - struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); u32 cmd, cfg0, cfg1, ecc_bch_cfg; if (read) { @@ -710,17 +709,17 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE; } - nandc_set_reg(nandc, NAND_FLASH_CMD, cmd); - nandc_set_reg(nandc, NAND_DEV0_CFG0, cfg0); - nandc_set_reg(nandc, NAND_DEV0_CFG1, cfg1); - nandc_set_reg(nandc, NAND_DEV0_ECC_CFG, ecc_bch_cfg); - nandc_set_reg(nandc, NAND_EBI2_ECC_BUF_CFG, host->ecc_buf_cfg); - nandc_set_reg(nandc, NAND_FLASH_STATUS, host->clrflashstatus); - nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus); - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_FLASH_CMD, cmd); + nandc_set_reg(chip, NAND_DEV0_CFG0, cfg0); + nandc_set_reg(chip, NAND_DEV0_CFG1, cfg1); + nandc_set_reg(chip, NAND_DEV0_ECC_CFG, ecc_bch_cfg); + nandc_set_reg(chip, NAND_EBI2_ECC_BUF_CFG, host->ecc_buf_cfg); + nandc_set_reg(chip, NAND_FLASH_STATUS, host->clrflashstatus); + nandc_set_reg(chip, NAND_READ_STATUS, host->clrreadstatus); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); if (read) - nandc_set_read_loc(nandc, 0, 0, host->use_ecc ? + nandc_set_read_loc(chip, 0, 0, host->use_ecc ? host->cw_data : host->cw_size, 1); } @@ -1079,8 +1078,10 @@ static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off, * Helper to prepare DMA descriptors for configuring registers * before reading a NAND page. */ -static void config_nand_page_read(struct qcom_nand_controller *nandc) +static void config_nand_page_read(struct nand_chip *chip) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + write_reg_dma(nandc, NAND_ADDR0, 2, 0); write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0); write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0); @@ -1094,8 +1095,10 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc) * before reading each codeword in NAND page. */ static void -config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc) +config_nand_cw_read(struct nand_chip *chip, bool use_ecc) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + if (nandc->props->is_bam) write_reg_dma(nandc, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL); @@ -1117,19 +1120,21 @@ config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc) * single codeword in page */ static void -config_nand_single_cw_page_read(struct qcom_nand_controller *nandc, +config_nand_single_cw_page_read(struct nand_chip *chip, bool use_ecc) { - config_nand_page_read(nandc); - config_nand_cw_read(nandc, use_ecc); + config_nand_page_read(chip); + config_nand_cw_read(chip, use_ecc); } /* * Helper to prepare DMA descriptors used to configure registers needed for * before writing a NAND page. */ -static void config_nand_page_write(struct qcom_nand_controller *nandc) +static void config_nand_page_write(struct nand_chip *chip) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + write_reg_dma(nandc, NAND_ADDR0, 2, 0); write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0); write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, @@ -1140,8 +1145,10 @@ static void config_nand_page_write(struct qcom_nand_controller *nandc) * Helper to prepare DMA descriptors for configuring registers * before writing each codeword in NAND page. */ -static void config_nand_cw_write(struct qcom_nand_controller *nandc) +static void config_nand_cw_write(struct nand_chip *chip) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -1168,44 +1175,44 @@ static int nandc_param(struct qcom_nand_host *host) * bytes to read onfi params */ if (nandc->props->qpic_v2) - nandc_set_reg(nandc, NAND_FLASH_CMD, OP_PAGE_READ_ONFI_READ | + nandc_set_reg(chip, NAND_FLASH_CMD, OP_PAGE_READ_ONFI_READ | PAGE_ACC | LAST_PAGE); else - nandc_set_reg(nandc, NAND_FLASH_CMD, OP_PAGE_READ | + nandc_set_reg(chip, NAND_FLASH_CMD, OP_PAGE_READ | PAGE_ACC | LAST_PAGE); - nandc_set_reg(nandc, NAND_ADDR0, 0); - nandc_set_reg(nandc, NAND_ADDR1, 0); - nandc_set_reg(nandc, NAND_DEV0_CFG0, 0 << CW_PER_PAGE + nandc_set_reg(chip, NAND_ADDR0, 0); + nandc_set_reg(chip, NAND_ADDR1, 0); + nandc_set_reg(chip, NAND_DEV0_CFG0, 0 << CW_PER_PAGE | 512 << UD_SIZE_BYTES | 5 << NUM_ADDR_CYCLES | 0 << SPARE_SIZE_BYTES); - nandc_set_reg(nandc, NAND_DEV0_CFG1, 7 << NAND_RECOVERY_CYCLES + nandc_set_reg(chip, NAND_DEV0_CFG1, 7 << NAND_RECOVERY_CYCLES | 0 << CS_ACTIVE_BSY | 17 << BAD_BLOCK_BYTE_NUM | 1 << BAD_BLOCK_IN_SPARE_AREA | 2 << WR_RD_BSY_GAP | 0 << WIDE_FLASH | 1 << DEV0_CFG1_ECC_DISABLE); - nandc_set_reg(nandc, NAND_EBI2_ECC_BUF_CFG, 1 << ECC_CFG_ECC_DISABLE); + nandc_set_reg(chip, NAND_EBI2_ECC_BUF_CFG, 1 << ECC_CFG_ECC_DISABLE); /* configure CMD1 and VLD for ONFI param probing in QPIC v1 */ if (!nandc->props->qpic_v2) { - nandc_set_reg(nandc, NAND_DEV_CMD_VLD, + nandc_set_reg(chip, NAND_DEV_CMD_VLD, (nandc->vld & ~READ_START_VLD)); - nandc_set_reg(nandc, NAND_DEV_CMD1, + nandc_set_reg(chip, NAND_DEV_CMD1, (nandc->cmd1 & ~(0xFF << READ_ADDR)) | NAND_CMD_PARAM << READ_ADDR); } - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); if (!nandc->props->qpic_v2) { - nandc_set_reg(nandc, NAND_DEV_CMD1_RESTORE, nandc->cmd1); - nandc_set_reg(nandc, NAND_DEV_CMD_VLD_RESTORE, nandc->vld); + nandc_set_reg(chip, NAND_DEV_CMD1_RESTORE, nandc->cmd1); + nandc_set_reg(chip, NAND_DEV_CMD_VLD_RESTORE, nandc->vld); } - nandc_set_read_loc(nandc, 0, 0, 512, 1); + nandc_set_read_loc(chip, 0, 0, 512, 1); if (!nandc->props->qpic_v2) { write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0); @@ -1215,7 +1222,7 @@ static int nandc_param(struct qcom_nand_host *host) nandc->buf_count = 512; memset(nandc->data_buffer, 0xff, nandc->buf_count); - config_nand_single_cw_page_read(nandc, false); + config_nand_single_cw_page_read(chip, false); read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, nandc->buf_count, 0); @@ -1235,16 +1242,16 @@ static int erase_block(struct qcom_nand_host *host, int page_addr) struct nand_chip *chip = &host->chip; struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - nandc_set_reg(nandc, NAND_FLASH_CMD, + nandc_set_reg(chip, NAND_FLASH_CMD, OP_BLOCK_ERASE | PAGE_ACC | LAST_PAGE); - nandc_set_reg(nandc, NAND_ADDR0, page_addr); - nandc_set_reg(nandc, NAND_ADDR1, 0); - nandc_set_reg(nandc, NAND_DEV0_CFG0, + nandc_set_reg(chip, NAND_ADDR0, page_addr); + nandc_set_reg(chip, NAND_ADDR1, 0); + nandc_set_reg(chip, NAND_DEV0_CFG0, host->cfg0_raw & ~(7 << CW_PER_PAGE)); - nandc_set_reg(nandc, NAND_DEV0_CFG1, host->cfg1_raw); - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); - nandc_set_reg(nandc, NAND_FLASH_STATUS, host->clrflashstatus); - nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus); + nandc_set_reg(chip, NAND_DEV0_CFG1, host->cfg1_raw); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_FLASH_STATUS, host->clrflashstatus); + nandc_set_reg(chip, NAND_READ_STATUS, host->clrreadstatus); write_reg_dma(nandc, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL); @@ -1267,12 +1274,12 @@ static int read_id(struct qcom_nand_host *host, int column) if (column == -1) return 0; - nandc_set_reg(nandc, NAND_FLASH_CMD, OP_FETCH_ID); - nandc_set_reg(nandc, NAND_ADDR0, column); - nandc_set_reg(nandc, NAND_ADDR1, 0); - nandc_set_reg(nandc, NAND_FLASH_CHIP_SELECT, + nandc_set_reg(chip, NAND_FLASH_CMD, OP_FETCH_ID); + nandc_set_reg(chip, NAND_ADDR0, column); + nandc_set_reg(chip, NAND_ADDR1, 0); + nandc_set_reg(chip, NAND_FLASH_CHIP_SELECT, nandc->props->is_bam ? 0 : DM_EN); - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); write_reg_dma(nandc, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -1288,8 +1295,8 @@ static int reset(struct qcom_nand_host *host) struct nand_chip *chip = &host->chip; struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); - nandc_set_reg(nandc, NAND_FLASH_CMD, OP_RESET_DEVICE); - nandc_set_reg(nandc, NAND_EXEC_CMD, 1); + nandc_set_reg(chip, NAND_FLASH_CMD, OP_RESET_DEVICE); + nandc_set_reg(chip, NAND_EXEC_CMD, 1); write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -1617,7 +1624,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, clear_bam_transaction(nandc); set_address(host, host->cw_size * cw, page); update_rw_regs(host, 1, true); - config_nand_page_read(nandc); + config_nand_page_read(chip); data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; @@ -1633,19 +1640,19 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, } if (nandc->props->is_bam) { - nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0); + nandc_set_read_loc(chip, 0, read_loc, data_size1, 0); read_loc += data_size1; - nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0); + nandc_set_read_loc(chip, 1, read_loc, oob_size1, 0); read_loc += oob_size1; - nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0); + nandc_set_read_loc(chip, 2, read_loc, data_size2, 0); read_loc += data_size2; - nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1); + nandc_set_read_loc(chip, 3, read_loc, oob_size2, 1); } - config_nand_cw_read(nandc, false); + config_nand_cw_read(chip, false); read_data_dma(nandc, reg_off, data_buf, data_size1, 0); reg_off += data_size1; @@ -1856,7 +1863,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, u8 *data_buf_start = data_buf, *oob_buf_start = oob_buf; int i, ret; - config_nand_page_read(nandc); + config_nand_page_read(chip); /* queue cmd descs for each codeword */ for (i = 0; i < ecc->steps; i++) { @@ -1873,18 +1880,18 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, if (nandc->props->is_bam) { if (data_buf && oob_buf) { - nandc_set_read_loc(nandc, 0, 0, data_size, 0); - nandc_set_read_loc(nandc, 1, data_size, + nandc_set_read_loc(chip, 0, 0, data_size, 0); + nandc_set_read_loc(chip, 1, data_size, oob_size, 1); } else if (data_buf) { - nandc_set_read_loc(nandc, 0, 0, data_size, 1); + nandc_set_read_loc(chip, 0, 0, data_size, 1); } else { - nandc_set_read_loc(nandc, 0, data_size, + nandc_set_read_loc(chip, 0, data_size, oob_size, 1); } } - config_nand_cw_read(nandc, true); + config_nand_cw_read(chip, true); if (data_buf) read_data_dma(nandc, FLASH_BUF_ACC, data_buf, @@ -1946,7 +1953,7 @@ static int copy_last_cw(struct qcom_nand_host *host, int page) set_address(host, host->cw_size * (ecc->steps - 1), page); update_rw_regs(host, 1, true); - config_nand_single_cw_page_read(nandc, host->use_ecc); + config_nand_single_cw_page_read(chip, host->use_ecc); read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0); @@ -2036,7 +2043,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, host->use_ecc = true; update_rw_regs(host, ecc->steps, false); - config_nand_page_write(nandc); + config_nand_page_write(chip); for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; @@ -2068,7 +2075,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, oob_buf, oob_size, 0); } - config_nand_cw_write(nandc); + config_nand_cw_write(chip); data_buf += data_size; oob_buf += oob_size; @@ -2107,7 +2114,7 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, host->use_ecc = false; update_rw_regs(host, ecc->steps, false); - config_nand_page_write(nandc); + config_nand_page_write(chip); for (i = 0; i < ecc->steps; i++) { int data_size1, data_size2, oob_size1, oob_size2; @@ -2144,7 +2151,7 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0); oob_buf += oob_size2; - config_nand_cw_write(nandc); + config_nand_cw_write(chip); } ret = submit_descs(nandc); @@ -2191,10 +2198,10 @@ static int qcom_nandc_write_oob(struct nand_chip *chip, int page) set_address(host, host->cw_size * (ecc->steps - 1), page); update_rw_regs(host, 1, false); - config_nand_page_write(nandc); + config_nand_page_write(chip); write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, data_size + oob_size, 0); - config_nand_cw_write(nandc); + config_nand_cw_write(chip); ret = submit_descs(nandc); @@ -2270,10 +2277,10 @@ static int qcom_nandc_block_markbad(struct nand_chip *chip, loff_t ofs) set_address(host, host->cw_size * (ecc->steps - 1), page); update_rw_regs(host, 1, false); - config_nand_page_write(nandc); + config_nand_page_write(chip); write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, host->cw_size, 0); - config_nand_cw_write(nandc); + config_nand_cw_write(chip); ret = submit_descs(nandc); -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 2/5] mtd: rawnand: qcom: Add helper to check last code word 2021-02-23 19:38 ` Md Sadre Alam @ 2021-02-23 19:38 ` Md Sadre Alam -1 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:38 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan Add the qcom_nandc_is_last_cw() helper which checks if the input cw index is the last one or not. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 4898d32..9a890ef 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -662,6 +662,12 @@ static void nandc_set_reg(struct nand_chip *chip, int offset, *reg = cpu_to_le32(val); } +/* Helper to check the code word, whether it is last cw or not */ +static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw) +{ + return cw == (ecc->steps - 1); +} + /* helper to configure address register values */ static void set_address(struct qcom_nand_host *host, u16 column, int page) { @@ -1629,7 +1635,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; - if (cw == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, cw)) { data_size2 = ecc->size - data_size1 - ((ecc->steps - 1) * 4); oob_size2 = (ecc->steps * 4) + host->ecc_bytes_hw + @@ -1710,7 +1716,7 @@ check_for_erased_page(struct qcom_nand_host *host, u8 *data_buf, } for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) { - if (cw == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, cw)) { data_size = ecc->size - ((ecc->steps - 1) * 4); oob_size = (ecc->steps * 4) + host->ecc_bytes_hw; } else { @@ -1770,7 +1776,7 @@ static int parse_read_errors(struct qcom_nand_host *host, u8 *data_buf, u32 flash, buffer, erased_cw; int data_len, oob_len; - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { data_len = ecc->size - ((ecc->steps - 1) << 2); oob_len = ecc->steps << 2; } else { @@ -1869,7 +1875,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { data_size = ecc->size - ((ecc->steps - 1) << 2); oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + host->spare_bytes; @@ -2048,7 +2054,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { data_size = ecc->size - ((ecc->steps - 1) << 2); oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + host->spare_bytes; @@ -2068,7 +2074,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, * itself. For the last codeword, we skip the bbm positions and * write to the free oob area. */ - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { oob_buf += host->bbm_size; write_data_dma(nandc, FLASH_BUF_ACC + data_size, @@ -2123,7 +2129,7 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { data_size2 = ecc->size - data_size1 - ((ecc->steps - 1) << 2); oob_size2 = (ecc->steps << 2) + host->ecc_bytes_hw + -- 2.7.4 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 2/5] mtd: rawnand: qcom: Add helper to check last code word @ 2021-02-23 19:38 ` Md Sadre Alam 0 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:38 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan Add the qcom_nandc_is_last_cw() helper which checks if the input cw index is the last one or not. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 4898d32..9a890ef 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -662,6 +662,12 @@ static void nandc_set_reg(struct nand_chip *chip, int offset, *reg = cpu_to_le32(val); } +/* Helper to check the code word, whether it is last cw or not */ +static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw) +{ + return cw == (ecc->steps - 1); +} + /* helper to configure address register values */ static void set_address(struct qcom_nand_host *host, u16 column, int page) { @@ -1629,7 +1635,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; - if (cw == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, cw)) { data_size2 = ecc->size - data_size1 - ((ecc->steps - 1) * 4); oob_size2 = (ecc->steps * 4) + host->ecc_bytes_hw + @@ -1710,7 +1716,7 @@ check_for_erased_page(struct qcom_nand_host *host, u8 *data_buf, } for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) { - if (cw == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, cw)) { data_size = ecc->size - ((ecc->steps - 1) * 4); oob_size = (ecc->steps * 4) + host->ecc_bytes_hw; } else { @@ -1770,7 +1776,7 @@ static int parse_read_errors(struct qcom_nand_host *host, u8 *data_buf, u32 flash, buffer, erased_cw; int data_len, oob_len; - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { data_len = ecc->size - ((ecc->steps - 1) << 2); oob_len = ecc->steps << 2; } else { @@ -1869,7 +1875,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { data_size = ecc->size - ((ecc->steps - 1) << 2); oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + host->spare_bytes; @@ -2048,7 +2054,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, for (i = 0; i < ecc->steps; i++) { int data_size, oob_size; - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { data_size = ecc->size - ((ecc->steps - 1) << 2); oob_size = (ecc->steps << 2) + host->ecc_bytes_hw + host->spare_bytes; @@ -2068,7 +2074,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, * itself. For the last codeword, we skip the bbm positions and * write to the free oob area. */ - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { oob_buf += host->bbm_size; write_data_dma(nandc, FLASH_BUF_ACC + data_size, @@ -2123,7 +2129,7 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); oob_size1 = host->bbm_size; - if (i == (ecc->steps - 1)) { + if (qcom_nandc_is_last_cw(ecc, i)) { data_size2 = ecc->size - data_size1 - ((ecc->steps - 1) << 2); oob_size2 = (ecc->steps << 2) + host->ecc_bytes_hw + -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 2/5] mtd: rawnand: qcom: Add helper to check last code word 2021-02-23 19:38 ` Md Sadre Alam @ 2021-03-02 16:32 ` Miquel Raynal -1 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2021-03-02 16:32 UTC (permalink / raw) To: Md Sadre Alam, miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: sricharan On Tue, 2021-02-23 at 19:38:58 UTC, Md Sadre Alam wrote: > Add the qcom_nandc_is_last_cw() helper which checks if > the input cw index is the last one or not. > > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks. Miquel ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/5] mtd: rawnand: qcom: Add helper to check last code word @ 2021-03-02 16:32 ` Miquel Raynal 0 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2021-03-02 16:32 UTC (permalink / raw) To: Md Sadre Alam, miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: sricharan On Tue, 2021-02-23 at 19:38:58 UTC, Md Sadre Alam wrote: > Add the qcom_nandc_is_last_cw() helper which checks if > the input cw index is the last one or not. > > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks. Miquel ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 3/5] mtd: rawnand: qcom: Rename parameter name in macro 2021-02-23 19:38 ` Md Sadre Alam @ 2021-02-23 19:38 ` Md Sadre Alam -1 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:38 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan Rename the parameters of the nandc_set_read_loc() macro to avoid the confusion between is_last_read_loc which is last location in a read code word and last_cw which is last code word of a page data. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 9a890ef..f1aafee 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -181,11 +181,11 @@ #define ECC_BCH_4BIT BIT(2) #define ECC_BCH_8BIT BIT(3) -#define nandc_set_read_loc(chip, reg, offset, size, is_last) \ +#define nandc_set_read_loc(chip, reg, cw_offset, read_size, is_last_read_loc) \ nandc_set_reg(chip, NAND_READ_LOCATION_##reg, \ - ((offset) << READ_LOCATION_OFFSET) | \ - ((size) << READ_LOCATION_SIZE) | \ - ((is_last) << READ_LOCATION_LAST)) + ((cw_offset) << READ_LOCATION_OFFSET) | \ + ((read_size) << READ_LOCATION_SIZE) | \ + ((is_last_read_loc) << READ_LOCATION_LAST)) /* * Returns the actual register address for all NAND_DEV_ registers -- 2.7.4 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 3/5] mtd: rawnand: qcom: Rename parameter name in macro @ 2021-02-23 19:38 ` Md Sadre Alam 0 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:38 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan Rename the parameters of the nandc_set_read_loc() macro to avoid the confusion between is_last_read_loc which is last location in a read code word and last_cw which is last code word of a page data. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 9a890ef..f1aafee 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -181,11 +181,11 @@ #define ECC_BCH_4BIT BIT(2) #define ECC_BCH_8BIT BIT(3) -#define nandc_set_read_loc(chip, reg, offset, size, is_last) \ +#define nandc_set_read_loc(chip, reg, cw_offset, read_size, is_last_read_loc) \ nandc_set_reg(chip, NAND_READ_LOCATION_##reg, \ - ((offset) << READ_LOCATION_OFFSET) | \ - ((size) << READ_LOCATION_SIZE) | \ - ((is_last) << READ_LOCATION_LAST)) + ((cw_offset) << READ_LOCATION_OFFSET) | \ + ((read_size) << READ_LOCATION_SIZE) | \ + ((is_last_read_loc) << READ_LOCATION_LAST)) /* * Returns the actual register address for all NAND_DEV_ registers -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] mtd: rawnand: qcom: Rename parameter name in macro 2021-02-23 19:38 ` Md Sadre Alam @ 2021-03-02 16:32 ` Miquel Raynal -1 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2021-03-02 16:32 UTC (permalink / raw) To: Md Sadre Alam, miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: sricharan On Tue, 2021-02-23 at 19:38:59 UTC, Md Sadre Alam wrote: > Rename the parameters of the nandc_set_read_loc() macro > to avoid the confusion between is_last_read_loc which > is last location in a read code word and last_cw which > is last code word of a page data. > > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks. Miquel ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] mtd: rawnand: qcom: Rename parameter name in macro @ 2021-03-02 16:32 ` Miquel Raynal 0 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2021-03-02 16:32 UTC (permalink / raw) To: Md Sadre Alam, miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: sricharan On Tue, 2021-02-23 at 19:38:59 UTC, Md Sadre Alam wrote: > Rename the parameters of the nandc_set_read_loc() macro > to avoid the confusion between is_last_read_loc which > is last location in a read code word and last_cw which > is last code word of a page data. > > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks. Miquel ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 4/5] mtd: rawnand: qcom: Add helper to configure location register 2021-02-23 19:38 ` Md Sadre Alam @ 2021-02-23 19:39 ` Md Sadre Alam -1 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:39 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan Create a nandc_set_read_loc() helper to abstract the configuration of the location register. QPIC v2 onwards features a separate location register for the last codeword, so introducing this extra helper which will simplify the addition of QPIC v2 support. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index f1aafee..57d2ad02 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -181,8 +181,8 @@ #define ECC_BCH_4BIT BIT(2) #define ECC_BCH_8BIT BIT(3) -#define nandc_set_read_loc(chip, reg, cw_offset, read_size, is_last_read_loc) \ -nandc_set_reg(chip, NAND_READ_LOCATION_##reg, \ +#define nandc_set_read_loc_first(chip, reg, cw_offset, read_size, is_last_read_loc) \ +nandc_set_reg(chip, reg, \ ((cw_offset) << READ_LOCATION_OFFSET) | \ ((read_size) << READ_LOCATION_SIZE) | \ ((is_last_read_loc) << READ_LOCATION_LAST)) @@ -668,6 +668,18 @@ static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw) return cw == (ecc->steps - 1); } +/* helper to configure location register values */ +static void nandc_set_read_loc(struct nand_chip *chip, int cw, int reg, + int cw_offset, int read_size, int is_last_read_loc) +{ + int reg_base = NAND_READ_LOCATION_0; + + reg_base += reg * 4; + + return nandc_set_read_loc_first(chip, reg_base, cw_offset, + read_size, is_last_read_loc); +} + /* helper to configure address register values */ static void set_address(struct qcom_nand_host *host, u16 column, int page) { @@ -725,7 +737,7 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) nandc_set_reg(chip, NAND_EXEC_CMD, 1); if (read) - nandc_set_read_loc(chip, 0, 0, host->use_ecc ? + nandc_set_read_loc(chip, 0, 0, 0, host->use_ecc ? host->cw_data : host->cw_size, 1); } @@ -1218,7 +1230,7 @@ static int nandc_param(struct qcom_nand_host *host) nandc_set_reg(chip, NAND_DEV_CMD_VLD_RESTORE, nandc->vld); } - nandc_set_read_loc(chip, 0, 0, 512, 1); + nandc_set_read_loc(chip, 0, 0, 0, 512, 1); if (!nandc->props->qpic_v2) { write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0); @@ -1646,16 +1658,16 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, } if (nandc->props->is_bam) { - nandc_set_read_loc(chip, 0, read_loc, data_size1, 0); + nandc_set_read_loc(chip, cw, 0, read_loc, data_size1, 0); read_loc += data_size1; - nandc_set_read_loc(chip, 1, read_loc, oob_size1, 0); + nandc_set_read_loc(chip, cw, 1, read_loc, oob_size1, 0); read_loc += oob_size1; - nandc_set_read_loc(chip, 2, read_loc, data_size2, 0); + nandc_set_read_loc(chip, cw, 2, read_loc, data_size2, 0); read_loc += data_size2; - nandc_set_read_loc(chip, 3, read_loc, oob_size2, 1); + nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1); } config_nand_cw_read(chip, false); @@ -1886,13 +1898,13 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, if (nandc->props->is_bam) { if (data_buf && oob_buf) { - nandc_set_read_loc(chip, 0, 0, data_size, 0); - nandc_set_read_loc(chip, 1, data_size, + nandc_set_read_loc(chip, i, 0, 0, data_size, 0); + nandc_set_read_loc(chip, i, 1, data_size, oob_size, 1); } else if (data_buf) { - nandc_set_read_loc(chip, 0, 0, data_size, 1); + nandc_set_read_loc(chip, i, 0, 0, data_size, 1); } else { - nandc_set_read_loc(chip, 0, data_size, + nandc_set_read_loc(chip, i, 0, data_size, oob_size, 1); } } -- 2.7.4 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 4/5] mtd: rawnand: qcom: Add helper to configure location register @ 2021-02-23 19:39 ` Md Sadre Alam 0 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:39 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan Create a nandc_set_read_loc() helper to abstract the configuration of the location register. QPIC v2 onwards features a separate location register for the last codeword, so introducing this extra helper which will simplify the addition of QPIC v2 support. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index f1aafee..57d2ad02 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -181,8 +181,8 @@ #define ECC_BCH_4BIT BIT(2) #define ECC_BCH_8BIT BIT(3) -#define nandc_set_read_loc(chip, reg, cw_offset, read_size, is_last_read_loc) \ -nandc_set_reg(chip, NAND_READ_LOCATION_##reg, \ +#define nandc_set_read_loc_first(chip, reg, cw_offset, read_size, is_last_read_loc) \ +nandc_set_reg(chip, reg, \ ((cw_offset) << READ_LOCATION_OFFSET) | \ ((read_size) << READ_LOCATION_SIZE) | \ ((is_last_read_loc) << READ_LOCATION_LAST)) @@ -668,6 +668,18 @@ static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw) return cw == (ecc->steps - 1); } +/* helper to configure location register values */ +static void nandc_set_read_loc(struct nand_chip *chip, int cw, int reg, + int cw_offset, int read_size, int is_last_read_loc) +{ + int reg_base = NAND_READ_LOCATION_0; + + reg_base += reg * 4; + + return nandc_set_read_loc_first(chip, reg_base, cw_offset, + read_size, is_last_read_loc); +} + /* helper to configure address register values */ static void set_address(struct qcom_nand_host *host, u16 column, int page) { @@ -725,7 +737,7 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) nandc_set_reg(chip, NAND_EXEC_CMD, 1); if (read) - nandc_set_read_loc(chip, 0, 0, host->use_ecc ? + nandc_set_read_loc(chip, 0, 0, 0, host->use_ecc ? host->cw_data : host->cw_size, 1); } @@ -1218,7 +1230,7 @@ static int nandc_param(struct qcom_nand_host *host) nandc_set_reg(chip, NAND_DEV_CMD_VLD_RESTORE, nandc->vld); } - nandc_set_read_loc(chip, 0, 0, 512, 1); + nandc_set_read_loc(chip, 0, 0, 0, 512, 1); if (!nandc->props->qpic_v2) { write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0); @@ -1646,16 +1658,16 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, } if (nandc->props->is_bam) { - nandc_set_read_loc(chip, 0, read_loc, data_size1, 0); + nandc_set_read_loc(chip, cw, 0, read_loc, data_size1, 0); read_loc += data_size1; - nandc_set_read_loc(chip, 1, read_loc, oob_size1, 0); + nandc_set_read_loc(chip, cw, 1, read_loc, oob_size1, 0); read_loc += oob_size1; - nandc_set_read_loc(chip, 2, read_loc, data_size2, 0); + nandc_set_read_loc(chip, cw, 2, read_loc, data_size2, 0); read_loc += data_size2; - nandc_set_read_loc(chip, 3, read_loc, oob_size2, 1); + nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1); } config_nand_cw_read(chip, false); @@ -1886,13 +1898,13 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, if (nandc->props->is_bam) { if (data_buf && oob_buf) { - nandc_set_read_loc(chip, 0, 0, data_size, 0); - nandc_set_read_loc(chip, 1, data_size, + nandc_set_read_loc(chip, i, 0, 0, data_size, 0); + nandc_set_read_loc(chip, i, 1, data_size, oob_size, 1); } else if (data_buf) { - nandc_set_read_loc(chip, 0, 0, data_size, 1); + nandc_set_read_loc(chip, i, 0, 0, data_size, 1); } else { - nandc_set_read_loc(chip, 0, data_size, + nandc_set_read_loc(chip, i, 0, data_size, oob_size, 1); } } -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 4/5] mtd: rawnand: qcom: Add helper to configure location register 2021-02-23 19:39 ` Md Sadre Alam @ 2021-03-02 16:32 ` Miquel Raynal -1 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2021-03-02 16:32 UTC (permalink / raw) To: Md Sadre Alam, miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: sricharan On Tue, 2021-02-23 at 19:39:00 UTC, Md Sadre Alam wrote: > Create a nandc_set_read_loc() helper to abstract the > configuration of the location register. > > QPIC v2 onwards features a separate location register > for the last codeword, so introducing this extra helper > which will simplify the addition of QPIC v2 support. > > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks. Miquel ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/5] mtd: rawnand: qcom: Add helper to configure location register @ 2021-03-02 16:32 ` Miquel Raynal 0 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2021-03-02 16:32 UTC (permalink / raw) To: Md Sadre Alam, miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: sricharan On Tue, 2021-02-23 at 19:39:00 UTC, Md Sadre Alam wrote: > Create a nandc_set_read_loc() helper to abstract the > configuration of the location register. > > QPIC v2 onwards features a separate location register > for the last codeword, so introducing this extra helper > which will simplify the addition of QPIC v2 support. > > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks. Miquel ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 5/5] mtd: rawnand: qcom: update last code word register 2021-02-23 19:38 ` Md Sadre Alam @ 2021-02-23 19:39 ` Md Sadre Alam -1 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:39 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan From QPIC v2 onwards a new register got added to read last code word.Add support for this READ_LOCATION_LAST_CW_n register. In the case of QPIC v2, codewords 0, 1 and 2 will be accessed through READ_LOCATION_n, while codeword 3 will be accessed through READ_LOCATION_LAST_CW_n. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 79 ++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 57d2ad02..754c009 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -48,6 +48,10 @@ #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 write_reg_dma */ #define NAND_DEV_CMD1_RESTORE 0xdead @@ -187,6 +191,11 @@ nandc_set_reg(chip, reg, \ ((read_size) << READ_LOCATION_SIZE) | \ ((is_last_read_loc) << READ_LOCATION_LAST)) +#define nandc_set_read_loc_last(chip, reg, cw_offset, read_size, is_last_read_loc) \ +nandc_set_reg(chip, reg, \ + ((cw_offset) << READ_LOCATION_OFFSET) | \ + ((read_size) << READ_LOCATION_SIZE) | \ + ((is_last_read_loc) << READ_LOCATION_LAST)) /* * 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) @@ -316,6 +325,10 @@ struct nandc_regs { __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 erased_cw_detect_cfg_clr; __le32 erased_cw_detect_cfg_set; @@ -644,6 +657,14 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset) return ®s->read_location2; case NAND_READ_LOCATION_3: return ®s->read_location3; + case NAND_READ_LOCATION_LAST_CW_0: + return ®s->read_location_last0; + case NAND_READ_LOCATION_LAST_CW_1: + return ®s->read_location_last1; + case NAND_READ_LOCATION_LAST_CW_2: + return ®s->read_location_last2; + case NAND_READ_LOCATION_LAST_CW_3: + return ®s->read_location_last3; default: return NULL; } @@ -672,12 +693,22 @@ static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw) static void nandc_set_read_loc(struct nand_chip *chip, int cw, int reg, int cw_offset, int read_size, int is_last_read_loc) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + struct nand_ecc_ctrl *ecc = &chip->ecc; + int reg_base = NAND_READ_LOCATION_0; + if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) + reg_base = NAND_READ_LOCATION_LAST_CW_0; + reg_base += reg * 4; - return nandc_set_read_loc_first(chip, reg_base, cw_offset, - read_size, is_last_read_loc); + if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) + return nandc_set_read_loc_last(chip, reg_base, cw_offset, + read_size, is_last_read_loc); + else + return nandc_set_read_loc_first(chip, reg_base, cw_offset, + read_size, is_last_read_loc); } /* helper to configure address register values */ @@ -698,8 +729,9 @@ static void set_address(struct qcom_nand_host *host, u16 column, int page) * * @num_cw: number of steps for the read/write operation * @read: read or write operation + * @cw : which code word */ -static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) +static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, int cw) { struct nand_chip *chip = &host->chip; u32 cmd, cfg0, cfg1, ecc_bch_cfg; @@ -737,7 +769,7 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) nandc_set_reg(chip, NAND_EXEC_CMD, 1); if (read) - nandc_set_read_loc(chip, 0, 0, 0, host->use_ecc ? + nandc_set_read_loc(chip, cw, 0, 0, host->use_ecc ? host->cw_data : host->cw_size, 1); } @@ -1113,13 +1145,18 @@ static void config_nand_page_read(struct nand_chip *chip) * before reading each codeword in NAND page. */ static void -config_nand_cw_read(struct nand_chip *chip, bool use_ecc) +config_nand_cw_read(struct nand_chip *chip, bool use_ecc, int cw) { struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + struct nand_ecc_ctrl *ecc = &chip->ecc; + + int reg = NAND_READ_LOCATION_0; + + if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) + reg = NAND_READ_LOCATION_LAST_CW_0; if (nandc->props->is_bam) - write_reg_dma(nandc, NAND_READ_LOCATION_0, 4, - NAND_BAM_NEXT_SGL); + write_reg_dma(nandc, reg, 4, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -1139,10 +1176,10 @@ config_nand_cw_read(struct nand_chip *chip, bool use_ecc) */ static void config_nand_single_cw_page_read(struct nand_chip *chip, - bool use_ecc) + bool use_ecc, int cw) { config_nand_page_read(chip); - config_nand_cw_read(chip, use_ecc); + config_nand_cw_read(chip, use_ecc, cw); } /* @@ -1240,7 +1277,7 @@ static int nandc_param(struct qcom_nand_host *host) nandc->buf_count = 512; memset(nandc->data_buffer, 0xff, nandc->buf_count); - config_nand_single_cw_page_read(chip, false); + config_nand_single_cw_page_read(chip, false, 0); read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, nandc->buf_count, 0); @@ -1517,7 +1554,7 @@ static void qcom_nandc_command(struct nand_chip *chip, unsigned int command, host->use_ecc = true; set_address(host, 0, page_addr); - update_rw_regs(host, ecc->steps, true); + update_rw_regs(host, ecc->steps, true, 0); break; case NAND_CMD_SEQIN: @@ -1641,7 +1678,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, clear_bam_transaction(nandc); set_address(host, host->cw_size * cw, page); - update_rw_regs(host, 1, true); + update_rw_regs(host, 1, true, cw); config_nand_page_read(chip); data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); @@ -1670,7 +1707,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1); } - config_nand_cw_read(chip, false); + config_nand_cw_read(chip, false, cw); read_data_dma(nandc, reg_off, data_buf, data_size1, 0); reg_off += data_size1; @@ -1909,7 +1946,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, } } - config_nand_cw_read(chip, true); + config_nand_cw_read(chip, true, i); if (data_buf) read_data_dma(nandc, FLASH_BUF_ACC, data_buf, @@ -1969,9 +2006,9 @@ static int copy_last_cw(struct qcom_nand_host *host, int page) memset(nandc->data_buffer, 0xff, size); set_address(host, host->cw_size * (ecc->steps - 1), page); - update_rw_regs(host, 1, true); + update_rw_regs(host, 1, true, ecc->steps - 1); - config_nand_single_cw_page_read(chip, host->use_ecc); + config_nand_single_cw_page_read(chip, host->use_ecc, ecc->steps - 1); read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0); @@ -2036,7 +2073,7 @@ static int qcom_nandc_read_oob(struct nand_chip *chip, int page) host->use_ecc = true; set_address(host, 0, page); - update_rw_regs(host, ecc->steps, true); + update_rw_regs(host, ecc->steps, true, 0); return read_page_ecc(host, NULL, chip->oob_poi, page); } @@ -2060,7 +2097,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, oob_buf = chip->oob_poi; host->use_ecc = true; - update_rw_regs(host, ecc->steps, false); + update_rw_regs(host, ecc->steps, false, 0); config_nand_page_write(chip); for (i = 0; i < ecc->steps; i++) { @@ -2131,7 +2168,7 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, oob_buf = chip->oob_poi; host->use_ecc = false; - update_rw_regs(host, ecc->steps, false); + update_rw_regs(host, ecc->steps, false, 0); config_nand_page_write(chip); for (i = 0; i < ecc->steps; i++) { @@ -2214,7 +2251,7 @@ static int qcom_nandc_write_oob(struct nand_chip *chip, int page) 0, mtd->oobavail); set_address(host, host->cw_size * (ecc->steps - 1), page); - update_rw_regs(host, 1, false); + update_rw_regs(host, 1, false, 0); config_nand_page_write(chip); write_data_dma(nandc, FLASH_BUF_ACC, @@ -2293,7 +2330,7 @@ static int qcom_nandc_block_markbad(struct nand_chip *chip, loff_t ofs) /* prepare write */ host->use_ecc = false; set_address(host, host->cw_size * (ecc->steps - 1), page); - update_rw_regs(host, 1, false); + update_rw_regs(host, 1, false, ecc->steps - 1); config_nand_page_write(chip); write_data_dma(nandc, FLASH_BUF_ACC, -- 2.7.4 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 5/5] mtd: rawnand: qcom: update last code word register @ 2021-02-23 19:39 ` Md Sadre Alam 0 siblings, 0 replies; 18+ messages in thread From: Md Sadre Alam @ 2021-02-23 19:39 UTC (permalink / raw) To: miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: mdalam, sricharan From QPIC v2 onwards a new register got added to read last code word.Add support for this READ_LOCATION_LAST_CW_n register. In the case of QPIC v2, codewords 0, 1 and 2 will be accessed through READ_LOCATION_n, while codeword 3 will be accessed through READ_LOCATION_LAST_CW_n. Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> --- drivers/mtd/nand/raw/qcom_nandc.c | 79 ++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 57d2ad02..754c009 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -48,6 +48,10 @@ #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 write_reg_dma */ #define NAND_DEV_CMD1_RESTORE 0xdead @@ -187,6 +191,11 @@ nandc_set_reg(chip, reg, \ ((read_size) << READ_LOCATION_SIZE) | \ ((is_last_read_loc) << READ_LOCATION_LAST)) +#define nandc_set_read_loc_last(chip, reg, cw_offset, read_size, is_last_read_loc) \ +nandc_set_reg(chip, reg, \ + ((cw_offset) << READ_LOCATION_OFFSET) | \ + ((read_size) << READ_LOCATION_SIZE) | \ + ((is_last_read_loc) << READ_LOCATION_LAST)) /* * 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) @@ -316,6 +325,10 @@ struct nandc_regs { __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 erased_cw_detect_cfg_clr; __le32 erased_cw_detect_cfg_set; @@ -644,6 +657,14 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset) return ®s->read_location2; case NAND_READ_LOCATION_3: return ®s->read_location3; + case NAND_READ_LOCATION_LAST_CW_0: + return ®s->read_location_last0; + case NAND_READ_LOCATION_LAST_CW_1: + return ®s->read_location_last1; + case NAND_READ_LOCATION_LAST_CW_2: + return ®s->read_location_last2; + case NAND_READ_LOCATION_LAST_CW_3: + return ®s->read_location_last3; default: return NULL; } @@ -672,12 +693,22 @@ static bool qcom_nandc_is_last_cw(struct nand_ecc_ctrl *ecc, int cw) static void nandc_set_read_loc(struct nand_chip *chip, int cw, int reg, int cw_offset, int read_size, int is_last_read_loc) { + struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + struct nand_ecc_ctrl *ecc = &chip->ecc; + int reg_base = NAND_READ_LOCATION_0; + if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) + reg_base = NAND_READ_LOCATION_LAST_CW_0; + reg_base += reg * 4; - return nandc_set_read_loc_first(chip, reg_base, cw_offset, - read_size, is_last_read_loc); + if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) + return nandc_set_read_loc_last(chip, reg_base, cw_offset, + read_size, is_last_read_loc); + else + return nandc_set_read_loc_first(chip, reg_base, cw_offset, + read_size, is_last_read_loc); } /* helper to configure address register values */ @@ -698,8 +729,9 @@ static void set_address(struct qcom_nand_host *host, u16 column, int page) * * @num_cw: number of steps for the read/write operation * @read: read or write operation + * @cw : which code word */ -static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) +static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, int cw) { struct nand_chip *chip = &host->chip; u32 cmd, cfg0, cfg1, ecc_bch_cfg; @@ -737,7 +769,7 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) nandc_set_reg(chip, NAND_EXEC_CMD, 1); if (read) - nandc_set_read_loc(chip, 0, 0, 0, host->use_ecc ? + nandc_set_read_loc(chip, cw, 0, 0, host->use_ecc ? host->cw_data : host->cw_size, 1); } @@ -1113,13 +1145,18 @@ static void config_nand_page_read(struct nand_chip *chip) * before reading each codeword in NAND page. */ static void -config_nand_cw_read(struct nand_chip *chip, bool use_ecc) +config_nand_cw_read(struct nand_chip *chip, bool use_ecc, int cw) { struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); + struct nand_ecc_ctrl *ecc = &chip->ecc; + + int reg = NAND_READ_LOCATION_0; + + if (nandc->props->qpic_v2 && qcom_nandc_is_last_cw(ecc, cw)) + reg = NAND_READ_LOCATION_LAST_CW_0; if (nandc->props->is_bam) - write_reg_dma(nandc, NAND_READ_LOCATION_0, 4, - NAND_BAM_NEXT_SGL); + write_reg_dma(nandc, reg, 4, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -1139,10 +1176,10 @@ config_nand_cw_read(struct nand_chip *chip, bool use_ecc) */ static void config_nand_single_cw_page_read(struct nand_chip *chip, - bool use_ecc) + bool use_ecc, int cw) { config_nand_page_read(chip); - config_nand_cw_read(chip, use_ecc); + config_nand_cw_read(chip, use_ecc, cw); } /* @@ -1240,7 +1277,7 @@ static int nandc_param(struct qcom_nand_host *host) nandc->buf_count = 512; memset(nandc->data_buffer, 0xff, nandc->buf_count); - config_nand_single_cw_page_read(chip, false); + config_nand_single_cw_page_read(chip, false, 0); read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, nandc->buf_count, 0); @@ -1517,7 +1554,7 @@ static void qcom_nandc_command(struct nand_chip *chip, unsigned int command, host->use_ecc = true; set_address(host, 0, page_addr); - update_rw_regs(host, ecc->steps, true); + update_rw_regs(host, ecc->steps, true, 0); break; case NAND_CMD_SEQIN: @@ -1641,7 +1678,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, clear_bam_transaction(nandc); set_address(host, host->cw_size * cw, page); - update_rw_regs(host, 1, true); + update_rw_regs(host, 1, true, cw); config_nand_page_read(chip); data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1); @@ -1670,7 +1707,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip, nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1); } - config_nand_cw_read(chip, false); + config_nand_cw_read(chip, false, cw); read_data_dma(nandc, reg_off, data_buf, data_size1, 0); reg_off += data_size1; @@ -1909,7 +1946,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf, } } - config_nand_cw_read(chip, true); + config_nand_cw_read(chip, true, i); if (data_buf) read_data_dma(nandc, FLASH_BUF_ACC, data_buf, @@ -1969,9 +2006,9 @@ static int copy_last_cw(struct qcom_nand_host *host, int page) memset(nandc->data_buffer, 0xff, size); set_address(host, host->cw_size * (ecc->steps - 1), page); - update_rw_regs(host, 1, true); + update_rw_regs(host, 1, true, ecc->steps - 1); - config_nand_single_cw_page_read(chip, host->use_ecc); + config_nand_single_cw_page_read(chip, host->use_ecc, ecc->steps - 1); read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0); @@ -2036,7 +2073,7 @@ static int qcom_nandc_read_oob(struct nand_chip *chip, int page) host->use_ecc = true; set_address(host, 0, page); - update_rw_regs(host, ecc->steps, true); + update_rw_regs(host, ecc->steps, true, 0); return read_page_ecc(host, NULL, chip->oob_poi, page); } @@ -2060,7 +2097,7 @@ static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, oob_buf = chip->oob_poi; host->use_ecc = true; - update_rw_regs(host, ecc->steps, false); + update_rw_regs(host, ecc->steps, false, 0); config_nand_page_write(chip); for (i = 0; i < ecc->steps; i++) { @@ -2131,7 +2168,7 @@ static int qcom_nandc_write_page_raw(struct nand_chip *chip, oob_buf = chip->oob_poi; host->use_ecc = false; - update_rw_regs(host, ecc->steps, false); + update_rw_regs(host, ecc->steps, false, 0); config_nand_page_write(chip); for (i = 0; i < ecc->steps; i++) { @@ -2214,7 +2251,7 @@ static int qcom_nandc_write_oob(struct nand_chip *chip, int page) 0, mtd->oobavail); set_address(host, host->cw_size * (ecc->steps - 1), page); - update_rw_regs(host, 1, false); + update_rw_regs(host, 1, false, 0); config_nand_page_write(chip); write_data_dma(nandc, FLASH_BUF_ACC, @@ -2293,7 +2330,7 @@ static int qcom_nandc_block_markbad(struct nand_chip *chip, loff_t ofs) /* prepare write */ host->use_ecc = false; set_address(host, host->cw_size * (ecc->steps - 1), page); - update_rw_regs(host, 1, false); + update_rw_regs(host, 1, false, ecc->steps - 1); config_nand_page_write(chip); write_data_dma(nandc, FLASH_BUF_ACC, -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 1/5] mtd: rawnand: qcom: Convert nandc to chip in Read/Write helper 2021-02-23 19:38 ` Md Sadre Alam @ 2021-03-02 16:32 ` Miquel Raynal -1 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2021-03-02 16:32 UTC (permalink / raw) To: Md Sadre Alam, miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: sricharan On Tue, 2021-02-23 at 19:38:57 UTC, Md Sadre Alam wrote: > This change will convert nandc to chip in Read/Write helper, this > change is needed because if we wnated to access number of steps > in Read/Write helper then we need to get the chip->ecc.steps, > currentlly its not possible.After this change we can directly > acces chip->ecc.steps in Read/Write helper. > > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks. Miquel ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/5] mtd: rawnand: qcom: Convert nandc to chip in Read/Write helper @ 2021-03-02 16:32 ` Miquel Raynal 0 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2021-03-02 16:32 UTC (permalink / raw) To: Md Sadre Alam, miquel.raynal, mani, boris.brezillon, linux-mtd, linux-kernel Cc: sricharan On Tue, 2021-02-23 at 19:38:57 UTC, Md Sadre Alam wrote: > This change will convert nandc to chip in Read/Write helper, this > change is needed because if we wnated to access number of steps > in Read/Write helper then we need to get the chip->ecc.steps, > currentlly its not possible.After this change we can directly > acces chip->ecc.steps in Read/Write helper. > > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks. Miquel ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2021-03-03 19:40 UTC | newest] Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-02-23 19:38 [PATCH 1/5] mtd: rawnand: qcom: Convert nandc to chip in Read/Write helper Md Sadre Alam 2021-02-23 19:38 ` Md Sadre Alam 2021-02-23 19:38 ` [PATCH 2/5] mtd: rawnand: qcom: Add helper to check last code word Md Sadre Alam 2021-02-23 19:38 ` Md Sadre Alam 2021-03-02 16:32 ` Miquel Raynal 2021-03-02 16:32 ` Miquel Raynal 2021-02-23 19:38 ` [PATCH 3/5] mtd: rawnand: qcom: Rename parameter name in macro Md Sadre Alam 2021-02-23 19:38 ` Md Sadre Alam 2021-03-02 16:32 ` Miquel Raynal 2021-03-02 16:32 ` Miquel Raynal 2021-02-23 19:39 ` [PATCH 4/5] mtd: rawnand: qcom: Add helper to configure location register Md Sadre Alam 2021-02-23 19:39 ` Md Sadre Alam 2021-03-02 16:32 ` Miquel Raynal 2021-03-02 16:32 ` Miquel Raynal 2021-02-23 19:39 ` [PATCH 5/5] mtd: rawnand: qcom: update last code word register Md Sadre Alam 2021-02-23 19:39 ` Md Sadre Alam 2021-03-02 16:32 ` [PATCH 1/5] mtd: rawnand: qcom: Convert nandc to chip in Read/Write helper Miquel Raynal 2021-03-02 16:32 ` Miquel Raynal
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.