Commit 85632c17 authored by Abhishek Sahu's avatar Abhishek Sahu Committed by Miquel Raynal

mtd: rawnand: qcom: code reorganization for raw read

Make separate function to perform raw read for one codeword and
call this function multiple times for each codeword in case of
raw page read. This separate function will help in subsequent
patches related with erased codeword bitflip detection.

It will decrease throughput for raw page read. Raw page read
is used for debug purpose so it won't affect normal flash
operations.
Signed-off-by: default avatarAbhishek Sahu <absahu@codeaurora.org>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
parent 5bc36b2b
......@@ -1587,6 +1587,74 @@ static int check_flash_errors(struct qcom_nand_host *host, int cw_cnt)
return 0;
}
/* performs raw read for one codeword */
static int
qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
u8 *data_buf, u8 *oob_buf, int page, int cw)
{
struct qcom_nand_host *host = to_qcom_nand_host(chip);
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
struct nand_ecc_ctrl *ecc = &chip->ecc;
int data_size1, data_size2, oob_size1, oob_size2;
int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
nand_read_page_op(chip, page, 0, NULL, 0);
host->use_ecc = false;
clear_bam_transaction(nandc);
set_address(host, host->cw_size * cw, page);
update_rw_regs(host, 1, true);
config_nand_page_read(nandc);
data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
oob_size1 = host->bbm_size;
if (cw == (ecc->steps - 1)) {
data_size2 = ecc->size - data_size1 -
((ecc->steps - 1) * 4);
oob_size2 = (ecc->steps * 4) + host->ecc_bytes_hw +
host->spare_bytes;
} else {
data_size2 = host->cw_data - data_size1;
oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
}
if (nandc->props->is_bam) {
nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
read_loc += data_size1;
nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
read_loc += oob_size1;
nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
read_loc += data_size2;
nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
}
config_nand_cw_read(nandc, false);
read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
reg_off += data_size1;
read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0);
reg_off += oob_size1;
read_data_dma(nandc, reg_off, data_buf + data_size1, data_size2, 0);
reg_off += data_size2;
read_data_dma(nandc, reg_off, oob_buf + oob_size1, oob_size2, 0);
ret = submit_descs(nandc);
free_descs(nandc);
if (ret) {
dev_err(nandc->dev, "failure to read raw cw %d\n", cw);
return ret;
}
return check_flash_errors(host, 1);
}
/*
* reads back status registers set by the controller to notify page read
* errors. this is equivalent to what 'ecc->correct()' would do.
......@@ -1851,79 +1919,21 @@ static int qcom_nandc_read_page_raw(struct mtd_info *mtd,
int oob_required, int page)
{
struct qcom_nand_host *host = to_qcom_nand_host(chip);
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
u8 *data_buf, *oob_buf;
struct nand_ecc_ctrl *ecc = &chip->ecc;
int i, ret;
int read_loc;
int cw, ret;
u8 *data_buf = buf, *oob_buf = chip->oob_poi;
nand_read_page_op(chip, page, 0, NULL, 0);
data_buf = buf;
oob_buf = chip->oob_poi;
host->use_ecc = false;
clear_bam_transaction(nandc);
update_rw_regs(host, ecc->steps, true);
config_nand_page_read(nandc);
for (i = 0; i < ecc->steps; i++) {
int data_size1, data_size2, oob_size1, oob_size2;
int reg_off = FLASH_BUF_ACC;
data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
oob_size1 = host->bbm_size;
if (i == (ecc->steps - 1)) {
data_size2 = ecc->size - data_size1 -
((ecc->steps - 1) << 2);
oob_size2 = (ecc->steps << 2) + host->ecc_bytes_hw +
host->spare_bytes;
} else {
data_size2 = host->cw_data - data_size1;
oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
}
if (nandc->props->is_bam) {
read_loc = 0;
nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
read_loc += data_size1;
nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
read_loc += oob_size1;
nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
read_loc += data_size2;
nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
}
config_nand_cw_read(nandc, false);
read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
reg_off += data_size1;
data_buf += data_size1;
read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0);
reg_off += oob_size1;
oob_buf += oob_size1;
read_data_dma(nandc, reg_off, data_buf, data_size2, 0);
reg_off += data_size2;
data_buf += data_size2;
read_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
oob_buf += oob_size2;
}
ret = submit_descs(nandc);
free_descs(nandc);
if (ret) {
dev_err(nandc->dev, "failure to read raw page\n");
for (cw = 0; cw < ecc->steps; cw++) {
ret = qcom_nandc_read_cw_raw(mtd, chip, data_buf, oob_buf,
page, cw);
if (ret)
return ret;
data_buf += host->cw_data;
oob_buf += ecc->bytes;
}
return check_flash_errors(host, ecc->steps);
return 0;
}
/* implements ecc->read_oob() */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment