* [PATCH 0/8] MLC in SLC mode @ 2019-12-30 16:51 Miquel Raynal 2019-12-30 16:51 ` [PATCH 1/8] mtd: rawnand: toshiba: Add a specific init for TC58TEG5DCLTA00 Miquel Raynal ` (7 more replies) 0 siblings, 8 replies; 18+ messages in thread From: Miquel Raynal @ 2019-12-30 16:51 UTC (permalink / raw) To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Thomas Petazzoni, Miquel Raynal Hello, This series has been lying since a long time in Boris tree, it is clean enough to be upstreamed now. This work is based on the "MTD partition handling rework" patch. It basically allows to work "safely" with MLC NANDs, details inside. Cheers, Miquèl Boris Brezillon (8): mtd: rawnand: toshiba: Add a specific init for TC58TEG5DCLTA00 mtd: rawnand: Define the "distance 3" MLC pairing scheme mtd: rawnand: toshiba: Set the pairing scheme for TC58TEG5DCLTA00 mtd: Add support for emulated SLC mode on MLC NANDs dt-bindings: mtd: partition: Document the slc-mode property mtd: partitions: ofpart: Parse the slc-mode property mtd: cmdlinepart: Add an slc option to use SLC mode on a part ubi: Relax the 'no MLC' rule and allow MLCs operating in SLC mode .../devicetree/bindings/mtd/partition.txt | 3 + drivers/mtd/mtdcore.c | 189 ++++++++++++++++-- drivers/mtd/mtdpart.c | 54 ++--- drivers/mtd/nand/raw/internals.h | 3 + drivers/mtd/nand/raw/nand_base.c | 50 +++++ drivers/mtd/nand/raw/nand_toshiba.c | 14 ++ drivers/mtd/parsers/cmdlinepart.c | 12 +- drivers/mtd/parsers/ofpart.c | 3 + drivers/mtd/ubi/build.c | 5 +- include/linux/mtd/mtd.h | 7 +- include/linux/mtd/partitions.h | 2 + include/uapi/mtd/mtd-abi.h | 1 + scripts/pnmtologo | Bin 0 -> 22416 bytes 13 files changed, 300 insertions(+), 43 deletions(-) create mode 100755 scripts/pnmtologo -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/8] mtd: rawnand: toshiba: Add a specific init for TC58TEG5DCLTA00 2019-12-30 16:51 [PATCH 0/8] MLC in SLC mode Miquel Raynal @ 2019-12-30 16:51 ` Miquel Raynal 2019-12-30 16:51 ` [PATCH 2/8] mtd: rawnand: Define the "distance 3" MLC pairing scheme Miquel Raynal ` (6 subsequent siblings) 7 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2019-12-30 16:51 UTC (permalink / raw) To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Boris Brezillon, Thomas Petazzoni, Miquel Raynal From: Boris Brezillon <boris.brezillon@bootlin.com> TC58TEG5DCLTA00 is an MLC NAND which requires scrambling and supports SDR timings mode 5. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- drivers/mtd/nand/raw/nand_toshiba.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index 9c03fbb1f47d..9114b96880d7 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -140,6 +140,14 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) } } +static int tc58teg5dclta00_init(struct nand_chip *chip) +{ + chip->onfi_timing_mode_default = 5; + chip->options |= NAND_NEED_SCRAMBLING; + + return 0; +} + static int toshiba_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) @@ -150,6 +158,9 @@ static int toshiba_nand_init(struct nand_chip *chip) chip->id.data[4] & TOSHIBA_NAND_ID4_IS_BENAND) toshiba_nand_benand_init(chip); + if (!strcmp("TC58TEG5DCLTA00", chip->parameters.model)) + tc58teg5dclta00_init(chip); + return 0; } -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 2/8] mtd: rawnand: Define the "distance 3" MLC pairing scheme 2019-12-30 16:51 [PATCH 0/8] MLC in SLC mode Miquel Raynal 2019-12-30 16:51 ` [PATCH 1/8] mtd: rawnand: toshiba: Add a specific init for TC58TEG5DCLTA00 Miquel Raynal @ 2019-12-30 16:51 ` Miquel Raynal 2019-12-30 16:51 ` [PATCH 3/8] mtd: rawnand: toshiba: Set the pairing scheme for TC58TEG5DCLTA00 Miquel Raynal ` (5 subsequent siblings) 7 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2019-12-30 16:51 UTC (permalink / raw) To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Boris Brezillon, Thomas Petazzoni, Miquel Raynal From: Boris Brezillon <boris.brezillon@bootlin.com> Define a new page pairing scheme for MLC NANDs with a distance of 3 pages between the lower and upper page. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- drivers/mtd/nand/raw/internals.h | 3 ++ drivers/mtd/nand/raw/nand_base.c | 50 ++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index cba6fe7dd8c4..8f6fdda681cc 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h @@ -74,6 +74,9 @@ extern const struct nand_manufacturer_ops micron_nand_manuf_ops; extern const struct nand_manufacturer_ops samsung_nand_manuf_ops; extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops; +/* MLC pairing schemes */ +extern const struct mtd_pairing_scheme dist3_pairing_scheme; + /* Core functions */ const struct nand_manufacturer *nand_get_manufacturer(u8 id); int nand_bbm_get_next_page(struct nand_chip *chip, int page); diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index f64e3b6605c6..a471f5714cd6 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -205,6 +205,56 @@ static const struct mtd_ooblayout_ops nand_ooblayout_lp_hamming_ops = { .free = nand_ooblayout_free_lp_hamming, }; +static int nand_pairing_dist3_get_info(struct mtd_info *mtd, int page, + struct mtd_pairing_info *info) +{ + int lastpage = (mtd->erasesize / mtd->writesize) - 1; + int dist = 3; + + if (page == lastpage) + dist = 2; + + if (!page || (page & 1)) { + info->group = 0; + info->pair = (page + 1) / 2; + } else { + info->group = 1; + info->pair = (page + 1 - dist) / 2; + } + + return 0; +} + +static int nand_pairing_dist3_get_wunit(struct mtd_info *mtd, + const struct mtd_pairing_info *info) +{ + int lastpair = ((mtd->erasesize / mtd->writesize) - 1) / 2; + int page = info->pair * 2; + int dist = 3; + + if (!info->group && !info->pair) + return 0; + + if (info->pair == lastpair && info->group) + dist = 2; + + if (!info->group) + page--; + else if (info->pair) + page += dist - 1; + + if (page >= mtd->erasesize / mtd->writesize) + return -EINVAL; + + return page; +} + +const struct mtd_pairing_scheme dist3_pairing_scheme = { + .ngroups = 2, + .get_info = nand_pairing_dist3_get_info, + .get_wunit = nand_pairing_dist3_get_wunit, +}; + static int check_offs_len(struct nand_chip *chip, loff_t ofs, uint64_t len) { int ret = 0; -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 3/8] mtd: rawnand: toshiba: Set the pairing scheme for TC58TEG5DCLTA00 2019-12-30 16:51 [PATCH 0/8] MLC in SLC mode Miquel Raynal 2019-12-30 16:51 ` [PATCH 1/8] mtd: rawnand: toshiba: Add a specific init for TC58TEG5DCLTA00 Miquel Raynal 2019-12-30 16:51 ` [PATCH 2/8] mtd: rawnand: Define the "distance 3" MLC pairing scheme Miquel Raynal @ 2019-12-30 16:51 ` Miquel Raynal 2019-12-30 16:51 ` [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs Miquel Raynal ` (4 subsequent siblings) 7 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2019-12-30 16:51 UTC (permalink / raw) To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Boris Brezillon, Thomas Petazzoni, Miquel Raynal From: Boris Brezillon <boris.brezillon@bootlin.com> TC58TEG5DCLTA00 uses a stride of 3 between its lower and upper page. Set the appropriate pairing scheme at init time. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- drivers/mtd/nand/raw/nand_toshiba.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index 9114b96880d7..ed758ff80080 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -142,8 +142,11 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) static int tc58teg5dclta00_init(struct nand_chip *chip) { + struct mtd_info *mtd = nand_to_mtd(chip); + chip->onfi_timing_mode_default = 5; chip->options |= NAND_NEED_SCRAMBLING; + mtd_set_pairing_scheme(mtd, &dist3_pairing_scheme); return 0; } -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs 2019-12-30 16:51 [PATCH 0/8] MLC in SLC mode Miquel Raynal ` (2 preceding siblings ...) 2019-12-30 16:51 ` [PATCH 3/8] mtd: rawnand: toshiba: Set the pairing scheme for TC58TEG5DCLTA00 Miquel Raynal @ 2019-12-30 16:51 ` Miquel Raynal 2020-01-08 23:49 ` Richard Weinberger 2019-12-30 16:51 ` [PATCH 5/8] dt-bindings: mtd: partition: Document the slc-mode property Miquel Raynal ` (3 subsequent siblings) 7 siblings, 1 reply; 18+ messages in thread From: Miquel Raynal @ 2019-12-30 16:51 UTC (permalink / raw) To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Boris Brezillon, Thomas Petazzoni, Miquel Raynal From: Boris Brezillon <boris.brezillon@bootlin.com> MLC NANDs can be made a bit more reliable if we only program the lower page of each pair. At least, this solves the paired-pages corruption issue. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- drivers/mtd/mtdcore.c | 189 ++++++++++++++++++++++++++++++--- drivers/mtd/mtdpart.c | 54 ++++++---- include/linux/mtd/mtd.h | 7 +- include/linux/mtd/partitions.h | 2 + include/uapi/mtd/mtd-abi.h | 1 + 5 files changed, 213 insertions(+), 40 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 2916674208b3..de0a692ecb29 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -617,6 +617,19 @@ int add_mtd_device(struct mtd_info *mtd) !(mtd->flags & MTD_NO_ERASE))) return -EINVAL; + /* + * MTD_MLC_IN_SLC_MODE can only be set on partitions, when the master + * is an MLC NAND and has a proper pairing scheme defined. + * We also reject masters that implement ->_writev() for now, because + * NAND controller drivers don't implement this hook, and adding the + * SLC -> MLC address/length conversion to this path is useless if we + * don't have a user. + */ + if (mtd->flags & MTD_MLC_IN_SLC_MODE && + (!mtd_is_partition(mtd) || master->type != MTD_MLCNANDFLASH || + !master->pairing || master->_writev)) + return -EINVAL; + mutex_lock(&mtd_table_mutex); i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); @@ -632,6 +645,14 @@ int add_mtd_device(struct mtd_info *mtd) if (mtd->bitflip_threshold == 0) mtd->bitflip_threshold = mtd->ecc_strength; + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { + int ngroups = mtd_pairing_groups(master); + + mtd->erasesize /= ngroups; + mtd->size = (u64)mtd_div_by_eb(mtd->size, master) * + mtd->erasesize; + } + if (is_power_of_2(mtd->erasesize)) mtd->erasesize_shift = ffs(mtd->erasesize) - 1; else @@ -1074,9 +1095,11 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) { struct mtd_info *master = mtd_get_master(mtd); u64 mst_ofs = mtd_get_master_ofs(mtd, 0); + struct erase_info adjinstr; int ret; instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + adjinstr = *instr; if (!mtd->erasesize || !master->_erase) return -ENOTSUPP; @@ -1091,12 +1114,27 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) ledtrig_mtd_activity(); - instr->addr += mst_ofs; - ret = master->_erase(master, instr); - if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) - instr->fail_addr -= mst_ofs; + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { + adjinstr.addr = (loff_t)mtd_div_by_eb(instr->addr, mtd) * + master->erasesize; + adjinstr.len = ((u64)mtd_div_by_eb(instr->addr + instr->len, mtd) * + master->erasesize) - + adjinstr.addr; + } + + adjinstr.addr += mst_ofs; + + ret = master->_erase(master, &adjinstr); + + if (adjinstr.fail_addr != MTD_FAIL_ADDR_UNKNOWN) { + instr->fail_addr = adjinstr.fail_addr - mst_ofs; + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { + instr->fail_addr = mtd_div_by_eb(instr->fail_addr, + master); + instr->fail_addr *= mtd->erasesize; + } + } - instr->addr -= mst_ofs; return ret; } EXPORT_SYMBOL_GPL(mtd_erase); @@ -1276,6 +1314,101 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs, return 0; } +static int mtd_read_oob_std(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) +{ + struct mtd_info *master = mtd_get_master(mtd); + int ret; + + from = mtd_get_master_ofs(mtd, from); + if (master->_read_oob) + ret = master->_read_oob(master, from, ops); + else + ret = master->_read(master, from, ops->len, &ops->retlen, + ops->datbuf); + + return ret; +} + +static int mtd_write_oob_std(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) +{ + struct mtd_info *master = mtd_get_master(mtd); + int ret; + + to = mtd_get_master_ofs(mtd, to); + if (master->_write_oob) + ret = master->_write_oob(master, to, ops); + else + ret = master->_write(master, to, ops->len, &ops->retlen, + ops->datbuf); + + return ret; +} + +static int mtd_oob_io_slc(struct mtd_info *mtd, loff_t start, bool read, + struct mtd_oob_ops *ops) +{ + struct mtd_info *master = mtd_get_master(mtd); + int ngroups = mtd_pairing_groups(master); + int npairs = mtd_wunit_per_eb(master) / ngroups; + struct mtd_oob_ops adjops = *ops; + unsigned int wunit, oobavail; + struct mtd_pairing_info info; + int max_bitflips = 0; + u32 ebofs, pageofs; + loff_t base, pos; + + ebofs = mtd_mod_by_eb(start, mtd); + base = (loff_t)mtd_div_by_eb(start, mtd) * master->erasesize; + info.group = 0; + info.pair = mtd_div_by_ws(ebofs, mtd); + pageofs = mtd_mod_by_ws(ebofs, mtd); + oobavail = mtd_oobavail(mtd, ops); + + while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) { + int ret; + + if (info.pair >= npairs) { + info.pair = 0; + base += master->erasesize; + } + + wunit = mtd_pairing_info_to_wunit(master, &info); + pos = mtd_wunit_to_offset(mtd, base, wunit); + + adjops.len = ops->len - ops->retlen; + if (adjops.len > mtd->writesize - pageofs) + adjops.len = mtd->writesize - pageofs; + + adjops.ooblen = ops->ooblen - ops->oobretlen; + if (adjops.ooblen > oobavail - adjops.ooboffs) + adjops.ooblen = oobavail - adjops.ooboffs; + + if (read) { + ret = mtd_read_oob_std(mtd, pos + pageofs, &adjops); + if (ret > 0) + max_bitflips = max(max_bitflips, ret); + } else { + ret = mtd_write_oob_std(mtd, pos + pageofs, &adjops); + } + + if (ret < 0) + return ret; + + max_bitflips = max(max_bitflips, ret); + ops->retlen += adjops.retlen; + ops->oobretlen += adjops.oobretlen; + adjops.datbuf += adjops.retlen; + adjops.oobbuf += adjops.oobretlen; + adjops.ooboffs = 0; + pageofs = 0; + info.pair++; + } + + return max_bitflips; +} + int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { struct mtd_info *master = mtd_get_master(mtd); @@ -1294,12 +1427,10 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) if (!master->_read_oob && (!master->_read || ops->oobbuf)) return -EOPNOTSUPP; - from = mtd_get_master_ofs(mtd, from); - if (master->_read_oob) - ret_code = master->_read_oob(master, from, ops); + if (mtd->flags & MTD_MLC_IN_SLC_MODE) + ret_code = mtd_oob_io_slc(mtd, from, true, ops); else - ret_code = master->_read(master, from, ops->len, &ops->retlen, - ops->datbuf); + ret_code = mtd_read_oob_std(mtd, from, ops); mtd_update_ecc_stats(mtd, master, &old_stats); @@ -1338,13 +1469,10 @@ int mtd_write_oob(struct mtd_info *mtd, loff_t to, if (!master->_write_oob && (!master->_write || ops->oobbuf)) return -EOPNOTSUPP; - to = mtd_get_master_ofs(mtd, to); + if (mtd->flags & MTD_MLC_IN_SLC_MODE) + return mtd_oob_io_slc(mtd, to, false, ops); - if (master->_write_oob) - return master->_write_oob(master, to, ops); - else - return master->_write(master, to, ops->len, &ops->retlen, - ops->datbuf); + return mtd_write_oob_std(mtd, to, ops); } EXPORT_SYMBOL_GPL(mtd_write_oob); @@ -1817,6 +1945,12 @@ int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) return -EINVAL; if (!len) return 0; + + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { + ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; + len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize; + } + return master->_lock(master, mtd_get_master_ofs(mtd, ofs), len); } EXPORT_SYMBOL_GPL(mtd_lock); @@ -1831,6 +1965,12 @@ int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) return -EINVAL; if (!len) return 0; + + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { + ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; + len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize; + } + return master->_unlock(master, mtd_get_master_ofs(mtd, ofs), len); } EXPORT_SYMBOL_GPL(mtd_unlock); @@ -1845,6 +1985,12 @@ int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) return -EINVAL; if (!len) return 0; + + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { + ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; + len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize; + } + return master->_is_locked(master, mtd_get_master_ofs(mtd, ofs), len); } EXPORT_SYMBOL_GPL(mtd_is_locked); @@ -1857,6 +2003,10 @@ int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs) return -EINVAL; if (!master->_block_isreserved) return 0; + + if (mtd->flags & MTD_MLC_IN_SLC_MODE) + ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; + return master->_block_isreserved(master, mtd_get_master_ofs(mtd, ofs)); } EXPORT_SYMBOL_GPL(mtd_block_isreserved); @@ -1869,6 +2019,10 @@ int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) return -EINVAL; if (!master->_block_isbad) return 0; + + if (mtd->flags & MTD_MLC_IN_SLC_MODE) + ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; + return master->_block_isbad(master, mtd_get_master_ofs(mtd, ofs)); } EXPORT_SYMBOL_GPL(mtd_block_isbad); @@ -1885,6 +2039,9 @@ int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; + if (mtd->flags & MTD_MLC_IN_SLC_MODE) + ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; + ret = master->_block_markbad(master, mtd_get_master_ofs(mtd, ofs)); if (ret) return ret; diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 93ef8fdf1634..ca2d213f70a1 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -35,9 +35,12 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, const struct mtd_partition *part, int partno, uint64_t cur_offset) { - int wr_alignment = (parent->flags & MTD_NO_ERASE) ? parent->writesize : - parent->erasesize; - struct mtd_info *child, *master = mtd_get_master(parent); + struct mtd_info *master = mtd_get_master(parent); + int wr_alignment = (parent->flags & MTD_NO_ERASE) ? + master->writesize : master->erasesize; + u64 parent_size = mtd_is_partition(parent) ? + parent->part.size : parent->size; + struct mtd_info *child; u32 remainder; char *name; u64 tmp; @@ -56,8 +59,9 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, /* set up the MTD object for this partition */ child->type = parent->type; child->part.flags = parent->flags & ~part->mask_flags; + child->part.flags |= part->add_flags; child->flags = child->part.flags; - child->size = part->size; + child->part.size = part->size; child->writesize = parent->writesize; child->writebufsize = parent->writebufsize; child->oobsize = parent->oobsize; @@ -98,29 +102,29 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, } if (child->part.offset == MTDPART_OFS_RETAIN) { child->part.offset = cur_offset; - if (parent->size - child->part.offset >= child->size) { - child->size = parent->size - child->part.offset - - child->size; + if (parent_size - child->part.offset >= child->part.size) { + child->part.size = parent_size - child->part.offset - + child->part.size; } else { printk(KERN_ERR "mtd partition \"%s\" doesn't have enough space: %#llx < %#llx, disabled\n", - part->name, parent->size - child->part.offset, - child->size); + part->name, parent_size - child->part.offset, + child->part.size); /* register to preserve ordering */ goto out_register; } } - if (child->size == MTDPART_SIZ_FULL) - child->size = parent->size - child->part.offset; + if (child->part.size == MTDPART_SIZ_FULL) + child->part.size = parent_size - child->part.offset; printk(KERN_NOTICE "0x%012llx-0x%012llx : \"%s\"\n", - child->part.offset, child->part.offset + child->size, + child->part.offset, child->part.offset + child->part.size, child->name); /* let's do some sanity checks */ - if (child->part.offset >= parent->size) { + if (child->part.offset >= parent_size) { /* let's register it anyway to preserve ordering */ child->part.offset = 0; - child->size = 0; + child->part.size = 0; /* Initialize ->erasesize to make add_mtd_device() happy. */ child->erasesize = parent->erasesize; @@ -128,15 +132,16 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, part->name); goto out_register; } - if (child->part.offset + child->size > parent->size) { - child->size = parent->size - child->part.offset; + if (child->part.offset + child->part.size > parent->size) { + child->part.size = parent_size - child->part.offset; printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#llx\n", - part->name, parent->name, child->size); + part->name, parent->name, child->part.size); } + if (parent->numeraseregions > 1) { /* Deal with variable erase size stuff */ int i, max = parent->numeraseregions; - u64 end = child->part.offset + child->size; + u64 end = child->part.offset + child->part.size; struct mtd_erase_region_info *regions = parent->eraseregions; /* Find the first erase regions which is part of this @@ -156,7 +161,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, BUG_ON(child->erasesize == 0); } else { /* Single erase size */ - child->erasesize = parent->erasesize; + child->erasesize = master->erasesize; } /* @@ -178,7 +183,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, part->name); } - tmp = mtd_get_master_ofs(child, 0) + child->size; + tmp = mtd_get_master_ofs(child, 0) + child->part.size; remainder = do_div(tmp, wr_alignment); if ((child->flags & MTD_WRITEABLE) && remainder) { child->flags &= ~MTD_WRITEABLE; @@ -186,6 +191,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, part->name); } + child->size = child->part.size; child->ecc_step_size = parent->ecc_step_size; child->ecc_strength = parent->ecc_strength; child->bitflip_threshold = parent->bitflip_threshold; @@ -193,7 +199,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, if (master->_block_isbad) { uint64_t offs = 0; - while (offs < child->size) { + while (offs < child->part.size) { if (mtd_block_isreserved(child, offs)) child->ecc_stats.bbtblocks++; else if (mtd_block_isbad(child, offs)) @@ -234,6 +240,8 @@ int mtd_add_partition(struct mtd_info *parent, const char *name, long long offset, long long length) { struct mtd_info *master = mtd_get_master(parent); + u64 parent_size = mtd_is_partition(parent) ? + parent->part.size : parent->size; struct mtd_partition part; struct mtd_info *child; int ret = 0; @@ -244,7 +252,7 @@ int mtd_add_partition(struct mtd_info *parent, const char *name, return -EINVAL; if (length == MTDPART_SIZ_FULL) - length = parent->size - offset; + length = parent_size - offset; if (length <= 0) return -EINVAL; @@ -419,7 +427,7 @@ int add_mtd_partitions(struct mtd_info *parent, /* Look for subpartitions */ parse_mtd_partitions(child, parts[i].types, NULL); - cur_offset = child->part.offset + child->size; + cur_offset = child->part.offset + child->part.size; } return 0; diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 508d14d45439..9fcac902d989 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -200,6 +200,8 @@ struct mtd_debug_info { * * @node: list node used to add an MTD partition to the parent partition list * @offset: offset of the partition relatively to the parent offset + * @size: partition size. Should be equal to mtd->size unless + * MTD_MLC_IN_SLC_MODE is set * @flags: original flags (before the mtdpart logic decided to tweak them based * on flash constraints, like eraseblock/pagesize alignment) * @@ -209,6 +211,7 @@ struct mtd_debug_info { struct mtd_part { struct list_head node; u64 offset; + u64 size; u32 flags; }; @@ -619,7 +622,9 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) static inline int mtd_wunit_per_eb(struct mtd_info *mtd) { - return mtd->erasesize / mtd->writesize; + struct mtd_info *master = mtd_get_master(mtd); + + return master->erasesize / mtd->writesize; } static inline int mtd_offset_to_wunit(struct mtd_info *mtd, loff_t offs) diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index e545c050d3e8..b74a539ec581 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -37,6 +37,7 @@ * master MTD flag set for the corresponding MTD partition. * For example, to force a read-only partition, simply adding * MTD_WRITEABLE to the mask_flags will do the trick. + * add_flags: contains flags to add to the parent flags * * Note: writeable partitions require their size and offset be * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). @@ -48,6 +49,7 @@ struct mtd_partition { uint64_t size; /* partition size */ uint64_t offset; /* offset within the master MTD space */ uint32_t mask_flags; /* master MTD flags to mask out for this partition */ + uint32_t add_flags; /* flags to add to the partition */ struct device_node *of_node; }; diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h index 47ffe3208c27..4af24cc56b88 100644 --- a/include/uapi/mtd/mtd-abi.h +++ b/include/uapi/mtd/mtd-abi.h @@ -104,6 +104,7 @@ struct mtd_write_req { #define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */ #define MTD_NO_ERASE 0x1000 /* No erase necessary */ #define MTD_POWERUP_LOCK 0x2000 /* Always locked after reset */ +#define MTD_MLC_IN_SLC_MODE 0x4000 /* Emulate SLC behavior on MLC NANDs */ /* Some common devices / combinations of capabilities */ #define MTD_CAP_ROM 0 -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs 2019-12-30 16:51 ` [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs Miquel Raynal @ 2020-01-08 23:49 ` Richard Weinberger 2020-01-09 18:16 ` Miquel Raynal 2020-01-14 10:04 ` Miquel Raynal 0 siblings, 2 replies; 18+ messages in thread From: Richard Weinberger @ 2020-01-08 23:49 UTC (permalink / raw) To: Miquel Raynal Cc: Vignesh Raghavendra, Tudor Ambarus, Boris Brezillon, Boris Brezillon, linux-mtd, Thomas Petazzoni ----- Ursprüngliche Mail ----- > Von: "Miquel Raynal" <miquel.raynal@bootlin.com> > An: "richard" <richard@nod.at>, "Vignesh Raghavendra" <vigneshr@ti.com>, "Tudor Ambarus" <Tudor.Ambarus@microchip.com>, > "linux-mtd" <linux-mtd@lists.infradead.org> > CC: "Boris Brezillon" <boris.brezillon@collabora.com>, "Thomas Petazzoni" <thomas.petazzoni@bootlin.com>, "Boris > Brezillon" <boris.brezillon@bootlin.com>, "Miquel Raynal" <miquel.raynal@bootlin.com> > Gesendet: Montag, 30. Dezember 2019 17:51:25 > Betreff: [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs > From: Boris Brezillon <boris.brezillon@bootlin.com> > > MLC NANDs can be made a bit more reliable if we only program the lower > page of each pair. At least, this solves the paired-pages corruption > issue. > > Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> > --- > drivers/mtd/mtdcore.c | 189 ++++++++++++++++++++++++++++++--- > drivers/mtd/mtdpart.c | 54 ++++++---- > include/linux/mtd/mtd.h | 7 +- > include/linux/mtd/partitions.h | 2 + > include/uapi/mtd/mtd-abi.h | 1 + > 5 files changed, 213 insertions(+), 40 deletions(-) > > diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c > index 2916674208b3..de0a692ecb29 100644 > --- a/drivers/mtd/mtdcore.c > +++ b/drivers/mtd/mtdcore.c > @@ -617,6 +617,19 @@ int add_mtd_device(struct mtd_info *mtd) > !(mtd->flags & MTD_NO_ERASE))) > return -EINVAL; > > + /* > + * MTD_MLC_IN_SLC_MODE can only be set on partitions, when the master I suggest giving a name which indicates that we are actually emulating an SLC. Maybe MTD_SLC_EMULATION? Some MLC NANDs support SLC mode in hardware, MTD_MLC_IN_SLC_MODE reads like this feature. > + * is an MLC NAND and has a proper pairing scheme defined. > + * We also reject masters that implement ->_writev() for now, because > + * NAND controller drivers don't implement this hook, and adding the > + * SLC -> MLC address/length conversion to this path is useless if we > + * don't have a user. > + */ > + if (mtd->flags & MTD_MLC_IN_SLC_MODE && > + (!mtd_is_partition(mtd) || master->type != MTD_MLCNANDFLASH || > + !master->pairing || master->_writev)) > + return -EINVAL; > + > mutex_lock(&mtd_table_mutex); > > i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); > @@ -632,6 +645,14 @@ int add_mtd_device(struct mtd_info *mtd) > if (mtd->bitflip_threshold == 0) > mtd->bitflip_threshold = mtd->ecc_strength; > > + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { > + int ngroups = mtd_pairing_groups(master); > + > + mtd->erasesize /= ngroups; > + mtd->size = (u64)mtd_div_by_eb(mtd->size, master) * > + mtd->erasesize; Can we please have a helper for this? You use this formula many times. > + } > + > if (is_power_of_2(mtd->erasesize)) > mtd->erasesize_shift = ffs(mtd->erasesize) - 1; > else > @@ -1074,9 +1095,11 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info > *instr) > { > struct mtd_info *master = mtd_get_master(mtd); > u64 mst_ofs = mtd_get_master_ofs(mtd, 0); > + struct erase_info adjinstr; > int ret; > > instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; > + adjinstr = *instr; > > if (!mtd->erasesize || !master->_erase) > return -ENOTSUPP; > @@ -1091,12 +1114,27 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info > *instr) > > ledtrig_mtd_activity(); > > - instr->addr += mst_ofs; > - ret = master->_erase(master, instr); > - if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) > - instr->fail_addr -= mst_ofs; > + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { > + adjinstr.addr = (loff_t)mtd_div_by_eb(instr->addr, mtd) * > + master->erasesize; > + adjinstr.len = ((u64)mtd_div_by_eb(instr->addr + instr->len, mtd) * > + master->erasesize) - > + adjinstr.addr; > + } > + > + adjinstr.addr += mst_ofs; > + > + ret = master->_erase(master, &adjinstr); > + > + if (adjinstr.fail_addr != MTD_FAIL_ADDR_UNKNOWN) { > + instr->fail_addr = adjinstr.fail_addr - mst_ofs; > + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { > + instr->fail_addr = mtd_div_by_eb(instr->fail_addr, > + master); > + instr->fail_addr *= mtd->erasesize; > + } > + } > > - instr->addr -= mst_ofs; > return ret; > } > EXPORT_SYMBOL_GPL(mtd_erase); > @@ -1276,6 +1314,101 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, > loff_t offs, > return 0; > } > > +static int mtd_read_oob_std(struct mtd_info *mtd, loff_t from, > + struct mtd_oob_ops *ops) > +{ > + struct mtd_info *master = mtd_get_master(mtd); > + int ret; > + > + from = mtd_get_master_ofs(mtd, from); > + if (master->_read_oob) > + ret = master->_read_oob(master, from, ops); > + else > + ret = master->_read(master, from, ops->len, &ops->retlen, > + ops->datbuf); > + > + return ret; > +} > + > +static int mtd_write_oob_std(struct mtd_info *mtd, loff_t to, > + struct mtd_oob_ops *ops) > +{ > + struct mtd_info *master = mtd_get_master(mtd); > + int ret; > + > + to = mtd_get_master_ofs(mtd, to); > + if (master->_write_oob) > + ret = master->_write_oob(master, to, ops); > + else > + ret = master->_write(master, to, ops->len, &ops->retlen, > + ops->datbuf); > + > + return ret; > +} > + > +static int mtd_oob_io_slc(struct mtd_info *mtd, loff_t start, bool read, > + struct mtd_oob_ops *ops) The name is misleading. We don't do OOB IO on a SLC NAND, we emulate SLC. Thanks, //richard ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs 2020-01-08 23:49 ` Richard Weinberger @ 2020-01-09 18:16 ` Miquel Raynal 2020-01-09 18:39 ` Richard Weinberger 2020-01-14 10:04 ` Miquel Raynal 1 sibling, 1 reply; 18+ messages in thread From: Miquel Raynal @ 2020-01-09 18:16 UTC (permalink / raw) To: Richard Weinberger Cc: Vignesh Raghavendra, Tudor Ambarus, Boris Brezillon, Boris Brezillon, linux-mtd, Thomas Petazzoni Hi Richard, Richard Weinberger <richard@nod.at> wrote on Thu, 9 Jan 2020 00:49:02 +0100 (CET): > ----- Ursprüngliche Mail ----- > > Von: "Miquel Raynal" <miquel.raynal@bootlin.com> > > An: "richard" <richard@nod.at>, "Vignesh Raghavendra" <vigneshr@ti.com>, "Tudor Ambarus" <Tudor.Ambarus@microchip.com>, > > "linux-mtd" <linux-mtd@lists.infradead.org> > > CC: "Boris Brezillon" <boris.brezillon@collabora.com>, "Thomas Petazzoni" <thomas.petazzoni@bootlin.com>, "Boris > > Brezillon" <boris.brezillon@bootlin.com>, "Miquel Raynal" <miquel.raynal@bootlin.com> > > Gesendet: Montag, 30. Dezember 2019 17:51:25 > > Betreff: [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs > > > From: Boris Brezillon <boris.brezillon@bootlin.com> > > > > MLC NANDs can be made a bit more reliable if we only program the lower > > page of each pair. At least, this solves the paired-pages corruption > > issue. > > > > Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> > > --- > > drivers/mtd/mtdcore.c | 189 ++++++++++++++++++++++++++++++--- > > drivers/mtd/mtdpart.c | 54 ++++++---- > > include/linux/mtd/mtd.h | 7 +- > > include/linux/mtd/partitions.h | 2 + > > include/uapi/mtd/mtd-abi.h | 1 + > > 5 files changed, 213 insertions(+), 40 deletions(-) > > > > diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c > > index 2916674208b3..de0a692ecb29 100644 > > --- a/drivers/mtd/mtdcore.c > > +++ b/drivers/mtd/mtdcore.c > > @@ -617,6 +617,19 @@ int add_mtd_device(struct mtd_info *mtd) > > !(mtd->flags & MTD_NO_ERASE))) > > return -EINVAL; > > > > + /* > > + * MTD_MLC_IN_SLC_MODE can only be set on partitions, when the master > > I suggest giving a name which indicates that we are actually emulating > an SLC. Maybe MTD_SLC_EMULATION? > Some MLC NANDs support SLC mode in hardware, MTD_MLC_IN_SLC_MODE reads like > this feature. You're right. What about MTD_SLC_ON_MLC_EMULATION? I like to see that we are manipulating MLC NANDs. > > > + * is an MLC NAND and has a proper pairing scheme defined. > > + * We also reject masters that implement ->_writev() for now, because > > + * NAND controller drivers don't implement this hook, and adding the > > + * SLC -> MLC address/length conversion to this path is useless if we > > + * don't have a user. > > + */ > > + if (mtd->flags & MTD_MLC_IN_SLC_MODE && > > + (!mtd_is_partition(mtd) || master->type != MTD_MLCNANDFLASH || > > + !master->pairing || master->_writev)) > > + return -EINVAL; > > + > > mutex_lock(&mtd_table_mutex); > > > > i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); > > @@ -632,6 +645,14 @@ int add_mtd_device(struct mtd_info *mtd) > > if (mtd->bitflip_threshold == 0) > > mtd->bitflip_threshold = mtd->ecc_strength; > > > > + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { > > + int ngroups = mtd_pairing_groups(master); > > + > > + mtd->erasesize /= ngroups; > > + mtd->size = (u64)mtd_div_by_eb(mtd->size, master) * > > + mtd->erasesize; > > Can we please have a helper for this? You use this formula many times. Absolutely! > > > + } > > + > > if (is_power_of_2(mtd->erasesize)) > > mtd->erasesize_shift = ffs(mtd->erasesize) - 1; > > else > > @@ -1074,9 +1095,11 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info > > *instr) > > { > > struct mtd_info *master = mtd_get_master(mtd); > > u64 mst_ofs = mtd_get_master_ofs(mtd, 0); > > + struct erase_info adjinstr; > > int ret; > > > > instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; > > + adjinstr = *instr; > > > > if (!mtd->erasesize || !master->_erase) > > return -ENOTSUPP; > > @@ -1091,12 +1114,27 @@ int mtd_erase(struct mtd_info *mtd, struct erase_info > > *instr) > > > > ledtrig_mtd_activity(); > > > > - instr->addr += mst_ofs; > > - ret = master->_erase(master, instr); > > - if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) > > - instr->fail_addr -= mst_ofs; > > + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { > > + adjinstr.addr = (loff_t)mtd_div_by_eb(instr->addr, mtd) * > > + master->erasesize; > > + adjinstr.len = ((u64)mtd_div_by_eb(instr->addr + instr->len, mtd) * > > + master->erasesize) - > > + adjinstr.addr; > > + } > > + > > + adjinstr.addr += mst_ofs; > > + > > + ret = master->_erase(master, &adjinstr); > > + > > + if (adjinstr.fail_addr != MTD_FAIL_ADDR_UNKNOWN) { > > + instr->fail_addr = adjinstr.fail_addr - mst_ofs; > > + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { > > + instr->fail_addr = mtd_div_by_eb(instr->fail_addr, > > + master); > > + instr->fail_addr *= mtd->erasesize; > > + } > > + } > > > > - instr->addr -= mst_ofs; > > return ret; > > } > > EXPORT_SYMBOL_GPL(mtd_erase); > > @@ -1276,6 +1314,101 @@ static int mtd_check_oob_ops(struct mtd_info *mtd, > > loff_t offs, > > return 0; > > } > > > > +static int mtd_read_oob_std(struct mtd_info *mtd, loff_t from, > > + struct mtd_oob_ops *ops) > > +{ > > + struct mtd_info *master = mtd_get_master(mtd); > > + int ret; > > + > > + from = mtd_get_master_ofs(mtd, from); > > + if (master->_read_oob) > > + ret = master->_read_oob(master, from, ops); > > + else > > + ret = master->_read(master, from, ops->len, &ops->retlen, > > + ops->datbuf); > > + > > + return ret; > > +} > > + > > +static int mtd_write_oob_std(struct mtd_info *mtd, loff_t to, > > + struct mtd_oob_ops *ops) > > +{ > > + struct mtd_info *master = mtd_get_master(mtd); > > + int ret; > > + > > + to = mtd_get_master_ofs(mtd, to); > > + if (master->_write_oob) > > + ret = master->_write_oob(master, to, ops); > > + else > > + ret = master->_write(master, to, ops->len, &ops->retlen, > > + ops->datbuf); > > + > > + return ret; > > +} > > + > > +static int mtd_oob_io_slc(struct mtd_info *mtd, loff_t start, bool read, > > + struct mtd_oob_ops *ops) > > The name is misleading. We don't do OOB IO on a SLC NAND, > we emulate SLC. What would you recommend? mtd_oob_io_emul_slc? > > Thanks, > //richard Thanks, Miquèl ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs 2020-01-09 18:16 ` Miquel Raynal @ 2020-01-09 18:39 ` Richard Weinberger 2020-01-09 19:19 ` Boris Brezillon 0 siblings, 1 reply; 18+ messages in thread From: Richard Weinberger @ 2020-01-09 18:39 UTC (permalink / raw) To: Miquel Raynal Cc: Vignesh Raghavendra, Tudor Ambarus, Boris Brezillon, Boris Brezillon, linux-mtd, Thomas Petazzoni Miquel, ----- Ursprüngliche Mail ----- >> I suggest giving a name which indicates that we are actually emulating >> an SLC. Maybe MTD_SLC_EMULATION? >> Some MLC NANDs support SLC mode in hardware, MTD_MLC_IN_SLC_MODE reads like >> this feature. > > You're right. What about MTD_SLC_ON_MLC_EMULATION? Makes sense. >> The name is misleading. We don't do OOB IO on a SLC NAND, >> we emulate SLC. > > What would you recommend? mtd_oob_io_emul_slc? Yes. Let's use "emul_slc" to indicate SLC emulation. Thanks, //richard ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs 2020-01-09 18:39 ` Richard Weinberger @ 2020-01-09 19:19 ` Boris Brezillon 2020-01-09 19:22 ` Miquel Raynal 0 siblings, 1 reply; 18+ messages in thread From: Boris Brezillon @ 2020-01-09 19:19 UTC (permalink / raw) To: Richard Weinberger Cc: Vignesh Raghavendra, Tudor Ambarus, Boris Brezillon, linux-mtd, Thomas Petazzoni, Miquel Raynal On Thu, 9 Jan 2020 19:39:42 +0100 (CET) Richard Weinberger <richard@nod.at> wrote: > Miquel, > > ----- Ursprüngliche Mail ----- > >> I suggest giving a name which indicates that we are actually emulating > >> an SLC. Maybe MTD_SLC_EMULATION? > >> Some MLC NANDs support SLC mode in hardware, MTD_MLC_IN_SLC_MODE reads like > >> this feature. > > > > You're right. What about MTD_SLC_ON_MLC_EMULATION? > > Makes sense. > > >> The name is misleading. We don't do OOB IO on a SLC NAND, > >> we emulate SLC. We should really replace those mtd_oob_ prefixes by something more accurate like mtd_io_ at some point (those helpers can do more than just read/write the OOB region). > > > > What would you recommend? mtd_oob_io_emul_slc? > > Yes. Let's use "emul_slc" to indicate SLC emulation. How about mtd_io_emulated_slc()? ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs 2020-01-09 19:19 ` Boris Brezillon @ 2020-01-09 19:22 ` Miquel Raynal 0 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2020-01-09 19:22 UTC (permalink / raw) To: Boris Brezillon Cc: Vignesh Raghavendra, Tudor Ambarus, Richard Weinberger, Boris Brezillon, linux-mtd, Thomas Petazzoni Hi Boris, Boris Brezillon <boris.brezillon@collabora.com> wrote on Thu, 9 Jan 2020 20:19:35 +0100: > On Thu, 9 Jan 2020 19:39:42 +0100 (CET) > Richard Weinberger <richard@nod.at> wrote: > > > Miquel, > > > > ----- Ursprüngliche Mail ----- > > >> I suggest giving a name which indicates that we are actually emulating > > >> an SLC. Maybe MTD_SLC_EMULATION? > > >> Some MLC NANDs support SLC mode in hardware, MTD_MLC_IN_SLC_MODE reads like > > >> this feature. > > > > > > You're right. What about MTD_SLC_ON_MLC_EMULATION? > > > > Makes sense. > > > > >> The name is misleading. We don't do OOB IO on a SLC NAND, > > >> we emulate SLC. > > We should really replace those mtd_oob_ prefixes by something > more accurate like mtd_io_ at some point (those helpers can do more than > just read/write the OOB region). I think I have some WIP about this. Not the time for everything just during these vacations :p > > > > > > > What would you recommend? mtd_oob_io_emul_slc? > > > > Yes. Let's use "emul_slc" to indicate SLC emulation. > > How about mtd_io_emulated_slc()? Fine! Thanks, Miquèl ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs 2020-01-08 23:49 ` Richard Weinberger 2020-01-09 18:16 ` Miquel Raynal @ 2020-01-14 10:04 ` Miquel Raynal 1 sibling, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2020-01-14 10:04 UTC (permalink / raw) To: Richard Weinberger Cc: Vignesh Raghavendra, Tudor Ambarus, Boris Brezillon, Boris Brezillon, linux-mtd, Thomas Petazzoni Hi Richard, A very simple question below. > > > + * is an MLC NAND and has a proper pairing scheme defined. > > + * We also reject masters that implement ->_writev() for now, because > > + * NAND controller drivers don't implement this hook, and adding the > > + * SLC -> MLC address/length conversion to this path is useless if we > > + * don't have a user. > > + */ > > + if (mtd->flags & MTD_MLC_IN_SLC_MODE && > > + (!mtd_is_partition(mtd) || master->type != MTD_MLCNANDFLASH || > > + !master->pairing || master->_writev)) > > + return -EINVAL; > > + > > mutex_lock(&mtd_table_mutex); > > > > i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); > > @@ -632,6 +645,14 @@ int add_mtd_device(struct mtd_info *mtd) > > if (mtd->bitflip_threshold == 0) > > mtd->bitflip_threshold = mtd->ecc_strength; > > > > + if (mtd->flags & MTD_MLC_IN_SLC_MODE) { > > + int ngroups = mtd_pairing_groups(master); > > + > > + mtd->erasesize /= ngroups; > > + mtd->size = (u64)mtd_div_by_eb(mtd->size, master) * > > + mtd->erasesize; > > Can we please have a helper for this? You use this formula many times. I thought you were talking about the mtd->size calculation but this line appears only once as-is. the whole 'if' block is never exactly the same so it cannot be factored out. The only line that is actually repeating is the if condition. Do you mean you would like something like this? static bool mtd_emulates_slc(struct mtd_info *mtd) { return mtd->flags & MTD_EMULATE_SLC_ON_MLC; } Thanks, Miquèl ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 5/8] dt-bindings: mtd: partition: Document the slc-mode property 2019-12-30 16:51 [PATCH 0/8] MLC in SLC mode Miquel Raynal ` (3 preceding siblings ...) 2019-12-30 16:51 ` [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs Miquel Raynal @ 2019-12-30 16:51 ` Miquel Raynal 2019-12-31 3:53 ` Florian Fainelli 2019-12-30 16:51 ` [PATCH 6/8] mtd: partitions: ofpart: Parse " Miquel Raynal ` (2 subsequent siblings) 7 siblings, 1 reply; 18+ messages in thread From: Miquel Raynal @ 2019-12-30 16:51 UTC (permalink / raw) To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Boris Brezillon, Thomas Petazzoni, Miquel Raynal From: Boris Brezillon <boris.brezillon@bootlin.com> Add a boolean property to force a specific partition attached to an MLC NAND to be accessed in an emulated SLC mode this making this partition immune to paired-pages corruptions. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- .../devicetree/bindings/mtd/partition.txt | 3 +++ scripts/pnmtologo | Bin 0 -> 22416 bytes 2 files changed, 3 insertions(+) create mode 100755 scripts/pnmtologo diff --git a/Documentation/devicetree/bindings/mtd/partition.txt b/Documentation/devicetree/bindings/mtd/partition.txt index afbbd870496d..4a39698221a2 100644 --- a/Documentation/devicetree/bindings/mtd/partition.txt +++ b/Documentation/devicetree/bindings/mtd/partition.txt @@ -61,6 +61,9 @@ Optional properties: clobbered. - lock : Do not unlock the partition at initialization time (not supported on all devices) +- slc-mode: This parameter, if present, allows one to emulate SLC mode on a + partition attached to an MLC NAND thus making this partition immune to + paired-pages corruptions Examples: diff --git a/scripts/pnmtologo b/scripts/pnmtologo new file mode 100755 index 0000000000000000000000000000000000000000..ddb4f779cfa46fd92b802097fb2dd301bbe91912 GIT binary patch literal 22416 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 literal 0 HcmV?d00001 -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 5/8] dt-bindings: mtd: partition: Document the slc-mode property 2019-12-30 16:51 ` [PATCH 5/8] dt-bindings: mtd: partition: Document the slc-mode property Miquel Raynal @ 2019-12-31 3:53 ` Florian Fainelli 2020-01-14 9:33 ` Miquel Raynal 0 siblings, 1 reply; 18+ messages in thread From: Florian Fainelli @ 2019-12-31 3:53 UTC (permalink / raw) To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Boris Brezillon, Thomas Petazzoni On 12/30/2019 8:51 AM, Miquel Raynal wrote: > From: Boris Brezillon <boris.brezillon@bootlin.com> > > Add a boolean property to force a specific partition attached to an MLC > NAND to be accessed in an emulated SLC mode this making this partition > immune to paired-pages corruptions. > > Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> > --- > .../devicetree/bindings/mtd/partition.txt | 3 +++ > scripts/pnmtologo | Bin 0 -> 22416 bytes You will probably want to remove that file from the final commit and/or add pnmtologo to .gitignore as a separate patch. -- Florian ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 5/8] dt-bindings: mtd: partition: Document the slc-mode property 2019-12-31 3:53 ` Florian Fainelli @ 2020-01-14 9:33 ` Miquel Raynal 0 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2020-01-14 9:33 UTC (permalink / raw) To: Florian Fainelli Cc: Vignesh Raghavendra, Tudor Ambarus, Richard Weinberger, Boris Brezillon, Boris Brezillon, linux-mtd, Thomas Petazzoni Hi Florian, Florian Fainelli <f.fainelli@gmail.com> wrote on Mon, 30 Dec 2019 19:53:11 -0800: > On 12/30/2019 8:51 AM, Miquel Raynal wrote: > > From: Boris Brezillon <boris.brezillon@bootlin.com> > > > > Add a boolean property to force a specific partition attached to an MLC > > NAND to be accessed in an emulated SLC mode this making this partition > > immune to paired-pages corruptions. > > > > Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> > > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> > > --- > > .../devicetree/bindings/mtd/partition.txt | 3 +++ > > scripts/pnmtologo | Bin 0 -> 22416 bytes > > You will probably want to remove that file from the final commit and/or > add pnmtologo to .gitignore as a separate patch. Done, thanks for the warning! Thanks, Miquèl ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 6/8] mtd: partitions: ofpart: Parse the slc-mode property 2019-12-30 16:51 [PATCH 0/8] MLC in SLC mode Miquel Raynal ` (4 preceding siblings ...) 2019-12-30 16:51 ` [PATCH 5/8] dt-bindings: mtd: partition: Document the slc-mode property Miquel Raynal @ 2019-12-30 16:51 ` Miquel Raynal 2019-12-30 16:51 ` [PATCH 7/8] mtd: cmdlinepart: Add an slc option to use SLC mode on a part Miquel Raynal 2019-12-30 16:51 ` [PATCH 8/8] ubi: Relax the 'no MLC' rule and allow MLCs operating in SLC mode Miquel Raynal 7 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2019-12-30 16:51 UTC (permalink / raw) To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Boris Brezillon, Thomas Petazzoni, Miquel Raynal From: Boris Brezillon <boris.brezillon@bootlin.com> Parse the slc-mode property and set the MTD_MLC_IN_SLC_MODE flag when present. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- drivers/mtd/parsers/ofpart.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/parsers/ofpart.c b/drivers/mtd/parsers/ofpart.c index 3caeabf27987..0a67fd15ab54 100644 --- a/drivers/mtd/parsers/ofpart.c +++ b/drivers/mtd/parsers/ofpart.c @@ -117,6 +117,9 @@ static int parse_fixed_partitions(struct mtd_info *master, if (of_get_property(pp, "lock", &len)) parts[i].mask_flags |= MTD_POWERUP_LOCK; + if (of_property_read_bool(pp, "slc-mode")) + parts[i].add_flags |= MTD_MLC_IN_SLC_MODE; + i++; } -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7/8] mtd: cmdlinepart: Add an slc option to use SLC mode on a part 2019-12-30 16:51 [PATCH 0/8] MLC in SLC mode Miquel Raynal ` (5 preceding siblings ...) 2019-12-30 16:51 ` [PATCH 6/8] mtd: partitions: ofpart: Parse " Miquel Raynal @ 2019-12-30 16:51 ` Miquel Raynal 2019-12-30 16:51 ` [PATCH 8/8] ubi: Relax the 'no MLC' rule and allow MLCs operating in SLC mode Miquel Raynal 7 siblings, 0 replies; 18+ messages in thread From: Miquel Raynal @ 2019-12-30 16:51 UTC (permalink / raw) To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Boris Brezillon, Thomas Petazzoni, Miquel Raynal From: Boris Brezillon <boris.brezillon@bootlin.com> Add a new option to set the MTD_MLC_IN_SLC_MODE flag. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- drivers/mtd/parsers/cmdlinepart.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/parsers/cmdlinepart.c b/drivers/mtd/parsers/cmdlinepart.c index c86f2db8c882..089fdf83b088 100644 --- a/drivers/mtd/parsers/cmdlinepart.c +++ b/drivers/mtd/parsers/cmdlinepart.c @@ -9,7 +9,7 @@ * * mtdparts=<mtddef>[;<mtddef] * <mtddef> := <mtd-id>:<partdef>[,<partdef>] - * <partdef> := <size>[@<offset>][<name>][ro][lk] + * <partdef> := <size>[@<offset>][<name>][ro][lk][slc] * <mtd-id> := unique name used in mapping driver/device (mtd->name) * <size> := standard linux memsize OR "-" to denote all remaining space * size is automatically truncated at end of device @@ -92,7 +92,7 @@ static struct mtd_partition * newpart(char *s, int name_len; unsigned char *extra_mem; char delim; - unsigned int mask_flags; + unsigned int mask_flags, add_flags; /* fetch the partition size */ if (*s == '-') { @@ -109,6 +109,7 @@ static struct mtd_partition * newpart(char *s, /* fetch partition name and flags */ mask_flags = 0; /* this is going to be a regular partition */ + add_flags = 0; delim = 0; /* check for offset */ @@ -152,6 +153,12 @@ static struct mtd_partition * newpart(char *s, s += 2; } + /* if slc is found use emulated SLC mode on this partition*/ + if (!strncmp(s, "slc", 3)) { + add_flags |= MTD_MLC_IN_SLC_MODE; + s += 3; + } + /* test if more partitions are following */ if (*s == ',') { if (size == SIZE_REMAINING) { @@ -184,6 +191,7 @@ static struct mtd_partition * newpart(char *s, parts[this_part].size = size; parts[this_part].offset = offset; parts[this_part].mask_flags = mask_flags; + parts[this_part].add_flags = add_flags; if (name) strlcpy(extra_mem, name, name_len + 1); else -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 8/8] ubi: Relax the 'no MLC' rule and allow MLCs operating in SLC mode 2019-12-30 16:51 [PATCH 0/8] MLC in SLC mode Miquel Raynal ` (6 preceding siblings ...) 2019-12-30 16:51 ` [PATCH 7/8] mtd: cmdlinepart: Add an slc option to use SLC mode on a part Miquel Raynal @ 2019-12-30 16:51 ` Miquel Raynal 2020-01-08 23:50 ` Richard Weinberger 7 siblings, 1 reply; 18+ messages in thread From: Miquel Raynal @ 2019-12-30 16:51 UTC (permalink / raw) To: Richard Weinberger, Vignesh Raghavendra, Tudor Ambarus, linux-mtd Cc: Boris Brezillon, Boris Brezillon, Thomas Petazzoni, Miquel Raynal From: Boris Brezillon <boris.brezillon@bootlin.com> The MTD layer provides an SLC mode (purely software emulation of SLC behavior) addressing the paired-pages corruption issue, which was the main reason for refusing attaching MLC NANDs to UBI. Relax this rule and allow partitions that have the MTD_MLC_IN_SLC_MODE flag set to be attached. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> --- drivers/mtd/ubi/build.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index d636bbe214cb..d917cc4cd937 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -846,8 +846,11 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes. * MLC NAND is different and needs special care, otherwise UBI or UBIFS * will die soon and you will lose all your data. + * Relax this rule if the partition we're attaching to operates in SLC + * mode. */ - if (mtd->type == MTD_MLCNANDFLASH) { + if (mtd->type == MTD_MLCNANDFLASH && + !(mtd->flags & MTD_MLC_IN_SLC_MODE)) { pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n", mtd->index); return -EINVAL; -- 2.20.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 8/8] ubi: Relax the 'no MLC' rule and allow MLCs operating in SLC mode 2019-12-30 16:51 ` [PATCH 8/8] ubi: Relax the 'no MLC' rule and allow MLCs operating in SLC mode Miquel Raynal @ 2020-01-08 23:50 ` Richard Weinberger 0 siblings, 0 replies; 18+ messages in thread From: Richard Weinberger @ 2020-01-08 23:50 UTC (permalink / raw) To: Miquel Raynal Cc: Vignesh Raghavendra, Tudor Ambarus, Boris Brezillon, Boris Brezillon, linux-mtd, Thomas Petazzoni ----- Ursprüngliche Mail ----- > Von: "Miquel Raynal" <miquel.raynal@bootlin.com> > An: "richard" <richard@nod.at>, "Vignesh Raghavendra" <vigneshr@ti.com>, "Tudor Ambarus" <Tudor.Ambarus@microchip.com>, > "linux-mtd" <linux-mtd@lists.infradead.org> > CC: "Boris Brezillon" <boris.brezillon@collabora.com>, "Thomas Petazzoni" <thomas.petazzoni@bootlin.com>, "Boris > Brezillon" <boris.brezillon@bootlin.com>, "Miquel Raynal" <miquel.raynal@bootlin.com> > Gesendet: Montag, 30. Dezember 2019 17:51:29 > Betreff: [PATCH 8/8] ubi: Relax the 'no MLC' rule and allow MLCs operating in SLC mode > From: Boris Brezillon <boris.brezillon@bootlin.com> > > The MTD layer provides an SLC mode (purely software emulation of SLC > behavior) addressing the paired-pages corruption issue, which was the > main reason for refusing attaching MLC NANDs to UBI. > > Relax this rule and allow partitions that have the MTD_MLC_IN_SLC_MODE > flag set to be attached. > > Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> > --- > drivers/mtd/ubi/build.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c > index d636bbe214cb..d917cc4cd937 100644 > --- a/drivers/mtd/ubi/build.c > +++ b/drivers/mtd/ubi/build.c > @@ -846,8 +846,11 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, > * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes. > * MLC NAND is different and needs special care, otherwise UBI or UBIFS > * will die soon and you will lose all your data. > + * Relax this rule if the partition we're attaching to operates in SLC > + * mode. > */ > - if (mtd->type == MTD_MLCNANDFLASH) { > + if (mtd->type == MTD_MLCNANDFLASH && > + !(mtd->flags & MTD_MLC_IN_SLC_MODE)) { > pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n", > mtd->index); > return -EINVAL; Acked-by: Richard Weinberger <richard@nod.at> Thanks, //richard ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2020-01-14 10:04 UTC | newest] Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-12-30 16:51 [PATCH 0/8] MLC in SLC mode Miquel Raynal 2019-12-30 16:51 ` [PATCH 1/8] mtd: rawnand: toshiba: Add a specific init for TC58TEG5DCLTA00 Miquel Raynal 2019-12-30 16:51 ` [PATCH 2/8] mtd: rawnand: Define the "distance 3" MLC pairing scheme Miquel Raynal 2019-12-30 16:51 ` [PATCH 3/8] mtd: rawnand: toshiba: Set the pairing scheme for TC58TEG5DCLTA00 Miquel Raynal 2019-12-30 16:51 ` [PATCH 4/8] mtd: Add support for emulated SLC mode on MLC NANDs Miquel Raynal 2020-01-08 23:49 ` Richard Weinberger 2020-01-09 18:16 ` Miquel Raynal 2020-01-09 18:39 ` Richard Weinberger 2020-01-09 19:19 ` Boris Brezillon 2020-01-09 19:22 ` Miquel Raynal 2020-01-14 10:04 ` Miquel Raynal 2019-12-30 16:51 ` [PATCH 5/8] dt-bindings: mtd: partition: Document the slc-mode property Miquel Raynal 2019-12-31 3:53 ` Florian Fainelli 2020-01-14 9:33 ` Miquel Raynal 2019-12-30 16:51 ` [PATCH 6/8] mtd: partitions: ofpart: Parse " Miquel Raynal 2019-12-30 16:51 ` [PATCH 7/8] mtd: cmdlinepart: Add an slc option to use SLC mode on a part Miquel Raynal 2019-12-30 16:51 ` [PATCH 8/8] ubi: Relax the 'no MLC' rule and allow MLCs operating in SLC mode Miquel Raynal 2020-01-08 23:50 ` Richard Weinberger
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).