Message ID | 20190304201522.11323-2-miquel.raynal@bootlin.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mtd: rawnand: 5th batch of cleanups | expand |
Hi Miquel, > static const struct spinand_info macronix_spinand_table[] = { > SPINAND_INFO("MX35LF1GE4AB", 0x12, > - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), > + NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1), > NAND_ECCREQ(4, 512), > SPINAND_INFO_OP_VARIANTS(&read_cache_variants, > &write_cache_variants, > @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = { > SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, > mx35lf1ge4ab_ecc_get_status)), > SPINAND_INFO("MX35LF2GE4AB", 0x22, > - NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), > + NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1), > NAND_ECCREQ(4, 512), Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped here, i.e. isn't it the larger flash that has more max bad blocks than the smaller one? /Emil
Hi Emil, On 04.06.19 10:01, Emil Lenngren wrote: > Hi Miquel, > >> static const struct spinand_info macronix_spinand_table[] = { >> SPINAND_INFO("MX35LF1GE4AB", 0x12, >> - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), >> + NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1), >> NAND_ECCREQ(4, 512), >> SPINAND_INFO_OP_VARIANTS(&read_cache_variants, >> &write_cache_variants, >> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = { >> SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, >> mx35lf1ge4ab_ecc_get_status)), >> SPINAND_INFO("MX35LF2GE4AB", 0x22, >> - NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), >> + NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1), >> NAND_ECCREQ(4, 512), > > Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped > here, i.e. isn't it the larger flash that has more max bad blocks than > the smaller one? I think Miquel is out of office for some days, so I just checked and you are right, the maximum number of bad blocks should be swapped. Actually there is also a wrong value in the GigaDevice driver: For the GD5F4GQ4xA it should be 80 instead of 40. Would you mind sending a patch with a "Fixes:" tag, that fixes both, the Macronix and the GigaDevice driver? Or should I send one? Thanks, Frieder
On Thu, 6 Jun 2019 08:27:11 +0000 Schrempf Frieder <frieder.schrempf@kontron.de> wrote: > Hi Emil, > > On 04.06.19 10:01, Emil Lenngren wrote: > > Hi Miquel, > > > >> static const struct spinand_info macronix_spinand_table[] = { > >> SPINAND_INFO("MX35LF1GE4AB", 0x12, > >> - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), > >> + NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1), > >> NAND_ECCREQ(4, 512), > >> SPINAND_INFO_OP_VARIANTS(&read_cache_variants, > >> &write_cache_variants, > >> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = { > >> SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, > >> mx35lf1ge4ab_ecc_get_status)), > >> SPINAND_INFO("MX35LF2GE4AB", 0x22, > >> - NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), > >> + NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1), > >> NAND_ECCREQ(4, 512), > > > > Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped > > here, i.e. isn't it the larger flash that has more max bad blocks than > > the smaller one? > > I think Miquel is out of office for some days, so I just checked and you > are right, the maximum number of bad blocks should be swapped. > > Actually there is also a wrong value in the GigaDevice driver: For the > GD5F4GQ4xA it should be 80 instead of 40. Haven't checked the datasheet, but keep in mind that this is the max number of eraseblock per LUN.
On 06.06.19 10:39, Boris Brezillon wrote: > On Thu, 6 Jun 2019 08:27:11 +0000 > Schrempf Frieder <frieder.schrempf@kontron.de> wrote: > >> Hi Emil, >> >> On 04.06.19 10:01, Emil Lenngren wrote: >>> Hi Miquel, >>> >>>> static const struct spinand_info macronix_spinand_table[] = { >>>> SPINAND_INFO("MX35LF1GE4AB", 0x12, >>>> - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), >>>> + NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1), >>>> NAND_ECCREQ(4, 512), >>>> SPINAND_INFO_OP_VARIANTS(&read_cache_variants, >>>> &write_cache_variants, >>>> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = { >>>> SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, >>>> mx35lf1ge4ab_ecc_get_status)), >>>> SPINAND_INFO("MX35LF2GE4AB", 0x22, >>>> - NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), >>>> + NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1), >>>> NAND_ECCREQ(4, 512), >>> >>> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped >>> here, i.e. isn't it the larger flash that has more max bad blocks than >>> the smaller one? >> >> I think Miquel is out of office for some days, so I just checked and you >> are right, the maximum number of bad blocks should be swapped. >> >> Actually there is also a wrong value in the GigaDevice driver: For the >> GD5F4GQ4xA it should be 80 instead of 40. > > Haven't checked the datasheet, but keep in mind that this is the max > number of eraseblock per LUN. The datasheet gives 20 for the 1G type and 40 for the 2G type. Both types have only one LUN. Only the 2G type has 2 planes, but that shouldn't make a difference, right?
On 06.06.19 10:52, Frieder Schrempf wrote: > On 06.06.19 10:39, Boris Brezillon wrote: >> On Thu, 6 Jun 2019 08:27:11 +0000 >> Schrempf Frieder <frieder.schrempf@kontron.de> wrote: >> >>> Hi Emil, >>> >>> On 04.06.19 10:01, Emil Lenngren wrote: >>>> Hi Miquel, >>>>> static const struct spinand_info macronix_spinand_table[] = { >>>>> SPINAND_INFO("MX35LF1GE4AB", 0x12, >>>>> - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), >>>>> + NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1), >>>>> NAND_ECCREQ(4, 512), >>>>> SPINAND_INFO_OP_VARIANTS(&read_cache_variants, >>>>> &write_cache_variants, >>>>> @@ -103,7 +103,7 @@ static const struct spinand_info >>>>> macronix_spinand_table[] = { >>>>> SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, >>>>> mx35lf1ge4ab_ecc_get_status)), >>>>> SPINAND_INFO("MX35LF2GE4AB", 0x22, >>>>> - NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), >>>>> + NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1), >>>>> NAND_ECCREQ(4, 512), >>>> >>>> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped >>>> here, i.e. isn't it the larger flash that has more max bad blocks than >>>> the smaller one? >>> >>> I think Miquel is out of office for some days, so I just checked and you >>> are right, the maximum number of bad blocks should be swapped. >>> >>> Actually there is also a wrong value in the GigaDevice driver: For the >>> GD5F4GQ4xA it should be 80 instead of 40. >> >> Haven't checked the datasheet, but keep in mind that this is the max >> number of eraseblock per LUN. > > The datasheet gives 20 for the 1G type and 40 for the 2G type. Both > types have only one LUN. Only the 2G type has 2 planes, but that > shouldn't make a difference, right? Sorry, I was referring to the Macronix chips. You were probably talking about the GigaDevice. But they all have only one LUN, too. So I think I got it right.
On Thu, 6 Jun 2019 08:57:32 +0000 Schrempf Frieder <frieder.schrempf@kontron.de> wrote: > On 06.06.19 10:52, Frieder Schrempf wrote: > > On 06.06.19 10:39, Boris Brezillon wrote: > >> On Thu, 6 Jun 2019 08:27:11 +0000 > >> Schrempf Frieder <frieder.schrempf@kontron.de> wrote: > >> > >>> Hi Emil, > >>> > >>> On 04.06.19 10:01, Emil Lenngren wrote: > >>>> Hi Miquel, > >>>>> static const struct spinand_info macronix_spinand_table[] = { > >>>>> SPINAND_INFO("MX35LF1GE4AB", 0x12, > >>>>> - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), > >>>>> + NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1), > >>>>> NAND_ECCREQ(4, 512), > >>>>> SPINAND_INFO_OP_VARIANTS(&read_cache_variants, > >>>>> &write_cache_variants, > >>>>> @@ -103,7 +103,7 @@ static const struct spinand_info > >>>>> macronix_spinand_table[] = { > >>>>> SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, > >>>>> mx35lf1ge4ab_ecc_get_status)), > >>>>> SPINAND_INFO("MX35LF2GE4AB", 0x22, > >>>>> - NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), > >>>>> + NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1), > >>>>> NAND_ECCREQ(4, 512), > >>>> > >>>> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped > >>>> here, i.e. isn't it the larger flash that has more max bad blocks than > >>>> the smaller one? > >>> > >>> I think Miquel is out of office for some days, so I just checked and you > >>> are right, the maximum number of bad blocks should be swapped. > >>> > >>> Actually there is also a wrong value in the GigaDevice driver: For the > >>> GD5F4GQ4xA it should be 80 instead of 40. > >> > >> Haven't checked the datasheet, but keep in mind that this is the max > >> number of eraseblock per LUN. > > > > The datasheet gives 20 for the 1G type and 40 for the 2G type. Both > > types have only one LUN. Only the 2G type has 2 planes, but that > > shouldn't make a difference, right? > > Sorry, I was referring to the Macronix chips. You were probably talking > about the GigaDevice. But they all have only one LUN, too. So I think I > got it right. Good, just wanted to make sure you were aware of that fact. As I said, I didn't check the datasheet, so I trust you on this one.
Hi Schrempf, Den tors 6 juni 2019 kl 10:27 skrev Schrempf Frieder <frieder.schrempf@kontron.de>: > > Hi Emil, > > On 04.06.19 10:01, Emil Lenngren wrote: > > Hi Miquel, > > > >> static const struct spinand_info macronix_spinand_table[] = { > >> SPINAND_INFO("MX35LF1GE4AB", 0x12, > >> - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), > >> + NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1), > >> NAND_ECCREQ(4, 512), > >> SPINAND_INFO_OP_VARIANTS(&read_cache_variants, > >> &write_cache_variants, > >> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = { > >> SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, > >> mx35lf1ge4ab_ecc_get_status)), > >> SPINAND_INFO("MX35LF2GE4AB", 0x22, > >> - NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), > >> + NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1), > >> NAND_ECCREQ(4, 512), > > > > Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped > > here, i.e. isn't it the larger flash that has more max bad blocks than > > the smaller one? > > I think Miquel is out of office for some days, so I just checked and you > are right, the maximum number of bad blocks should be swapped. > > Actually there is also a wrong value in the GigaDevice driver: For the > GD5F4GQ4xA it should be 80 instead of 40. > > Would you mind sending a patch with a "Fixes:" tag, that fixes both, the > Macronix and the GigaDevice driver? Or should I send one? Please go ahead :) /Emil
diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c index e6554b401813..0a2be5e6d669 100644 --- a/drivers/mtd/nand/core.c +++ b/drivers/mtd/nand/core.c @@ -173,6 +173,40 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo) } EXPORT_SYMBOL_GPL(nanddev_mtd_erase); +/** + * nanddev_mtd_max_bad_blocks() - Get the maximum number of bad eraseblock on + * a specific region of the NAND device + * @mtd: MTD device + * @offs: offset of the NAND region + * @len: length of the NAND region + * + * Default implementation for mtd->_max_bad_blocks(). Only works if + * nand->memorg.max_bad_eraseblocks_per_lun is > 0. + * + * Return: a positive number encoding the maximum number of eraseblocks on a + * portion of memory, a negative error code otherwise. + */ +int nanddev_mtd_max_bad_blocks(struct mtd_info *mtd, loff_t offs, size_t len) +{ + struct nand_device *nand = mtd_to_nanddev(mtd); + struct nand_pos pos, end; + unsigned int max_bb = 0; + + if (!nand->memorg.max_bad_eraseblocks_per_lun) + return -ENOTSUPP; + + nanddev_offs_to_pos(nand, offs, &pos); + nanddev_offs_to_pos(nand, offs + len, &end); + + for (nanddev_offs_to_pos(nand, offs, &pos); + nanddev_pos_cmp(&pos, &end) < 0; + nanddev_pos_next_lun(nand, &pos)) + max_bb += nand->memorg.max_bad_eraseblocks_per_lun; + + return max_bb; +} +EXPORT_SYMBOL_GPL(nanddev_mtd_max_bad_blocks); + /** * nanddev_init() - Initialize a NAND device * @nand: NAND device diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c index e4141c20947a..c434fbed3ce5 100644 --- a/drivers/mtd/nand/spi/gigadevice.c +++ b/drivers/mtd/nand/spi/gigadevice.c @@ -88,7 +88,7 @@ static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = { static const struct spinand_info gigadevice_spinand_table[] = { SPINAND_INFO("GD5F1GQ4xA", 0xF1, - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, @@ -97,7 +97,7 @@ static const struct spinand_info gigadevice_spinand_table[] = { SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, gd5fxgq4xa_ecc_get_status)), SPINAND_INFO("GD5F2GQ4xA", 0xF2, - NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, @@ -106,7 +106,7 @@ static const struct spinand_info gigadevice_spinand_table[] = { SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, gd5fxgq4xa_ecc_get_status)), SPINAND_INFO("GD5F4GQ4xA", 0xF4, - NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1), + NAND_MEMORG(1, 2048, 64, 64, 4096, 40, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c index 98f6b9c4b684..c6300d9d63f9 100644 --- a/drivers/mtd/nand/spi/macronix.c +++ b/drivers/mtd/nand/spi/macronix.c @@ -94,7 +94,7 @@ static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand, static const struct spinand_info macronix_spinand_table[] = { SPINAND_INFO("MX35LF1GE4AB", 0x12, - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), + NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1), NAND_ECCREQ(4, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = { SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, mx35lf1ge4ab_ecc_get_status)), SPINAND_INFO("MX35LF2GE4AB", 0x22, - NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), + NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1), NAND_ECCREQ(4, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c index 9c4381d6847b..7d7b1f7fcf71 100644 --- a/drivers/mtd/nand/spi/micron.c +++ b/drivers/mtd/nand/spi/micron.c @@ -92,7 +92,7 @@ static int mt29f2g01abagd_ecc_get_status(struct spinand_device *spinand, static const struct spinand_info micron_spinand_table[] = { SPINAND_INFO("MT29F2G01ABAGD", 0x24, - NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c index 081265557e70..00ddab08e6c6 100644 --- a/drivers/mtd/nand/spi/toshiba.c +++ b/drivers/mtd/nand/spi/toshiba.c @@ -95,7 +95,7 @@ static int tc58cvg2s0h_ecc_get_status(struct spinand_device *spinand, static const struct spinand_info toshiba_spinand_table[] = { SPINAND_INFO("TC58CVG2S0H", 0xCD, - NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c index 5d944580b898..a6c17e0cace8 100644 --- a/drivers/mtd/nand/spi/winbond.c +++ b/drivers/mtd/nand/spi/winbond.c @@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct spinand_device *spinand, static const struct spinand_info winbond_spinand_table[] = { SPINAND_INFO("W25M02GV", 0xAB, - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 2), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2), NAND_ECCREQ(1, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, @@ -85,7 +85,7 @@ static const struct spinand_info winbond_spinand_table[] = { SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), SPINAND_SELECT_TARGET(w25m02gv_select_target)), SPINAND_INFO("W25N01GV", 0xAA, - NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), NAND_ECCREQ(1, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 7f53ece2c039..d32bb623d532 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -19,6 +19,7 @@ * @oobsize: OOB area size * @pages_per_eraseblock: number of pages per eraseblock * @eraseblocks_per_lun: number of eraseblocks per LUN (Logical Unit Number) + * @max_bad_eraseblocks_per_lun: maximum number of eraseblocks per LUN * @planes_per_lun: number of planes per LUN * @luns_per_target: number of LUN per target (target is a synonym for die) * @ntargets: total number of targets exposed by the NAND device @@ -29,18 +30,20 @@ struct nand_memory_organization { unsigned int oobsize; unsigned int pages_per_eraseblock; unsigned int eraseblocks_per_lun; + unsigned int max_bad_eraseblocks_per_lun; unsigned int planes_per_lun; unsigned int luns_per_target; unsigned int ntargets; }; -#define NAND_MEMORG(bpc, ps, os, ppe, epl, ppl, lpt, nt) \ +#define NAND_MEMORG(bpc, ps, os, ppe, epl, mbb, ppl, lpt, nt) \ { \ .bits_per_cell = (bpc), \ .pagesize = (ps), \ .oobsize = (os), \ .pages_per_eraseblock = (ppe), \ .eraseblocks_per_lun = (epl), \ + .max_bad_eraseblocks_per_lun = (mbb), \ .planes_per_lun = (ppl), \ .luns_per_target = (lpt), \ .ntargets = (nt), \ @@ -729,5 +732,6 @@ static inline bool nanddev_bbt_is_initialized(struct nand_device *nand) /* MTD -> NAND helper functions. */ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo); +int nanddev_mtd_max_bad_blocks(struct mtd_info *mtd, loff_t offs, size_t len); #endif /* __LINUX_MTD_NAND_H */