linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/4] Add SR 4bit block protection support
@ 2020-03-24  6:01 Tudor.Ambarus
  2020-03-24  6:01 ` [PATCH v4 1/4] mtd: spi-nor: Set all BP bits to one when lock_len == mtd->size Tudor.Ambarus
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Tudor.Ambarus @ 2020-03-24  6:01 UTC (permalink / raw)
  To: js07.lee, michael, vigneshr; +Cc: linux-mtd, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Hi,

In v4, I dropped patch 1/5 and stripped the changelog that I had
above my S-o-b tag in each patch.

Jungseung Lee (3):
  mtd: spi-nor: Add new formula for SR block protection handling
  mtd: spi-nor: Add SR 4bit block protection support
  mtd: spi-nor: Enable locking for n25q512ax3/n25q512a

Tudor Ambarus (1):
  mtd: spi-nor: Set all BP bits to one when lock_len == mtd->size

 drivers/mtd/spi-nor/core.c      | 144 +++++++++++++++++++++-----------
 drivers/mtd/spi-nor/core.h      |  10 +++
 drivers/mtd/spi-nor/micron-st.c |   8 +-
 include/linux/mtd/spi-nor.h     |   2 +
 4 files changed, 113 insertions(+), 51 deletions(-)

-- 
2.23.0

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

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

* [PATCH v4 1/4] mtd: spi-nor: Set all BP bits to one when lock_len == mtd->size
  2020-03-24  6:01 [PATCH v4 0/4] Add SR 4bit block protection support Tudor.Ambarus
@ 2020-03-24  6:01 ` Tudor.Ambarus
  2020-03-24  6:01 ` [PATCH v4 2/4] mtd: spi-nor: Add new formula for SR block protection handling Tudor.Ambarus
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Tudor.Ambarus @ 2020-03-24  6:01 UTC (permalink / raw)
  To: js07.lee, michael, vigneshr; +Cc: linux-mtd, Tudor.Ambarus

From: Tudor Ambarus <tudor.ambarus@microchip.com>

When there are more BP settings than needed for defining the protected
areas of the flash memory, most flashes will define the remaining
settings as "protect all", i.e. the equivalent of having all the BP bits
set to one. But there are flashes where the in-between BP values
are undefined (not mentioned), and only the "all bits set" is protecting
the entire memory. One such example is w25q80, where BP[2:0]=0b101 and
0b110 are not defined.

Set all the BP bits to one when lock_len == mtd->size, to treat this
special case.

Suggested-by: Michael Walle <michael@walle.cc>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Jungseung Lee <js07.lee@samsung.com>
Reviewed-by: Michael Walle <michael@walle.cc>
---
 drivers/mtd/spi-nor/core.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index e0021dd34bfe..bc57b1b5ec62 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1682,13 +1682,19 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	 *
 	 *   pow = ceil(log2(size / len)) = log2(size) - floor(log2(len))
 	 */
-	pow = ilog2(mtd->size) - ilog2(lock_len);
-	val = mask - (pow << SR_BP_SHIFT);
-	if (val & ~mask)
-		return -EINVAL;
-	/* Don't "lock" with no region! */
-	if (!(val & mask))
-		return -EINVAL;
+	if (lock_len == mtd->size) {
+		val = mask;
+	} else {
+		pow = ilog2(mtd->size) - ilog2(lock_len);
+		val = mask - (pow << SR_BP_SHIFT);
+
+		if (val & ~mask)
+			return -EINVAL;
+
+		/* Don't "lock" with no region! */
+		if (!(val & mask))
+			return -EINVAL;
+	}
 
 	status_new = (status_old & ~mask & ~tb_mask) | val;
 
-- 
2.23.0

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

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

* [PATCH v4 2/4] mtd: spi-nor: Add new formula for SR block protection handling
  2020-03-24  6:01 [PATCH v4 0/4] Add SR 4bit block protection support Tudor.Ambarus
  2020-03-24  6:01 ` [PATCH v4 1/4] mtd: spi-nor: Set all BP bits to one when lock_len == mtd->size Tudor.Ambarus
