public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] mtd: spi-nor: core: Set mtd->eraseregions for non-uniform erase map
@ 2023-12-25  8:03 tkuw584924
  2024-01-05 12:23 ` Michael Walle
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: tkuw584924 @ 2023-12-25  8:03 UTC (permalink / raw)
  To: linux-mtd
  Cc: tudor.ambarus, pratyush, michael, miquel.raynal, richard,
	vigneshr, tkuw584924, Bacem.Daassi, Takahiro Kuwano

From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>

Some of Infineon SPI NOR flash devices support hybrid sector layout that
overlays 4KB sectors on a 256KB sector and SPI NOR framework recognizes
that by parsing SMPT and construct params->erase_map. The hybrid sector
layout is similar to CFI flash devices that have small sectors on top
and/or bottom address. In case of CFI flash devices, the erase map
information is parsed through CFI table and populated into
mtd->eraseregions so that users can create MTD partitions that aligned with
small sector boundaries. This patch provides the same capability to SPI
NOR flash devices that have non-uniform erase map.

Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
---
The s25hs512t has 32 x 4KB, 1 x 128KB, and 255 x 256KB sectors by default.
Let's think about creating three MTD partitions that align to region
boundary.

BEFORE applying this patch, 1st and 2nd region are forced to read-only:

---kernel log---
...
spi-nor spi0.0: s25hs512t (65536 Kbytes)
3 fixed-partitions partitions found on MTD device spi0.0
Creating 3 MTD partitions on "spi0.0":
0x000000000000-0x000000020000 : "4KB x 32"
mtd: partition "4KB x 32" doesn't end on an erase/write block -- force read-only
0x000000020000-0x000000040000 : "128KB x 1"
mtd: partition "128KB x 1" doesn't start on an erase/write block boundary -- force read-only
0x000000040000-0x000004000000 : "256KB x 255"
...

---MTD Info---
zynq> mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_ROM
mtd.size = 131072 (128K)
mtd.erasesize = 262144 (256K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0

zynq> mtd_debug info /dev/mtd1
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_ROM
mtd.size = 131072 (128K)
mtd.erasesize = 262144 (256K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0

zynq> mtd_debug info /dev/mtd2
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 66846720 (63M)
mtd.erasesize = 262144 (256K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0



AFTER applying this patch, erasesize is correctly informed and no read-only:

---kernel log---
...
spi-nor spi0.0: s25hs512t (65536 Kbytes)
3 fixed-partitions partitions found on MTD device spi0.0
Creating 3 MTD partitions on "spi0.0":
0x000000000000-0x000000020000 : "4KB x 32"
0x000000020000-0x000000040000 : "128KB x 1"
0x000000040000-0x000004000000 : "256KB x 255"
...

---MTD Info---
zynq> mtd_debug info /dev/mtd0
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 131072 (128K)
mtd.erasesize = 4096 (4K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0

zynq> mtd_debug info /dev/mtd1
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 131072 (128K)
mtd.erasesize = 131072 (128K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0

zynq> mtd_debug info /dev/mtd2
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 66846720 (63M)
mtd.erasesize = 262144 (256K)
mtd.writesize = 16
mtd.oobsize = 0
regions = 0

---
 drivers/mtd/spi-nor/core.c | 55 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 1b0c6770c14e..e512491733a8 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3408,7 +3408,51 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
 	return info;
 }
 
-static void spi_nor_set_mtd_info(struct spi_nor *nor)
+static int spi_nor_set_mtd_eraseregions(struct spi_nor *nor)
+{
+	struct spi_nor_erase_map *map = &nor->params->erase_map;
+	struct spi_nor_erase_region *region = map->regions;
+	struct mtd_info *mtd = &nor->mtd;
+	struct mtd_erase_region_info *mtd_region;
+	u32 erase_size;
+	u8 erase_mask;
+	int n_regions, i, j;
+
+	for (i = 0; !spi_nor_region_is_last(&region[i]); i++)
+		;
+
+	n_regions = i + 1;
+	mtd_region = devm_kcalloc(nor->dev, n_regions, sizeof(*mtd_region),
+				  GFP_KERNEL);
+	if (!mtd_region)
+		return -ENOMEM;
+
+	for (i = 0; i < n_regions; i++) {
+		if (region[i].offset & SNOR_OVERLAID_REGION) {
+			erase_size = region[i].size;
+		} else {
+			erase_mask = region[i].offset & SNOR_ERASE_TYPE_MASK;
+
+			for (j = SNOR_ERASE_TYPE_MAX - 1; j >= 0; j--) {
+				if (erase_mask & BIT(j)) {
+					erase_size = map->erase_type[j].size;
+					break;
+				}
+			}
+		}
+		mtd_region[i].erasesize = erase_size;
+		mtd_region[i].numblocks = div64_ul(region[i].size, erase_size);
+		mtd_region[i].offset = region[i].offset &
+				       ~SNOR_ERASE_FLAGS_MASK;
+	}
+
+	mtd->numeraseregions = n_regions;
+	mtd->eraseregions = mtd_region;
+
+	return 0;
+}
+
+static int spi_nor_set_mtd_info(struct spi_nor *nor)
 {
 	struct mtd_info *mtd = &nor->mtd;
 	struct device *dev = nor->dev;
@@ -3439,6 +3483,11 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor)
 	mtd->_resume = spi_nor_resume;
 	mtd->_get_device = spi_nor_get_device;
 	mtd->_put_device = spi_nor_put_device;
+
+	if (spi_nor_has_uniform_erase(nor))
+		return 0;
+
+	return spi_nor_set_mtd_eraseregions(nor);
 }
 
 static int spi_nor_hw_reset(struct spi_nor *nor)
@@ -3531,7 +3580,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 		return ret;
 
 	/* No mtd_info fields should be used up to this point. */
-	spi_nor_set_mtd_info(nor);
+	ret = spi_nor_set_mtd_info(nor);
+	if (ret)
+		return ret;
 
 	dev_info(dev, "%s (%lld Kbytes)\n", info->name,
 			(long long)mtd->size >> 10);
-- 
2.34.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2024-01-19 14:01 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-25  8:03 [PATCH] mtd: spi-nor: core: Set mtd->eraseregions for non-uniform erase map tkuw584924
2024-01-05 12:23 ` Michael Walle
2024-01-12  7:14   ` Takahiro Kuwano
2024-01-12  9:22     ` Tudor Ambarus
2024-01-19  6:29     ` Takahiro Kuwano
2024-01-19  6:55       ` Tudor Ambarus
2024-01-19  8:35         ` Takahiro Kuwano
2024-01-19 12:49         ` Michael Walle
2024-01-12  9:43 ` Tudor Ambarus
2024-01-12 10:12 ` Tudor Ambarus
2024-01-12 12:01   ` Michael Walle
2024-01-12 12:22     ` Tudor Ambarus
2024-01-12 12:28       ` Michael Walle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox