Commit b451f5be authored by Miquel Raynal's avatar Miquel Raynal

mtd: rawnand: Give the possibility to verify a read operation is supported

This can be used to discriminate between two path in the parameter
page detection: use data_in cycles (like before) if supported, use the
CHANGE READ COLUMN command otherwise.
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Link: https://lore.kernel.org/linux-mtd/20200507105241.14299-9-miquel.raynal@bootlin.com
parent 93037025
...@@ -694,7 +694,7 @@ static int fsmc_read_page_hwecc(struct nand_chip *chip, u8 *buf, ...@@ -694,7 +694,7 @@ static int fsmc_read_page_hwecc(struct nand_chip *chip, u8 *buf,
for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) { for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
nand_read_page_op(chip, page, s * eccsize, NULL, 0); nand_read_page_op(chip, page, s * eccsize, NULL, 0);
chip->ecc.hwctl(chip, NAND_ECC_READ); chip->ecc.hwctl(chip, NAND_ECC_READ);
ret = nand_read_data_op(chip, p, eccsize, false); ret = nand_read_data_op(chip, p, eccsize, false, false);
if (ret) if (ret)
return ret; return ret;
......
...@@ -1224,12 +1224,12 @@ static int marvell_nfc_hw_ecc_bch_read_page_raw(struct nand_chip *chip, u8 *buf, ...@@ -1224,12 +1224,12 @@ static int marvell_nfc_hw_ecc_bch_read_page_raw(struct nand_chip *chip, u8 *buf,
/* Read spare bytes */ /* Read spare bytes */
nand_read_data_op(chip, oob + (lt->spare_bytes * chunk), nand_read_data_op(chip, oob + (lt->spare_bytes * chunk),
spare_len, false); spare_len, false, false);
/* Read ECC bytes */ /* Read ECC bytes */
nand_read_data_op(chip, oob + ecc_offset + nand_read_data_op(chip, oob + ecc_offset +
(ALIGN(lt->ecc_bytes, 32) * chunk), (ALIGN(lt->ecc_bytes, 32) * chunk),
ecc_len, false); ecc_len, false, false);
} }
return 0; return 0;
......
...@@ -740,7 +740,8 @@ int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms) ...@@ -740,7 +740,8 @@ int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms)
*/ */
timeout_ms = jiffies + msecs_to_jiffies(timeout_ms) + 1; timeout_ms = jiffies + msecs_to_jiffies(timeout_ms) + 1;
do { do {
ret = nand_read_data_op(chip, &status, sizeof(status), true); ret = nand_read_data_op(chip, &status, sizeof(status), true,
false);
if (ret) if (ret)
break; break;
...@@ -820,7 +821,7 @@ void panic_nand_wait(struct nand_chip *chip, unsigned long timeo) ...@@ -820,7 +821,7 @@ void panic_nand_wait(struct nand_chip *chip, unsigned long timeo)
u8 status; u8 status;
ret = nand_read_data_op(chip, &status, sizeof(status), ret = nand_read_data_op(chip, &status, sizeof(status),
true); true, false);
if (ret) if (ret)
return; return;
...@@ -1918,6 +1919,8 @@ EXPORT_SYMBOL_GPL(nand_reset_op); ...@@ -1918,6 +1919,8 @@ EXPORT_SYMBOL_GPL(nand_reset_op);
* @buf: buffer used to store the data * @buf: buffer used to store the data
* @len: length of the buffer * @len: length of the buffer
* @force_8bit: force 8-bit bus access * @force_8bit: force 8-bit bus access
* @check_only: do not actually run the command, only checks if the
* controller driver supports it
* *
* This function does a raw data read on the bus. Usually used after launching * This function does a raw data read on the bus. Usually used after launching
* another NAND operation like nand_read_page_op(). * another NAND operation like nand_read_page_op().
...@@ -1926,7 +1929,7 @@ EXPORT_SYMBOL_GPL(nand_reset_op); ...@@ -1926,7 +1929,7 @@ EXPORT_SYMBOL_GPL(nand_reset_op);
* Returns 0 on success, a negative error code otherwise. * Returns 0 on success, a negative error code otherwise.
*/ */
int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
bool force_8bit) bool force_8bit, bool check_only)
{ {
if (!len || !buf) if (!len || !buf)
return -EINVAL; return -EINVAL;
...@@ -1939,9 +1942,15 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, ...@@ -1939,9 +1942,15 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
instrs[0].ctx.data.force_8bit = force_8bit; instrs[0].ctx.data.force_8bit = force_8bit;
if (check_only)
return nand_check_op(chip, &op);
return nand_exec_op(chip, &op); return nand_exec_op(chip, &op);
} }
if (check_only)
return 0;
if (force_8bit) { if (force_8bit) {
u8 *p = buf; u8 *p = buf;
unsigned int i; unsigned int i;
...@@ -2670,7 +2679,7 @@ int nand_read_page_raw(struct nand_chip *chip, uint8_t *buf, int oob_required, ...@@ -2670,7 +2679,7 @@ int nand_read_page_raw(struct nand_chip *chip, uint8_t *buf, int oob_required,
if (oob_required) { if (oob_required) {
ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
false); false, false);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -2702,7 +2711,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf, ...@@ -2702,7 +2711,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,
return ret; return ret;
for (steps = chip->ecc.steps; steps > 0; steps--) { for (steps = chip->ecc.steps; steps > 0; steps--) {
ret = nand_read_data_op(chip, buf, eccsize, false); ret = nand_read_data_op(chip, buf, eccsize, false, false);
if (ret) if (ret)
return ret; return ret;
...@@ -2710,14 +2719,14 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf, ...@@ -2710,14 +2719,14 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,
if (chip->ecc.prepad) { if (chip->ecc.prepad) {
ret = nand_read_data_op(chip, oob, chip->ecc.prepad, ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
false); false, false);
if (ret) if (ret)
return ret; return ret;
oob += chip->ecc.prepad; oob += chip->ecc.prepad;
} }
ret = nand_read_data_op(chip, oob, eccbytes, false); ret = nand_read_data_op(chip, oob, eccbytes, false, false);
if (ret) if (ret)
return ret; return ret;
...@@ -2725,7 +2734,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf, ...@@ -2725,7 +2734,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,
if (chip->ecc.postpad) { if (chip->ecc.postpad) {
ret = nand_read_data_op(chip, oob, chip->ecc.postpad, ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
false); false, false);
if (ret) if (ret)
return ret; return ret;
...@@ -2735,7 +2744,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf, ...@@ -2735,7 +2744,7 @@ static int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf,
size = mtd->oobsize - (oob - chip->oob_poi); size = mtd->oobsize - (oob - chip->oob_poi);
if (size) { if (size) {
ret = nand_read_data_op(chip, oob, size, false); ret = nand_read_data_op(chip, oob, size, false, false);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -2928,14 +2937,15 @@ static int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf, ...@@ -2928,14 +2937,15 @@ static int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf,
for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
chip->ecc.hwctl(chip, NAND_ECC_READ); chip->ecc.hwctl(chip, NAND_ECC_READ);
ret = nand_read_data_op(chip, p, eccsize, false); ret = nand_read_data_op(chip, p, eccsize, false, false);
if (ret) if (ret)
return ret; return ret;
chip->ecc.calculate(chip, p, &ecc_calc[i]); chip->ecc.calculate(chip, p, &ecc_calc[i]);
} }
ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false); ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false,
false);
if (ret) if (ret)
return ret; return ret;
...@@ -3014,7 +3024,7 @@ static int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf, ...@@ -3014,7 +3024,7 @@ static int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf,
chip->ecc.hwctl(chip, NAND_ECC_READ); chip->ecc.hwctl(chip, NAND_ECC_READ);
ret = nand_read_data_op(chip, p, eccsize, false); ret = nand_read_data_op(chip, p, eccsize, false, false);
if (ret) if (ret)
return ret; return ret;
...@@ -3071,13 +3081,13 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf, ...@@ -3071,13 +3081,13 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,
chip->ecc.hwctl(chip, NAND_ECC_READ); chip->ecc.hwctl(chip, NAND_ECC_READ);
ret = nand_read_data_op(chip, p, eccsize, false); ret = nand_read_data_op(chip, p, eccsize, false, false);
if (ret) if (ret)
return ret; return ret;
if (chip->ecc.prepad) { if (chip->ecc.prepad) {
ret = nand_read_data_op(chip, oob, chip->ecc.prepad, ret = nand_read_data_op(chip, oob, chip->ecc.prepad,
false); false, false);
if (ret) if (ret)
return ret; return ret;
...@@ -3086,7 +3096,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf, ...@@ -3086,7 +3096,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,
chip->ecc.hwctl(chip, NAND_ECC_READSYN); chip->ecc.hwctl(chip, NAND_ECC_READSYN);
ret = nand_read_data_op(chip, oob, eccbytes, false); ret = nand_read_data_op(chip, oob, eccbytes, false, false);
if (ret) if (ret)
return ret; return ret;
...@@ -3096,7 +3106,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf, ...@@ -3096,7 +3106,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,
if (chip->ecc.postpad) { if (chip->ecc.postpad) {
ret = nand_read_data_op(chip, oob, chip->ecc.postpad, ret = nand_read_data_op(chip, oob, chip->ecc.postpad,
false); false, false);
if (ret) if (ret)
return ret; return ret;
...@@ -3124,7 +3134,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf, ...@@ -3124,7 +3134,7 @@ static int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf,
/* Calculate remaining oob bytes */ /* Calculate remaining oob bytes */
i = mtd->oobsize - (oob - chip->oob_poi); i = mtd->oobsize - (oob - chip->oob_poi);
if (i) { if (i) {
ret = nand_read_data_op(chip, oob, i, false); ret = nand_read_data_op(chip, oob, i, false, false);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -3426,7 +3436,7 @@ static int nand_read_oob_syndrome(struct nand_chip *chip, int page) ...@@ -3426,7 +3436,7 @@ static int nand_read_oob_syndrome(struct nand_chip *chip, int page)
sndrnd = 1; sndrnd = 1;
toread = min_t(int, length, chunk); toread = min_t(int, length, chunk);
ret = nand_read_data_op(chip, bufpoi, toread, false); ret = nand_read_data_op(chip, bufpoi, toread, false, false);
if (ret) if (ret)
return ret; return ret;
...@@ -3434,7 +3444,7 @@ static int nand_read_oob_syndrome(struct nand_chip *chip, int page) ...@@ -3434,7 +3444,7 @@ static int nand_read_oob_syndrome(struct nand_chip *chip, int page)
length -= toread; length -= toread;
} }
if (length > 0) { if (length > 0) {
ret = nand_read_data_op(chip, bufpoi, length, false); ret = nand_read_data_op(chip, bufpoi, length, false, false);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -51,7 +51,7 @@ int nand_jedec_detect(struct nand_chip *chip) ...@@ -51,7 +51,7 @@ int nand_jedec_detect(struct nand_chip *chip)
} }
for (i = 0; i < JEDEC_PARAM_PAGES; i++) { for (i = 0; i < JEDEC_PARAM_PAGES; i++) {
ret = nand_read_data_op(chip, p, sizeof(*p), true); ret = nand_read_data_op(chip, p, sizeof(*p), true, false);
if (ret) { if (ret) {
ret = 0; ret = 0;
goto free_jedec_param_page; goto free_jedec_param_page;
......
...@@ -225,7 +225,8 @@ static void nand_wait_status_ready(struct nand_chip *chip, unsigned long timeo) ...@@ -225,7 +225,8 @@ static void nand_wait_status_ready(struct nand_chip *chip, unsigned long timeo)
do { do {
u8 status; u8 status;
ret = nand_read_data_op(chip, &status, sizeof(status), true); ret = nand_read_data_op(chip, &status, sizeof(status), true,
false);
if (ret) if (ret)
return; return;
...@@ -552,7 +553,8 @@ static int nand_wait(struct nand_chip *chip) ...@@ -552,7 +553,8 @@ static int nand_wait(struct nand_chip *chip)
break; break;
} else { } else {
ret = nand_read_data_op(chip, &status, ret = nand_read_data_op(chip, &status,
sizeof(status), true); sizeof(status), true,
false);
if (ret) if (ret)
return ret; return ret;
...@@ -563,7 +565,7 @@ static int nand_wait(struct nand_chip *chip) ...@@ -563,7 +565,7 @@ static int nand_wait(struct nand_chip *chip)
} while (time_before(jiffies, timeo)); } while (time_before(jiffies, timeo));
} }
ret = nand_read_data_op(chip, &status, sizeof(status), true); ret = nand_read_data_op(chip, &status, sizeof(status), true, false);
if (ret) if (ret)
return ret; return ret;
......
...@@ -212,7 +212,7 @@ static int micron_nand_on_die_ecc_status_4(struct nand_chip *chip, u8 status, ...@@ -212,7 +212,7 @@ static int micron_nand_on_die_ecc_status_4(struct nand_chip *chip, u8 status,
*/ */
if (!oob_required) { if (!oob_required) {
ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
false); false, false);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -304,10 +304,10 @@ micron_nand_read_page_on_die_ecc(struct nand_chip *chip, uint8_t *buf, ...@@ -304,10 +304,10 @@ micron_nand_read_page_on_die_ecc(struct nand_chip *chip, uint8_t *buf,
if (ret) if (ret)
goto out; goto out;
ret = nand_read_data_op(chip, buf, mtd->writesize, false); ret = nand_read_data_op(chip, buf, mtd->writesize, false, false);
if (!ret && oob_required) if (!ret && oob_required)
ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize,
false); false, false);
if (chip->ecc.strength == 4) if (chip->ecc.strength == 4)
max_bitflips = micron_nand_on_die_ecc_status_4(chip, status, max_bitflips = micron_nand_on_die_ecc_status_4(chip, status,
......
...@@ -167,7 +167,8 @@ int nand_onfi_detect(struct nand_chip *chip) ...@@ -167,7 +167,8 @@ int nand_onfi_detect(struct nand_chip *chip)
} }
for (i = 0; i < ONFI_PARAM_PAGES; i++) { for (i = 0; i < ONFI_PARAM_PAGES; i++) {
ret = nand_read_data_op(chip, &pbuf[i], sizeof(*pbuf), true); ret = nand_read_data_op(chip, &pbuf[i], sizeof(*pbuf), true,
false);
if (ret) { if (ret) {
ret = 0; ret = 0;
goto free_onfi_param_page; goto free_onfi_param_page;
......
...@@ -1363,7 +1363,7 @@ int nand_change_write_column_op(struct nand_chip *chip, ...@@ -1363,7 +1363,7 @@ int nand_change_write_column_op(struct nand_chip *chip,
unsigned int offset_in_page, const void *buf, unsigned int offset_in_page, const void *buf,
unsigned int len, bool force_8bit); unsigned int len, bool force_8bit);
int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
bool force_8bit); bool force_8bit, bool check_only);
int nand_write_data_op(struct nand_chip *chip, const void *buf, int nand_write_data_op(struct nand_chip *chip, const void *buf,
unsigned int len, bool force_8bit); unsigned int len, bool force_8bit);
......
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