@ 2020-03-24  6:01 ` Tudor.Ambarus
  2020-03-24  6:01 ` [PATCH v4 4/4] mtd: spi-nor: Enable locking for n25q512ax3/n25q512a Tudor.Ambarus
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Tudor.Ambarus @ 2020-03-24  6:01 UTC (permalink / raw)
  To: js07.lee, michael, vigneshr; +Cc: linux-mtd, Tudor.Ambarus

From: Jungseung Lee <js07.lee@samsung.com>

The current mainline locking was restricted and could only be applied
to flashes that have 3 block protection bits and fixed locking ratio.

A new method of normalization was reached at the end of the discussion [1].

    (1) - if bp slot is insufficient.
    (2) - if bp slot is sufficient.

    if (bp_slots_needed > bp_slots)    // (1)
        min_prot_length = sector_size << (bp_slots_needed - bp_slots);
    else                               // (2)
        min_prot_length = sector_size;

This patch changes logic to handle block protection based on min_prot_length.
It is suitable for the overall flashes with exception of some corner cases
(see EON and catalyst) and easy to extend and apply for the case of 2bit or
4bit block protection.

[1] http://lists.infradead.org/pipermail/linux-mtd/2020-February/093934.html

Signed-off-by: Jungseung Lee <js07.lee@samsung.com>
Reviewed-by: Michael Walle <michael@walle.cc>
Tested-by: Michael Walle <michael@walle.cc>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/core.c | 72 ++++++++++++++++++++++----------------
 1 file changed, 41 insertions(+), 31 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index bc57b1b5ec62..8146d82afe61 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1536,29 +1536,51 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	return ret;
 }
 
