|
14 | 14 | /* Recommended to rewrite for BENAND */
|
15 | 15 | #define TOSHIBA_NAND_STATUS_REWRITE_RECOMMENDED BIT(3)
|
16 | 16 |
|
| 17 | +/* ECC Status Read Command for BENAND */ |
| 18 | +#define TOSHIBA_NAND_CMD_ECC_STATUS_READ 0x7A |
| 19 | + |
| 20 | +/* ECC Status Mask for BENAND */ |
| 21 | +#define TOSHIBA_NAND_ECC_STATUS_MASK 0x0F |
| 22 | + |
| 23 | +/* Uncorrectable Error for BENAND */ |
| 24 | +#define TOSHIBA_NAND_ECC_STATUS_UNCORR 0x0F |
| 25 | + |
| 26 | +/* Max ECC Steps for BENAND */ |
| 27 | +#define TOSHIBA_NAND_MAX_ECC_STEPS 8 |
| 28 | + |
| 29 | +static int toshiba_nand_benand_read_eccstatus_op(struct nand_chip *chip, |
| 30 | + u8 *buf) |
| 31 | +{ |
| 32 | + u8 *ecc_status = buf; |
| 33 | + |
| 34 | + if (nand_has_exec_op(chip)) { |
| 35 | + const struct nand_sdr_timings *sdr = |
| 36 | + nand_get_sdr_timings(&chip->data_interface); |
| 37 | + struct nand_op_instr instrs[] = { |
| 38 | + NAND_OP_CMD(TOSHIBA_NAND_CMD_ECC_STATUS_READ, |
| 39 | + PSEC_TO_NSEC(sdr->tADL_min)), |
| 40 | + NAND_OP_8BIT_DATA_IN(chip->ecc.steps, ecc_status, 0), |
| 41 | + }; |
| 42 | + struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs); |
| 43 | + |
| 44 | + return nand_exec_op(chip, &op); |
| 45 | + } |
| 46 | + |
| 47 | + return -ENOTSUPP; |
| 48 | +} |
| 49 | + |
17 | 50 | static int toshiba_nand_benand_eccstatus(struct nand_chip *chip)
|
18 | 51 | {
|
19 | 52 | struct mtd_info *mtd = nand_to_mtd(chip);
|
20 | 53 | int ret;
|
21 | 54 | unsigned int max_bitflips = 0;
|
22 |
| - u8 status; |
| 55 | + u8 status, ecc_status[TOSHIBA_NAND_MAX_ECC_STEPS]; |
23 | 56 |
|
24 | 57 | /* Check Status */
|
| 58 | + ret = toshiba_nand_benand_read_eccstatus_op(chip, ecc_status); |
| 59 | + if (!ret) { |
| 60 | + unsigned int i, bitflips = 0; |
| 61 | + |
| 62 | + for (i = 0; i < chip->ecc.steps; i++) { |
| 63 | + bitflips = ecc_status[i] & TOSHIBA_NAND_ECC_STATUS_MASK; |
| 64 | + if (bitflips == TOSHIBA_NAND_ECC_STATUS_UNCORR) { |
| 65 | + mtd->ecc_stats.failed++; |
| 66 | + } else { |
| 67 | + mtd->ecc_stats.corrected += bitflips; |
| 68 | + max_bitflips = max(max_bitflips, bitflips); |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + return max_bitflips; |
| 73 | + } |
| 74 | + |
| 75 | + /* |
| 76 | + * Fallback to regular status check if |
| 77 | + * toshiba_nand_benand_read_eccstatus_op() failed. |
| 78 | + */ |
25 | 79 | ret = nand_status_op(chip, &status);
|
26 | 80 | if (ret)
|
27 | 81 | return ret;
|
@@ -108,7 +162,7 @@ static void toshiba_nand_decode_id(struct nand_chip *chip)
|
108 | 162 | */
|
109 | 163 | if (chip->id.len >= 6 && nand_is_slc(chip) &&
|
110 | 164 | (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ &&
|
111 |
| - !(chip->id.data[4] & 0x80) /* !BENAND */) { |
| 165 | + !(chip->id.data[4] & TOSHIBA_NAND_ID4_IS_BENAND) /* !BENAND */) { |
112 | 166 | memorg->oobsize = 32 * memorg->pagesize >> 9;
|
113 | 167 | mtd->oobsize = memorg->oobsize;
|
114 | 168 | }
|
|
0 commit comments