mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 08:07:32 -04:00
Merge "mtd: msm_qpic_nand: Add support to read one codeword"
This commit is contained in:
commit
cc2c00539e
1 changed files with 66 additions and 19 deletions
|
|
@ -17,6 +17,7 @@
|
|||
#define MAX_DESC 16
|
||||
#define SMEM_AARM_PARTITION_TABLE 9
|
||||
#define SMEM_APPS 0
|
||||
#define ONE_CODEWORD_SIZE 516
|
||||
|
||||
/*
|
||||
* Get the DMA memory for requested amount of size. It returns the pointer
|
||||
|
|
@ -1076,10 +1077,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);
|
||||
|
|
@ -1092,7 +1099,10 @@ 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) {
|
||||
args->page_count = ops->len / mtd->writesize;
|
||||
if (ops->len <= ONE_CODEWORD_SIZE)
|
||||
args->page_count = 1;
|
||||
else
|
||||
args->page_count = ops->len / mtd->writesize;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1138,12 +1148,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;
|
||||
|
|
@ -1151,7 +1169,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;
|
||||
|
|
@ -1195,6 +1213,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];
|
||||
|
|
@ -1287,10 +1310,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;
|
||||
size = (curr_cw < (args->cwperpage - 1)) ? 516 :
|
||||
(512 - ((args->cwperpage - 1) << 2));
|
||||
last_read = (curr_cw < (args->cwperpage - 1)) ? 1 :
|
||||
(ops->oobbuf ? 0 : 1);
|
||||
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);
|
||||
}
|
||||
rdata = (offset << 0) | (size << 16) |
|
||||
(last_read << 31);
|
||||
|
||||
|
|
@ -1306,7 +1334,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)
|
||||
|
|
@ -1364,6 +1392,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;
|
||||
|
|
@ -1372,7 +1405,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 */
|
||||
|
|
@ -1387,7 +1420,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,
|
||||
|
|
@ -1400,8 +1433,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;
|
||||
|
|
@ -1409,7 +1447,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,
|
||||
|
|
@ -1421,7 +1459,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;
|
||||
|
|
@ -2590,6 +2628,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;
|
||||
|
||||
|
|
@ -2667,7 +2708,7 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from,
|
|||
} else if (ops->mode == MTD_OPS_AUTO_OOB) {
|
||||
if (ops->datbuf)
|
||||
submitted_num_desc = cwperpage -
|
||||
rw_params.start_sector;
|
||||
rw_params.start_sector;
|
||||
if (ops->oobbuf)
|
||||
submitted_num_desc++;
|
||||
}
|
||||
|
|
@ -2846,7 +2887,10 @@ free_dma:
|
|||
}
|
||||
validate_mtd_params_failed:
|
||||
if (ops->mode != MTD_OPS_RAW)
|
||||
ops->retlen = mtd->writesize * pages_read;
|
||||
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;
|
||||
ops->oobretlen = ops->ooblen - rw_params.oob_len_data;
|
||||
|
|
@ -2917,8 +2961,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…
Reference in a new issue