+static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
+{
+	unsigned int bp_slots, bp_slots_needed;
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	/* Reserved one for "protect none" and one for "protect all". */
+	bp_slots = (mask >> SR_BP_SHIFT) + 1 - 2;
+	bp_slots_needed = ilog2(nor->info->n_sectors);
+
+	if (bp_slots_needed > bp_slots)
+		return nor->info->sector_size <<
+			(bp_slots_needed - bp_slots);
+	else
+		return nor->info->sector_size;
+}
+
 static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
 					uint64_t *len)
 {
 	struct mtd_info *mtd = &nor->mtd;
+	u64 min_prot_len;
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 	u8 tb_mask = SR_TB_BIT5;
-	int pow;
+	u8 bp = (sr & mask) >> SR_BP_SHIFT;
 
 	if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
 		tb_mask = SR_TB_BIT6;
 
-	if (!(sr & mask)) {
+	if (!bp) {
 		/* No protection */
 		*ofs = 0;
 		*len = 0;
-	} else {
-		pow = ((sr & mask) ^ mask) >> SR_BP_SHIFT;
-		*len = mtd->size >> pow;
-		if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask)
-			*ofs = 0;
-		else
-			*ofs = mtd->size - *len;
+		return;
 	}
+
+	min_prot_len = spi_nor_get_min_prot_length_sr(nor);
+	*len = min_prot_len << (bp - 1);
+
+	if (*len > mtd->size)
+		*len = mtd->size;
+
+	if (nor->flags & SNOR_F_HAS_SR_TB && sr & tb_mask)
+		*ofs = 0;
+	else
+		*ofs = mtd->size - *len;
 }
 
 /*
@@ -1631,6 +1653,7 @@ static int spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
 static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
 	struct mtd_info *mtd = &nor->mtd;
+	u64 min_prot_len;
 	int ret, status_old, status_new;
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 	u8 tb_mask = SR_TB_BIT5;
@@ -1673,20 +1696,12 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
 		tb_mask = SR_TB_BIT6;
 
-	/*
-	 * Need smallest pow such that:
-	 *
-	 *   1 / (2^pow) <= (len / size)
-	 *
-	 * so (assuming power-of-2 size) we do:
-	 *
-	 *   pow = ceil(log2(size / len)) = log2(size) - floor(log2(len))
-	 */
 	if (lock_len == mtd->size) {
 		val = mask;
 	} else {
-		pow = ilog2(mtd->size) - ilog2(lock_len);
-		val = mask - (pow << SR_BP_SHIFT);
+		min_prot_len = spi_nor_get_min_prot_length_sr(nor);
+		pow = ilog2(lock_len) - ilog2(min_prot_len) + 1;
+		val = pow << SR_BP_SHIFT;
 
 		if (val & ~mask)
 			return -EINVAL;
@@ -1723,6 +1738,7 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
 	struct mtd_info *mtd = &nor->mtd;
+	u64 min_prot_len;
 	int ret, status_old, status_new;
 	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
 	u8 tb_mask = SR_TB_BIT5;
@@ -1764,20 +1780,14 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 
 	if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
 		tb_mask = SR_TB_BIT6;
-	/*
-	 * Need largest pow such that:
-	 *
-	 *   1 / (2^pow) >= (len / size)
-	 *
-	 * so (assuming power-of-2 size) we do:
-	 *
-	 *   pow = floor(log2(size / len)) = log2(size) - ceil(log2(len))
-	 */
-	pow = ilog2(mtd->size) - order_base_2(lock_len);
+
 	if (lock_len == 0) {
 		val = 0; /* fully unlocked */
 	} else {
-		val = mask - (pow << SR_BP_SHIFT);
+		min_prot_len = spi_nor_get_min_prot_length_sr(nor);
+		pow = ilog2(lock_len) - ilog2(min_prot_len) + 1;
+		val = pow << SR_BP_SHIFT;
+
 		/* Some power-of-two sizes are not supported */
 		if (val & ~mask)
 			return -EINVAL;
-- 
2.23.0

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

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

* [PATCH v4 4/4] mtd: spi-nor: Enable locking for n25q512ax3/n25q512a
  2020-03-24  6:01 [PATCH v4 0/4] Add SR 4bit block protection support Tudor.Ambarus
  2020-03-24  6:01 ` [PATCH v4 1/4] mtd: spi-nor: Set all BP bits to one when lock_len == mtd->size Tudor.Ambarus
  2020-03-24  6:01 ` [PATCH v4 2/4] mtd: spi-nor: Add new formula for SR block protection handling Tudor.Ambarus
@ 2020-03-24  6:01 ` Tudor.Ambarus
  2020-03-24  6:01 ` [PATCH v4 3/4] mtd: spi-nor: Add SR 4bit block protection support Tudor.Ambarus
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Tudor.Ambarus @ 2020-03-24  6:01 UTC (permalink / raw)
  To: js07.lee, michael, vigneshr; +Cc: linux-mtd, Tudor.Ambarus

From: Jungseung Lee <js07.lee@samsung.com>

Some Micron models are known to have lock/unlock support,
and that also support 4bit block protection (BP0-3).

This patch support lock/unlock feature on the flashes.
Tested on n25q512ax3. The other is modified following the datasheet.

Signed-off-by: Jungseung Lee <js07.lee@samsung.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/micron-st.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index 3874a62d8b47..6c034b9718e2 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -47,12 +47,16 @@ static const struct flash_info st_parts[] = {
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
 			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
 	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024,
-			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
+			      SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
+			      SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6) },
 	{ "mt25qu512a",  INFO6(0x20bb20, 0x104400, 64 * 1024, 1024,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
 			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
 	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024,
-			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
+			      SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
+			      SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6) },
 	{ "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048,
 			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
 			      NO_CHIP_ERASE) },
-- 
2.23.0

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

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

* [PATCH v4 3/4] mtd: spi-nor: Add SR 4bit block protection support
  2020-03-24  6:01 [PATCH v4 0/4] Add SR 4bit block protection support Tudor.Ambarus
                   ` (2 preceding siblings ...)
  2020-03-24  6:01 ` [PATCH v4 4/4] mtd: spi-nor: Enable locking for n25q512ax3/n25q512a Tudor.Ambarus
