Loading drivers/mtd/devices/msm_qpic_nand.c +67 −19 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #define MAX_DESC 16 #define SMEM_AARM_PARTITION_TABLE 9 #define SMEM_APPS 0 #define ONE_CODEWORD_SIZE 516 static bool enable_euclean; static bool enable_perfstats; Loading Loading @@ -1183,10 +1185,16 @@ static int msm_nand_validate_mtd_params(struct mtd_info *mtd, bool read, err = -EINVAL; goto out; } args->page_count = ops->len / (mtd->writesize + mtd->oobsize); if (ops->len <= ONE_CODEWORD_SIZE) args->page_count = 1; else args->page_count = ops->len / (mtd->writesize + mtd->oobsize); } else if (ops->mode == MTD_OPS_AUTO_OOB) { if (ops->datbuf && (ops->len % mtd->writesize) != 0) { if (ops->datbuf && (ops->len % ((ops->len <= ONE_CODEWORD_SIZE) ? ONE_CODEWORD_SIZE : mtd->writesize)) != 0) { /* when ops->datbuf is NULL, ops->len can be ooblen */ pr_err("unsupported data len %d for AUTO mode\n", ops->len); Loading @@ -1199,6 +1207,9 @@ static int msm_nand_validate_mtd_params(struct mtd_info *mtd, bool read, if ((args->page_count == 0) && (ops->ooblen)) args->page_count = 1; } else if (ops->datbuf) { if (ops->len <= ONE_CODEWORD_SIZE) args->page_count = 1; else args->page_count = ops->len / mtd->writesize; } } Loading Loading @@ -1245,12 +1256,20 @@ static void msm_nand_update_rw_reg_data(struct msm_nand_chip *chip, struct msm_nand_rw_params *args, struct msm_nand_rw_reg_data *data) { /* * While reading one codeword, CW_PER_PAGE bits of QPIC_NAND_DEV0_CFG0 * should be set to 0, which implies 1 codeword per page. 'n' below, * is used to configure cfg0 for reading one full page or one single * codeword. */ int n = (ops->len <= ONE_CODEWORD_SIZE) ? args->cwperpage : 1; if (args->read) { if (ops->mode != MTD_OPS_RAW) { data->cmd = MSM_NAND_CMD_PAGE_READ_ECC; data->cfg0 = (chip->cfg0 & ~(7U << CW_PER_PAGE)) | (((args->cwperpage-1) - args->start_sector) (((args->cwperpage-n) - args->start_sector) << CW_PER_PAGE); data->cfg1 = chip->cfg1; data->ecc_bch_cfg = chip->ecc_bch_cfg; Loading @@ -1258,7 +1277,7 @@ static void msm_nand_update_rw_reg_data(struct msm_nand_chip *chip, data->cmd = MSM_NAND_CMD_PAGE_READ_ALL; data->cfg0 = (chip->cfg0_raw & ~(7U << CW_PER_PAGE)) | (((args->cwperpage-1) - args->start_sector) (((args->cwperpage-n) - args->start_sector) << CW_PER_PAGE); data->cfg1 = chip->cfg1_raw; data->ecc_bch_cfg = chip->ecc_cfg_raw; Loading Loading @@ -1302,6 +1321,11 @@ static void msm_nand_prep_rw_cmd_desc(struct mtd_oob_ops *ops, uint32_t offset, size, last_read; struct sps_command_element *curr_ce, *start_ce; uint32_t *flags_ptr, *num_ce_ptr; /* * Variable to configure read_location register parameters * while reading one codeword or one full page */ int n = (ops->len <= ONE_CODEWORD_SIZE) ? args->cwperpage : 1; if (curr_cw == args->start_sector) { curr_ce = start_ce = &cmd_list->setup_desc.ce[0]; Loading Loading @@ -1394,10 +1418,15 @@ static void msm_nand_prep_rw_cmd_desc(struct mtd_oob_ops *ops, if (ops->mode == MTD_OPS_AUTO_OOB) { if (ops->datbuf) { offset = 0; if (ops->len <= ONE_CODEWORD_SIZE) { size = ONE_CODEWORD_SIZE; last_read = 1; } else { size = (curr_cw < (args->cwperpage - 1)) ? 516 : (512 - ((args->cwperpage - 1) << 2)); last_read = (curr_cw < (args->cwperpage - 1)) ? 1 : (ops->oobbuf ? 0 : 1); last_read = (curr_cw < (args->cwperpage - 1)) ? 1 : (ops->oobbuf ? 0 : 1); } rdata = (offset << 0) | (size << 16) | (last_read << 31); Loading @@ -1413,7 +1442,7 @@ static void msm_nand_prep_rw_cmd_desc(struct mtd_oob_ops *ops, curr_ce++; } } if (curr_cw == (args->cwperpage - 1) && ops->oobbuf) { if (curr_cw == (args->cwperpage - n) && ops->oobbuf) { offset = 512 - ((args->cwperpage - 1) << 2); size = (args->cwperpage) << 2; if (size > args->oob_len_cmd) Loading Loading @@ -1471,6 +1500,11 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, uint32_t sectordatasize, sectoroobsize; uint32_t sps_flags = 0; int err = 0; /* * Variable to configure sectordatasize and sectoroobsize * while reading one codeword or one full page. */ int n = (ops->len <= ONE_CODEWORD_SIZE) ? args->cwperpage : 1; if (args->read) data_pipe_handle = info->sps.data_prod.handle; Loading @@ -1479,7 +1513,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, if (ops->mode == MTD_OPS_RAW) { if (ecc_parity_bytes && args->read) { if (curr_cw == (args->cwperpage - 1)) if (curr_cw == (args->cwperpage - n)) sps_flags |= SPS_IOVEC_FLAG_INT; /* read only ecc bytes */ Loading @@ -1494,7 +1528,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, sectordatasize = chip->cw_size; if (!args->read) sps_flags = SPS_IOVEC_FLAG_EOT; if (curr_cw == (args->cwperpage - 1)) if (curr_cw == (args->cwperpage - n)) sps_flags |= SPS_IOVEC_FLAG_INT; err = sps_transfer_one(data_pipe_handle, Loading @@ -1507,8 +1541,13 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, } } else if (ops->mode == MTD_OPS_AUTO_OOB) { if (ops->datbuf) { sectordatasize = (curr_cw < (args->cwperpage - 1)) ? 516 : (512 - ((args->cwperpage - 1) << 2)); if (ops->len <= ONE_CODEWORD_SIZE) sectordatasize = ONE_CODEWORD_SIZE; else sectordatasize = (curr_cw < (args->cwperpage - 1)) ? 516 : (512 - ((args->cwperpage - 1) << 2)); if (!args->read) { sps_flags = SPS_IOVEC_FLAG_EOT; Loading @@ -1516,7 +1555,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, ops->oobbuf) sps_flags = 0; } if ((curr_cw == (args->cwperpage - 1)) && !ops->oobbuf) if ((curr_cw == (args->cwperpage - n)) && !ops->oobbuf) sps_flags |= SPS_IOVEC_FLAG_INT; err = sps_transfer_one(data_pipe_handle, Loading @@ -1528,7 +1567,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, args->data_dma_addr_curr += sectordatasize; } if (ops->oobbuf && (curr_cw == (args->cwperpage - 1))) { if (ops->oobbuf && (curr_cw == (args->cwperpage - n))) { sectoroobsize = args->cwperpage << 2; if (sectoroobsize > args->oob_len_data) sectoroobsize = args->oob_len_data; Loading Loading @@ -2757,6 +2796,9 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, data.addr0 = (rw_params.page << 16) | rw_params.oob_col; data.addr1 = (rw_params.page >> 16) & 0xff; if (ops->len <= ONE_CODEWORD_SIZE) cwperpage = 1; for (n = rw_params.start_sector; n < cwperpage; n++) { struct sps_command_element *curr_ce, *start_ce; Loading Loading @@ -3054,6 +3096,9 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, } validate_mtd_params_failed: if (ops->mode != MTD_OPS_RAW) if (ops->len <= ONE_CODEWORD_SIZE) ops->retlen = ONE_CODEWORD_SIZE; else ops->retlen = mtd->writesize * pages_read; else ops->retlen = (mtd->writesize + mtd->oobsize) * pages_read; Loading Loading @@ -3127,8 +3172,11 @@ static int msm_nand_read_partial_page(struct mtd_info *mtd, ops->datbuf = no_copy ? actual_buf : bounce_buf; if (info->nand_chip.caps & MSM_NAND_CAP_PAGE_SCOPE_READ) err = msm_nand_read_pagescope(mtd, aligned_from, ops); else else { if ((len <= ONE_CODEWORD_SIZE) && (offset == 0)) ops->len = ONE_CODEWORD_SIZE; err = msm_nand_read_oob(mtd, aligned_from, ops); } if (err == -EUCLEAN) { is_euclean = 1; err = 0; Loading Loading
drivers/mtd/devices/msm_qpic_nand.c +67 −19 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ #define MAX_DESC 16 #define SMEM_AARM_PARTITION_TABLE 9 #define SMEM_APPS 0 #define ONE_CODEWORD_SIZE 516 static bool enable_euclean; static bool enable_perfstats; Loading Loading @@ -1183,10 +1185,16 @@ static int msm_nand_validate_mtd_params(struct mtd_info *mtd, bool read, err = -EINVAL; goto out; } args->page_count = ops->len / (mtd->writesize + mtd->oobsize); if (ops->len <= ONE_CODEWORD_SIZE) args->page_count = 1; else args->page_count = ops->len / (mtd->writesize + mtd->oobsize); } else if (ops->mode == MTD_OPS_AUTO_OOB) { if (ops->datbuf && (ops->len % mtd->writesize) != 0) { if (ops->datbuf && (ops->len % ((ops->len <= ONE_CODEWORD_SIZE) ? ONE_CODEWORD_SIZE : mtd->writesize)) != 0) { /* when ops->datbuf is NULL, ops->len can be ooblen */ pr_err("unsupported data len %d for AUTO mode\n", ops->len); Loading @@ -1199,6 +1207,9 @@ static int msm_nand_validate_mtd_params(struct mtd_info *mtd, bool read, if ((args->page_count == 0) && (ops->ooblen)) args->page_count = 1; } else if (ops->datbuf) { if (ops->len <= ONE_CODEWORD_SIZE) args->page_count = 1; else args->page_count = ops->len / mtd->writesize; } } Loading Loading @@ -1245,12 +1256,20 @@ static void msm_nand_update_rw_reg_data(struct msm_nand_chip *chip, struct msm_nand_rw_params *args, struct msm_nand_rw_reg_data *data) { /* * While reading one codeword, CW_PER_PAGE bits of QPIC_NAND_DEV0_CFG0 * should be set to 0, which implies 1 codeword per page. 'n' below, * is used to configure cfg0 for reading one full page or one single * codeword. */ int n = (ops->len <= ONE_CODEWORD_SIZE) ? args->cwperpage : 1; if (args->read) { if (ops->mode != MTD_OPS_RAW) { data->cmd = MSM_NAND_CMD_PAGE_READ_ECC; data->cfg0 = (chip->cfg0 & ~(7U << CW_PER_PAGE)) | (((args->cwperpage-1) - args->start_sector) (((args->cwperpage-n) - args->start_sector) << CW_PER_PAGE); data->cfg1 = chip->cfg1; data->ecc_bch_cfg = chip->ecc_bch_cfg; Loading @@ -1258,7 +1277,7 @@ static void msm_nand_update_rw_reg_data(struct msm_nand_chip *chip, data->cmd = MSM_NAND_CMD_PAGE_READ_ALL; data->cfg0 = (chip->cfg0_raw & ~(7U << CW_PER_PAGE)) | (((args->cwperpage-1) - args->start_sector) (((args->cwperpage-n) - args->start_sector) << CW_PER_PAGE); data->cfg1 = chip->cfg1_raw; data->ecc_bch_cfg = chip->ecc_cfg_raw; Loading Loading @@ -1302,6 +1321,11 @@ static void msm_nand_prep_rw_cmd_desc(struct mtd_oob_ops *ops, uint32_t offset, size, last_read; struct sps_command_element *curr_ce, *start_ce; uint32_t *flags_ptr, *num_ce_ptr; /* * Variable to configure read_location register parameters * while reading one codeword or one full page */ int n = (ops->len <= ONE_CODEWORD_SIZE) ? args->cwperpage : 1; if (curr_cw == args->start_sector) { curr_ce = start_ce = &cmd_list->setup_desc.ce[0]; Loading Loading @@ -1394,10 +1418,15 @@ static void msm_nand_prep_rw_cmd_desc(struct mtd_oob_ops *ops, if (ops->mode == MTD_OPS_AUTO_OOB) { if (ops->datbuf) { offset = 0; if (ops->len <= ONE_CODEWORD_SIZE) { size = ONE_CODEWORD_SIZE; last_read = 1; } else { size = (curr_cw < (args->cwperpage - 1)) ? 516 : (512 - ((args->cwperpage - 1) << 2)); last_read = (curr_cw < (args->cwperpage - 1)) ? 1 : (ops->oobbuf ? 0 : 1); last_read = (curr_cw < (args->cwperpage - 1)) ? 1 : (ops->oobbuf ? 0 : 1); } rdata = (offset << 0) | (size << 16) | (last_read << 31); Loading @@ -1413,7 +1442,7 @@ static void msm_nand_prep_rw_cmd_desc(struct mtd_oob_ops *ops, curr_ce++; } } if (curr_cw == (args->cwperpage - 1) && ops->oobbuf) { if (curr_cw == (args->cwperpage - n) && ops->oobbuf) { offset = 512 - ((args->cwperpage - 1) << 2); size = (args->cwperpage) << 2; if (size > args->oob_len_cmd) Loading Loading @@ -1471,6 +1500,11 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, uint32_t sectordatasize, sectoroobsize; uint32_t sps_flags = 0; int err = 0; /* * Variable to configure sectordatasize and sectoroobsize * while reading one codeword or one full page. */ int n = (ops->len <= ONE_CODEWORD_SIZE) ? args->cwperpage : 1; if (args->read) data_pipe_handle = info->sps.data_prod.handle; Loading @@ -1479,7 +1513,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, if (ops->mode == MTD_OPS_RAW) { if (ecc_parity_bytes && args->read) { if (curr_cw == (args->cwperpage - 1)) if (curr_cw == (args->cwperpage - n)) sps_flags |= SPS_IOVEC_FLAG_INT; /* read only ecc bytes */ Loading @@ -1494,7 +1528,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, sectordatasize = chip->cw_size; if (!args->read) sps_flags = SPS_IOVEC_FLAG_EOT; if (curr_cw == (args->cwperpage - 1)) if (curr_cw == (args->cwperpage - n)) sps_flags |= SPS_IOVEC_FLAG_INT; err = sps_transfer_one(data_pipe_handle, Loading @@ -1507,8 +1541,13 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, } } else if (ops->mode == MTD_OPS_AUTO_OOB) { if (ops->datbuf) { sectordatasize = (curr_cw < (args->cwperpage - 1)) ? 516 : (512 - ((args->cwperpage - 1) << 2)); if (ops->len <= ONE_CODEWORD_SIZE) sectordatasize = ONE_CODEWORD_SIZE; else sectordatasize = (curr_cw < (args->cwperpage - 1)) ? 516 : (512 - ((args->cwperpage - 1) << 2)); if (!args->read) { sps_flags = SPS_IOVEC_FLAG_EOT; Loading @@ -1516,7 +1555,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, ops->oobbuf) sps_flags = 0; } if ((curr_cw == (args->cwperpage - 1)) && !ops->oobbuf) if ((curr_cw == (args->cwperpage - n)) && !ops->oobbuf) sps_flags |= SPS_IOVEC_FLAG_INT; err = sps_transfer_one(data_pipe_handle, Loading @@ -1528,7 +1567,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops, args->data_dma_addr_curr += sectordatasize; } if (ops->oobbuf && (curr_cw == (args->cwperpage - 1))) { if (ops->oobbuf && (curr_cw == (args->cwperpage - n))) { sectoroobsize = args->cwperpage << 2; if (sectoroobsize > args->oob_len_data) sectoroobsize = args->oob_len_data; Loading Loading @@ -2757,6 +2796,9 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, data.addr0 = (rw_params.page << 16) | rw_params.oob_col; data.addr1 = (rw_params.page >> 16) & 0xff; if (ops->len <= ONE_CODEWORD_SIZE) cwperpage = 1; for (n = rw_params.start_sector; n < cwperpage; n++) { struct sps_command_element *curr_ce, *start_ce; Loading Loading @@ -3054,6 +3096,9 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, } validate_mtd_params_failed: if (ops->mode != MTD_OPS_RAW) if (ops->len <= ONE_CODEWORD_SIZE) ops->retlen = ONE_CODEWORD_SIZE; else ops->retlen = mtd->writesize * pages_read; else ops->retlen = (mtd->writesize + mtd->oobsize) * pages_read; Loading Loading @@ -3127,8 +3172,11 @@ static int msm_nand_read_partial_page(struct mtd_info *mtd, ops->datbuf = no_copy ? actual_buf : bounce_buf; if (info->nand_chip.caps & MSM_NAND_CAP_PAGE_SCOPE_READ) err = msm_nand_read_pagescope(mtd, aligned_from, ops); else else { if ((len <= ONE_CODEWORD_SIZE) && (offset == 0)) ops->len = ONE_CODEWORD_SIZE; err = msm_nand_read_oob(mtd, aligned_from, ops); } if (err == -EUCLEAN) { is_euclean = 1; err = 0; Loading