@ 2020-03-24  6:01 ` Tudor.Ambarus
  2020-03-24  8:49 ` [PATCH v4 0/4] " Michael Walle
  2020-03-24 13:47 ` Tudor.Ambarus
  5 siblings, 0 replies; 7+ messages in thread
From: Tudor.Ambarus @ 2020-03-24  6:01 UTC (permalink / raw)
  To: js07.lee, michael, vigneshr; +Cc: linux-mtd, Tudor.Ambarus

From: Jungseung Lee <js07.lee@samsung.com>

Currently, we are supporting block protection only for flash chips with
3 block protection bits (BP0-2) in the SR register.

Enable block protection support for flashes with 4 block protection bits
(BP0-3).

Add a flash_info flag for flashes that describe 4 block protection bits.
Add another flash_info flag for flashes in which BP3 bit is not adjacent
to the BP0-2 bits.

Tested with a n25q512ax3 (bp0-3) and w25q128 (bp0-2).

Signed-off-by: Jungseung Lee <js07.lee@samsung.com>
Reviewed-by: Michael Walle <michael@walle.cc>
Tested-by: Michael Walle <michael@walle.cc>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/core.c  | 66 +++++++++++++++++++++++++++----------
 drivers/mtd/spi-nor/core.h  | 10 ++++++
 include/linux/mtd/spi-nor.h |  2 ++
 3 files changed, 60 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 8146d82afe61..cc68ea84318e 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1536,13 +1536,34 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	return ret;
 }
 
+static u8 spi_nor_get_sr_bp_mask(struct spi_nor *nor)
+{
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6)
+		return mask | SR_BP3_BIT6;
+
+	if (nor->flags & SNOR_F_HAS_4BIT_BP)
+		return mask | SR_BP3;
+
+	return mask;
+}
+
+static u8 spi_nor_get_sr_tb_mask(struct spi_nor *nor)
+{
+	if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
+		return SR_TB_BIT6;
+	else
+		return SR_TB_BIT5;
+}
+
 static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor)
 {
 	unsigned int bp_slots, bp_slots_needed;
-	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+	u8 mask = spi_nor_get_sr_bp_mask(nor);
 
 	/* Reserved one for "protect none" and one for "protect all". */
-	bp_slots = (mask >> SR_BP_SHIFT) + 1 - 2;
+	bp_slots = (1 << hweight8(mask)) - 2;
 	bp_slots_needed = ilog2(nor->info->n_sectors);
 
 	if (bp_slots_needed > bp_slots)
@@ -1557,12 +1578,14 @@ static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs,
 {
 	struct mtd_info *mtd = &nor->mtd;
 	u64 min_prot_len;
-	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
-	u8 tb_mask = SR_TB_BIT5;
-	u8 bp = (sr & mask) >> SR_BP_SHIFT;
+	u8 mask = spi_nor_get_sr_bp_mask(nor);
+	u8 tb_mask = spi_nor_get_sr_tb_mask(nor);
+	u8 bp, val = sr & mask;
 
-	if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
-		tb_mask = SR_TB_BIT6;
+	if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3_BIT6)
+		val = (val & ~SR_BP3_BIT6) | SR_BP3;
+
+	bp = val >> SR_BP_SHIFT;
 
 	if (!bp) {
 		/* No protection */
@@ -1620,7 +1643,8 @@ static int spi_nor_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
 
 /*
  * Lock a region of the flash. Compatible with ST Micro and similar flash.
- * Supports the block protection bits BP{0,1,2} in the status register
+ * Supports the block protection bits BP{0,1,2}/BP{0,1,2,3} in the status
+ * register
  * (SR). Does not support these features found in newer SR bitfields:
  *   - SEC: sector/block protect - only handle SEC=0 (block protect)
  *   - CMP: complement protect - only support CMP=0 (range is not complemented)
@@ -1655,8 +1679,8 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	struct mtd_info *mtd = &nor->mtd;
 	u64 min_prot_len;
 	int ret, status_old, status_new;
-	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
-	u8 tb_mask = SR_TB_BIT5;
+	u8 mask = spi_nor_get_sr_bp_mask(nor);
+	u8 tb_mask = spi_nor_get_sr_tb_mask(nor);
 	u8 pow, val;
 	loff_t lock_len;
 	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
@@ -1693,9 +1717,6 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	else
 		lock_len = ofs + len;
 
-	if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
-		tb_mask = SR_TB_BIT6;
-
 	if (lock_len == mtd->size) {
 		val = mask;
 	} else {
@@ -1703,6 +1724,9 @@ static int spi_nor_sr_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 		pow = ilog2(lock_len) - ilog2(min_prot_len) + 1;
 		val = pow << SR_BP_SHIFT;
 
+		if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3)
+			val = (val & ~SR_BP3) | SR_BP3_BIT6;
+
 		if (val & ~mask)
 			return -EINVAL;
 
@@ -1740,8 +1764,8 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	struct mtd_info *mtd = &nor->mtd;
 	u64 min_prot_len;
 	int ret, status_old, status_new;
-	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
-	u8 tb_mask = SR_TB_BIT5;
+	u8 mask = spi_nor_get_sr_bp_mask(nor);
+	u8 tb_mask = spi_nor_get_sr_tb_mask(nor);
 	u8 pow, val;
 	loff_t lock_len;
 	bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
@@ -1778,9 +1802,6 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	else
 		lock_len = ofs;
 
-	if (nor->flags & SNOR_F_HAS_SR_TB_BIT6)
-		tb_mask = SR_TB_BIT6;
-
 	if (lock_len == 0) {
 		val = 0; /* fully unlocked */
 	} else {
@@ -1788,6 +1809,9 @@ static int spi_nor_sr_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 		pow = ilog2(lock_len) - ilog2(min_prot_len) + 1;
 		val = pow << SR_BP_SHIFT;
 
+		if (nor->flags & SNOR_F_HAS_SR_BP3_BIT6 && val & SR_BP3)
+			val = (val & ~SR_BP3) | SR_BP3_BIT6;
+
 		/* Some power-of-two sizes are not supported */
 		if (val & ~mask)
 			return -EINVAL;
@@ -3147,6 +3171,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (info->flags & USE_CLSR)
 		nor->flags |= SNOR_F_USE_CLSR;
 
+	if (info->flags & SPI_NOR_4BIT_BP) {
+		nor->flags |= SNOR_F_HAS_4BIT_BP;
+		if (info->flags & SPI_NOR_BP3_SR_BIT6)
+			nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
+	}
+
 	if (info->flags & SPI_NOR_NO_ERASE)
 		mtd->flags |= MTD_NO_ERASE;
 
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 3ce826b35ad1..6f2f6b27173f 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -24,6 +24,8 @@ enum spi_nor_option_flags {
 	SNOR_F_HAS_16BIT_SR	= BIT(9),
 	SNOR_F_NO_READ_CR	= BIT(10),
 	SNOR_F_HAS_SR_TB_BIT6	= BIT(11),
+	SNOR_F_HAS_4BIT_BP      = BIT(12),
+	SNOR_F_HAS_SR_BP3_BIT6  = BIT(13),
 };
 
 struct spi_nor_read_command {
@@ -301,6 +303,14 @@ struct flash_info {
 					 * status register. Must be used with
 					 * SPI_NOR_HAS_TB.
 					 */
+#define SPI_NOR_4BIT_BP		BIT(17) /*
+					 * Flash SR has 4 bit fields (BP0-3)
+					 * for block protection.
+					 */
+#define SPI_NOR_BP3_SR_BIT6	BIT(18) /*
+					 * BP3 is bit 6 of status register.
+					 * Must be used with SPI_NOR_4BIT_BP.
+					 */
 
 	/* Part specific fixup hooks. */
 	const struct spi_nor_fixups *fixups;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index e656858b50a5..1e2af0ec1f03 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -111,7 +111,9 @@
 #define SR_BP0			BIT(2)	/* Block protect 0 */
 #define SR_BP1			BIT(3)	/* Block protect 1 */
 #define SR_BP2			BIT(4)	/* Block protect 2 */
+#define SR_BP3			BIT(5)	/* Block protect 3 */
 #define SR_TB_BIT5		BIT(5)	/* Top/Bottom protect */
+#define SR_BP3_BIT6		BIT(6)	/* Block protect 3 */
 #define SR_TB_BIT6		BIT(6)	/* Top/Bottom protect */
 #define SR_SRWD			BIT(7)	/* SR write protect */
 /* Spansion/Cypress specific status bits */
-- 
2.23.0

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

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

* Re: [PATCH v4 0/4] Add SR 4bit block protection support
  2020-03-24  6:01 [PATCH v4 0/4] Add SR 4bit block protection support Tudor.Ambarus
                   ` (3 preceding siblings ...)
  2020-03-24  6:01 ` [PATCH v4 3/4] mtd: spi-nor: Add SR 4bit block protection support Tudor.Ambarus
@ 2020-03-24  8:49 ` Michael Walle
  2020-03-24 13:47 ` Tudor.Ambarus
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Walle @ 2020-03-24  8:49 UTC (permalink / raw)
  To: Tudor.Ambarus; +Cc: linux-mtd, vigneshr, js07.lee

Am 2020-03-24 07:01, schrieb Tudor.Ambarus@microchip.com:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Hi,
> 
> In v4, I dropped patch 1/5 and stripped the changelog that I had
> above my S-o-b tag in each patch.

looks, good, will you merge this into next today?

-michael

> 
> Jungseung Lee (3):
>   mtd: spi-nor: Add new formula for SR block protection handling
>   mtd: spi-nor: Add SR 4bit block protection support
>   mtd: spi-nor: Enable locking for n25q512ax3/n25q512a
> 
> Tudor Ambarus (1):
>   mtd: spi-nor: Set all BP bits to one when lock_len == mtd->size
> 
>  drivers/mtd/spi-nor/core.c      | 144 +++++++++++++++++++++-----------
>  drivers/mtd/spi-nor/core.h      |  10 +++
>  drivers/mtd/spi-nor/micron-st.c |   8 +-
>  include/linux/mtd/spi-nor.h     |   2 +
>  4 files changed, 113 insertions(+), 51 deletions(-)

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

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

* Re: [PATCH v4 0/4] Add SR 4bit block protection support
  2020-03-24  6:01 [PATCH v4 0/4] Add SR 4bit block protection support Tudor.Ambarus
                   ` (4 preceding siblings ...)
  2020-03-24  8:49 ` [PATCH v4 0/4] " Michael Walle
@ 2020-03-24 13:47 ` Tudor.Ambarus
  5 siblings, 0 replies; 7+ messages in thread
From: Tudor.Ambarus @ 2020-03-24 13:47 UTC (permalink / raw)
  To: js07.lee; +Cc: michael, linux-mtd, vigneshr

On Tuesday, March 24, 2020 8:01:27 AM EET Tudor Ambarus - M18064 wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Hi,
> 
> In v4, I dropped patch 1/5 and stripped the changelog that I had
> above my S-o-b tag in each patch.
> 
> Jungseung Lee (3):
>   mtd: spi-nor: Add new formula for SR block protection handling
>   mtd: spi-nor: Add SR 4bit block protection support
>   mtd: spi-nor: Enable locking for n25q512ax3/n25q512a
> 
> Tudor Ambarus (1):
>   mtd: spi-nor: Set all BP bits to one when lock_len == mtd->size
> 
>  drivers/mtd/spi-nor/core.c      | 144 +++++++++++++++++++++-----------
>  drivers/mtd/spi-nor/core.h      |  10 +++
>  drivers/mtd/spi-nor/micron-st.c |   8 +-
>  include/linux/mtd/spi-nor.h     |   2 +
>  4 files changed, 113 insertions(+), 51 deletions(-)

All applied, thanks.
ta



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

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

end of thread, other threads:[~2020-03-24 13:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-24  6:01 [PATCH v4 0/4] Add SR 4bit block protection support Tudor.Ambarus
2020-03-24  6:01 ` [PATCH v4 1/4] mtd: spi-nor: Set all BP bits to one when lock_len == mtd->size Tudor.Ambarus
2020-03-24  6:01 ` [PATCH v4 2/4] mtd: spi-nor: Add new formula for SR block protection handling Tudor.Ambarus
2020-03-24  6:01 ` [PATCH v4 4/4] mtd: spi-nor: Enable locking for n25q512ax3/n25q512a Tudor.Ambarus
2020-03-24  6:01 ` [PATCH v4 3/4] mtd: spi-nor: Add SR 4bit block protection support Tudor.Ambarus
2020-03-24  8:49 ` [PATCH v4 0/4] " Michael Walle
2020-03-24 13:47 ` Tudor.Ambarus

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).