All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3] spi-nor block protection
@ 2019-03-20  7:16 Jonas Bonn
  2019-03-20  7:16 ` [PATCH v4 1/3] spi-nor: always respect write-protect input Jonas Bonn
                   ` (2 more replies)
  0 siblings, 3 replies; 62+ messages in thread
From: Jonas Bonn @ 2019-03-20  7:16 UTC (permalink / raw)
  To: linux-mtd; +Cc: Jonas Bonn, tudor.ambarus

Changed in v4:
* Send to right mailing list! :)
* Re-add BPNV patch so that the idea does not get lost... undecided what
to do with it, still.

Changed in v3:
* Fix up patch esthetics
* Drop BPNV patch from series

Changed in v2:
* Provide the below cover letter
* Rebase patches so they apply cleanly on linux-next


In order to make device that's effectively read-only except to an
authorized user we need:

i)  Some way of defaulting block-protection to on when device is first
powered
ii)  Some way of controlling the write-protect signal so that the BP
(block protect) bits can't be changed

Some SPI flashes support the BPNV configuration register bit:  block
protect non-volatile.  When this bit is set, the block protection bits
BP0, BP1, and BP2 default to 1, effectively causing the flash memory to
becomes read-only at power on.  If we can set this bit, we solve problem
i) above.

Controlling the write-protect input is a matter for something external
to the flash itself.  Unfortunately, the WP# signal is only honoured if
the status register bit SRWD (status register write disable) is set.  If
we can have this bit always set, then we solve problem ii) above.

This short patch series provides the above bits, allowing for the
creation of a device that's effectively read-only to any actor who isn't
able to control the WP# signal.

Jonas Bonn (3):
  spi-nor: always respect write-protect input
  spi-nor: s25fl512s supports region locking
  spi-nor: allow setting the BPNV (default locked) bit

 drivers/mtd/mtdchar.c         |   6 ++
 drivers/mtd/mtdcore.c         |   8 +++
 drivers/mtd/spi-nor/spi-nor.c | 119 +++++++++++++++++++++++-----------
 include/linux/mtd/mtd.h       |   2 +
 include/linux/mtd/spi-nor.h   |   1 +
 include/uapi/mtd/mtd-abi.h    |   1 +
 6 files changed, 99 insertions(+), 38 deletions(-)

-- 
2.19.1


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

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

* [PATCH v4 1/3] spi-nor: always respect write-protect input
  2019-03-20  7:16 [PATCH v4 0/3] spi-nor block protection Jonas Bonn
@ 2019-03-20  7:16 ` Jonas Bonn
  2019-03-20  7:16 ` [PATCH v4 2/3] spi-nor: s25fl512s supports region locking Jonas Bonn
  2019-03-20  7:16 ` [PATCH v4 3/3] spi-nor: allow setting the BPNV (default locked) bit Jonas Bonn
  2 siblings, 0 replies; 62+ messages in thread
From: Jonas Bonn @ 2019-03-20  7:16 UTC (permalink / raw)
  To: linux-mtd; +Cc: Jonas Bonn, tudor.ambarus

The status register bit SRWD (status register write disable) is
described in many words in the datasheets but effectively boils down to:

i) if set, respect WP# when trying to change protection bits;
ii) if unset, ignore WP# when trying to change protection bits

In short, the bit determines whether the WP# signal is honored or not.

It's difficult to imagine the use-case where the WP# is connected and
asserted but the user doesn't want to respect its setting.  As such,
this patch sets the SRWD bit unconditionally so that the WP# is _always_
respected; hardware that doesn't care about WP# normally won't even have
it connected.

Tested on a Cypress s25fl512s.  With this patch, the WP# is always
respected, irregardless of whether any flash protection bits are set.

Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
---
 drivers/mtd/spi-nor/spi-nor.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index fae147452aff..0cc0ef4fbf3a 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1231,9 +1231,6 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 
 	status_new = (status_old & ~mask & ~SR_TB) | val;
 
-	/* Disallow further writes if WP pin is asserted */
-	status_new |= SR_SRWD;
-
 	if (!use_top)
 		status_new |= SR_TB;
 
@@ -1313,10 +1310,6 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 
 	status_new = (status_old & ~mask & ~SR_TB) | val;
 
-	/* Don't protect status register if we're fully unlocked */
-	if (lock_len == 0)
-		status_new &= ~SR_SRWD;
-
 	if (!use_top)
 		status_new |= SR_TB;
 
@@ -3909,6 +3902,7 @@ static int spi_nor_setup(struct spi_nor *nor,
 static int spi_nor_init(struct spi_nor *nor)
 {
 	int err;
+	int sr;
 
 	/*
 	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
@@ -3944,6 +3938,16 @@ static int spi_nor_init(struct spi_nor *nor)
 		set_4byte(nor, true);
 	}
 
+	/* Always respect the WP# (write-protect) input */
+	sr = read_sr(nor);
+	if (sr < 0) {
+		dev_err(nor->dev, "error while reading status register\n");
+		return -EINVAL;
+	}
+	sr |= SR_SRWD;
+	return write_sr_and_check(nor, sr, SR_SRWD);
+
+
 	return 0;
 }
 
-- 
2.19.1


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

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

* [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-03-20  7:16 [PATCH v4 0/3] spi-nor block protection Jonas Bonn
  2019-03-20  7:16 ` [PATCH v4 1/3] spi-nor: always respect write-protect input Jonas Bonn
@ 2019-03-20  7:16 ` Jonas Bonn
  2019-03-20  7:39   ` Tudor.Ambarus
                     ` (2 more replies)
  2019-03-20  7:16 ` [PATCH v4 3/3] spi-nor: allow setting the BPNV (default locked) bit Jonas Bonn
  2 siblings, 3 replies; 62+ messages in thread
From: Jonas Bonn @ 2019-03-20  7:16 UTC (permalink / raw)
  To: linux-mtd; +Cc: Jonas Bonn, tudor.ambarus

Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
Tested and verified on a Cypress s25fl512s.

Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
---
 drivers/mtd/spi-nor/spi-nor.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 0cc0ef4fbf3a..9abac9e326a1 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
 			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
 	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
 	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
-	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
+	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
+			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
 	{ "s25fs512s",  INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
-- 
2.19.1


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

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

* [PATCH v4 3/3] spi-nor: allow setting the BPNV (default locked) bit
  2019-03-20  7:16 [PATCH v4 0/3] spi-nor block protection Jonas Bonn
  2019-03-20  7:16 ` [PATCH v4 1/3] spi-nor: always respect write-protect input Jonas Bonn
  2019-03-20  7:16 ` [PATCH v4 2/3] spi-nor: s25fl512s supports region locking Jonas Bonn
@ 2019-03-20  7:16 ` Jonas Bonn
  2019-04-02  5:27   ` Vignesh Raghavendra
  2 siblings, 1 reply; 62+ messages in thread
From: Jonas Bonn @ 2019-03-20  7:16 UTC (permalink / raw)
  To: linux-mtd; +Cc: Jonas Bonn, tudor.ambarus

Setting the BPNV bit defaults the block protection bits BP0-2 to 1 at
reset.  This means that all the flash sectors are protected until they
are explicity unlocked by the user.

Together with protection of the status register via the SRWD bit and the
WP# signal, this allows a flash device to be effectively protected from
erasure by unauthorized actors.

The patch has been tested with a Cypress s25fl512s and works as
advertised.  The concern that I have with this, though, is that the BPNV
bit is "write once":  if somebody inadvertently sets this feature on the
device, it is irrevocable!  Whether or not this actually belongs in the
mainline kernel is therefore up for debate...

Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
---
 drivers/mtd/mtdchar.c         |   6 ++
 drivers/mtd/mtdcore.c         |   8 +++
 drivers/mtd/spi-nor/spi-nor.c | 103 +++++++++++++++++++++++-----------
 include/linux/mtd/mtd.h       |   2 +
 include/linux/mtd/spi-nor.h   |   1 +
 include/uapi/mtd/mtd-abi.h    |   1 +
 6 files changed, 88 insertions(+), 33 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 02389528f622..72842308087b 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -800,6 +800,12 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 		break;
 	}
 
+	case MEMSETDEFAULTLOCKED:
+	{
+		ret = mtd_set_default_locked(mtd);
+		break;
+	}
+
 	case MEMLOCK:
 	{
 		struct erase_info_user einfo;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 76b4264936ff..811fe0f3c24a 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1681,6 +1681,14 @@ int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
 }
 EXPORT_SYMBOL_GPL(mtd_lock_user_prot_reg);
 
+int mtd_set_default_locked(struct mtd_info *mtd)
+{
+	if (!mtd->_set_default_locked)
+		return -EOPNOTSUPP;
+	return mtd->_set_default_locked(mtd);
+}
+EXPORT_SYMBOL_GPL(mtd_set_default_locked);
+
 /* Chip-supported device locking */
 int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 9abac9e326a1..8a30cdac6f88 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -250,7 +250,8 @@ struct flash_info {
 	u16		page_size;
 	u16		addr_width;
 
-	u16		flags;
+	u16		__unused16;
+	u32		flags;
 #define SECT_4K			BIT(0)	/* SPINOR_OP_BE_4K works uniformly */
 #define SPI_NOR_NO_ERASE	BIT(1)	/* No erase command needed */
 #define SST_WRITE		BIT(2)	/* use SST byte programming */
@@ -279,6 +280,10 @@ struct flash_info {
 #define SPI_NOR_SKIP_SFDP	BIT(13)	/* Skip parsing of SFDP tables */
 #define USE_CLSR		BIT(14)	/* use CLSR command */
 #define SPI_NOR_OCTAL_READ	BIT(15)	/* Flash supports Octal Read */
+#define SPI_NOR_HAS_BPNV	BIT(16) /* Block protection bits can be set
+					 * non-volatile, meaning all blocks
+					 * are protected by default at reset
+					 */
 
 	/* Part specific fixup hooks. */
 	const struct spi_nor_fixups *fixups;
@@ -1324,6 +1329,36 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	return write_sr_and_check(nor, status_new, mask);
 }
 
+/*
+ * Write status Register and configuration register with 2 bytes
+ * The first byte will be written to the status register, while the
+ * second byte will be written to the configuration register.
+ * Return negative if error occurred.
+ */
+static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
+{
+	int ret;
+
+	write_enable(nor);
+
+	ret = nor->write_reg(nor, SPINOR_OP_WRSR, sr_cr, 2);
+	if (ret < 0) {
+		dev_err(nor->dev,
+			"error while writing configuration register\n");
+		return -EINVAL;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret) {
+		dev_err(nor->dev,
+			"timeout while writing configuration register\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+
 /*
  * Check if a region of the flash is (completely) locked. See stm_lock() for
  * more info.
@@ -1342,6 +1377,35 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	return stm_is_locked_sr(nor, ofs, len, status);
 }
 
+static int spi_nor_set_default_locked(struct mtd_info *mtd)
+{
+	struct spi_nor *nor = mtd_to_spi_nor(mtd);
+	struct device *dev = nor->dev;
+	u8 sr_cr[2];
+	int ret;
+
+	ret = read_cr(nor);
+	if (ret < 0) {
+		dev_err(dev, "error while reading configuration register\n");
+		return -EINVAL;
+	}
+
+	if (ret & CR_BPNV)
+		return 0;
+
+	sr_cr[1] = ret | CR_BPNV;
+
+	/* Keep the current value of the Status Register. */
+	ret = read_sr(nor);
+	if (ret < 0) {
+		dev_err(dev, "error while reading status register\n");
+		return -EINVAL;
+	}
+	sr_cr[0] = ret;
+
+	return write_sr_cr(nor, sr_cr);
+}
+
 static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
 	struct spi_nor *nor = mtd_to_spi_nor(mtd);
@@ -1387,35 +1451,6 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	return ret;
 }
 
-/*
- * Write status Register and configuration register with 2 bytes
- * The first byte will be written to the status register, while the
- * second byte will be written to the configuration register.
- * Return negative if error occurred.
- */
-static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
-{
-	int ret;
-
-	write_enable(nor);
-
-	ret = nor->write_reg(nor, SPINOR_OP_WRSR, sr_cr, 2);
-	if (ret < 0) {
-		dev_err(nor->dev,
-			"error while writing configuration register\n");
-		return -EINVAL;
-	}
-
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret) {
-		dev_err(nor->dev,
-			"timeout while writing configuration register\n");
-		return ret;
-	}
-
-	return 0;
-}
-
 /**
  * macronix_quad_enable() - set QE bit in Status Register.
  * @nor:	pointer to a 'struct spi_nor'
@@ -1898,9 +1933,7 @@ static const struct flash_info spi_nor_ids[] = {
 			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
 	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
 	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
-	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
-			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
+	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_HAS_BPNV | USE_CLSR) },
 	{ "s25fs512s",  INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
@@ -4082,6 +4115,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 		mtd->_is_locked = spi_nor_is_locked;
 	}
 
+	if (info->flags & SPI_NOR_HAS_BPNV) {
+		mtd->_set_default_locked = spi_nor_set_default_locked;
+	}
+
 	/* sst nor chips use AAI word program */
 	if (info->flags & SST_WRITE)
 		mtd->_write = sst_write;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 677768b21a1d..30ee6f1c1142 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -313,6 +313,7 @@ struct mtd_info {
 	int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
 			unsigned long count, loff_t to, size_t *retlen);
 	void (*_sync) (struct mtd_info *mtd);
+	int (*_set_default_locked) (struct mtd_info *mtd);
 	int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
 	int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
 	int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
@@ -451,6 +452,7 @@ static inline void mtd_sync(struct mtd_info *mtd)
 int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+int mtd_set_default_locked(struct mtd_info *mtd);
 int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs);
 int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
 int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index b3d360b0ee3d..40d575a1431f 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -144,6 +144,7 @@
 #define FSR_PT_ERR		BIT(1)	/* Protection error bit */
 
 /* Configuration Register bits. */
+#define CR_BPNV			BIT(3)	/* Block protection non-volatile */
 #define CR_QUAD_EN_SPAN		BIT(1)	/* Spansion Quad I/O */
 
 /* Status Register 2 bits. */
diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
index aff5b5e59845..27b752796efa 100644
--- a/include/uapi/mtd/mtd-abi.h
+++ b/include/uapi/mtd/mtd-abi.h
@@ -204,6 +204,7 @@ struct otp_info {
  * without OOB, e.g., NOR flash.
  */
 #define MEMWRITE		_IOWR('M', 24, struct mtd_write_req)
+#define MEMSETDEFAULTLOCKED	_IO('M', 25)
 
 /*
  * Obsolete legacy interface. Keep it in order not to break userspace
-- 
2.19.1


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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-03-20  7:16 ` [PATCH v4 2/3] spi-nor: s25fl512s supports region locking Jonas Bonn
@ 2019-03-20  7:39   ` Tudor.Ambarus
  2019-03-21 16:48   ` Tudor.Ambarus
  2019-05-07  9:53     ` Geert Uytterhoeven
  2 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-03-20  7:39 UTC (permalink / raw)
  To: jonas, linux-mtd



On 03/20/2019 09:16 AM, Jonas Bonn wrote:
> External E-Mail
> 
> 
> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
> Tested and verified on a Cypress s25fl512s.
> 
> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 0cc0ef4fbf3a..9abac9e326a1 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>  			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>  	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>  	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> -	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> +	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
> +			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> +			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
>  	{ "s25fs512s",  INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>  	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
>  	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
> 
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-03-20  7:16 ` [PATCH v4 2/3] spi-nor: s25fl512s supports region locking Jonas Bonn
  2019-03-20  7:39   ` Tudor.Ambarus
@ 2019-03-21 16:48   ` Tudor.Ambarus
  2019-05-07  9:53     ` Geert Uytterhoeven
  2 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-03-21 16:48 UTC (permalink / raw)
  To: jonas, linux-mtd



On 03/20/2019 09:16 AM, Jonas Bonn wrote:
> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
> Tested and verified on a Cypress s25fl512s.
> 
> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Applied to http://git.infradead.org/linux-mtd.git, spi-nor/next. Thanks.
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v4 3/3] spi-nor: allow setting the BPNV (default locked) bit
  2019-03-20  7:16 ` [PATCH v4 3/3] spi-nor: allow setting the BPNV (default locked) bit Jonas Bonn
@ 2019-04-02  5:27   ` Vignesh Raghavendra
  2019-05-01  4:42     ` [PATCH v5 1/1] spi-nor: allow setting the BPNV (powerup lock) bit Jonas Bonn
  0 siblings, 1 reply; 62+ messages in thread
From: Vignesh Raghavendra @ 2019-04-02  5:27 UTC (permalink / raw)
  To: Jonas Bonn, linux-mtd; +Cc: tudor.ambarus

Hi,

On 20/03/19 12:46 PM, Jonas Bonn wrote:
> Setting the BPNV bit defaults the block protection bits BP0-2 to 1 at
> reset.  This means that all the flash sectors are protected until they
> are explicity unlocked by the user.
> 

s/explicity/explicitly

> Together with protection of the status register via the SRWD bit and the
> WP# signal, this allows a flash device to be effectively protected from
> erasure by unauthorized actors.
> 
> The patch has been tested with a Cypress s25fl512s and works as
> advertised.  The concern that I have with this, though, is that the BPNV
> bit is "write once":  if somebody inadvertently sets this feature on the
> device, it is irrevocable!  Whether or not this actually belongs in the
> mainline kernel is therefore up for debate...
>

I am fine with this in general as setting BPNV is OTP but wont
necessarily brick the flash. More comments below:

> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
> ---
>  drivers/mtd/mtdchar.c         |   6 ++
>  drivers/mtd/mtdcore.c         |   8 +++
>  drivers/mtd/spi-nor/spi-nor.c | 103 +++++++++++++++++++++++-----------
>  include/linux/mtd/mtd.h       |   2 +
>  include/linux/mtd/spi-nor.h   |   1 +
>  include/uapi/mtd/mtd-abi.h    |   1 +
>  6 files changed, 88 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
> index 02389528f622..72842308087b 100644
> --- a/drivers/mtd/mtdchar.c
> +++ b/drivers/mtd/mtdchar.c
> @@ -800,6 +800,12 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
>  		break;
>  	}
>  
> +	case MEMSETDEFAULTLOCKED:
> +	{
> +		ret = mtd_set_default_locked(mtd);
> +		break;
> +	}
> +
>  	case MEMLOCK:
>  	{
>  		struct erase_info_user einfo;
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index 76b4264936ff..811fe0f3c24a 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -1681,6 +1681,14 @@ int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
>  }
>  EXPORT_SYMBOL_GPL(mtd_lock_user_prot_reg);
>  
> +int mtd_set_default_locked(struct mtd_info *mtd)
> +{
> +	if (!mtd->_set_default_locked)
> +		return -EOPNOTSUPP;
> +	return mtd->_set_default_locked(mtd);
> +}
> +EXPORT_SYMBOL_GPL(mtd_set_default_locked);
> +
>  /* Chip-supported device locking */
>  int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>  {
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 9abac9e326a1..8a30cdac6f88 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -250,7 +250,8 @@ struct flash_info {
>  	u16		page_size;
>  	u16		addr_width;
>  
> -	u16		flags;
> +	u16		__unused16;

Why is this needed?

> +	u32		flags;
>  #define SECT_4K			BIT(0)	/* SPINOR_OP_BE_4K works uniformly */
>  #define SPI_NOR_NO_ERASE	BIT(1)	/* No erase command needed */
>  #define SST_WRITE		BIT(2)	/* use SST byte programming */
> @@ -279,6 +280,10 @@ struct flash_info {
>  #define SPI_NOR_SKIP_SFDP	BIT(13)	/* Skip parsing of SFDP tables */
>  #define USE_CLSR		BIT(14)	/* use CLSR command */
>  #define SPI_NOR_OCTAL_READ	BIT(15)	/* Flash supports Octal Read */
> +#define SPI_NOR_HAS_BPNV	BIT(16) /* Block protection bits can be set
> +					 * non-volatile, meaning all blocks
> +					 * are protected by default at reset
> +					 */
>  

Setting BPNV actually makes the BP bits _volatile_ and therefore are
reset to 1 on power up. Above comment and commit log should reflect the
same.

>  	/* Part specific fixup hooks. */
>  	const struct spi_nor_fixups *fixups;
> @@ -1324,6 +1329,36 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  	return write_sr_and_check(nor, status_new, mask);
>  }
>  
> +/*
> + * Write status Register and configuration register with 2 bytes
> + * The first byte will be written to the status register, while the
> + * second byte will be written to the configuration register.
> + * Return negative if error occurred.
> + */
> +static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
> +{
> +	int ret;
> +
> +	write_enable(nor);
> +
> +	ret = nor->write_reg(nor, SPINOR_OP_WRSR, sr_cr, 2);
> +	if (ret < 0) {
> +		dev_err(nor->dev,
> +			"error while writing configuration register\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = spi_nor_wait_till_ready(nor);
> +	if (ret) {
> +		dev_err(nor->dev,
> +			"timeout while writing configuration register\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +

Is there a real need to move this function over here? This messes up
looking at history using git blame. Please do not move the code around
unless needed

>  /*
>   * Check if a region of the flash is (completely) locked. See stm_lock() for
>   * more info.
> @@ -1342,6 +1377,35 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
>  	return stm_is_locked_sr(nor, ofs, len, status);
>  }
>  
> +static int spi_nor_set_default_locked(struct mtd_info *mtd)
> +{
> +	struct spi_nor *nor = mtd_to_spi_nor(mtd);
> +	struct device *dev = nor->dev;
> +	u8 sr_cr[2];
> +	int ret;
> +
> +	ret = read_cr(nor);
> +	if (ret < 0) {
> +		dev_err(dev, "error while reading configuration register\n");
> +		return -EINVAL;
> +	}
> +
> +	if (ret & CR_BPNV)
> +		return 0;
> +
> +	sr_cr[1] = ret | CR_BPNV;
> +
> +	/* Keep the current value of the Status Register. */
> +	ret = read_sr(nor);
> +	if (ret < 0) {
> +		dev_err(dev, "error while reading status register\n");
> +		return -EINVAL;
> +	}
> +	sr_cr[0] = ret;
> +
> +	return write_sr_cr(nor, sr_cr);
> +}
> +
>  static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>  {
>  	struct spi_nor *nor = mtd_to_spi_nor(mtd);
> @@ -1387,35 +1451,6 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>  	return ret;
>  }
>  
> -/*
> - * Write status Register and configuration register with 2 bytes
> - * The first byte will be written to the status register, while the
> - * second byte will be written to the configuration register.
> - * Return negative if error occurred.
> - */
> -static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
> -{
> -	int ret;
> -
> -	write_enable(nor);
> -
> -	ret = nor->write_reg(nor, SPINOR_OP_WRSR, sr_cr, 2);
> -	if (ret < 0) {
> -		dev_err(nor->dev,
> -			"error while writing configuration register\n");
> -		return -EINVAL;
> -	}
> -
> -	ret = spi_nor_wait_till_ready(nor);
> -	if (ret) {
> -		dev_err(nor->dev,
> -			"timeout while writing configuration register\n");
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
>  /**
>   * macronix_quad_enable() - set QE bit in Status Register.
>   * @nor:	pointer to a 'struct spi_nor'
> @@ -1898,9 +1933,7 @@ static const struct flash_info spi_nor_ids[] = {
>  			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>  	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>  	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> -	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
> -			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> -			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
> +	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_HAS_BPNV | USE_CLSR) },

Please limit to 80 char as before. That is the preferred style going forward

>  	{ "s25fs512s",  INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>  	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
>  	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
> @@ -4082,6 +4115,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  		mtd->_is_locked = spi_nor_is_locked;
>  	}
>  
> +	if (info->flags & SPI_NOR_HAS_BPNV) {
> +		mtd->_set_default_locked = spi_nor_set_default_locked;
> +	}
> +
>  	/* sst nor chips use AAI word program */
>  	if (info->flags & SST_WRITE)
>  		mtd->_write = sst_write;
> diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
> index 677768b21a1d..30ee6f1c1142 100644
> --- a/include/linux/mtd/mtd.h
> +++ b/include/linux/mtd/mtd.h
> @@ -313,6 +313,7 @@ struct mtd_info {
>  	int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
>  			unsigned long count, loff_t to, size_t *retlen);
>  	void (*_sync) (struct mtd_info *mtd);
> +	int (*_set_default_locked) (struct mtd_info *mtd);
>  	int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
>  	int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
>  	int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
> @@ -451,6 +452,7 @@ static inline void mtd_sync(struct mtd_info *mtd)
>  int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
>  int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
>  int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
> +int mtd_set_default_locked(struct mtd_info *mtd);
>  int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs);
>  int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
>  int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index b3d360b0ee3d..40d575a1431f 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -144,6 +144,7 @@
>  #define FSR_PT_ERR		BIT(1)	/* Protection error bit */
>  
>  /* Configuration Register bits. */
> +#define CR_BPNV			BIT(3)	/* Block protection non-volatile */
>  #define CR_QUAD_EN_SPAN		BIT(1)	/* Spansion Quad I/O */
>  
>  /* Status Register 2 bits. */
> diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
> index aff5b5e59845..27b752796efa 100644
> --- a/include/uapi/mtd/mtd-abi.h
> +++ b/include/uapi/mtd/mtd-abi.h
> @@ -204,6 +204,7 @@ struct otp_info {
>   * without OOB, e.g., NOR flash.
>   */
>  #define MEMWRITE		_IOWR('M', 24, struct mtd_write_req)
> +#define MEMSETDEFAULTLOCKED	_IO('M', 25)
>  

There should be a comment to warn users that above ioctl might end up
setting a OTP bit as this is not clear from the name of the macro.

There is MTD_POWERUP_LOCK flag to indicate flash device is locked after
reset. To be consistent, above ioctl would need to be named
MEMSETPOWERUPLOCKED.


Also, spi-nor framework should detect the state of BPNV on powerup and
set MTD_POWERUP_LOCK in mtd->flags accordingly to honor ABI here[1]:


What:		/sys/class/mtd/mtdX/flags
Date:		April 2009
KernelVersion:	2.6.29
Contact:	linux-mtd@lists.infradead.org
Description:
		A hexadecimal value representing the device flags, ORed
		together:

		0x0400: MTD_WRITEABLE - device is writable
		0x0800: MTD_BIT_WRITEABLE - single bits can be flipped
		0x1000: MTD_NO_ERASE - no erase necessary
		0x2000: MTD_POWERUP_LOCK - always locked after reset

[1]https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-mtd



-- 
Regards
Vignesh

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

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

* [PATCH v5 1/1] spi-nor: allow setting the BPNV (powerup lock) bit
  2019-04-02  5:27   ` Vignesh Raghavendra
@ 2019-05-01  4:42     ` Jonas Bonn
  0 siblings, 0 replies; 62+ messages in thread
From: Jonas Bonn @ 2019-05-01  4:42 UTC (permalink / raw)
  To: linux-mtd, vigneshr; +Cc: Jonas Bonn, tudor.ambarus

Setting the BPNV bit forces the block protection bits BP0-2 to 1 at
reset.  This means that all the flash sectors are protected until they
are explicitly unlocked by the user.

Together with protection of the status register via the SRWD bit and the
WP# signal, this allows a flash device to be effectively protected from
erasure by unauthorized actors.

NB:  the BPNV bit is an OTP bit so this setting is irreversible.

Tested with a Cypress s25fl512s.

Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
---
 drivers/mtd/mtdchar.c         |  6 ++++
 drivers/mtd/mtdcore.c         |  8 +++++
 drivers/mtd/spi-nor/spi-nor.c | 59 +++++++++++++++++++++++++++++++++--
 include/linux/mtd/mtd.h       |  2 ++
 include/linux/mtd/spi-nor.h   |  1 +
 include/uapi/mtd/mtd-abi.h    |  4 +++
 6 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 02389528f622..c14ee4c6e3d3 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -800,6 +800,12 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 		break;
 	}
 
+	case MEMSETPOWERUPLOCK:
+	{
+		ret = mtd_set_powerup_lock(mtd);
+		break;
+	}
+
 	case MEMLOCK:
 	{
 		struct erase_info_user einfo;
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 76b4264936ff..f2296e6845ca 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1681,6 +1681,14 @@ int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
 }
 EXPORT_SYMBOL_GPL(mtd_lock_user_prot_reg);
 
+int mtd_set_powerup_lock(struct mtd_info *mtd)
+{
+	if (!mtd->_set_powerup_lock)
+		return -EOPNOTSUPP;
+	return mtd->_set_powerup_lock(mtd);
+}
+EXPORT_SYMBOL_GPL(mtd_set_powerup_lock);
+
 /* Chip-supported device locking */
 int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index a3f551413539..e8d008c4ff75 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -250,7 +250,7 @@ struct flash_info {
 	u16		page_size;
 	u16		addr_width;
 
-	u16		flags;
+	u32		flags;
 #define SECT_4K			BIT(0)	/* SPINOR_OP_BE_4K works uniformly */
 #define SPI_NOR_NO_ERASE	BIT(1)	/* No erase command needed */
 #define SST_WRITE		BIT(2)	/* use SST byte programming */
@@ -279,6 +279,11 @@ struct flash_info {
 #define SPI_NOR_SKIP_SFDP	BIT(13)	/* Skip parsing of SFDP tables */
 #define USE_CLSR		BIT(14)	/* use CLSR command */
 #define SPI_NOR_OCTAL_READ	BIT(15)	/* Flash supports Octal Read */
+#define SPI_NOR_HAS_BPNV	BIT(16) /* Block protection bits can be set
+					 * volatile, meaning all blocks
+					 * are protected by default at reset
+					 * (BP[0-2] reset to 1 at power up)
+					 */
 
 	/* Part specific fixup hooks. */
 	const struct spi_nor_fixups *fixups;
@@ -1345,6 +1350,43 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
 	return stm_is_locked_sr(nor, ofs, len, status);
 }
 
+static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr);
+
+static int spi_nor_set_powerup_lock(struct mtd_info *mtd)
+{
+	struct spi_nor *nor = mtd_to_spi_nor(mtd);
+	struct device *dev = nor->dev;
+	u8 sr_cr[2];
+	int ret;
+
+	ret = read_cr(nor);
+	if (ret < 0) {
+		dev_err(dev, "error while reading configuration register\n");
+		return -EINVAL;
+	}
+
+	if (ret & CR_BPNV)
+		return 0;
+
+	sr_cr[1] = ret | CR_BPNV;
+
+	/* Keep the current value of the Status Register. */
+	ret = read_sr(nor);
+	if (ret < 0) {
+		dev_err(dev, "error while reading status register\n");
+		return -EINVAL;
+	}
+	sr_cr[0] = ret;
+
+	ret = write_sr_cr(nor, sr_cr);
+	if (ret)
+		return ret;
+
+	mtd->flags |= MTD_POWERUP_LOCK;
+
+	return 0;
+}
+
 static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
 	struct spi_nor *nor = mtd_to_spi_nor(mtd);
@@ -1903,7 +1945,8 @@ static const struct flash_info spi_nor_ids[] = {
 	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
 	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
 			SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
+			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
+			SPI_NOR_HAS_BPNV | USE_CLSR) },
 	{ "s25fs512s",  INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
@@ -4074,6 +4117,18 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 		mtd->_is_locked = spi_nor_is_locked;
 	}
 
+	if (info->flags & SPI_NOR_HAS_BPNV) {
+		mtd->_set_powerup_lock = spi_nor_set_powerup_lock;
+
+		ret = read_cr(nor);
+		if (ret >= 0) {
+			if (ret & CR_BPNV)
+				mtd->flags |= MTD_POWERUP_LOCK;
+		} else {
+			dev_err(dev, "error reading configuration register\n");
+		}
+	}
+
 	/* sst nor chips use AAI word program */
 	if (info->flags & SST_WRITE)
 		mtd->_write = sst_write;
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 677768b21a1d..15d04b065182 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -313,6 +313,7 @@ struct mtd_info {
 	int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
 			unsigned long count, loff_t to, size_t *retlen);
 	void (*_sync) (struct mtd_info *mtd);
+	int (*_set_powerup_lock) (struct mtd_info *mtd);
 	int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
 	int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
 	int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
@@ -451,6 +452,7 @@ static inline void mtd_sync(struct mtd_info *mtd)
 int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+int mtd_set_powerup_lock(struct mtd_info *mtd);
 int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs);
 int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
 int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index b3d360b0ee3d..40d575a1431f 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -144,6 +144,7 @@
 #define FSR_PT_ERR		BIT(1)	/* Protection error bit */
 
 /* Configuration Register bits. */
+#define CR_BPNV			BIT(3)	/* Block protection non-volatile */
 #define CR_QUAD_EN_SPAN		BIT(1)	/* Spansion Quad I/O */
 
 /* Status Register 2 bits. */
diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
index aff5b5e59845..a78b2dce084f 100644
--- a/include/uapi/mtd/mtd-abi.h
+++ b/include/uapi/mtd/mtd-abi.h
@@ -204,6 +204,10 @@ struct otp_info {
  * without OOB, e.g., NOR flash.
  */
 #define MEMWRITE		_IOWR('M', 24, struct mtd_write_req)
+/* Set device to revert to locked state at reset; NB, on some devices this
+ * is an OTP bit so this setting may be irreversible
+ */
+#define MEMSETPOWERUPLOCK	_IO('M', 25)
 
 /*
  * Obsolete legacy interface. Keep it in order not to break userspace
-- 
2.20.1


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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-03-20  7:16 ` [PATCH v4 2/3] spi-nor: s25fl512s supports region locking Jonas Bonn
@ 2019-05-07  9:53     ` Geert Uytterhoeven
  2019-03-21 16:48   ` Tudor.Ambarus
  2019-05-07  9:53     ` Geert Uytterhoeven
  2 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-07  9:53 UTC (permalink / raw)
  To: Jonas Bonn; +Cc: MTD Maling List, Tudor Ambarus, Marek Vasut, Linux-Renesas

Hi Jonas,

On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
> Tested and verified on a Cypress s25fl512s.
>
> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>

This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
locking") in mtd/next.

> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>                         SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>         { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>         { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },

Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
probing.

Before/after:

    -m25p80 spi0.0: s25fl512s (65536 Kbytes)
    -3 fixed-partitions partitions found on MTD device spi0.0
    -Creating 3 MTD partitions on "spi0.0":
    -0x000000000000-0x000000080000 : "loader"
    -0x000000080000-0x000000600000 : "user"
    -0x000000600000-0x000004000000 : "flash"
    +m25p80 spi0.0: Erase Error occurred
    +m25p80 spi0.0: Erase Error occurred
    +m25p80 spi0.0: timeout while writing configuration register
    +m25p80 spi0.0: quad mode not supported
    +m25p80: probe of spi0.0 failed with error -5

FLASH chip is SPANSION FL512SAIFG1 311QQ063 A ©11 SPANSION
JEDEC id bytes: 01 02 20 4d 00 80

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-07  9:53     ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-07  9:53 UTC (permalink / raw)
  To: Jonas Bonn; +Cc: Linux-Renesas, Marek Vasut, MTD Maling List, Tudor Ambarus

Hi Jonas,

On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
> Tested and verified on a Cypress s25fl512s.
>
> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>

This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
locking") in mtd/next.

> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>                         SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>         { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>         { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },

Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
probing.

Before/after:

    -m25p80 spi0.0: s25fl512s (65536 Kbytes)
    -3 fixed-partitions partitions found on MTD device spi0.0
    -Creating 3 MTD partitions on "spi0.0":
    -0x000000000000-0x000000080000 : "loader"
    -0x000000080000-0x000000600000 : "user"
    -0x000000600000-0x000004000000 : "flash"
    +m25p80 spi0.0: Erase Error occurred
    +m25p80 spi0.0: Erase Error occurred
    +m25p80 spi0.0: timeout while writing configuration register
    +m25p80 spi0.0: quad mode not supported
    +m25p80: probe of spi0.0 failed with error -5

FLASH chip is SPANSION FL512SAIFG1 311QQ063 A ©11 SPANSION
JEDEC id bytes: 01 02 20 4d 00 80

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-07  9:53     ` Geert Uytterhoeven
@ 2019-05-07 10:42       ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-07 10:42 UTC (permalink / raw)
  To: geert, jonas; +Cc: linux-mtd, marek.vasut+renesas, linux-renesas-soc

Hi, Geert,

On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Jonas,
> 
> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
>> Tested and verified on a Cypress s25fl512s.
>>
>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
> 
> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
> locking") in mtd/next.
> 
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>>                         SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>         { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>>         { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
> 
> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
> probing.
> 
> Before/after:
> 
>     -m25p80 spi0.0: s25fl512s (65536 Kbytes)
>     -3 fixed-partitions partitions found on MTD device spi0.0
>     -Creating 3 MTD partitions on "spi0.0":
>     -0x000000000000-0x000000080000 : "loader"
>     -0x000000080000-0x000000600000 : "user"
>     -0x000000600000-0x000004000000 : "flash"
>     +m25p80 spi0.0: Erase Error occurred
>     +m25p80 spi0.0: Erase Error occurred
>     +m25p80 spi0.0: timeout while writing configuration register
>     +m25p80 spi0.0: quad mode not supported
>     +m25p80: probe of spi0.0 failed with error -5
> 
> FLASH chip is SPANSION FL512SAIFG1 311QQ063 A ©11 SPANSION
> JEDEC id bytes: 01 02 20 4d 00 80

That's curious. Did you revert this patch and probe was ok? Are you sure it is
not related to the recent changes on spi-rspi.c?

Cheers,
ta

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-07 10:42       ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-07 10:42 UTC (permalink / raw)
  To: geert, jonas; +Cc: linux-renesas-soc, linux-mtd, marek.vasut+renesas

Hi, Geert,

On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Jonas,
> 
> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
>> Tested and verified on a Cypress s25fl512s.
>>
>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
> 
> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
> locking") in mtd/next.
> 
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>>                         SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>         { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>>         { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
> 
> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
> probing.
> 
> Before/after:
> 
>     -m25p80 spi0.0: s25fl512s (65536 Kbytes)
>     -3 fixed-partitions partitions found on MTD device spi0.0
>     -Creating 3 MTD partitions on "spi0.0":
>     -0x000000000000-0x000000080000 : "loader"
>     -0x000000080000-0x000000600000 : "user"
>     -0x000000600000-0x000004000000 : "flash"
>     +m25p80 spi0.0: Erase Error occurred
>     +m25p80 spi0.0: Erase Error occurred
>     +m25p80 spi0.0: timeout while writing configuration register
>     +m25p80 spi0.0: quad mode not supported
>     +m25p80: probe of spi0.0 failed with error -5
> 
> FLASH chip is SPANSION FL512SAIFG1 311QQ063 A ©11 SPANSION
> JEDEC id bytes: 01 02 20 4d 00 80

That's curious. Did you revert this patch and probe was ok? Are you sure it is
not related to the recent changes on spi-rspi.c?

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-07 10:42       ` Tudor.Ambarus
@ 2019-05-07 10:50         ` Geert Uytterhoeven
  -1 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-07 10:50 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Jonas Bonn, MTD Maling List, Marek Vasut, Linux-Renesas

Hi Tudor,

On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
> > On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
> >> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
> >> Tested and verified on a Cypress s25fl512s.
> >>
> >> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
> >
> > This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
> > locking") in mtd/next.
> >
> >> --- a/drivers/mtd/spi-nor/spi-nor.c
> >> +++ b/drivers/mtd/spi-nor/spi-nor.c
> >> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
> >>                         SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >>         { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
> >>         { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
> >> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> >> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
> >
> > Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
> > probing.
> >
> > Before/after:
> >
> >     -m25p80 spi0.0: s25fl512s (65536 Kbytes)
> >     -3 fixed-partitions partitions found on MTD device spi0.0
> >     -Creating 3 MTD partitions on "spi0.0":
> >     -0x000000000000-0x000000080000 : "loader"
> >     -0x000000080000-0x000000600000 : "user"
> >     -0x000000600000-0x000004000000 : "flash"
> >     +m25p80 spi0.0: Erase Error occurred
> >     +m25p80 spi0.0: Erase Error occurred
> >     +m25p80 spi0.0: timeout while writing configuration register
> >     +m25p80 spi0.0: quad mode not supported
> >     +m25p80: probe of spi0.0 failed with error -5
> >
> > FLASH chip is SPANSION FL512SAIFG1 311QQ063 A ©11 SPANSION
> > JEDEC id bytes: 01 02 20 4d 00 80
>
> That's curious. Did you revert this patch and probe was ok? Are you sure it is

Yes, a revert fixes the the probe.
I had tried all combinations of the 2 newly set flags, and only
SPI_NOR_HAS_LOCK is a problem.

> not related to the recent changes on spi-rspi.c?

These changes affect QSPI transfers only.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-07 10:50         ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-07 10:50 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Linux-Renesas, Jonas Bonn, MTD Maling List, Marek Vasut

Hi Tudor,

On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
> > On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
> >> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
> >> Tested and verified on a Cypress s25fl512s.
> >>
> >> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
> >
> > This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
> > locking") in mtd/next.
> >
> >> --- a/drivers/mtd/spi-nor/spi-nor.c
> >> +++ b/drivers/mtd/spi-nor/spi-nor.c
> >> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
> >>                         SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >>         { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
> >>         { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
> >> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> >> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
> >
> > Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
> > probing.
> >
> > Before/after:
> >
> >     -m25p80 spi0.0: s25fl512s (65536 Kbytes)
> >     -3 fixed-partitions partitions found on MTD device spi0.0
> >     -Creating 3 MTD partitions on "spi0.0":
> >     -0x000000000000-0x000000080000 : "loader"
> >     -0x000000080000-0x000000600000 : "user"
> >     -0x000000600000-0x000004000000 : "flash"
> >     +m25p80 spi0.0: Erase Error occurred
> >     +m25p80 spi0.0: Erase Error occurred
> >     +m25p80 spi0.0: timeout while writing configuration register
> >     +m25p80 spi0.0: quad mode not supported
> >     +m25p80: probe of spi0.0 failed with error -5
> >
> > FLASH chip is SPANSION FL512SAIFG1 311QQ063 A ©11 SPANSION
> > JEDEC id bytes: 01 02 20 4d 00 80
>
> That's curious. Did you revert this patch and probe was ok? Are you sure it is

Yes, a revert fixes the the probe.
I had tried all combinations of the 2 newly set flags, and only
SPI_NOR_HAS_LOCK is a problem.

> not related to the recent changes on spi-rspi.c?

These changes affect QSPI transfers only.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-07 10:50         ` Geert Uytterhoeven
@ 2019-05-07 11:13           ` Jonas Bonn
  -1 siblings, 0 replies; 62+ messages in thread
From: Jonas Bonn @ 2019-05-07 11:13 UTC (permalink / raw)
  To: Geert Uytterhoeven, Tudor Ambarus
  Cc: MTD Maling List, Marek Vasut, Linux-Renesas

Hi Geert,

On 07/05/2019 12:50, Geert Uytterhoeven wrote:
> Hi Tudor,
> 
> On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
>> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
>>> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
>>>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
>>>> Tested and verified on a Cypress s25fl512s.
>>>>
>>>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
>>>
>>> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
>>> locking") in mtd/next.
>>>
>>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>>>>                          SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>          { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>>>>          { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
>>>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
>>>
>>> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
>>> probing.
>>>
>>> Before/after:
>>>
>>>      -m25p80 spi0.0: s25fl512s (65536 Kbytes)
>>>      -3 fixed-partitions partitions found on MTD device spi0.0
>>>      -Creating 3 MTD partitions on "spi0.0":
>>>      -0x000000000000-0x000000080000 : "loader"
>>>      -0x000000080000-0x000000600000 : "user"
>>>      -0x000000600000-0x000004000000 : "flash"
>>>      +m25p80 spi0.0: Erase Error occurred
>>>      +m25p80 spi0.0: Erase Error occurred
>>>      +m25p80 spi0.0: timeout while writing configuration register
>>>      +m25p80 spi0.0: quad mode not supported
>>>      +m25p80: probe of spi0.0 failed with error -5
>>>

In drivers/mtd/spi-nor/spi-nor.c you have:

static int spi_nor_init(struct spi_nor *nor)
{
         int err;

         /*
          * Atmel, SST, Intel/Numonyx, and others serial NOR tend to 
power up
          * with the software protection bits set
          */
         if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
             JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
             JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
             nor->info->flags & SPI_NOR_HAS_LOCK) {
                 write_enable(nor);
                 write_sr(nor, 0);
                 spi_nor_wait_till_ready(nor);
         }

         if (nor->quad_enable) {
                 err = nor->quad_enable(nor);
                 if (err) {
                         dev_err(nor->dev, "quad mode not supported\n");
                         return err;
                 }
         }

This is the only meaningful thing that I can see may have changed with 
this flag.  We now have an additional write_enable before quad_enable. 
What happens if you swap those two blocks above so that quad_enable is 
called first?

If it's not that, I can't see how the extra flags can have any effect.

Regards,
Jonas

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-07 11:13           ` Jonas Bonn
  0 siblings, 0 replies; 62+ messages in thread
From: Jonas Bonn @ 2019-05-07 11:13 UTC (permalink / raw)
  To: Geert Uytterhoeven, Tudor Ambarus
  Cc: Linux-Renesas, MTD Maling List, Marek Vasut

Hi Geert,

On 07/05/2019 12:50, Geert Uytterhoeven wrote:
> Hi Tudor,
> 
> On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
>> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
>>> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
>>>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
>>>> Tested and verified on a Cypress s25fl512s.
>>>>
>>>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
>>>
>>> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
>>> locking") in mtd/next.
>>>
>>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>>>>                          SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>          { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>>>>          { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
>>>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
>>>
>>> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
>>> probing.
>>>
>>> Before/after:
>>>
>>>      -m25p80 spi0.0: s25fl512s (65536 Kbytes)
>>>      -3 fixed-partitions partitions found on MTD device spi0.0
>>>      -Creating 3 MTD partitions on "spi0.0":
>>>      -0x000000000000-0x000000080000 : "loader"
>>>      -0x000000080000-0x000000600000 : "user"
>>>      -0x000000600000-0x000004000000 : "flash"
>>>      +m25p80 spi0.0: Erase Error occurred
>>>      +m25p80 spi0.0: Erase Error occurred
>>>      +m25p80 spi0.0: timeout while writing configuration register
>>>      +m25p80 spi0.0: quad mode not supported
>>>      +m25p80: probe of spi0.0 failed with error -5
>>>

In drivers/mtd/spi-nor/spi-nor.c you have:

static int spi_nor_init(struct spi_nor *nor)
{
         int err;

         /*
          * Atmel, SST, Intel/Numonyx, and others serial NOR tend to 
power up
          * with the software protection bits set
          */
         if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
             JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
             JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
             nor->info->flags & SPI_NOR_HAS_LOCK) {
                 write_enable(nor);
                 write_sr(nor, 0);
                 spi_nor_wait_till_ready(nor);
         }

         if (nor->quad_enable) {
                 err = nor->quad_enable(nor);
                 if (err) {
                         dev_err(nor->dev, "quad mode not supported\n");
                         return err;
                 }
         }

This is the only meaningful thing that I can see may have changed with 
this flag.  We now have an additional write_enable before quad_enable. 
What happens if you swap those two blocks above so that quad_enable is 
called first?

If it's not that, I can't see how the extra flags can have any effect.

Regards,
Jonas

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-07 11:13           ` Jonas Bonn
@ 2019-05-07 12:52             ` Geert Uytterhoeven
  -1 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-07 12:52 UTC (permalink / raw)
  To: Jonas Bonn; +Cc: Tudor Ambarus, MTD Maling List, Marek Vasut, Linux-Renesas

Hi Jonas,

On Tue, May 7, 2019 at 1:14 PM Jonas Bonn <jonas@norrbonn.se> wrote:
> On 07/05/2019 12:50, Geert Uytterhoeven wrote:
> > On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
> >> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
> >>> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
> >>>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
> >>>> Tested and verified on a Cypress s25fl512s.
> >>>>
> >>>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
> >>>
> >>> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
> >>> locking") in mtd/next.
> >>>
> >>>> --- a/drivers/mtd/spi-nor/spi-nor.c
> >>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
> >>>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
> >>>>                          SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >>>>          { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
> >>>>          { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >>>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >>>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
> >>>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> >>>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
> >>>
> >>> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
> >>> probing.
> >>>
> >>> Before/after:
> >>>
> >>>      -m25p80 spi0.0: s25fl512s (65536 Kbytes)
> >>>      -3 fixed-partitions partitions found on MTD device spi0.0
> >>>      -Creating 3 MTD partitions on "spi0.0":
> >>>      -0x000000000000-0x000000080000 : "loader"
> >>>      -0x000000080000-0x000000600000 : "user"
> >>>      -0x000000600000-0x000004000000 : "flash"
> >>>      +m25p80 spi0.0: Erase Error occurred
> >>>      +m25p80 spi0.0: Erase Error occurred
> >>>      +m25p80 spi0.0: timeout while writing configuration register
> >>>      +m25p80 spi0.0: quad mode not supported
> >>>      +m25p80: probe of spi0.0 failed with error -5
> >>>
>
> In drivers/mtd/spi-nor/spi-nor.c you have:
>
> static int spi_nor_init(struct spi_nor *nor)
> {
>          int err;
>
>          /*
>           * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
>           * with the software protection bits set
>           */
>          if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
>              JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
>              JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>              nor->info->flags & SPI_NOR_HAS_LOCK) {
>                  write_enable(nor);

With more debug prints:

    m25p80 spi0.0: spi_nor_init:3925: write_enable() returned 0

>                  write_sr(nor, 0);

    m25p80 spi0.0: spi_nor_init:3927: write_sr() returned 0

>                  spi_nor_wait_till_ready(nor);

    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
                                     ...
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
    m25p80 spi0.0: Erase Error occurred
    m25p80 spi0.0: spi_nor_init:3929: spi_nor_wait_till_ready() returned -5

>          }
>
>          if (nor->quad_enable) {
>                  err = nor->quad_enable(nor);

    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
    m25p80 spi0.0: Erase Error occurred
    m25p80 spi0.0: timeout while writing configuration register
    m25p80 spi0.0: spi_nor_init:3937: spansion_quad_enable() returned -5

>                  if (err) {
>                          dev_err(nor->dev, "quad mode not supported\n");
>                          return err;
>                  }
>          }
>
> This is the only meaningful thing that I can see may have changed with
> this flag.  We now have an additional write_enable before quad_enable.
> What happens if you swap those two blocks above so that quad_enable is
> called first?

With the two blocks swapped:

    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x0
    m25p80 spi0.0: spi_nor_init:3919: spansion_quad_enable() returned 0
    m25p80 spi0.0: spi_nor_init:3937: write_enable() returned 0
    m25p80 spi0.0: spi_nor_init:3939: write_sr() returned 0
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
                                                                  ...
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
    m25p80 spi0.0: Erase Error occurred
    m25p80 spi0.0: spi_nor_init:3941: spi_nor_wait_till_ready() returned -5
    m25p80 spi0.0: s25fl512s (65536 Kbytes)
    3 fixed-partitions partitions found on MTD device spi0.0
    Creating 3 MTD partitions on "spi0.0":
    0x000000000000-0x000000080000 : "loader"
    0x000000080000-0x000000600000 : "user"
    0x000000600000-0x000004000000 : "flash"

Note that spi_nor_wait_till_ready() still fails.

While the device (which contains the boot loader) now appears to be
detected fine, reading returns bogus repetitive data, for all partitions:

    # hd /dev/mtd0 | head
    00000000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
|3333333333;.....|
    00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
|................|
    *
    00001000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
|3333333333;.....|
    00001010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
|................|
    *

If I remove the call to "write_sr(nor, 0)", everything works as
before, regardless
of swapping the blocks.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-07 12:52             ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-07 12:52 UTC (permalink / raw)
  To: Jonas Bonn; +Cc: Linux-Renesas, Marek Vasut, MTD Maling List, Tudor Ambarus

Hi Jonas,

On Tue, May 7, 2019 at 1:14 PM Jonas Bonn <jonas@norrbonn.se> wrote:
> On 07/05/2019 12:50, Geert Uytterhoeven wrote:
> > On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
> >> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
> >>> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
> >>>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
> >>>> Tested and verified on a Cypress s25fl512s.
> >>>>
> >>>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
> >>>
> >>> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
> >>> locking") in mtd/next.
> >>>
> >>>> --- a/drivers/mtd/spi-nor/spi-nor.c
> >>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
> >>>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
> >>>>                          SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >>>>          { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
> >>>>          { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >>>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
> >>>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
> >>>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> >>>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
> >>>
> >>> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
> >>> probing.
> >>>
> >>> Before/after:
> >>>
> >>>      -m25p80 spi0.0: s25fl512s (65536 Kbytes)
> >>>      -3 fixed-partitions partitions found on MTD device spi0.0
> >>>      -Creating 3 MTD partitions on "spi0.0":
> >>>      -0x000000000000-0x000000080000 : "loader"
> >>>      -0x000000080000-0x000000600000 : "user"
> >>>      -0x000000600000-0x000004000000 : "flash"
> >>>      +m25p80 spi0.0: Erase Error occurred
> >>>      +m25p80 spi0.0: Erase Error occurred
> >>>      +m25p80 spi0.0: timeout while writing configuration register
> >>>      +m25p80 spi0.0: quad mode not supported
> >>>      +m25p80: probe of spi0.0 failed with error -5
> >>>
>
> In drivers/mtd/spi-nor/spi-nor.c you have:
>
> static int spi_nor_init(struct spi_nor *nor)
> {
>          int err;
>
>          /*
>           * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
>           * with the software protection bits set
>           */
>          if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
>              JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
>              JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>              nor->info->flags & SPI_NOR_HAS_LOCK) {
>                  write_enable(nor);

With more debug prints:

    m25p80 spi0.0: spi_nor_init:3925: write_enable() returned 0

>                  write_sr(nor, 0);

    m25p80 spi0.0: spi_nor_init:3927: write_sr() returned 0

>                  spi_nor_wait_till_ready(nor);

    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
                                     ...
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
    m25p80 spi0.0: Erase Error occurred
    m25p80 spi0.0: spi_nor_init:3929: spi_nor_wait_till_ready() returned -5

>          }
>
>          if (nor->quad_enable) {
>                  err = nor->quad_enable(nor);

    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
    m25p80 spi0.0: Erase Error occurred
    m25p80 spi0.0: timeout while writing configuration register
    m25p80 spi0.0: spi_nor_init:3937: spansion_quad_enable() returned -5

>                  if (err) {
>                          dev_err(nor->dev, "quad mode not supported\n");
>                          return err;
>                  }
>          }
>
> This is the only meaningful thing that I can see may have changed with
> this flag.  We now have an additional write_enable before quad_enable.
> What happens if you swap those two blocks above so that quad_enable is
> called first?

With the two blocks swapped:

    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x0
    m25p80 spi0.0: spi_nor_init:3919: spansion_quad_enable() returned 0
    m25p80 spi0.0: spi_nor_init:3937: write_enable() returned 0
    m25p80 spi0.0: spi_nor_init:3939: write_sr() returned 0
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
                                                                  ...
    m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
    m25p80 spi0.0: Erase Error occurred
    m25p80 spi0.0: spi_nor_init:3941: spi_nor_wait_till_ready() returned -5
    m25p80 spi0.0: s25fl512s (65536 Kbytes)
    3 fixed-partitions partitions found on MTD device spi0.0
    Creating 3 MTD partitions on "spi0.0":
    0x000000000000-0x000000080000 : "loader"
    0x000000080000-0x000000600000 : "user"
    0x000000600000-0x000004000000 : "flash"

Note that spi_nor_wait_till_ready() still fails.

While the device (which contains the boot loader) now appears to be
detected fine, reading returns bogus repetitive data, for all partitions:

    # hd /dev/mtd0 | head
    00000000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
|3333333333;.....|
    00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
|................|
    *
    00001000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
|3333333333;.....|
    00001010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
|................|
    *

If I remove the call to "write_sr(nor, 0)", everything works as
before, regardless
of swapping the blocks.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-07 12:52             ` Geert Uytterhoeven
@ 2019-05-07 13:15               ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-07 13:15 UTC (permalink / raw)
  To: geert, jonas; +Cc: linux-renesas-soc, marek.vasut+renesas, linux-mtd

Geert,

On 05/07/2019 03:52 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Jonas,
> 
> On Tue, May 7, 2019 at 1:14 PM Jonas Bonn <jonas@norrbonn.se> wrote:
>> On 07/05/2019 12:50, Geert Uytterhoeven wrote:
>>> On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
>>>> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
>>>>> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
>>>>>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
>>>>>> Tested and verified on a Cypress s25fl512s.
>>>>>>
>>>>>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
>>>>>
>>>>> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
>>>>> locking") in mtd/next.
>>>>>
>>>>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>>>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>>>>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>>>>>>                          SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>>          { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>>>>>>          { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
>>>>>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>>>>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
>>>>>
>>>>> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
>>>>> probing.
>>>>>
>>>>> Before/after:
>>>>>
>>>>>      -m25p80 spi0.0: s25fl512s (65536 Kbytes)
>>>>>      -3 fixed-partitions partitions found on MTD device spi0.0
>>>>>      -Creating 3 MTD partitions on "spi0.0":
>>>>>      -0x000000000000-0x000000080000 : "loader"
>>>>>      -0x000000080000-0x000000600000 : "user"
>>>>>      -0x000000600000-0x000004000000 : "flash"
>>>>>      +m25p80 spi0.0: Erase Error occurred
>>>>>      +m25p80 spi0.0: Erase Error occurred
>>>>>      +m25p80 spi0.0: timeout while writing configuration register
>>>>>      +m25p80 spi0.0: quad mode not supported
>>>>>      +m25p80: probe of spi0.0 failed with error -5
>>>>>
>>
>> In drivers/mtd/spi-nor/spi-nor.c you have:
>>
>> static int spi_nor_init(struct spi_nor *nor)
>> {
>>          int err;
>>
>>          /*
>>           * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
>>           * with the software protection bits set
>>           */
>>          if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
>>              JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
>>              JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>>              nor->info->flags & SPI_NOR_HAS_LOCK) {
>>                  write_enable(nor);
> 
> With more debug prints:
> 
>     m25p80 spi0.0: spi_nor_init:3925: write_enable() returned 0
> 
>>                  write_sr(nor, 0);
> 
>     m25p80 spi0.0: spi_nor_init:3927: write_sr() returned 0
> 
>>                  spi_nor_wait_till_ready(nor);
> 
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>                                      ...
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>     m25p80 spi0.0: Erase Error occurred
>     m25p80 spi0.0: spi_nor_init:3929: spi_nor_wait_till_ready() returned -5
> 
>>          }
>>
>>          if (nor->quad_enable) {
>>                  err = nor->quad_enable(nor);
> 
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>     m25p80 spi0.0: Erase Error occurred
>     m25p80 spi0.0: timeout while writing configuration register
>     m25p80 spi0.0: spi_nor_init:3937: spansion_quad_enable() returned -5
> 
>>                  if (err) {
>>                          dev_err(nor->dev, "quad mode not supported\n");
>>                          return err;
>>                  }
>>          }
>>
>> This is the only meaningful thing that I can see may have changed with
>> this flag.  We now have an additional write_enable before quad_enable.
>> What happens if you swap those two blocks above so that quad_enable is
>> called first?
> 
> With the two blocks swapped:
> 
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x0
>     m25p80 spi0.0: spi_nor_init:3919: spansion_quad_enable() returned 0
>     m25p80 spi0.0: spi_nor_init:3937: write_enable() returned 0
>     m25p80 spi0.0: spi_nor_init:3939: write_sr() returned 0
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>                                                                   ...
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>     m25p80 spi0.0: Erase Error occurred
>     m25p80 spi0.0: spi_nor_init:3941: spi_nor_wait_till_ready() returned -5
>     m25p80 spi0.0: s25fl512s (65536 Kbytes)
>     3 fixed-partitions partitions found on MTD device spi0.0
>     Creating 3 MTD partitions on "spi0.0":
>     0x000000000000-0x000000080000 : "loader"
>     0x000000080000-0x000000600000 : "user"
>     0x000000600000-0x000004000000 : "flash"
> 
> Note that spi_nor_wait_till_ready() still fails.
> 
> While the device (which contains the boot loader) now appears to be
> detected fine, reading returns bogus repetitive data, for all partitions:
> 
>     # hd /dev/mtd0 | head
>     00000000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
> |3333333333;.....|
>     00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
> |................|
>     *
>     00001000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
> |3333333333;.....|
>     00001010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
> |................|
>     *
> 
> If I remove the call to "write_sr(nor, 0)", everything works as
> before, regardless
> of swapping the blocks.
> 

Can you try this one?

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 73172d7f512b..b94a6eaaaca5 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1551,6 +1551,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
        u8 sr_cr[2];
        int ret;
 
+       dev_err(dev, "%s\n", __FUNCTION__);
        /* Check current Quad Enable bit value. */
        ret = read_cr(nor);
        if (ret < 0) {
@@ -3911,6 +3912,12 @@ static int spi_nor_setup(struct spi_nor *nor,
 static int spi_nor_init(struct spi_nor *nor)
 {
        int err;
+       u8 val;
+       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+       /* Check current Quad Enable bit value. */
+       val = read_cr(nor);
+       dev_err(nor->dev, "%s val = %02x\n", val);
 
        /*
         * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
@@ -3921,7 +3928,7 @@ static int spi_nor_init(struct spi_nor *nor)
            JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
            nor->info->flags & SPI_NOR_HAS_LOCK) {
                write_enable(nor);
-               write_sr(nor, 0);
+               write_sr(nor, val & ~mask);
                spi_nor_wait_till_ready(nor);
        }
 


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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-07 13:15               ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-07 13:15 UTC (permalink / raw)
  To: geert, jonas; +Cc: linux-renesas-soc, linux-mtd, marek.vasut+renesas

Geert,

On 05/07/2019 03:52 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Jonas,
> 
> On Tue, May 7, 2019 at 1:14 PM Jonas Bonn <jonas@norrbonn.se> wrote:
>> On 07/05/2019 12:50, Geert Uytterhoeven wrote:
>>> On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
>>>> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
>>>>> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
>>>>>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
>>>>>> Tested and verified on a Cypress s25fl512s.
>>>>>>
>>>>>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
>>>>>
>>>>> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
>>>>> locking") in mtd/next.
>>>>>
>>>>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>>>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>>>>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>>>>>>                          SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>>          { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>>>>>>          { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
>>>>>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>>>>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
>>>>>
>>>>> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
>>>>> probing.
>>>>>
>>>>> Before/after:
>>>>>
>>>>>      -m25p80 spi0.0: s25fl512s (65536 Kbytes)
>>>>>      -3 fixed-partitions partitions found on MTD device spi0.0
>>>>>      -Creating 3 MTD partitions on "spi0.0":
>>>>>      -0x000000000000-0x000000080000 : "loader"
>>>>>      -0x000000080000-0x000000600000 : "user"
>>>>>      -0x000000600000-0x000004000000 : "flash"
>>>>>      +m25p80 spi0.0: Erase Error occurred
>>>>>      +m25p80 spi0.0: Erase Error occurred
>>>>>      +m25p80 spi0.0: timeout while writing configuration register
>>>>>      +m25p80 spi0.0: quad mode not supported
>>>>>      +m25p80: probe of spi0.0 failed with error -5
>>>>>
>>
>> In drivers/mtd/spi-nor/spi-nor.c you have:
>>
>> static int spi_nor_init(struct spi_nor *nor)
>> {
>>          int err;
>>
>>          /*
>>           * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
>>           * with the software protection bits set
>>           */
>>          if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
>>              JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
>>              JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>>              nor->info->flags & SPI_NOR_HAS_LOCK) {
>>                  write_enable(nor);
> 
> With more debug prints:
> 
>     m25p80 spi0.0: spi_nor_init:3925: write_enable() returned 0
> 
>>                  write_sr(nor, 0);
> 
>     m25p80 spi0.0: spi_nor_init:3927: write_sr() returned 0
> 
>>                  spi_nor_wait_till_ready(nor);
> 
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>                                      ...
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>     m25p80 spi0.0: Erase Error occurred
>     m25p80 spi0.0: spi_nor_init:3929: spi_nor_wait_till_ready() returned -5
> 
>>          }
>>
>>          if (nor->quad_enable) {
>>                  err = nor->quad_enable(nor);
> 
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>     m25p80 spi0.0: Erase Error occurred
>     m25p80 spi0.0: timeout while writing configuration register
>     m25p80 spi0.0: spi_nor_init:3937: spansion_quad_enable() returned -5
> 
>>                  if (err) {
>>                          dev_err(nor->dev, "quad mode not supported\n");
>>                          return err;
>>                  }
>>          }
>>
>> This is the only meaningful thing that I can see may have changed with
>> this flag.  We now have an additional write_enable before quad_enable.
>> What happens if you swap those two blocks above so that quad_enable is
>> called first?
> 
> With the two blocks swapped:
> 
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x0
>     m25p80 spi0.0: spi_nor_init:3919: spansion_quad_enable() returned 0
>     m25p80 spi0.0: spi_nor_init:3937: write_enable() returned 0
>     m25p80 spi0.0: spi_nor_init:3939: write_sr() returned 0
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>                                                                   ...
>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>     m25p80 spi0.0: Erase Error occurred
>     m25p80 spi0.0: spi_nor_init:3941: spi_nor_wait_till_ready() returned -5
>     m25p80 spi0.0: s25fl512s (65536 Kbytes)
>     3 fixed-partitions partitions found on MTD device spi0.0
>     Creating 3 MTD partitions on "spi0.0":
>     0x000000000000-0x000000080000 : "loader"
>     0x000000080000-0x000000600000 : "user"
>     0x000000600000-0x000004000000 : "flash"
> 
> Note that spi_nor_wait_till_ready() still fails.
> 
> While the device (which contains the boot loader) now appears to be
> detected fine, reading returns bogus repetitive data, for all partitions:
> 
>     # hd /dev/mtd0 | head
>     00000000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
> |3333333333;.....|
>     00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
> |................|
>     *
>     00001000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
> |3333333333;.....|
>     00001010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
> |................|
>     *
> 
> If I remove the call to "write_sr(nor, 0)", everything works as
> before, regardless
> of swapping the blocks.
> 

Can you try this one?

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 73172d7f512b..b94a6eaaaca5 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1551,6 +1551,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
        u8 sr_cr[2];
        int ret;
 
+       dev_err(dev, "%s\n", __FUNCTION__);
        /* Check current Quad Enable bit value. */
        ret = read_cr(nor);
        if (ret < 0) {
@@ -3911,6 +3912,12 @@ static int spi_nor_setup(struct spi_nor *nor,
 static int spi_nor_init(struct spi_nor *nor)
 {
        int err;
+       u8 val;
+       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+       /* Check current Quad Enable bit value. */
+       val = read_cr(nor);
+       dev_err(nor->dev, "%s val = %02x\n", val);
 
        /*
         * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
@@ -3921,7 +3928,7 @@ static int spi_nor_init(struct spi_nor *nor)
            JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
            nor->info->flags & SPI_NOR_HAS_LOCK) {
                write_enable(nor);
-               write_sr(nor, 0);
+               write_sr(nor, val & ~mask);
                spi_nor_wait_till_ready(nor);
        }
 

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-07 13:15               ` Tudor.Ambarus
@ 2019-05-07 13:18                 ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-07 13:18 UTC (permalink / raw)
  To: geert, jonas; +Cc: linux-renesas-soc, marek.vasut+renesas, linux-mtd



On 05/07/2019 04:15 PM, Tudor Ambarus wrote:
> Geert,
> 
> On 05/07/2019 03:52 PM, Geert Uytterhoeven wrote:
>> External E-Mail
>>
>>
>> Hi Jonas,
>>
>> On Tue, May 7, 2019 at 1:14 PM Jonas Bonn <jonas@norrbonn.se> wrote:
>>> On 07/05/2019 12:50, Geert Uytterhoeven wrote:
>>>> On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
>>>>> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
>>>>>> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
>>>>>>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
>>>>>>> Tested and verified on a Cypress s25fl512s.
>>>>>>>
>>>>>>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
>>>>>>
>>>>>> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
>>>>>> locking") in mtd/next.
>>>>>>
>>>>>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>>>>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>>>>>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>>>>>>>                          SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>>>          { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>>>>>>>          { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
>>>>>>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>>>>>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
>>>>>>
>>>>>> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
>>>>>> probing.
>>>>>>
>>>>>> Before/after:
>>>>>>
>>>>>>      -m25p80 spi0.0: s25fl512s (65536 Kbytes)
>>>>>>      -3 fixed-partitions partitions found on MTD device spi0.0
>>>>>>      -Creating 3 MTD partitions on "spi0.0":
>>>>>>      -0x000000000000-0x000000080000 : "loader"
>>>>>>      -0x000000080000-0x000000600000 : "user"
>>>>>>      -0x000000600000-0x000004000000 : "flash"
>>>>>>      +m25p80 spi0.0: Erase Error occurred
>>>>>>      +m25p80 spi0.0: Erase Error occurred
>>>>>>      +m25p80 spi0.0: timeout while writing configuration register
>>>>>>      +m25p80 spi0.0: quad mode not supported
>>>>>>      +m25p80: probe of spi0.0 failed with error -5
>>>>>>
>>>
>>> In drivers/mtd/spi-nor/spi-nor.c you have:
>>>
>>> static int spi_nor_init(struct spi_nor *nor)
>>> {
>>>          int err;
>>>
>>>          /*
>>>           * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
>>>           * with the software protection bits set
>>>           */
>>>          if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
>>>              JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
>>>              JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>>>              nor->info->flags & SPI_NOR_HAS_LOCK) {
>>>                  write_enable(nor);
>>
>> With more debug prints:
>>
>>     m25p80 spi0.0: spi_nor_init:3925: write_enable() returned 0
>>
>>>                  write_sr(nor, 0);
>>
>>     m25p80 spi0.0: spi_nor_init:3927: write_sr() returned 0
>>
>>>                  spi_nor_wait_till_ready(nor);
>>
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>                                      ...
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>>     m25p80 spi0.0: Erase Error occurred
>>     m25p80 spi0.0: spi_nor_init:3929: spi_nor_wait_till_ready() returned -5
>>
>>>          }
>>>
>>>          if (nor->quad_enable) {
>>>                  err = nor->quad_enable(nor);
>>
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>>     m25p80 spi0.0: Erase Error occurred
>>     m25p80 spi0.0: timeout while writing configuration register
>>     m25p80 spi0.0: spi_nor_init:3937: spansion_quad_enable() returned -5
>>
>>>                  if (err) {
>>>                          dev_err(nor->dev, "quad mode not supported\n");
>>>                          return err;
>>>                  }
>>>          }
>>>
>>> This is the only meaningful thing that I can see may have changed with
>>> this flag.  We now have an additional write_enable before quad_enable.
>>> What happens if you swap those two blocks above so that quad_enable is
>>> called first?
>>
>> With the two blocks swapped:
>>
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x0
>>     m25p80 spi0.0: spi_nor_init:3919: spansion_quad_enable() returned 0
>>     m25p80 spi0.0: spi_nor_init:3937: write_enable() returned 0
>>     m25p80 spi0.0: spi_nor_init:3939: write_sr() returned 0
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>                                                                   ...
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>>     m25p80 spi0.0: Erase Error occurred
>>     m25p80 spi0.0: spi_nor_init:3941: spi_nor_wait_till_ready() returned -5
>>     m25p80 spi0.0: s25fl512s (65536 Kbytes)
>>     3 fixed-partitions partitions found on MTD device spi0.0
>>     Creating 3 MTD partitions on "spi0.0":
>>     0x000000000000-0x000000080000 : "loader"
>>     0x000000080000-0x000000600000 : "user"
>>     0x000000600000-0x000004000000 : "flash"
>>
>> Note that spi_nor_wait_till_ready() still fails.
>>
>> While the device (which contains the boot loader) now appears to be
>> detected fine, reading returns bogus repetitive data, for all partitions:
>>
>>     # hd /dev/mtd0 | head
>>     00000000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
>> |3333333333;.....|
>>     00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
>> |................|
>>     *
>>     00001000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
>> |3333333333;.....|
>>     00001010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
>> |................|
>>     *
>>
>> If I remove the call to "write_sr(nor, 0)", everything works as
>> before, regardless
>> of swapping the blocks.
>>
> 
> Can you try this one?
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 73172d7f512b..b94a6eaaaca5 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1551,6 +1551,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>         u8 sr_cr[2];
>         int ret;
>  
> +       dev_err(dev, "%s\n", __FUNCTION__);
>         /* Check current Quad Enable bit value. */
>         ret = read_cr(nor);
>         if (ret < 0) {
> @@ -3911,6 +3912,12 @@ static int spi_nor_setup(struct spi_nor *nor,
>  static int spi_nor_init(struct spi_nor *nor)
>  {
>         int err;
> +       u8 val;
> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +       /* Check current Quad Enable bit value. */
> +       val = read_cr(nor);
> +       dev_err(nor->dev, "%s val = %02x\n", val);

        dev_err(nor->dev, "%s val = %02x\n", __FUNCTION__, val);

>  
>         /*
>          * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> @@ -3921,7 +3928,7 @@ static int spi_nor_init(struct spi_nor *nor)
>             JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>             nor->info->flags & SPI_NOR_HAS_LOCK) {
>                 write_enable(nor);
> -               write_sr(nor, 0);
> +               write_sr(nor, val & ~mask);
>                 spi_nor_wait_till_ready(nor);
>         }
>  
> 

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-07 13:18                 ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-07 13:18 UTC (permalink / raw)
  To: geert, jonas; +Cc: linux-renesas-soc, linux-mtd, marek.vasut+renesas



On 05/07/2019 04:15 PM, Tudor Ambarus wrote:
> Geert,
> 
> On 05/07/2019 03:52 PM, Geert Uytterhoeven wrote:
>> External E-Mail
>>
>>
>> Hi Jonas,
>>
>> On Tue, May 7, 2019 at 1:14 PM Jonas Bonn <jonas@norrbonn.se> wrote:
>>> On 07/05/2019 12:50, Geert Uytterhoeven wrote:
>>>> On Tue, May 7, 2019 at 12:42 PM <Tudor.Ambarus@microchip.com> wrote:
>>>>> On 05/07/2019 12:53 PM, Geert Uytterhoeven wrote:
>>>>>> On Wed, Mar 20, 2019 at 8:16 AM Jonas Bonn <jonas@norrbonn.se> wrote:
>>>>>>> Both the BP[0-2] bits and the TBPROT bit are supported on this chip.
>>>>>>> Tested and verified on a Cypress s25fl512s.
>>>>>>>
>>>>>>> Signed-off-by: Jonas Bonn <jonas@norrbonn.se>
>>>>>>
>>>>>> This is now commit dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region
>>>>>> locking") in mtd/next.
>>>>>>
>>>>>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>>>>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>>>>>> @@ -1898,7 +1898,9 @@ static const struct flash_info spi_nor_ids[] = {
>>>>>>>                          SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>>>          { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) },
>>>>>>>          { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>>> -       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
>>>>>>> +       { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
>>>>>>> +                       SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>>>>>> +                       SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) },
>>>>>>
>>>>>> Setting SPI_NOR_HAS_LOCK causes the QSPI FLASH on r8a7791/koelsch to fail
>>>>>> probing.
>>>>>>
>>>>>> Before/after:
>>>>>>
>>>>>>      -m25p80 spi0.0: s25fl512s (65536 Kbytes)
>>>>>>      -3 fixed-partitions partitions found on MTD device spi0.0
>>>>>>      -Creating 3 MTD partitions on "spi0.0":
>>>>>>      -0x000000000000-0x000000080000 : "loader"
>>>>>>      -0x000000080000-0x000000600000 : "user"
>>>>>>      -0x000000600000-0x000004000000 : "flash"
>>>>>>      +m25p80 spi0.0: Erase Error occurred
>>>>>>      +m25p80 spi0.0: Erase Error occurred
>>>>>>      +m25p80 spi0.0: timeout while writing configuration register
>>>>>>      +m25p80 spi0.0: quad mode not supported
>>>>>>      +m25p80: probe of spi0.0 failed with error -5
>>>>>>
>>>
>>> In drivers/mtd/spi-nor/spi-nor.c you have:
>>>
>>> static int spi_nor_init(struct spi_nor *nor)
>>> {
>>>          int err;
>>>
>>>          /*
>>>           * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
>>>           * with the software protection bits set
>>>           */
>>>          if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
>>>              JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
>>>              JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>>>              nor->info->flags & SPI_NOR_HAS_LOCK) {
>>>                  write_enable(nor);
>>
>> With more debug prints:
>>
>>     m25p80 spi0.0: spi_nor_init:3925: write_enable() returned 0
>>
>>>                  write_sr(nor, 0);
>>
>>     m25p80 spi0.0: spi_nor_init:3927: write_sr() returned 0
>>
>>>                  spi_nor_wait_till_ready(nor);
>>
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>                                      ...
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>>     m25p80 spi0.0: Erase Error occurred
>>     m25p80 spi0.0: spi_nor_init:3929: spi_nor_wait_till_ready() returned -5
>>
>>>          }
>>>
>>>          if (nor->quad_enable) {
>>>                  err = nor->quad_enable(nor);
>>
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>>     m25p80 spi0.0: Erase Error occurred
>>     m25p80 spi0.0: timeout while writing configuration register
>>     m25p80 spi0.0: spi_nor_init:3937: spansion_quad_enable() returned -5
>>
>>>                  if (err) {
>>>                          dev_err(nor->dev, "quad mode not supported\n");
>>>                          return err;
>>>                  }
>>>          }
>>>
>>> This is the only meaningful thing that I can see may have changed with
>>> this flag.  We now have an additional write_enable before quad_enable.
>>> What happens if you swap those two blocks above so that quad_enable is
>>> called first?
>>
>> With the two blocks swapped:
>>
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x0
>>     m25p80 spi0.0: spi_nor_init:3919: spansion_quad_enable() returned 0
>>     m25p80 spi0.0: spi_nor_init:3937: write_enable() returned 0
>>     m25p80 spi0.0: spi_nor_init:3939: write_sr() returned 0
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0x3
>>                                                                   ...
>>     m25p80 spi0.0: spi_nor_sr_ready:533: sr = 0xff
>>     m25p80 spi0.0: Erase Error occurred
>>     m25p80 spi0.0: spi_nor_init:3941: spi_nor_wait_till_ready() returned -5
>>     m25p80 spi0.0: s25fl512s (65536 Kbytes)
>>     3 fixed-partitions partitions found on MTD device spi0.0
>>     Creating 3 MTD partitions on "spi0.0":
>>     0x000000000000-0x000000080000 : "loader"
>>     0x000000080000-0x000000600000 : "user"
>>     0x000000600000-0x000004000000 : "flash"
>>
>> Note that spi_nor_wait_till_ready() still fails.
>>
>> While the device (which contains the boot loader) now appears to be
>> detected fine, reading returns bogus repetitive data, for all partitions:
>>
>>     # hd /dev/mtd0 | head
>>     00000000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
>> |3333333333;.....|
>>     00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
>> |................|
>>     *
>>     00001000  33 33 33 33 33 33 33 33  33 33 3b bb ff ff ff ff
>> |3333333333;.....|
>>     00001010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff
>> |................|
>>     *
>>
>> If I remove the call to "write_sr(nor, 0)", everything works as
>> before, regardless
>> of swapping the blocks.
>>
> 
> Can you try this one?
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 73172d7f512b..b94a6eaaaca5 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1551,6 +1551,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>         u8 sr_cr[2];
>         int ret;
>  
> +       dev_err(dev, "%s\n", __FUNCTION__);
>         /* Check current Quad Enable bit value. */
>         ret = read_cr(nor);
>         if (ret < 0) {
> @@ -3911,6 +3912,12 @@ static int spi_nor_setup(struct spi_nor *nor,
>  static int spi_nor_init(struct spi_nor *nor)
>  {
>         int err;
> +       u8 val;
> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +       /* Check current Quad Enable bit value. */
> +       val = read_cr(nor);
> +       dev_err(nor->dev, "%s val = %02x\n", val);

        dev_err(nor->dev, "%s val = %02x\n", __FUNCTION__, val);

>  
>         /*
>          * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> @@ -3921,7 +3928,7 @@ static int spi_nor_init(struct spi_nor *nor)
>             JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>             nor->info->flags & SPI_NOR_HAS_LOCK) {
>                 write_enable(nor);
> -               write_sr(nor, 0);
> +               write_sr(nor, val & ~mask);
>                 spi_nor_wait_till_ready(nor);
>         }
>  
> 
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-07 13:15               ` Tudor.Ambarus
@ 2019-05-07 13:25                 ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-07 13:25 UTC (permalink / raw)
  To: geert, jonas; +Cc: linux-renesas-soc, marek.vasut+renesas, linux-mtd



On 05/07/2019 04:15 PM, Tudor Ambarus wrote:
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 73172d7f512b..b94a6eaaaca5 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1551,6 +1551,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>         u8 sr_cr[2];
>         int ret;
>  
> +       dev_err(dev, "%s\n", __FUNCTION__);
>         /* Check current Quad Enable bit value. */
>         ret = read_cr(nor);
>         if (ret < 0) {
> @@ -3911,6 +3912,12 @@ static int spi_nor_setup(struct spi_nor *nor,
>  static int spi_nor_init(struct spi_nor *nor)
>  {
>         int err;
> +       u8 val;
> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +       /* Check current Quad Enable bit value. */
> +       val = read_cr(nor);
this should have been:
	val = read_sr(nor);
sorry.

> +       dev_err(nor->dev, "%s val = %02x\n", val);
and here 
	dev_err(nor->dev, "%s val = %02x\n", __FUNCTION__, val);
>  
>         /*
>          * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> @@ -3921,7 +3928,7 @@ static int spi_nor_init(struct spi_nor *nor)
>             JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>             nor->info->flags & SPI_NOR_HAS_LOCK) {
>                 write_enable(nor);
> -               write_sr(nor, 0);
> +               write_sr(nor, val & ~mask);
>                 spi_nor_wait_till_ready(nor);
>         }
>  

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-07 13:25                 ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-07 13:25 UTC (permalink / raw)
  To: geert, jonas; +Cc: linux-renesas-soc, linux-mtd, marek.vasut+renesas



On 05/07/2019 04:15 PM, Tudor Ambarus wrote:
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 73172d7f512b..b94a6eaaaca5 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1551,6 +1551,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
>         u8 sr_cr[2];
>         int ret;
>  
> +       dev_err(dev, "%s\n", __FUNCTION__);
>         /* Check current Quad Enable bit value. */
>         ret = read_cr(nor);
>         if (ret < 0) {
> @@ -3911,6 +3912,12 @@ static int spi_nor_setup(struct spi_nor *nor,
>  static int spi_nor_init(struct spi_nor *nor)
>  {
>         int err;
> +       u8 val;
> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +       /* Check current Quad Enable bit value. */
> +       val = read_cr(nor);
this should have been:
	val = read_sr(nor);
sorry.

> +       dev_err(nor->dev, "%s val = %02x\n", val);
and here 
	dev_err(nor->dev, "%s val = %02x\n", __FUNCTION__, val);
>  
>         /*
>          * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> @@ -3921,7 +3928,7 @@ static int spi_nor_init(struct spi_nor *nor)
>             JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
>             nor->info->flags & SPI_NOR_HAS_LOCK) {
>                 write_enable(nor);
> -               write_sr(nor, 0);
> +               write_sr(nor, val & ~mask);
>                 spi_nor_wait_till_ready(nor);
>         }
>  
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-07 13:25                 ` Tudor.Ambarus
@ 2019-05-07 14:33                   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-07 14:33 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Jonas Bonn, Linux-Renesas, Marek Vasut, MTD Maling List

Hi Tudor,

On Tue, May 7, 2019 at 3:25 PM <Tudor.Ambarus@microchip.com> wrote:
> On 05/07/2019 04:15 PM, Tudor Ambarus wrote:
> > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> > index 73172d7f512b..b94a6eaaaca5 100644
> > --- a/drivers/mtd/spi-nor/spi-nor.c
> > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > @@ -1551,6 +1551,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
> >         u8 sr_cr[2];
> >         int ret;
> >
> > +       dev_err(dev, "%s\n", __FUNCTION__);

This one isn't triggered.

> >         /* Check current Quad Enable bit value. */
> >         ret = read_cr(nor);
> >         if (ret < 0) {
> > @@ -3911,6 +3912,12 @@ static int spi_nor_setup(struct spi_nor *nor,
> >  static int spi_nor_init(struct spi_nor *nor)
> >  {
> >         int err;
> > +       u8 val;
> > +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> > +
> > +       /* Check current Quad Enable bit value. */
> > +       val = read_cr(nor);
> this should have been:
>         val = read_sr(nor);
> sorry.
>
> > +       dev_err(nor->dev, "%s val = %02x\n", val);
> and here
>         dev_err(nor->dev, "%s val = %02x\n", __FUNCTION__, val);

m25p80 spi0.0: spi_nor_init val = 00

so the masking trick doesn't help :-(

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-07 14:33                   ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-07 14:33 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Linux-Renesas, Jonas Bonn, MTD Maling List, Marek Vasut

Hi Tudor,

On Tue, May 7, 2019 at 3:25 PM <Tudor.Ambarus@microchip.com> wrote:
> On 05/07/2019 04:15 PM, Tudor Ambarus wrote:
> > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> > index 73172d7f512b..b94a6eaaaca5 100644
> > --- a/drivers/mtd/spi-nor/spi-nor.c
> > +++ b/drivers/mtd/spi-nor/spi-nor.c
> > @@ -1551,6 +1551,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
> >         u8 sr_cr[2];
> >         int ret;
> >
> > +       dev_err(dev, "%s\n", __FUNCTION__);

This one isn't triggered.

> >         /* Check current Quad Enable bit value. */
> >         ret = read_cr(nor);
> >         if (ret < 0) {
> > @@ -3911,6 +3912,12 @@ static int spi_nor_setup(struct spi_nor *nor,
> >  static int spi_nor_init(struct spi_nor *nor)
> >  {
> >         int err;
> > +       u8 val;
> > +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> > +
> > +       /* Check current Quad Enable bit value. */
> > +       val = read_cr(nor);
> this should have been:
>         val = read_sr(nor);
> sorry.
>
> > +       dev_err(nor->dev, "%s val = %02x\n", val);
> and here
>         dev_err(nor->dev, "%s val = %02x\n", __FUNCTION__, val);

m25p80 spi0.0: spi_nor_init val = 00

so the masking trick doesn't help :-(

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-07 14:33                   ` Geert Uytterhoeven
@ 2019-05-08 10:44                     ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-08 10:44 UTC (permalink / raw)
  To: geert; +Cc: jonas, linux-renesas-soc, marek.vasut+renesas, linux-mtd

Geert,

Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
and after the operations in cause.

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 73172d7f512b..20d0fdb1dc92 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -22,6 +22,8 @@
 #include <linux/spi/flash.h>
 #include <linux/mtd/spi-nor.h>

+#define DEBUG
+
 /* Define max times to check status register before we give up. */

 /*
@@ -200,7 +202,7 @@ struct sfdp_header {
  *         register does not modify status register 2.
  * - 101b: QE is bit 1 of status register 2. Status register 1 is read using
  *         Read Status instruction 05h. Status register2 is read using
- *         instruction 35h. QE is set via Writ Status instruction 01h with
+ *         instruction 35h. QE is set via Write Status instruction 01h with
  *         two data bytes where bit 1 of the second byte is one.
  *         [...]
  */
@@ -2795,8 +2797,11 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
 		return err;

 	/* Fix endianness of the BFPT DWORDs. */
-	for (i = 0; i < BFPT_DWORD_MAX; i++)
+	for (i = 0; i < BFPT_DWORD_MAX; i++) {
 		bfpt.dwords[i] = le32_to_cpu(bfpt.dwords[i]);
+		dev_dbg(nor->dev, "bfpt.dwords[%d] = %08x\n", i + 1,
+			bfpt.dwords[i]);
+	}

 	/* Number of address bytes. */
 	switch (bfpt.dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) {
@@ -3532,8 +3537,10 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
 	}

 	err = spi_nor_parse_bfpt(nor, bfpt_header, params);
-	if (err)
+	if (err) {
+		dev_dbg(dev, "failed to parse BFPT: err = %d\n", err);
 		goto exit;
+	}

 	/* Parse optional parameter tables. */
 	for (i = 0; i < header.nph; i++) {
@@ -3576,6 +3583,7 @@ static int spi_nor_init_params(struct spi_nor *nor,
 	struct spi_nor_erase_map *map = &nor->erase_map;
 	const struct flash_info *info = nor->info;
 	u8 i, erase_mask;
+	int ret;

 	/* Set legacy flash parameters as default. */
 	memset(params, 0, sizeof(*params));
@@ -3681,12 +3689,15 @@ static int spi_nor_init_params(struct spi_nor *nor,
 		memcpy(&sfdp_params, params, sizeof(sfdp_params));
 		memcpy(&prev_map, &nor->erase_map, sizeof(prev_map));

-		if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
+		ret = spi_nor_parse_sfdp(nor, &sfdp_params);
+		if (ret) {
 			nor->addr_width = 0;
 			nor->flags &= ~SNOR_F_4B_OPCODES;
 			/* restore previous erase map */
 			memcpy(&nor->erase_map, &prev_map,
 			       sizeof(nor->erase_map));
+			dev_dbg(nor->dev, "%s sfdp parse failed, ret =%d\n",
+				__FUNCTION__, ret);
 		} else {
 			memcpy(params, &sfdp_params, sizeof(*params));
 		}
@@ -3908,9 +3919,67 @@ static int spi_nor_setup(struct spi_nor *nor,
 	return 0;
 }

+static int spi_nor_dump_sr_cr(struct spi_nor *nor)
+{
+	int ret = read_sr(nor);
+
+	dev_dbg(nor->dev, "SR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading status register\n");
+                return ret;
+        }
+
+	ret = read_cr(nor);
+	dev_dbg(nor->dev, "CR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading configuration register\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int spi_nor_clear_block_protection(struct spi_nor *nor)
+{
+	int ret;
+	u8 val, mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	ret = spi_nor_dump_sr_cr(nor);
+	if (ret)
+		return ret;
+
+	/* clear just the BP bits */
+	ret = read_sr(nor);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading status register\n");
+                return ret;
+        }
+	val = ret;
+
+	ret = write_enable(nor);
+        if (ret < 0) {
+                dev_err(nor->dev, "error on write enable, err = %d\n", ret);
+                return ret;
+	}
+
+	ret = write_sr(nor, val & ~mask);
+        if (ret < 0) {
+                dev_err(nor->dev, "error on write_sr, err = %d\n", ret);
+                return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+        if (ret) {
+                dev_err(nor->dev, "timeout while writing SR, ret = %d\n", ret);
+		return spi_nor_dump_sr_cr(nor);
+        }
+
+	return 0;
+}
+
 static int spi_nor_init(struct spi_nor *nor)
 {
-	int err;
+	int err = 0, quad_err;

 	/*
 	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
@@ -3919,18 +3988,38 @@ static int spi_nor_init(struct spi_nor *nor)
 	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
 	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
 	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-	    nor->info->flags & SPI_NOR_HAS_LOCK) {
-		write_enable(nor);
-		write_sr(nor, 0);
-		spi_nor_wait_till_ready(nor);
+	    nor->info->flags & SPI_NOR_HAS_LOCK)
+		/*
+		 * this should be done only on demand, not for every flash that
+		 * has SPI_NOR_HAS_LOCK set
+		 */
+		err = spi_nor_clear_block_protection(nor);
+	if (err) {
+		dev_err(nor->dev, "clearing BP bits failed, err = %d\n", err);
+		return err;
 	}

 	if (nor->quad_enable) {
-		err = nor->quad_enable(nor);
+		dev_dbg(nor->dev, "SR and CR before quad_enable:\n");
+
+		err = spi_nor_dump_sr_cr(nor);
 		if (err) {
-			dev_err(nor->dev, "quad mode not supported\n");
+			dev_err(nor->dev, "dump_sr_cr before quad enable fail, err = %d\n", err);
 			return err;
 		}
+
+		quad_err = nor->quad_enable(nor);
+		dev_dbg(nor->dev, "SR and CR after quad_enable:\n");
+		err = spi_nor_dump_sr_cr(nor);
+		if (err) {
+			dev_err(nor->dev, "dump_sr_cr after quad enable fail, err = %d\n", err);
+			return err;
+		}
+
+		if (quad_err) {
+			dev_err(nor->dev, "quad mode not supported, err = %d\n", quad_err);
+			return quad_err;
+		}
 	}

 	if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) {


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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-08 10:44                     ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-08 10:44 UTC (permalink / raw)
  To: geert; +Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Geert,

Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
and after the operations in cause.

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 73172d7f512b..20d0fdb1dc92 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -22,6 +22,8 @@
 #include <linux/spi/flash.h>
 #include <linux/mtd/spi-nor.h>

+#define DEBUG
+
 /* Define max times to check status register before we give up. */

 /*
@@ -200,7 +202,7 @@ struct sfdp_header {
  *         register does not modify status register 2.
  * - 101b: QE is bit 1 of status register 2. Status register 1 is read using
  *         Read Status instruction 05h. Status register2 is read using
- *         instruction 35h. QE is set via Writ Status instruction 01h with
+ *         instruction 35h. QE is set via Write Status instruction 01h with
  *         two data bytes where bit 1 of the second byte is one.
  *         [...]
  */
@@ -2795,8 +2797,11 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
 		return err;

 	/* Fix endianness of the BFPT DWORDs. */
-	for (i = 0; i < BFPT_DWORD_MAX; i++)
+	for (i = 0; i < BFPT_DWORD_MAX; i++) {
 		bfpt.dwords[i] = le32_to_cpu(bfpt.dwords[i]);
+		dev_dbg(nor->dev, "bfpt.dwords[%d] = %08x\n", i + 1,
+			bfpt.dwords[i]);
+	}

 	/* Number of address bytes. */
 	switch (bfpt.dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) {
@@ -3532,8 +3537,10 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
 	}

 	err = spi_nor_parse_bfpt(nor, bfpt_header, params);
-	if (err)
+	if (err) {
+		dev_dbg(dev, "failed to parse BFPT: err = %d\n", err);
 		goto exit;
+	}

 	/* Parse optional parameter tables. */
 	for (i = 0; i < header.nph; i++) {
@@ -3576,6 +3583,7 @@ static int spi_nor_init_params(struct spi_nor *nor,
 	struct spi_nor_erase_map *map = &nor->erase_map;
 	const struct flash_info *info = nor->info;
 	u8 i, erase_mask;
+	int ret;

 	/* Set legacy flash parameters as default. */
 	memset(params, 0, sizeof(*params));
@@ -3681,12 +3689,15 @@ static int spi_nor_init_params(struct spi_nor *nor,
 		memcpy(&sfdp_params, params, sizeof(sfdp_params));
 		memcpy(&prev_map, &nor->erase_map, sizeof(prev_map));

-		if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
+		ret = spi_nor_parse_sfdp(nor, &sfdp_params);
+		if (ret) {
 			nor->addr_width = 0;
 			nor->flags &= ~SNOR_F_4B_OPCODES;
 			/* restore previous erase map */
 			memcpy(&nor->erase_map, &prev_map,
 			       sizeof(nor->erase_map));
+			dev_dbg(nor->dev, "%s sfdp parse failed, ret =%d\n",
+				__FUNCTION__, ret);
 		} else {
 			memcpy(params, &sfdp_params, sizeof(*params));
 		}
@@ -3908,9 +3919,67 @@ static int spi_nor_setup(struct spi_nor *nor,
 	return 0;
 }

+static int spi_nor_dump_sr_cr(struct spi_nor *nor)
+{
+	int ret = read_sr(nor);
+
+	dev_dbg(nor->dev, "SR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading status register\n");
+                return ret;
+        }
+
+	ret = read_cr(nor);
+	dev_dbg(nor->dev, "CR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading configuration register\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int spi_nor_clear_block_protection(struct spi_nor *nor)
+{
+	int ret;
+	u8 val, mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	ret = spi_nor_dump_sr_cr(nor);
+	if (ret)
+		return ret;
+
+	/* clear just the BP bits */
+	ret = read_sr(nor);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading status register\n");
+                return ret;
+        }
+	val = ret;
+
+	ret = write_enable(nor);
+        if (ret < 0) {
+                dev_err(nor->dev, "error on write enable, err = %d\n", ret);
+                return ret;
+	}
+
+	ret = write_sr(nor, val & ~mask);
+        if (ret < 0) {
+                dev_err(nor->dev, "error on write_sr, err = %d\n", ret);
+                return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+        if (ret) {
+                dev_err(nor->dev, "timeout while writing SR, ret = %d\n", ret);
+		return spi_nor_dump_sr_cr(nor);
+        }
+
+	return 0;
+}
+
 static int spi_nor_init(struct spi_nor *nor)
 {
-	int err;
+	int err = 0, quad_err;

 	/*
 	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
@@ -3919,18 +3988,38 @@ static int spi_nor_init(struct spi_nor *nor)
 	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
 	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
 	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-	    nor->info->flags & SPI_NOR_HAS_LOCK) {
-		write_enable(nor);
-		write_sr(nor, 0);
-		spi_nor_wait_till_ready(nor);
+	    nor->info->flags & SPI_NOR_HAS_LOCK)
+		/*
+		 * this should be done only on demand, not for every flash that
+		 * has SPI_NOR_HAS_LOCK set
+		 */
+		err = spi_nor_clear_block_protection(nor);
+	if (err) {
+		dev_err(nor->dev, "clearing BP bits failed, err = %d\n", err);
+		return err;
 	}

 	if (nor->quad_enable) {
-		err = nor->quad_enable(nor);
+		dev_dbg(nor->dev, "SR and CR before quad_enable:\n");
+
+		err = spi_nor_dump_sr_cr(nor);
 		if (err) {
-			dev_err(nor->dev, "quad mode not supported\n");
+			dev_err(nor->dev, "dump_sr_cr before quad enable fail, err = %d\n", err);
 			return err;
 		}
+
+		quad_err = nor->quad_enable(nor);
+		dev_dbg(nor->dev, "SR and CR after quad_enable:\n");
+		err = spi_nor_dump_sr_cr(nor);
+		if (err) {
+			dev_err(nor->dev, "dump_sr_cr after quad enable fail, err = %d\n", err);
+			return err;
+		}
+
+		if (quad_err) {
+			dev_err(nor->dev, "quad mode not supported, err = %d\n", quad_err);
+			return quad_err;
+		}
 	}

 	if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) {

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-08 10:44                     ` Tudor.Ambarus
@ 2019-05-08 13:11                       ` Geert Uytterhoeven
  -1 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-08 13:11 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Jonas Bonn, Linux-Renesas, Marek Vasut, MTD Maling List

Hi Tudor,

On Wed, May 8, 2019 at 12:44 PM <Tudor.Ambarus@microchip.com> wrote:
> Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
> and after the operations in cause.

Thanks, giving it a try...

> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 73172d7f512b..20d0fdb1dc92 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -22,6 +22,8 @@
>  #include <linux/spi/flash.h>
>  #include <linux/mtd/spi-nor.h>
>
> +#define DEBUG

Should be moved to the top of the file, before dev_dbg() is defined.

Result is:

m25p80 spi0.0: bfpt.dwords[1] = ffffffff
m25p80 spi0.0: bfpt.dwords[2] = ffffffff
m25p80 spi0.0: bfpt.dwords[3] = ffffffff
m25p80 spi0.0: bfpt.dwords[4] = ffffffff
m25p80 spi0.0: bfpt.dwords[5] = ffffffff
m25p80 spi0.0: bfpt.dwords[6] = ffffffff
m25p80 spi0.0: bfpt.dwords[7] = ffffffff
m25p80 spi0.0: bfpt.dwords[8] = ffffffff
m25p80 spi0.0: bfpt.dwords[9] = ffffffff
m25p80 spi0.0: bfpt.dwords[10] = 00000000
m25p80 spi0.0: bfpt.dwords[11] = 00000000
m25p80 spi0.0: bfpt.dwords[12] = 00000000
m25p80 spi0.0: bfpt.dwords[13] = 00000000
m25p80 spi0.0: bfpt.dwords[14] = 00000000
m25p80 spi0.0: bfpt.dwords[15] = 00000000
m25p80 spi0.0: bfpt.dwords[16] = 00000000
m25p80 spi0.0: failed to parse BFPT: err = -22
m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
m25p80 spi0.0: SR = 00000000
m25p80 spi0.0: CR = 00000002
m25p80 spi0.0: Erase Error occurred
m25p80 spi0.0: timeout while writing SR, ret = -5
m25p80 spi0.0: SR = 000000ff
m25p80 spi0.0: CR = 000000ff
m25p80 spi0.0: SR and CR before quad_enable:
m25p80 spi0.0: SR = 000000ff
m25p80 spi0.0: CR = 000000ff
m25p80 spi0.0: Erase Error occurred
m25p80 spi0.0: timeout while writing configuration register
m25p80 spi0.0: SR and CR after quad_enable:
m25p80 spi0.0: SR = 000000ff
m25p80 spi0.0: CR = 000000ff
m25p80 spi0.0: quad mode not supported, err = -5
m25p80: probe of spi0.0 failed with error -5

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-08 13:11                       ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-08 13:11 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Linux-Renesas, Jonas Bonn, MTD Maling List, Marek Vasut

Hi Tudor,

On Wed, May 8, 2019 at 12:44 PM <Tudor.Ambarus@microchip.com> wrote:
> Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
> and after the operations in cause.

Thanks, giving it a try...

> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 73172d7f512b..20d0fdb1dc92 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -22,6 +22,8 @@
>  #include <linux/spi/flash.h>
>  #include <linux/mtd/spi-nor.h>
>
> +#define DEBUG

Should be moved to the top of the file, before dev_dbg() is defined.

Result is:

m25p80 spi0.0: bfpt.dwords[1] = ffffffff
m25p80 spi0.0: bfpt.dwords[2] = ffffffff
m25p80 spi0.0: bfpt.dwords[3] = ffffffff
m25p80 spi0.0: bfpt.dwords[4] = ffffffff
m25p80 spi0.0: bfpt.dwords[5] = ffffffff
m25p80 spi0.0: bfpt.dwords[6] = ffffffff
m25p80 spi0.0: bfpt.dwords[7] = ffffffff
m25p80 spi0.0: bfpt.dwords[8] = ffffffff
m25p80 spi0.0: bfpt.dwords[9] = ffffffff
m25p80 spi0.0: bfpt.dwords[10] = 00000000
m25p80 spi0.0: bfpt.dwords[11] = 00000000
m25p80 spi0.0: bfpt.dwords[12] = 00000000
m25p80 spi0.0: bfpt.dwords[13] = 00000000
m25p80 spi0.0: bfpt.dwords[14] = 00000000
m25p80 spi0.0: bfpt.dwords[15] = 00000000
m25p80 spi0.0: bfpt.dwords[16] = 00000000
m25p80 spi0.0: failed to parse BFPT: err = -22
m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
m25p80 spi0.0: SR = 00000000
m25p80 spi0.0: CR = 00000002
m25p80 spi0.0: Erase Error occurred
m25p80 spi0.0: timeout while writing SR, ret = -5
m25p80 spi0.0: SR = 000000ff
m25p80 spi0.0: CR = 000000ff
m25p80 spi0.0: SR and CR before quad_enable:
m25p80 spi0.0: SR = 000000ff
m25p80 spi0.0: CR = 000000ff
m25p80 spi0.0: Erase Error occurred
m25p80 spi0.0: timeout while writing configuration register
m25p80 spi0.0: SR and CR after quad_enable:
m25p80 spi0.0: SR = 000000ff
m25p80 spi0.0: CR = 000000ff
m25p80 spi0.0: quad mode not supported, err = -5
m25p80: probe of spi0.0 failed with error -5

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-08 13:11                       ` Geert Uytterhoeven
@ 2019-05-08 14:23                         ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-08 14:23 UTC (permalink / raw)
  To: geert; +Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi, Geert,

On 05/08/2019 04:11 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Tudor,
> 
> On Wed, May 8, 2019 at 12:44 PM <Tudor.Ambarus@microchip.com> wrote:
>> Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
>> and after the operations in cause.
> 
> Thanks, giving it a try...
> 
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index 73172d7f512b..20d0fdb1dc92 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -22,6 +22,8 @@
>>  #include <linux/spi/flash.h>
>>  #include <linux/mtd/spi-nor.h>
>>
>> +#define DEBUG
> 
> Should be moved to the top of the file, before dev_dbg() is defined.
> 
> Result is:
> 
> m25p80 spi0.0: bfpt.dwords[1] = ffffffff
> m25p80 spi0.0: bfpt.dwords[2] = ffffffff
> m25p80 spi0.0: bfpt.dwords[3] = ffffffff
> m25p80 spi0.0: bfpt.dwords[4] = ffffffff
> m25p80 spi0.0: bfpt.dwords[5] = ffffffff
> m25p80 spi0.0: bfpt.dwords[6] = ffffffff
> m25p80 spi0.0: bfpt.dwords[7] = ffffffff
> m25p80 spi0.0: bfpt.dwords[8] = ffffffff
> m25p80 spi0.0: bfpt.dwords[9] = ffffffff
> m25p80 spi0.0: bfpt.dwords[10] = 00000000
> m25p80 spi0.0: bfpt.dwords[11] = 00000000
> m25p80 spi0.0: bfpt.dwords[12] = 00000000
> m25p80 spi0.0: bfpt.dwords[13] = 00000000
> m25p80 spi0.0: bfpt.dwords[14] = 00000000
> m25p80 spi0.0: bfpt.dwords[15] = 00000000
> m25p80 spi0.0: bfpt.dwords[16] = 00000000
> m25p80 spi0.0: failed to parse BFPT: err = -22
> m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
> m25p80 spi0.0: SR = 00000000
> m25p80 spi0.0: CR = 00000002
> m25p80 spi0.0: Erase Error occurred
> m25p80 spi0.0: timeout while writing SR, ret = -5
> m25p80 spi0.0: SR = 000000ff
> m25p80 spi0.0: CR = 000000ff

ff can mean that the lines are "in air", maybe the flash resets when we
write_sr(nor, 0)? How about adding a delay here to let the flash reset?

SR=0 and CR=2 after reset, both write_sr(nor, 0) and quad_enable can be avoided
-> read SR, clear BP bits only if they are set to 1, read CR -> set Quad Enable
bit only when it's zero.

Cheers,
ta

> m25p80 spi0.0: SR and CR before quad_enable:
> m25p80 spi0.0: SR = 000000ff
> m25p80 spi0.0: CR = 000000ff
> m25p80 spi0.0: Erase Error occurred
> m25p80 spi0.0: timeout while writing configuration register
> m25p80 spi0.0: SR and CR after quad_enable:
> m25p80 spi0.0: SR = 000000ff
> m25p80 spi0.0: CR = 000000ff
> m25p80 spi0.0: quad mode not supported, err = -5
> m25p80: probe of spi0.0 failed with error -5
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-08 14:23                         ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-08 14:23 UTC (permalink / raw)
  To: geert; +Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi, Geert,

On 05/08/2019 04:11 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Tudor,
> 
> On Wed, May 8, 2019 at 12:44 PM <Tudor.Ambarus@microchip.com> wrote:
>> Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
>> and after the operations in cause.
> 
> Thanks, giving it a try...
> 
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index 73172d7f512b..20d0fdb1dc92 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -22,6 +22,8 @@
>>  #include <linux/spi/flash.h>
>>  #include <linux/mtd/spi-nor.h>
>>
>> +#define DEBUG
> 
> Should be moved to the top of the file, before dev_dbg() is defined.
> 
> Result is:
> 
> m25p80 spi0.0: bfpt.dwords[1] = ffffffff
> m25p80 spi0.0: bfpt.dwords[2] = ffffffff
> m25p80 spi0.0: bfpt.dwords[3] = ffffffff
> m25p80 spi0.0: bfpt.dwords[4] = ffffffff
> m25p80 spi0.0: bfpt.dwords[5] = ffffffff
> m25p80 spi0.0: bfpt.dwords[6] = ffffffff
> m25p80 spi0.0: bfpt.dwords[7] = ffffffff
> m25p80 spi0.0: bfpt.dwords[8] = ffffffff
> m25p80 spi0.0: bfpt.dwords[9] = ffffffff
> m25p80 spi0.0: bfpt.dwords[10] = 00000000
> m25p80 spi0.0: bfpt.dwords[11] = 00000000
> m25p80 spi0.0: bfpt.dwords[12] = 00000000
> m25p80 spi0.0: bfpt.dwords[13] = 00000000
> m25p80 spi0.0: bfpt.dwords[14] = 00000000
> m25p80 spi0.0: bfpt.dwords[15] = 00000000
> m25p80 spi0.0: bfpt.dwords[16] = 00000000
> m25p80 spi0.0: failed to parse BFPT: err = -22
> m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
> m25p80 spi0.0: SR = 00000000
> m25p80 spi0.0: CR = 00000002
> m25p80 spi0.0: Erase Error occurred
> m25p80 spi0.0: timeout while writing SR, ret = -5
> m25p80 spi0.0: SR = 000000ff
> m25p80 spi0.0: CR = 000000ff

ff can mean that the lines are "in air", maybe the flash resets when we
write_sr(nor, 0)? How about adding a delay here to let the flash reset?

SR=0 and CR=2 after reset, both write_sr(nor, 0) and quad_enable can be avoided
-> read SR, clear BP bits only if they are set to 1, read CR -> set Quad Enable
bit only when it's zero.

Cheers,
ta

> m25p80 spi0.0: SR and CR before quad_enable:
> m25p80 spi0.0: SR = 000000ff
> m25p80 spi0.0: CR = 000000ff
> m25p80 spi0.0: Erase Error occurred
> m25p80 spi0.0: timeout while writing configuration register
> m25p80 spi0.0: SR and CR after quad_enable:
> m25p80 spi0.0: SR = 000000ff
> m25p80 spi0.0: CR = 000000ff
> m25p80 spi0.0: quad mode not supported, err = -5
> m25p80: probe of spi0.0 failed with error -5
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-08 14:23                         ` Tudor.Ambarus
@ 2019-05-08 17:00                           ` Geert Uytterhoeven
  -1 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-08 17:00 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Linux-Renesas, Jonas Bonn, MTD Maling List, Marek Vasut

Hi Tudor,

On Wed, May 8, 2019 at 4:23 PM <Tudor.Ambarus@microchip.com> wrote:
> On 05/08/2019 04:11 PM, Geert Uytterhoeven wrote:
> > On Wed, May 8, 2019 at 12:44 PM <Tudor.Ambarus@microchip.com> wrote:
> >> Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
> >> and after the operations in cause.
> >
> > Thanks, giving it a try...
> >
> >> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> >> index 73172d7f512b..20d0fdb1dc92 100644
> >> --- a/drivers/mtd/spi-nor/spi-nor.c
> >> +++ b/drivers/mtd/spi-nor/spi-nor.c
> >> @@ -22,6 +22,8 @@
> >>  #include <linux/spi/flash.h>
> >>  #include <linux/mtd/spi-nor.h>
> >>
> >> +#define DEBUG
> >
> > Should be moved to the top of the file, before dev_dbg() is defined.
> >
> > Result is:
> >
> > m25p80 spi0.0: bfpt.dwords[1] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[2] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[3] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[4] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[5] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[6] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[7] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[8] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[9] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[10] = 00000000
> > m25p80 spi0.0: bfpt.dwords[11] = 00000000
> > m25p80 spi0.0: bfpt.dwords[12] = 00000000
> > m25p80 spi0.0: bfpt.dwords[13] = 00000000
> > m25p80 spi0.0: bfpt.dwords[14] = 00000000
> > m25p80 spi0.0: bfpt.dwords[15] = 00000000
> > m25p80 spi0.0: bfpt.dwords[16] = 00000000
> > m25p80 spi0.0: failed to parse BFPT: err = -22
> > m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
> > m25p80 spi0.0: SR = 00000000
> > m25p80 spi0.0: CR = 00000002
> > m25p80 spi0.0: Erase Error occurred
> > m25p80 spi0.0: timeout while writing SR, ret = -5
> > m25p80 spi0.0: SR = 000000ff
> > m25p80 spi0.0: CR = 000000ff
>
> ff can mean that the lines are "in air", maybe the flash resets when we
> write_sr(nor, 0)? How about adding a delay here to let the flash reset?

No difference after adding msleep(1000).

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-08 17:00                           ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-08 17:00 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Linux-Renesas, Jonas Bonn, MTD Maling List, Marek Vasut

Hi Tudor,

On Wed, May 8, 2019 at 4:23 PM <Tudor.Ambarus@microchip.com> wrote:
> On 05/08/2019 04:11 PM, Geert Uytterhoeven wrote:
> > On Wed, May 8, 2019 at 12:44 PM <Tudor.Ambarus@microchip.com> wrote:
> >> Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
> >> and after the operations in cause.
> >
> > Thanks, giving it a try...
> >
> >> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> >> index 73172d7f512b..20d0fdb1dc92 100644
> >> --- a/drivers/mtd/spi-nor/spi-nor.c
> >> +++ b/drivers/mtd/spi-nor/spi-nor.c
> >> @@ -22,6 +22,8 @@
> >>  #include <linux/spi/flash.h>
> >>  #include <linux/mtd/spi-nor.h>
> >>
> >> +#define DEBUG
> >
> > Should be moved to the top of the file, before dev_dbg() is defined.
> >
> > Result is:
> >
> > m25p80 spi0.0: bfpt.dwords[1] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[2] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[3] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[4] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[5] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[6] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[7] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[8] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[9] = ffffffff
> > m25p80 spi0.0: bfpt.dwords[10] = 00000000
> > m25p80 spi0.0: bfpt.dwords[11] = 00000000
> > m25p80 spi0.0: bfpt.dwords[12] = 00000000
> > m25p80 spi0.0: bfpt.dwords[13] = 00000000
> > m25p80 spi0.0: bfpt.dwords[14] = 00000000
> > m25p80 spi0.0: bfpt.dwords[15] = 00000000
> > m25p80 spi0.0: bfpt.dwords[16] = 00000000
> > m25p80 spi0.0: failed to parse BFPT: err = -22
> > m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
> > m25p80 spi0.0: SR = 00000000
> > m25p80 spi0.0: CR = 00000002
> > m25p80 spi0.0: Erase Error occurred
> > m25p80 spi0.0: timeout while writing SR, ret = -5
> > m25p80 spi0.0: SR = 000000ff
> > m25p80 spi0.0: CR = 000000ff
>
> ff can mean that the lines are "in air", maybe the flash resets when we
> write_sr(nor, 0)? How about adding a delay here to let the flash reset?

No difference after adding msleep(1000).

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-08 17:00                           ` Geert Uytterhoeven
@ 2019-05-09  6:55                             ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-09  6:55 UTC (permalink / raw)
  To: geert; +Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi, Geert,

On 05/08/2019 08:00 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Tudor,>
> On Wed, May 8, 2019 at 4:23 PM <Tudor.Ambarus@microchip.com> wrote:
>> On 05/08/2019 04:11 PM, Geert Uytterhoeven wrote:
>>> On Wed, May 8, 2019 at 12:44 PM <Tudor.Ambarus@microchip.com> wrote:
>>>> Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
>>>> and after the operations in cause.
>>>
>>> Thanks, giving it a try...
>>>
>>>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>>>> index 73172d7f512b..20d0fdb1dc92 100644
>>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>>> @@ -22,6 +22,8 @@
>>>>  #include <linux/spi/flash.h>
>>>>  #include <linux/mtd/spi-nor.h>
>>>>
>>>> +#define DEBUG
>>>
>>> Should be moved to the top of the file, before dev_dbg() is defined.
>>>
>>> Result is:
>>>
>>> m25p80 spi0.0: bfpt.dwords[1] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[2] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[3] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[4] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[5] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[6] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[7] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[8] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[9] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[10] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[11] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[12] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[13] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[14] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[15] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[16] = 00000000
>>> m25p80 spi0.0: failed to parse BFPT: err = -22
>>> m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
>>> m25p80 spi0.0: SR = 00000000
>>> m25p80 spi0.0: CR = 00000002
>>> m25p80 spi0.0: Erase Error occurred
>>> m25p80 spi0.0: timeout while writing SR, ret = -5
>>> m25p80 spi0.0: SR = 000000ff
>>> m25p80 spi0.0: CR = 000000ff
>>
>> ff can mean that the lines are "in air", maybe the flash resets when we
>> write_sr(nor, 0)? How about adding a delay here to let the flash reset?
> 
> No difference after adding msleep(1000).
> 

When the configuration register QUAD bit CR[1] is 1, only the WRR command format
with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
FFs. You probably set quad bit in u-boot, while others don't. We can verify this
assumption with the patch form below. Can you try it?

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 73172d7f512b..0d636eab3ebf 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2005, Intec Automation Inc.
  * Copyright (C) 2014, Freescale Semiconductor, Inc.
  */
+#define DEBUG

 #include <linux/err.h>
 #include <linux/errno.h>
@@ -200,7 +201,7 @@ struct sfdp_header {
  *         register does not modify status register 2.
  * - 101b: QE is bit 1 of status register 2. Status register 1 is read using
  *         Read Status instruction 05h. Status register2 is read using
- *         instruction 35h. QE is set via Writ Status instruction 01h with
+ *         instruction 35h. QE is set via Write Status instruction 01h with
  *         two data bytes where bit 1 of the second byte is one.
  *         [...]
  */
@@ -2795,8 +2796,11 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
 		return err;

 	/* Fix endianness of the BFPT DWORDs. */
-	for (i = 0; i < BFPT_DWORD_MAX; i++)
+	for (i = 0; i < BFPT_DWORD_MAX; i++) {
 		bfpt.dwords[i] = le32_to_cpu(bfpt.dwords[i]);
+		dev_dbg(nor->dev, "bfpt.dwords[%d] = %08x\n", i + 1,
+			bfpt.dwords[i]);
+	}

 	/* Number of address bytes. */
 	switch (bfpt.dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) {
@@ -3532,8 +3536,10 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
 	}

 	err = spi_nor_parse_bfpt(nor, bfpt_header, params);
-	if (err)
+	if (err) {
+		dev_dbg(dev, "failed to parse BFPT: err = %d\n", err);
 		goto exit;
+	}

 	/* Parse optional parameter tables. */
 	for (i = 0; i < header.nph; i++) {
@@ -3576,6 +3582,7 @@ static int spi_nor_init_params(struct spi_nor *nor,
 	struct spi_nor_erase_map *map = &nor->erase_map;
 	const struct flash_info *info = nor->info;
 	u8 i, erase_mask;
+	int ret;

 	/* Set legacy flash parameters as default. */
 	memset(params, 0, sizeof(*params));
@@ -3681,12 +3688,15 @@ static int spi_nor_init_params(struct spi_nor *nor,
 		memcpy(&sfdp_params, params, sizeof(sfdp_params));
 		memcpy(&prev_map, &nor->erase_map, sizeof(prev_map));

-		if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
+		ret = spi_nor_parse_sfdp(nor, &sfdp_params);
+		if (ret) {
 			nor->addr_width = 0;
 			nor->flags &= ~SNOR_F_4B_OPCODES;
 			/* restore previous erase map */
 			memcpy(&nor->erase_map, &prev_map,
 			       sizeof(nor->erase_map));
+			dev_dbg(nor->dev, "%s sfdp parse failed, ret =%d\n",
+				__FUNCTION__, ret);
 		} else {
 			memcpy(params, &sfdp_params, sizeof(*params));
 		}
@@ -3908,9 +3918,86 @@ static int spi_nor_setup(struct spi_nor *nor,
 	return 0;
 }

+static int spi_nor_dump_sr_cr(struct spi_nor *nor)
+{
+	int ret = read_sr(nor);
+
+	dev_dbg(nor->dev, "SR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading status register\n");
+                return ret;
+        }
+
+	ret = read_cr(nor);
+	dev_dbg(nor->dev, "CR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading configuration register\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int spi_nor_clear_block_protection(struct spi_nor *nor)
+{
+	int ret;
+	u8 sr, cr, sr_cr[2] = {0};
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	ret = read_cr(nor);
+	dev_dbg(nor->dev, "CR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading CR\n");
+		return ret;
+	}
+	cr = ret;
+
+	if (cr & CR_QUAD_EN_SPAN) {
+		/* disable quad if already set, must do it with 16-bit WRR */
+		ret = write_sr_cr(nor, sr_cr);
+		if (ret) {
+			dev_err(nor->dev, "error diasbling quad mode\n");
+			return ret;
+		}
+
+		/* read back and check it */
+		ret = read_cr(nor);
+		if (ret >= 0 && (ret & CR_QUAD_EN_SPAN)) {
+			dev_err(nor->dev, "Spansion Quad bit not cleared\n");
+			return -EINVAL;
+		}
+	}
+
+	/* Clear BP bits with 8-bit WRR */
+	ret = read_sr(nor);
+	dev_dbg(nor->dev, "SR = %08x\n", ret);
+	if (ret < 0) {
+		dev_err(nor->dev, "error while reading SR\n");
+                return ret;
+	}
+	sr = ret;
+
+	ret = write_enable(nor);
+        if (ret < 0) {
+                dev_err(nor->dev, "error on write enable, err = %d\n", ret);
+                return ret;
+	}
+
+	ret = write_sr(nor, sr & ~mask);
+        if (ret < 0) {
+                dev_err(nor->dev, "error on write_sr, err = %d\n", ret);
+                return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+        if (ret)
+                dev_err(nor->dev, "timeout while writing SR, ret = %d\n", ret);
+	return spi_nor_dump_sr_cr(nor);
+}
+
 static int spi_nor_init(struct spi_nor *nor)
 {
-	int err;
+	int err = 0, quad_err;

 	/*
 	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
@@ -3919,18 +4006,38 @@ static int spi_nor_init(struct spi_nor *nor)
 	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
 	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
 	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-	    nor->info->flags & SPI_NOR_HAS_LOCK) {
-		write_enable(nor);
-		write_sr(nor, 0);
-		spi_nor_wait_till_ready(nor);
+	    nor->info->flags & SPI_NOR_HAS_LOCK)
+		/*
+		 * this should be done only on demand, not for every flash that
+		 * has SPI_NOR_HAS_LOCK set
+		 */
+		err = spi_nor_clear_block_protection(nor);
+	if (err) {
+		dev_err(nor->dev, "clearing BP bits failed, err = %d\n", err);
+		return err;
 	}

 	if (nor->quad_enable) {
-		err = nor->quad_enable(nor);
+		dev_dbg(nor->dev, "SR and CR before quad_enable:\n");
+
+		err = spi_nor_dump_sr_cr(nor);
 		if (err) {
-			dev_err(nor->dev, "quad mode not supported\n");
+			dev_err(nor->dev, "dump_sr_cr before quad enable fail, err = %d\n", err);
 			return err;
 		}
+
+		quad_err = nor->quad_enable(nor);
+		dev_dbg(nor->dev, "SR and CR after quad_enable:\n");
+		err = spi_nor_dump_sr_cr(nor);
+		if (err) {
+			dev_err(nor->dev, "dump_sr_cr after quad enable fail, err = %d\n", err);
+			return err;
+		}
+
+		if (quad_err) {
+			dev_err(nor->dev, "quad mode not supported, err = %d\n", quad_err);
+			return quad_err;
+		}
 	}

 	if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) {



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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-09  6:55                             ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-09  6:55 UTC (permalink / raw)
  To: geert; +Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi, Geert,

On 05/08/2019 08:00 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Tudor,>
> On Wed, May 8, 2019 at 4:23 PM <Tudor.Ambarus@microchip.com> wrote:
>> On 05/08/2019 04:11 PM, Geert Uytterhoeven wrote:
>>> On Wed, May 8, 2019 at 12:44 PM <Tudor.Ambarus@microchip.com> wrote:
>>>> Would you run this debug patch on top of mtd/next? I dumped the SR and CR before
>>>> and after the operations in cause.
>>>
>>> Thanks, giving it a try...
>>>
>>>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>>>> index 73172d7f512b..20d0fdb1dc92 100644
>>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>>> @@ -22,6 +22,8 @@
>>>>  #include <linux/spi/flash.h>
>>>>  #include <linux/mtd/spi-nor.h>
>>>>
>>>> +#define DEBUG
>>>
>>> Should be moved to the top of the file, before dev_dbg() is defined.
>>>
>>> Result is:
>>>
>>> m25p80 spi0.0: bfpt.dwords[1] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[2] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[3] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[4] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[5] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[6] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[7] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[8] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[9] = ffffffff
>>> m25p80 spi0.0: bfpt.dwords[10] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[11] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[12] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[13] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[14] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[15] = 00000000
>>> m25p80 spi0.0: bfpt.dwords[16] = 00000000
>>> m25p80 spi0.0: failed to parse BFPT: err = -22
>>> m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
>>> m25p80 spi0.0: SR = 00000000
>>> m25p80 spi0.0: CR = 00000002
>>> m25p80 spi0.0: Erase Error occurred
>>> m25p80 spi0.0: timeout while writing SR, ret = -5
>>> m25p80 spi0.0: SR = 000000ff
>>> m25p80 spi0.0: CR = 000000ff
>>
>> ff can mean that the lines are "in air", maybe the flash resets when we
>> write_sr(nor, 0)? How about adding a delay here to let the flash reset?
> 
> No difference after adding msleep(1000).
> 

When the configuration register QUAD bit CR[1] is 1, only the WRR command format
with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
FFs. You probably set quad bit in u-boot, while others don't. We can verify this
assumption with the patch form below. Can you try it?

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 73172d7f512b..0d636eab3ebf 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2005, Intec Automation Inc.
  * Copyright (C) 2014, Freescale Semiconductor, Inc.
  */
+#define DEBUG

 #include <linux/err.h>
 #include <linux/errno.h>
@@ -200,7 +201,7 @@ struct sfdp_header {
  *         register does not modify status register 2.
  * - 101b: QE is bit 1 of status register 2. Status register 1 is read using
  *         Read Status instruction 05h. Status register2 is read using
- *         instruction 35h. QE is set via Writ Status instruction 01h with
+ *         instruction 35h. QE is set via Write Status instruction 01h with
  *         two data bytes where bit 1 of the second byte is one.
  *         [...]
  */
@@ -2795,8 +2796,11 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
 		return err;

 	/* Fix endianness of the BFPT DWORDs. */
-	for (i = 0; i < BFPT_DWORD_MAX; i++)
+	for (i = 0; i < BFPT_DWORD_MAX; i++) {
 		bfpt.dwords[i] = le32_to_cpu(bfpt.dwords[i]);
+		dev_dbg(nor->dev, "bfpt.dwords[%d] = %08x\n", i + 1,
+			bfpt.dwords[i]);
+	}

 	/* Number of address bytes. */
 	switch (bfpt.dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) {
@@ -3532,8 +3536,10 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
 	}

 	err = spi_nor_parse_bfpt(nor, bfpt_header, params);
-	if (err)
+	if (err) {
+		dev_dbg(dev, "failed to parse BFPT: err = %d\n", err);
 		goto exit;
+	}

 	/* Parse optional parameter tables. */
 	for (i = 0; i < header.nph; i++) {
@@ -3576,6 +3582,7 @@ static int spi_nor_init_params(struct spi_nor *nor,
 	struct spi_nor_erase_map *map = &nor->erase_map;
 	const struct flash_info *info = nor->info;
 	u8 i, erase_mask;
+	int ret;

 	/* Set legacy flash parameters as default. */
 	memset(params, 0, sizeof(*params));
@@ -3681,12 +3688,15 @@ static int spi_nor_init_params(struct spi_nor *nor,
 		memcpy(&sfdp_params, params, sizeof(sfdp_params));
 		memcpy(&prev_map, &nor->erase_map, sizeof(prev_map));

-		if (spi_nor_parse_sfdp(nor, &sfdp_params)) {
+		ret = spi_nor_parse_sfdp(nor, &sfdp_params);
+		if (ret) {
 			nor->addr_width = 0;
 			nor->flags &= ~SNOR_F_4B_OPCODES;
 			/* restore previous erase map */
 			memcpy(&nor->erase_map, &prev_map,
 			       sizeof(nor->erase_map));
+			dev_dbg(nor->dev, "%s sfdp parse failed, ret =%d\n",
+				__FUNCTION__, ret);
 		} else {
 			memcpy(params, &sfdp_params, sizeof(*params));
 		}
@@ -3908,9 +3918,86 @@ static int spi_nor_setup(struct spi_nor *nor,
 	return 0;
 }

+static int spi_nor_dump_sr_cr(struct spi_nor *nor)
+{
+	int ret = read_sr(nor);
+
+	dev_dbg(nor->dev, "SR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading status register\n");
+                return ret;
+        }
+
+	ret = read_cr(nor);
+	dev_dbg(nor->dev, "CR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading configuration register\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int spi_nor_clear_block_protection(struct spi_nor *nor)
+{
+	int ret;
+	u8 sr, cr, sr_cr[2] = {0};
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	ret = read_cr(nor);
+	dev_dbg(nor->dev, "CR = %08x\n", ret);
+        if (ret < 0) {
+                dev_err(nor->dev, "error while reading CR\n");
+		return ret;
+	}
+	cr = ret;
+
+	if (cr & CR_QUAD_EN_SPAN) {
+		/* disable quad if already set, must do it with 16-bit WRR */
+		ret = write_sr_cr(nor, sr_cr);
+		if (ret) {
+			dev_err(nor->dev, "error diasbling quad mode\n");
+			return ret;
+		}
+
+		/* read back and check it */
+		ret = read_cr(nor);
+		if (ret >= 0 && (ret & CR_QUAD_EN_SPAN)) {
+			dev_err(nor->dev, "Spansion Quad bit not cleared\n");
+			return -EINVAL;
+		}
+	}
+
+	/* Clear BP bits with 8-bit WRR */
+	ret = read_sr(nor);
+	dev_dbg(nor->dev, "SR = %08x\n", ret);
+	if (ret < 0) {
+		dev_err(nor->dev, "error while reading SR\n");
+                return ret;
+	}
+	sr = ret;
+
+	ret = write_enable(nor);
+        if (ret < 0) {
+                dev_err(nor->dev, "error on write enable, err = %d\n", ret);
+                return ret;
+	}
+
+	ret = write_sr(nor, sr & ~mask);
+        if (ret < 0) {
+                dev_err(nor->dev, "error on write_sr, err = %d\n", ret);
+                return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+        if (ret)
+                dev_err(nor->dev, "timeout while writing SR, ret = %d\n", ret);
+	return spi_nor_dump_sr_cr(nor);
+}
+
 static int spi_nor_init(struct spi_nor *nor)
 {
-	int err;
+	int err = 0, quad_err;

 	/*
 	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
@@ -3919,18 +4006,38 @@ static int spi_nor_init(struct spi_nor *nor)
 	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
 	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
 	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-	    nor->info->flags & SPI_NOR_HAS_LOCK) {
-		write_enable(nor);
-		write_sr(nor, 0);
-		spi_nor_wait_till_ready(nor);
+	    nor->info->flags & SPI_NOR_HAS_LOCK)
+		/*
+		 * this should be done only on demand, not for every flash that
+		 * has SPI_NOR_HAS_LOCK set
+		 */
+		err = spi_nor_clear_block_protection(nor);
+	if (err) {
+		dev_err(nor->dev, "clearing BP bits failed, err = %d\n", err);
+		return err;
 	}

 	if (nor->quad_enable) {
-		err = nor->quad_enable(nor);
+		dev_dbg(nor->dev, "SR and CR before quad_enable:\n");
+
+		err = spi_nor_dump_sr_cr(nor);
 		if (err) {
-			dev_err(nor->dev, "quad mode not supported\n");
+			dev_err(nor->dev, "dump_sr_cr before quad enable fail, err = %d\n", err);
 			return err;
 		}
+
+		quad_err = nor->quad_enable(nor);
+		dev_dbg(nor->dev, "SR and CR after quad_enable:\n");
+		err = spi_nor_dump_sr_cr(nor);
+		if (err) {
+			dev_err(nor->dev, "dump_sr_cr after quad enable fail, err = %d\n", err);
+			return err;
+		}
+
+		if (quad_err) {
+			dev_err(nor->dev, "quad mode not supported, err = %d\n", quad_err);
+			return quad_err;
+		}
 	}

 	if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) {


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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-09  6:55                             ` Tudor.Ambarus
@ 2019-05-09  9:11                               ` Geert Uytterhoeven
  -1 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-09  9:11 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Linux-Renesas, Jonas Bonn, MTD Maling List, Marek Vasut

Hi Tudor,

On Thu, May 9, 2019 at 8:56 AM <Tudor.Ambarus@microchip.com> wrote:
> When the configuration register QUAD bit CR[1] is 1, only the WRR command format
> with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
> FFs. You probably set quad bit in u-boot, while others don't. We can verify this
> assumption with the patch form below. Can you try it?

Thanks!

> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c

> +static int spi_nor_clear_block_protection(struct spi_nor *nor)
> +{
> +       int ret;
> +       u8 sr, cr, sr_cr[2] = {0};
> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +       ret = read_cr(nor);
> +       dev_dbg(nor->dev, "CR = %08x\n", ret);
> +        if (ret < 0) {
> +                dev_err(nor->dev, "error while reading CR\n");
> +               return ret;
> +       }
> +       cr = ret;
> +
> +       if (cr & CR_QUAD_EN_SPAN) {
> +               /* disable quad if already set, must do it with 16-bit WRR */
> +               ret = write_sr_cr(nor, sr_cr);
> +               if (ret) {
> +                       dev_err(nor->dev, "error diasbling quad mode\n");

disabling

> +                       return ret;
> +               }

renesas_spi e6b10000.spi: DMA available
renesas_spi e6b10000.spi: registered master spi0
spi spi0.0: setup mode 3, 8 bits/w, 30000000 Hz max --> 0
m25p80 spi0.0: bfpt.dwords[1] = ffffffff
m25p80 spi0.0: bfpt.dwords[2] = ffffffff
m25p80 spi0.0: bfpt.dwords[3] = ffffffff
m25p80 spi0.0: bfpt.dwords[4] = ffffffff
m25p80 spi0.0: bfpt.dwords[5] = ffffffff
m25p80 spi0.0: bfpt.dwords[6] = ffffffff
m25p80 spi0.0: bfpt.dwords[7] = ffffffff
m25p80 spi0.0: bfpt.dwords[8] = ffffffff
m25p80 spi0.0: bfpt.dwords[9] = ffffffff
m25p80 spi0.0: bfpt.dwords[10] = 00000000
m25p80 spi0.0: bfpt.dwords[11] = 00000000
m25p80 spi0.0: bfpt.dwords[12] = 00000000
m25p80 spi0.0: bfpt.dwords[13] = 00000000
m25p80 spi0.0: bfpt.dwords[14] = 00000000
m25p80 spi0.0: bfpt.dwords[15] = 00000000
m25p80 spi0.0: bfpt.dwords[16] = 00000000
m25p80 spi0.0: failed to parse BFPT: err = -22
m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
m25p80 spi0.0: SR and CR before quad_enable:
m25p80 spi0.0: SR = 00000000
m25p80 spi0.0: CR = 00000002
m25p80 spi0.0: SR and CR after quad_enable:
m25p80 spi0.0: SR = 00000000
m25p80 spi0.0: CR = 00000002
m25p80 spi0.0: s25fl512s (65536 Kbytes)
m25p80 spi0.0: mtd .name = spi0.0, .size = 0x4000000 (64MiB),
.erasesize = 0x00040000 (256KiB) .numeraseregions = 0
3 fixed-partitions partitions found on MTD device spi0.0
Creating 3 MTD partitions on "spi0.0":
0x000000000000-0x000000080000 : "loader"
0x000000080000-0x000000600000 : "user"
0x000000600000-0x000004000000 : "flash"
renesas_spi e6b10000.spi: registered child spi0.0
renesas_spi e6b10000.spi: probed

And /dev/mtd0 reading works fine.
Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-09  9:11                               ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-09  9:11 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Linux-Renesas, Jonas Bonn, MTD Maling List, Marek Vasut

Hi Tudor,

On Thu, May 9, 2019 at 8:56 AM <Tudor.Ambarus@microchip.com> wrote:
> When the configuration register QUAD bit CR[1] is 1, only the WRR command format
> with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
> FFs. You probably set quad bit in u-boot, while others don't. We can verify this
> assumption with the patch form below. Can you try it?

Thanks!

> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c

> +static int spi_nor_clear_block_protection(struct spi_nor *nor)
> +{
> +       int ret;
> +       u8 sr, cr, sr_cr[2] = {0};
> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +       ret = read_cr(nor);
> +       dev_dbg(nor->dev, "CR = %08x\n", ret);
> +        if (ret < 0) {
> +                dev_err(nor->dev, "error while reading CR\n");
> +               return ret;
> +       }
> +       cr = ret;
> +
> +       if (cr & CR_QUAD_EN_SPAN) {
> +               /* disable quad if already set, must do it with 16-bit WRR */
> +               ret = write_sr_cr(nor, sr_cr);
> +               if (ret) {
> +                       dev_err(nor->dev, "error diasbling quad mode\n");

disabling

> +                       return ret;
> +               }

renesas_spi e6b10000.spi: DMA available
renesas_spi e6b10000.spi: registered master spi0
spi spi0.0: setup mode 3, 8 bits/w, 30000000 Hz max --> 0
m25p80 spi0.0: bfpt.dwords[1] = ffffffff
m25p80 spi0.0: bfpt.dwords[2] = ffffffff
m25p80 spi0.0: bfpt.dwords[3] = ffffffff
m25p80 spi0.0: bfpt.dwords[4] = ffffffff
m25p80 spi0.0: bfpt.dwords[5] = ffffffff
m25p80 spi0.0: bfpt.dwords[6] = ffffffff
m25p80 spi0.0: bfpt.dwords[7] = ffffffff
m25p80 spi0.0: bfpt.dwords[8] = ffffffff
m25p80 spi0.0: bfpt.dwords[9] = ffffffff
m25p80 spi0.0: bfpt.dwords[10] = 00000000
m25p80 spi0.0: bfpt.dwords[11] = 00000000
m25p80 spi0.0: bfpt.dwords[12] = 00000000
m25p80 spi0.0: bfpt.dwords[13] = 00000000
m25p80 spi0.0: bfpt.dwords[14] = 00000000
m25p80 spi0.0: bfpt.dwords[15] = 00000000
m25p80 spi0.0: bfpt.dwords[16] = 00000000
m25p80 spi0.0: failed to parse BFPT: err = -22
m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
m25p80 spi0.0: SR and CR before quad_enable:
m25p80 spi0.0: SR = 00000000
m25p80 spi0.0: CR = 00000002
m25p80 spi0.0: SR and CR after quad_enable:
m25p80 spi0.0: SR = 00000000
m25p80 spi0.0: CR = 00000002
m25p80 spi0.0: s25fl512s (65536 Kbytes)
m25p80 spi0.0: mtd .name = spi0.0, .size = 0x4000000 (64MiB),
.erasesize = 0x00040000 (256KiB) .numeraseregions = 0
3 fixed-partitions partitions found on MTD device spi0.0
Creating 3 MTD partitions on "spi0.0":
0x000000000000-0x000000080000 : "loader"
0x000000080000-0x000000600000 : "user"
0x000000600000-0x000004000000 : "flash"
renesas_spi e6b10000.spi: registered child spi0.0
renesas_spi e6b10000.spi: probed

And /dev/mtd0 reading works fine.
Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-09  9:11                               ` Geert Uytterhoeven
@ 2019-05-09 10:31                                 ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-09 10:31 UTC (permalink / raw)
  To: geert; +Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi, Geert,

On 05/09/2019 12:11 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Tudor,
> 
> On Thu, May 9, 2019 at 8:56 AM <Tudor.Ambarus@microchip.com> wrote:
>> When the configuration register QUAD bit CR[1] is 1, only the WRR command format
>> with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
>> FFs. You probably set quad bit in u-boot, while others don't. We can verify this
>> assumption with the patch form below. Can you try it?
> 
> Thanks!
> 
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
> 
>> +static int spi_nor_clear_block_protection(struct spi_nor *nor)
>> +{
>> +       int ret;
>> +       u8 sr, cr, sr_cr[2] = {0};
>> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
>> +
>> +       ret = read_cr(nor);
>> +       dev_dbg(nor->dev, "CR = %08x\n", ret);
>> +        if (ret < 0) {
>> +                dev_err(nor->dev, "error while reading CR\n");
>> +               return ret;
>> +       }
>> +       cr = ret;
>> +
>> +       if (cr & CR_QUAD_EN_SPAN) {
>> +               /* disable quad if already set, must do it with 16-bit WRR */
>> +               ret = write_sr_cr(nor, sr_cr);
>> +               if (ret) {
>> +                       dev_err(nor->dev, "error diasbling quad mode\n");
> 
> disabling
> 
>> +                       return ret;
>> +               }
> 
> renesas_spi e6b10000.spi: DMA available
> renesas_spi e6b10000.spi: registered master spi0
> spi spi0.0: setup mode 3, 8 bits/w, 30000000 Hz max --> 0
> m25p80 spi0.0: bfpt.dwords[1] = ffffffff
> m25p80 spi0.0: bfpt.dwords[2] = ffffffff
> m25p80 spi0.0: bfpt.dwords[3] = ffffffff
> m25p80 spi0.0: bfpt.dwords[4] = ffffffff
> m25p80 spi0.0: bfpt.dwords[5] = ffffffff
> m25p80 spi0.0: bfpt.dwords[6] = ffffffff
> m25p80 spi0.0: bfpt.dwords[7] = ffffffff
> m25p80 spi0.0: bfpt.dwords[8] = ffffffff
> m25p80 spi0.0: bfpt.dwords[9] = ffffffff
> m25p80 spi0.0: bfpt.dwords[10] = 00000000
> m25p80 spi0.0: bfpt.dwords[11] = 00000000
> m25p80 spi0.0: bfpt.dwords[12] = 00000000
> m25p80 spi0.0: bfpt.dwords[13] = 00000000
> m25p80 spi0.0: bfpt.dwords[14] = 00000000
> m25p80 spi0.0: bfpt.dwords[15] = 00000000
> m25p80 spi0.0: bfpt.dwords[16] = 00000000
> m25p80 spi0.0: failed to parse BFPT: err = -22
> m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
> m25p80 spi0.0: SR and CR before quad_enable:
> m25p80 spi0.0: SR = 00000000
> m25p80 spi0.0: CR = 00000002
> m25p80 spi0.0: SR and CR after quad_enable:
> m25p80 spi0.0: SR = 00000000
> m25p80 spi0.0: CR = 00000002
> m25p80 spi0.0: s25fl512s (65536 Kbytes)
> m25p80 spi0.0: mtd .name = spi0.0, .size = 0x4000000 (64MiB),
> .erasesize = 0x00040000 (256KiB) .numeraseregions = 0
> 3 fixed-partitions partitions found on MTD device spi0.0
> Creating 3 MTD partitions on "spi0.0":
> 0x000000000000-0x000000080000 : "loader"
> 0x000000080000-0x000000600000 : "user"
> 0x000000600000-0x000004000000 : "flash"
> renesas_spi e6b10000.spi: registered child spi0.0
> renesas_spi e6b10000.spi: probed
> 
> And /dev/mtd0 reading works fine.
> Thanks!
> 

I'm glad that it worked, thanks for the help. I'll do a patch to fix this case,
but probably it will qualify for -next. Is -next ok for you?

Cheers,
ta

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-09 10:31                                 ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-09 10:31 UTC (permalink / raw)
  To: geert; +Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi, Geert,

On 05/09/2019 12:11 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Tudor,
> 
> On Thu, May 9, 2019 at 8:56 AM <Tudor.Ambarus@microchip.com> wrote:
>> When the configuration register QUAD bit CR[1] is 1, only the WRR command format
>> with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
>> FFs. You probably set quad bit in u-boot, while others don't. We can verify this
>> assumption with the patch form below. Can you try it?
> 
> Thanks!
> 
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
> 
>> +static int spi_nor_clear_block_protection(struct spi_nor *nor)
>> +{
>> +       int ret;
>> +       u8 sr, cr, sr_cr[2] = {0};
>> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
>> +
>> +       ret = read_cr(nor);
>> +       dev_dbg(nor->dev, "CR = %08x\n", ret);
>> +        if (ret < 0) {
>> +                dev_err(nor->dev, "error while reading CR\n");
>> +               return ret;
>> +       }
>> +       cr = ret;
>> +
>> +       if (cr & CR_QUAD_EN_SPAN) {
>> +               /* disable quad if already set, must do it with 16-bit WRR */
>> +               ret = write_sr_cr(nor, sr_cr);
>> +               if (ret) {
>> +                       dev_err(nor->dev, "error diasbling quad mode\n");
> 
> disabling
> 
>> +                       return ret;
>> +               }
> 
> renesas_spi e6b10000.spi: DMA available
> renesas_spi e6b10000.spi: registered master spi0
> spi spi0.0: setup mode 3, 8 bits/w, 30000000 Hz max --> 0
> m25p80 spi0.0: bfpt.dwords[1] = ffffffff
> m25p80 spi0.0: bfpt.dwords[2] = ffffffff
> m25p80 spi0.0: bfpt.dwords[3] = ffffffff
> m25p80 spi0.0: bfpt.dwords[4] = ffffffff
> m25p80 spi0.0: bfpt.dwords[5] = ffffffff
> m25p80 spi0.0: bfpt.dwords[6] = ffffffff
> m25p80 spi0.0: bfpt.dwords[7] = ffffffff
> m25p80 spi0.0: bfpt.dwords[8] = ffffffff
> m25p80 spi0.0: bfpt.dwords[9] = ffffffff
> m25p80 spi0.0: bfpt.dwords[10] = 00000000
> m25p80 spi0.0: bfpt.dwords[11] = 00000000
> m25p80 spi0.0: bfpt.dwords[12] = 00000000
> m25p80 spi0.0: bfpt.dwords[13] = 00000000
> m25p80 spi0.0: bfpt.dwords[14] = 00000000
> m25p80 spi0.0: bfpt.dwords[15] = 00000000
> m25p80 spi0.0: bfpt.dwords[16] = 00000000
> m25p80 spi0.0: failed to parse BFPT: err = -22
> m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
> m25p80 spi0.0: SR and CR before quad_enable:
> m25p80 spi0.0: SR = 00000000
> m25p80 spi0.0: CR = 00000002
> m25p80 spi0.0: SR and CR after quad_enable:
> m25p80 spi0.0: SR = 00000000
> m25p80 spi0.0: CR = 00000002
> m25p80 spi0.0: s25fl512s (65536 Kbytes)
> m25p80 spi0.0: mtd .name = spi0.0, .size = 0x4000000 (64MiB),
> .erasesize = 0x00040000 (256KiB) .numeraseregions = 0
> 3 fixed-partitions partitions found on MTD device spi0.0
> Creating 3 MTD partitions on "spi0.0":
> 0x000000000000-0x000000080000 : "loader"
> 0x000000080000-0x000000600000 : "user"
> 0x000000600000-0x000004000000 : "flash"
> renesas_spi e6b10000.spi: registered child spi0.0
> renesas_spi e6b10000.spi: probed
> 
> And /dev/mtd0 reading works fine.
> Thanks!
> 

I'm glad that it worked, thanks for the help. I'll do a patch to fix this case,
but probably it will qualify for -next. Is -next ok for you?

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-09 10:31                                 ` Tudor.Ambarus
@ 2019-05-09 11:12                                   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-09 11:12 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Linux-Renesas, Jonas Bonn, MTD Maling List, Marek Vasut

Hi Tudor,

On Thu, May 9, 2019 at 12:31 PM <Tudor.Ambarus@microchip.com> wrote:
> On 05/09/2019 12:11 PM, Geert Uytterhoeven wrote:
> > On Thu, May 9, 2019 at 8:56 AM <Tudor.Ambarus@microchip.com> wrote:
> >> When the configuration register QUAD bit CR[1] is 1, only the WRR command format
> >> with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
> >> FFs. You probably set quad bit in u-boot, while others don't. We can verify this
> >> assumption with the patch form below. Can you try it?
> >
> > And /dev/mtd0 reading works fine.
> > Thanks!
> >
>
> I'm glad that it worked, thanks for the help. I'll do a patch to fix this case,
> but probably it will qualify for -next. Is -next ok for you?

Given the issue is present only in -next, fixing it in -next is fine for me.
Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-09 11:12                                   ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-05-09 11:12 UTC (permalink / raw)
  To: Tudor Ambarus; +Cc: Linux-Renesas, Jonas Bonn, MTD Maling List, Marek Vasut

Hi Tudor,

On Thu, May 9, 2019 at 12:31 PM <Tudor.Ambarus@microchip.com> wrote:
> On 05/09/2019 12:11 PM, Geert Uytterhoeven wrote:
> > On Thu, May 9, 2019 at 8:56 AM <Tudor.Ambarus@microchip.com> wrote:
> >> When the configuration register QUAD bit CR[1] is 1, only the WRR command format
> >> with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
> >> FFs. You probably set quad bit in u-boot, while others don't. We can verify this
> >> assumption with the patch form below. Can you try it?
> >
> > And /dev/mtd0 reading works fine.
> > Thanks!
> >
>
> I'm glad that it worked, thanks for the help. I'll do a patch to fix this case,
> but probably it will qualify for -next. Is -next ok for you?

Given the issue is present only in -next, fixing it in -next is fine for me.
Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-09 10:31                                 ` Tudor.Ambarus
@ 2019-05-09 15:57                                   ` Vignesh Raghavendra
  -1 siblings, 0 replies; 62+ messages in thread
From: Vignesh Raghavendra @ 2019-05-09 15:57 UTC (permalink / raw)
  To: Tudor.Ambarus, geert
  Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi Tudor,

On 09/05/19 4:01 PM, Tudor.Ambarus@microchip.com wrote:
[...]
>>
>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>
>>> +static int spi_nor_clear_block_protection(struct spi_nor *nor)
>>> +{
>>> +       int ret;
>>> +       u8 sr, cr, sr_cr[2] = {0};
>>> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
>>> +
>>> +       ret = read_cr(nor);
>>> +       dev_dbg(nor->dev, "CR = %08x\n", ret);
>>> +        if (ret < 0) {
>>> +                dev_err(nor->dev, "error while reading CR\n");
>>> +               return ret;
>>> +       }
>>> +       cr = ret;
>>> +
>>> +       if (cr & CR_QUAD_EN_SPAN) {
>>> +               /* disable quad if already set, must do it with 16-bit WRR */
>>> +               ret = write_sr_cr(nor, sr_cr);
>>> +               if (ret) {
>>> +                       dev_err(nor->dev, "error diasbling quad mode\n");
>>
>> disabling
>>
>>> +                       return ret;
>>> +               }
>>
>> renesas_spi e6b10000.spi: DMA available
>> renesas_spi e6b10000.spi: registered master spi0
>> spi spi0.0: setup mode 3, 8 bits/w, 30000000 Hz max --> 0
>> m25p80 spi0.0: bfpt.dwords[1] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[2] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[3] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[4] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[5] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[6] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[7] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[8] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[9] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[10] = 00000000
>> m25p80 spi0.0: bfpt.dwords[11] = 00000000
>> m25p80 spi0.0: bfpt.dwords[12] = 00000000
>> m25p80 spi0.0: bfpt.dwords[13] = 00000000
>> m25p80 spi0.0: bfpt.dwords[14] = 00000000
>> m25p80 spi0.0: bfpt.dwords[15] = 00000000
>> m25p80 spi0.0: bfpt.dwords[16] = 00000000
>> m25p80 spi0.0: failed to parse BFPT: err = -22
>> m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
>> m25p80 spi0.0: SR and CR before quad_enable:
>> m25p80 spi0.0: SR = 00000000
>> m25p80 spi0.0: CR = 00000002
>> m25p80 spi0.0: SR and CR after quad_enable:
>> m25p80 spi0.0: SR = 00000000
>> m25p80 spi0.0: CR = 00000002
>> m25p80 spi0.0: s25fl512s (65536 Kbytes)
>> m25p80 spi0.0: mtd .name = spi0.0, .size = 0x4000000 (64MiB),
>> .erasesize = 0x00040000 (256KiB) .numeraseregions = 0
>> 3 fixed-partitions partitions found on MTD device spi0.0
>> Creating 3 MTD partitions on "spi0.0":
>> 0x000000000000-0x000000080000 : "loader"
>> 0x000000080000-0x000000600000 : "user"
>> 0x000000600000-0x000004000000 : "flash"
>> renesas_spi e6b10000.spi: registered child spi0.0
>> renesas_spi e6b10000.spi: probed
>>
>> And /dev/mtd0 reading works fine.
>> Thanks!
>>
> 
> I'm glad that it worked, thanks for the help. I'll do a patch to fix this case,
> but probably it will qualify for -next. Is -next ok for you?

I think this fix should be forwarded to v5.2-rc1 (or -rc2 at least) as
patch in question ("spi-nor: s25fl512s supports region locking") is part
of SPI NOR pull request for v5.2-rc1 and therefore would end up in
mainline v5.2-rc1 during the merge window.

-- 
Regards
Vignesh

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-09 15:57                                   ` Vignesh Raghavendra
  0 siblings, 0 replies; 62+ messages in thread
From: Vignesh Raghavendra @ 2019-05-09 15:57 UTC (permalink / raw)
  To: Tudor.Ambarus, geert
  Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi Tudor,

On 09/05/19 4:01 PM, Tudor.Ambarus@microchip.com wrote:
[...]
>>
>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>
>>> +static int spi_nor_clear_block_protection(struct spi_nor *nor)
>>> +{
>>> +       int ret;
>>> +       u8 sr, cr, sr_cr[2] = {0};
>>> +       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
>>> +
>>> +       ret = read_cr(nor);
>>> +       dev_dbg(nor->dev, "CR = %08x\n", ret);
>>> +        if (ret < 0) {
>>> +                dev_err(nor->dev, "error while reading CR\n");
>>> +               return ret;
>>> +       }
>>> +       cr = ret;
>>> +
>>> +       if (cr & CR_QUAD_EN_SPAN) {
>>> +               /* disable quad if already set, must do it with 16-bit WRR */
>>> +               ret = write_sr_cr(nor, sr_cr);
>>> +               if (ret) {
>>> +                       dev_err(nor->dev, "error diasbling quad mode\n");
>>
>> disabling
>>
>>> +                       return ret;
>>> +               }
>>
>> renesas_spi e6b10000.spi: DMA available
>> renesas_spi e6b10000.spi: registered master spi0
>> spi spi0.0: setup mode 3, 8 bits/w, 30000000 Hz max --> 0
>> m25p80 spi0.0: bfpt.dwords[1] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[2] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[3] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[4] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[5] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[6] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[7] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[8] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[9] = ffffffff
>> m25p80 spi0.0: bfpt.dwords[10] = 00000000
>> m25p80 spi0.0: bfpt.dwords[11] = 00000000
>> m25p80 spi0.0: bfpt.dwords[12] = 00000000
>> m25p80 spi0.0: bfpt.dwords[13] = 00000000
>> m25p80 spi0.0: bfpt.dwords[14] = 00000000
>> m25p80 spi0.0: bfpt.dwords[15] = 00000000
>> m25p80 spi0.0: bfpt.dwords[16] = 00000000
>> m25p80 spi0.0: failed to parse BFPT: err = -22
>> m25p80 spi0.0: spi_nor_init_params sfdp parse failed, ret =-22
>> m25p80 spi0.0: SR and CR before quad_enable:
>> m25p80 spi0.0: SR = 00000000
>> m25p80 spi0.0: CR = 00000002
>> m25p80 spi0.0: SR and CR after quad_enable:
>> m25p80 spi0.0: SR = 00000000
>> m25p80 spi0.0: CR = 00000002
>> m25p80 spi0.0: s25fl512s (65536 Kbytes)
>> m25p80 spi0.0: mtd .name = spi0.0, .size = 0x4000000 (64MiB),
>> .erasesize = 0x00040000 (256KiB) .numeraseregions = 0
>> 3 fixed-partitions partitions found on MTD device spi0.0
>> Creating 3 MTD partitions on "spi0.0":
>> 0x000000000000-0x000000080000 : "loader"
>> 0x000000080000-0x000000600000 : "user"
>> 0x000000600000-0x000004000000 : "flash"
>> renesas_spi e6b10000.spi: registered child spi0.0
>> renesas_spi e6b10000.spi: probed
>>
>> And /dev/mtd0 reading works fine.
>> Thanks!
>>
> 
> I'm glad that it worked, thanks for the help. I'll do a patch to fix this case,
> but probably it will qualify for -next. Is -next ok for you?

I think this fix should be forwarded to v5.2-rc1 (or -rc2 at least) as
patch in question ("spi-nor: s25fl512s supports region locking") is part
of SPI NOR pull request for v5.2-rc1 and therefore would end up in
mainline v5.2-rc1 during the merge window.

-- 
Regards
Vignesh

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

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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
  2019-05-09 11:12                                   ` Geert Uytterhoeven
@ 2019-05-22 15:49                                     ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-22 15:49 UTC (permalink / raw)
  To: geert; +Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi, Geert,

On 05/09/2019 02:12 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Tudor,
> 
> On Thu, May 9, 2019 at 12:31 PM <Tudor.Ambarus@microchip.com> wrote:
>> On 05/09/2019 12:11 PM, Geert Uytterhoeven wrote:
>>> On Thu, May 9, 2019 at 8:56 AM <Tudor.Ambarus@microchip.com> wrote:
>>>> When the configuration register QUAD bit CR[1] is 1, only the WRR command format
>>>> with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
>>>> FFs. You probably set quad bit in u-boot, while others don't. We can verify this
>>>> assumption with the patch form below. Can you try it?
>>>
>>> And /dev/mtd0 reading works fine.
>>> Thanks!
>>>
>>
>> I'm glad that it worked, thanks for the help. I'll do a patch to fix this case,
>> but probably it will qualify for -next. Is -next ok for you?
> 
> Given the issue is present only in -next, fixing it in -next is fine for me.
> Thanks!
> 

I've started working to squash the bug discovered by this patch. spi-nor flashes
from different manufacturers have widely different configurations for status and
configuration registers. I have a work in progress patch, backward compatibility
requirements increased code complexity. I'll be out of office and will return on
3rd of June. Probably I will not finish it today, this is to inform you (and
others) that I'll be inactive next week.

Cheers,
ta


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

* Re: [PATCH v4 2/3] spi-nor: s25fl512s supports region locking
@ 2019-05-22 15:49                                     ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-05-22 15:49 UTC (permalink / raw)
  To: geert; +Cc: linux-renesas-soc, jonas, linux-mtd, marek.vasut+renesas

Hi, Geert,

On 05/09/2019 02:12 PM, Geert Uytterhoeven wrote:
> External E-Mail
> 
> 
> Hi Tudor,
> 
> On Thu, May 9, 2019 at 12:31 PM <Tudor.Ambarus@microchip.com> wrote:
>> On 05/09/2019 12:11 PM, Geert Uytterhoeven wrote:
>>> On Thu, May 9, 2019 at 8:56 AM <Tudor.Ambarus@microchip.com> wrote:
>>>> When the configuration register QUAD bit CR[1] is 1, only the WRR command format
>>>> with 16 data bits may be used, WRR with 8 bits is not recognized and hence the
>>>> FFs. You probably set quad bit in u-boot, while others don't. We can verify this
>>>> assumption with the patch form below. Can you try it?
>>>
>>> And /dev/mtd0 reading works fine.
>>> Thanks!
>>>
>>
>> I'm glad that it worked, thanks for the help. I'll do a patch to fix this case,
>> but probably it will qualify for -next. Is -next ok for you?
> 
> Given the issue is present only in -next, fixing it in -next is fine for me.
> Thanks!
> 

I've started working to squash the bug discovered by this patch. spi-nor flashes
from different manufacturers have widely different configurations for status and
configuration registers. I have a work in progress patch, backward compatibility
requirements increased code complexity. I'll be out of office and will return on
3rd of June. Probably I will not finish it today, this is to inform you (and
others) that I'll be inactive next week.

Cheers,
ta

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

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

* [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
  2019-05-22 15:49                                     ` Tudor.Ambarus
@ 2019-06-10  6:24                                       ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-06-10  6:24 UTC (permalink / raw)
  To: geert, marek.vasut+renesas, marek.vasut, vigneshr, jonas
  Cc: dwmw2, computersforpeace, miquel.raynal, richard, linux-mtd,
	linux-kernel, linux-renesas-soc, Tudor.Ambarus

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

SPI memory devices from different manufacturers have widely
different configurations for Status, Control and Configuration
registers. JEDEC 216C defines a new map for these common register
bits and their functions, and describes how the individual bits may
be accessed for a specific device. For the JEDEC 216B compliant
flashes, we can partially deduce Status and Configuration registers
functions by inspecting the 16th DWORD of BFPT. Older flashes that
don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
SPANSION) let the software decide how to interact with these registers.

The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
in the bootloader. When this bit is set, only the Write Register
WRR command format with 16 data bits may be used, WRR with 8 bits
is not recognized and hence the error when trying to clear the block
protection bits.

Fix the above by using 16-bits WRR command when Quad bit is set.

Backward compatibility should be fine. The newly introduced
spi_nor_spansion_clear_sr_bp() is tightly coupled with the
spansion_quad_enable() function. Both assume that the Write Register
with 16 bits, together with the Read Configuration Register (35h)
instructions are supported.

Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
Geert, Jonas,

This patch is compile-tested only. I don't have the flash, I need your
help for testing this.

Thanks,
ta

 drivers/mtd/spi-nor/spi-nor.c | 116 ++++++++++++++++++++++++++++++++++++++----
 include/linux/mtd/spi-nor.h   |   1 +
 2 files changed, 106 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index c0a8837c0575..af9ac7f09cc2 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1636,6 +1636,92 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	return 0;
 }
 
+/**
+ * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_clear_sr_bp(struct spi_nor *nor)
+{
+	int ret;
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	ret = read_sr(nor);
+	if (ret < 0) {
+		dev_err(nor->dev, "error while reading status register\n");
+		return ret;
+	}
+
+	write_enable(nor);
+
+	ret = write_sr(nor, ret & ~mask);
+	if (ret) {
+		dev_err(nor->dev, "write to status register failed\n");
+		return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		dev_err(nor->dev, "timeout while writing status register\n");
+	return ret;
+}
+
+/**
+ * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
+ * bits on spansion flashes.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits. The function is tightly
+ * coupled with the spansion_quad_enable() function. Both assume that the Write
+ * Register with 16 bits, together with the Read Configuration Register (35h)
+ * instructions are supported
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
+{
+	int ret;
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+	u8 sr_cr[2] = {0};
+
+	/* Check current Quad Enable bit value. */
+	ret = read_cr(nor);
+	if (ret < 0) {
+		dev_err(nor->dev,
+			"error while reading configuration register\n");
+		return ret;
+	}
+
+	/*
+	 * When the configuration register QUAD bit CR[1] is 1, only
+	 * the WRR command format with 16 data bits may be used.
+	 */
+	if (ret & CR_QUAD_EN_SPAN) {
+		sr_cr[1] = ret;
+
+		ret = read_sr(nor);
+		if (ret < 0) {
+			dev_err(nor->dev,
+				"error while reading status register\n");
+			return ret;
+		}
+		sr_cr[0] = ret & ~mask;
+
+		ret = write_sr_cr(nor, sr_cr);
+		if (ret)
+			dev_err(nor->dev, "16-bit write register failed\n");
+		return ret;
+	}
+
+	/* If quad bit is not set, use 8-bit WRR command. */
+	return spi_nor_clear_sr_bp(nor);
+}
+
 /* Used when the "_ext_id" is two bytes at most */
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
 		.id = {							\
@@ -3663,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
 		default:
 			/* Kept only for backward compatibility purpose. */
 			params->quad_enable = spansion_quad_enable;
+			if (nor->clear_sr_bp)
+				nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
 			break;
 		}
 
@@ -3915,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
 {
 	int err;
 
-	/*
-	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
-	 * with the software protection bits set
-	 */
-	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
-	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
-	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-	    nor->info->flags & SPI_NOR_HAS_LOCK) {
-		write_enable(nor);
-		write_sr(nor, 0);
-		spi_nor_wait_till_ready(nor);
+	if (nor->clear_sr_bp) {
+		err = nor->clear_sr_bp(nor);
+		if (err) {
+			dev_err(nor->dev,
+				"fail to clear block protection bits\n");
+			return err;
+		}
 	}
 
 	if (nor->quad_enable) {
@@ -4050,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (info->flags & SPI_S3AN)
 		nor->flags |=  SNOR_F_READY_XSR_RDY;
 
+	/*
+	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
+	 * with the software protection bits set.
+	 */
+	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
+	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
+	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
+	    nor->info->flags & SPI_NOR_HAS_LOCK)
+		nor->clear_sr_bp = spi_nor_clear_sr_bp;
+
 	/* Parse the Serial Flash Discoverable Parameters table. */
 	ret = spi_nor_init_params(nor, &params);
 	if (ret)
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index b3d360b0ee3d..566bd5010bc8 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -410,6 +410,7 @@ struct spi_nor {
 	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 	int (*quad_enable)(struct spi_nor *nor);
+	int (*clear_sr_bp)(struct spi_nor *nor);
 
 	void *priv;
 };
-- 
2.9.5


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

* [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
@ 2019-06-10  6:24                                       ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-06-10  6:24 UTC (permalink / raw)
  To: geert, marek.vasut+renesas, marek.vasut, vigneshr, jonas
  Cc: Tudor.Ambarus, richard, linux-kernel, linux-renesas-soc,
	linux-mtd, miquel.raynal, computersforpeace, dwmw2

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

SPI memory devices from different manufacturers have widely
different configurations for Status, Control and Configuration
registers. JEDEC 216C defines a new map for these common register
bits and their functions, and describes how the individual bits may
be accessed for a specific device. For the JEDEC 216B compliant
flashes, we can partially deduce Status and Configuration registers
functions by inspecting the 16th DWORD of BFPT. Older flashes that
don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
SPANSION) let the software decide how to interact with these registers.

The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
in the bootloader. When this bit is set, only the Write Register
WRR command format with 16 data bits may be used, WRR with 8 bits
is not recognized and hence the error when trying to clear the block
protection bits.

Fix the above by using 16-bits WRR command when Quad bit is set.

Backward compatibility should be fine. The newly introduced
spi_nor_spansion_clear_sr_bp() is tightly coupled with the
spansion_quad_enable() function. Both assume that the Write Register
with 16 bits, together with the Read Configuration Register (35h)
instructions are supported.

Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
Geert, Jonas,

This patch is compile-tested only. I don't have the flash, I need your
help for testing this.

Thanks,
ta

 drivers/mtd/spi-nor/spi-nor.c | 116 ++++++++++++++++++++++++++++++++++++++----
 include/linux/mtd/spi-nor.h   |   1 +
 2 files changed, 106 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index c0a8837c0575..af9ac7f09cc2 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1636,6 +1636,92 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	return 0;
 }
 
+/**
+ * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_clear_sr_bp(struct spi_nor *nor)
+{
+	int ret;
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	ret = read_sr(nor);
+	if (ret < 0) {
+		dev_err(nor->dev, "error while reading status register\n");
+		return ret;
+	}
+
+	write_enable(nor);
+
+	ret = write_sr(nor, ret & ~mask);
+	if (ret) {
+		dev_err(nor->dev, "write to status register failed\n");
+		return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		dev_err(nor->dev, "timeout while writing status register\n");
+	return ret;
+}
+
+/**
+ * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
+ * bits on spansion flashes.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits. The function is tightly
+ * coupled with the spansion_quad_enable() function. Both assume that the Write
+ * Register with 16 bits, together with the Read Configuration Register (35h)
+ * instructions are supported
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
+{
+	int ret;
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+	u8 sr_cr[2] = {0};
+
+	/* Check current Quad Enable bit value. */
+	ret = read_cr(nor);
+	if (ret < 0) {
+		dev_err(nor->dev,
+			"error while reading configuration register\n");
+		return ret;
+	}
+
+	/*
+	 * When the configuration register QUAD bit CR[1] is 1, only
+	 * the WRR command format with 16 data bits may be used.
+	 */
+	if (ret & CR_QUAD_EN_SPAN) {
+		sr_cr[1] = ret;
+
+		ret = read_sr(nor);
+		if (ret < 0) {
+			dev_err(nor->dev,
+				"error while reading status register\n");
+			return ret;
+		}
+		sr_cr[0] = ret & ~mask;
+
+		ret = write_sr_cr(nor, sr_cr);
+		if (ret)
+			dev_err(nor->dev, "16-bit write register failed\n");
+		return ret;
+	}
+
+	/* If quad bit is not set, use 8-bit WRR command. */
+	return spi_nor_clear_sr_bp(nor);
+}
+
 /* Used when the "_ext_id" is two bytes at most */
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
 		.id = {							\
@@ -3663,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
 		default:
 			/* Kept only for backward compatibility purpose. */
 			params->quad_enable = spansion_quad_enable;
+			if (nor->clear_sr_bp)
+				nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
 			break;
 		}
 
@@ -3915,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
 {
 	int err;
 
-	/*
-	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
-	 * with the software protection bits set
-	 */
-	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
-	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
-	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-	    nor->info->flags & SPI_NOR_HAS_LOCK) {
-		write_enable(nor);
-		write_sr(nor, 0);
-		spi_nor_wait_till_ready(nor);
+	if (nor->clear_sr_bp) {
+		err = nor->clear_sr_bp(nor);
+		if (err) {
+			dev_err(nor->dev,
+				"fail to clear block protection bits\n");
+			return err;
+		}
 	}
 
 	if (nor->quad_enable) {
@@ -4050,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (info->flags & SPI_S3AN)
 		nor->flags |=  SNOR_F_READY_XSR_RDY;
 
+	/*
+	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
+	 * with the software protection bits set.
+	 */
+	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
+	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
+	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
+	    nor->info->flags & SPI_NOR_HAS_LOCK)
+		nor->clear_sr_bp = spi_nor_clear_sr_bp;
+
 	/* Parse the Serial Flash Discoverable Parameters table. */
 	ret = spi_nor_init_params(nor, &params);
 	if (ret)
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index b3d360b0ee3d..566bd5010bc8 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -410,6 +410,7 @@ struct spi_nor {
 	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 	int (*quad_enable)(struct spi_nor *nor);
+	int (*clear_sr_bp)(struct spi_nor *nor);
 
 	void *priv;
 };
-- 
2.9.5

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

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
  2019-06-10  6:24                                       ` Tudor.Ambarus
@ 2019-06-10  9:28                                         ` Jonas Bonn
  -1 siblings, 0 replies; 62+ messages in thread
From: Jonas Bonn @ 2019-06-10  9:28 UTC (permalink / raw)
  To: Tudor.Ambarus, geert, marek.vasut+renesas, marek.vasut, vigneshr
  Cc: dwmw2, computersforpeace, miquel.raynal, richard, linux-mtd,
	linux-kernel, linux-renesas-soc

Hi Tudor,

On 10/06/2019 08:24, Tudor.Ambarus@microchip.com wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> SPI memory devices from different manufacturers have widely
> different configurations for Status, Control and Configuration
> registers. JEDEC 216C defines a new map for these common register
> bits and their functions, and describes how the individual bits may
> be accessed for a specific device. For the JEDEC 216B compliant
> flashes, we can partially deduce Status and Configuration registers
> functions by inspecting the 16th DWORD of BFPT. Older flashes that
> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
> SPANSION) let the software decide how to interact with these registers.
> 
> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
> in the bootloader. When this bit is set, only the Write Register
> WRR command format with 16 data bits may be used, WRR with 8 bits
> is not recognized and hence the error when trying to clear the block
> protection bits.
> 
> Fix the above by using 16-bits WRR command when Quad bit is set.
> 
> Backward compatibility should be fine. The newly introduced
> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
> spansion_quad_enable() function. Both assume that the Write Register
> with 16 bits, together with the Read Configuration Register (35h)
> instructions are supported.
> 
> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
> Geert, Jonas,
> 
> This patch is compile-tested only. I don't have the flash, I need your
> help for testing this.

Tested this on my hardware.  It works fine in the non-quad case.

Tested-by: Jonas Bonn <jonas@norrbonn.se>

/Jonas

> 
> Thanks,
> ta
> 
>   drivers/mtd/spi-nor/spi-nor.c | 116 ++++++++++++++++++++++++++++++++++++++----
>   include/linux/mtd/spi-nor.h   |   1 +
>   2 files changed, 106 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index c0a8837c0575..af9ac7f09cc2 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1636,6 +1636,92 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
>   	return 0;
>   }
>   
> +/**
> + * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
> + * @nor:        pointer to a 'struct spi_nor'
> + *
> + * Read-modify-write function that clears the Block Protection bits from the
> + * Status Register without affecting other bits.
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +static int spi_nor_clear_sr_bp(struct spi_nor *nor)
> +{
> +	int ret;
> +	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +	ret = read_sr(nor);
> +	if (ret < 0) {
> +		dev_err(nor->dev, "error while reading status register\n");
> +		return ret;
> +	}
> +
> +	write_enable(nor);
> +
> +	ret = write_sr(nor, ret & ~mask);
> +	if (ret) {
> +		dev_err(nor->dev, "write to status register failed\n");
> +		return ret;
> +	}
> +
> +	ret = spi_nor_wait_till_ready(nor);
> +	if (ret)
> +		dev_err(nor->dev, "timeout while writing status register\n");
> +	return ret;
> +}
> +
> +/**
> + * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
> + * bits on spansion flashes.
> + * @nor:        pointer to a 'struct spi_nor'
> + *
> + * Read-modify-write function that clears the Block Protection bits from the
> + * Status Register without affecting other bits. The function is tightly
> + * coupled with the spansion_quad_enable() function. Both assume that the Write
> + * Register with 16 bits, together with the Read Configuration Register (35h)
> + * instructions are supported
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
> +{
> +	int ret;
> +	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +	u8 sr_cr[2] = {0};
> +
> +	/* Check current Quad Enable bit value. */
> +	ret = read_cr(nor);
> +	if (ret < 0) {
> +		dev_err(nor->dev,
> +			"error while reading configuration register\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * When the configuration register QUAD bit CR[1] is 1, only
> +	 * the WRR command format with 16 data bits may be used.
> +	 */
> +	if (ret & CR_QUAD_EN_SPAN) {
> +		sr_cr[1] = ret;
> +
> +		ret = read_sr(nor);
> +		if (ret < 0) {
> +			dev_err(nor->dev,
> +				"error while reading status register\n");
> +			return ret;
> +		}
> +		sr_cr[0] = ret & ~mask;
> +
> +		ret = write_sr_cr(nor, sr_cr);
> +		if (ret)
> +			dev_err(nor->dev, "16-bit write register failed\n");
> +		return ret;
> +	}
> +
> +	/* If quad bit is not set, use 8-bit WRR command. */
> +	return spi_nor_clear_sr_bp(nor);
> +}
> +
>   /* Used when the "_ext_id" is two bytes at most */
>   #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
>   		.id = {							\
> @@ -3663,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
>   		default:
>   			/* Kept only for backward compatibility purpose. */
>   			params->quad_enable = spansion_quad_enable;
> +			if (nor->clear_sr_bp)
> +				nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
>   			break;
>   		}
>   
> @@ -3915,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
>   {
>   	int err;
>   
> -	/*
> -	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> -	 * with the software protection bits set
> -	 */
> -	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
> -	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
> -	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
> -	    nor->info->flags & SPI_NOR_HAS_LOCK) {
> -		write_enable(nor);
> -		write_sr(nor, 0);
> -		spi_nor_wait_till_ready(nor);
> +	if (nor->clear_sr_bp) {
> +		err = nor->clear_sr_bp(nor);
> +		if (err) {
> +			dev_err(nor->dev,
> +				"fail to clear block protection bits\n");
> +			return err;
> +		}




>   	}
>   
>   	if (nor->quad_enable) {
> @@ -4050,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>   	if (info->flags & SPI_S3AN)
>   		nor->flags |=  SNOR_F_READY_XSR_RDY;
>   
> +	/*
> +	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> +	 * with the software protection bits set.
> +	 */
> +	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
> +	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
> +	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
> +	    nor->info->flags & SPI_NOR_HAS_LOCK)
> +		nor->clear_sr_bp = spi_nor_clear_sr_bp;
> +
>   	/* Parse the Serial Flash Discoverable Parameters table. */
>   	ret = spi_nor_init_params(nor, &params);
>   	if (ret)
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index b3d360b0ee3d..566bd5010bc8 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -410,6 +410,7 @@ struct spi_nor {
>   	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
>   	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
>   	int (*quad_enable)(struct spi_nor *nor);
> +	int (*clear_sr_bp)(struct spi_nor *nor);
>   
>   	void *priv;
>   };
> 

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
@ 2019-06-10  9:28                                         ` Jonas Bonn
  0 siblings, 0 replies; 62+ messages in thread
From: Jonas Bonn @ 2019-06-10  9:28 UTC (permalink / raw)
  To: Tudor.Ambarus, geert, marek.vasut+renesas, marek.vasut, vigneshr
  Cc: richard, linux-kernel, linux-renesas-soc, linux-mtd,
	miquel.raynal, computersforpeace, dwmw2

Hi Tudor,

On 10/06/2019 08:24, Tudor.Ambarus@microchip.com wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> SPI memory devices from different manufacturers have widely
> different configurations for Status, Control and Configuration
> registers. JEDEC 216C defines a new map for these common register
> bits and their functions, and describes how the individual bits may
> be accessed for a specific device. For the JEDEC 216B compliant
> flashes, we can partially deduce Status and Configuration registers
> functions by inspecting the 16th DWORD of BFPT. Older flashes that
> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
> SPANSION) let the software decide how to interact with these registers.
> 
> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
> in the bootloader. When this bit is set, only the Write Register
> WRR command format with 16 data bits may be used, WRR with 8 bits
> is not recognized and hence the error when trying to clear the block
> protection bits.
> 
> Fix the above by using 16-bits WRR command when Quad bit is set.
> 
> Backward compatibility should be fine. The newly introduced
> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
> spansion_quad_enable() function. Both assume that the Write Register
> with 16 bits, together with the Read Configuration Register (35h)
> instructions are supported.
> 
> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
> Geert, Jonas,
> 
> This patch is compile-tested only. I don't have the flash, I need your
> help for testing this.

Tested this on my hardware.  It works fine in the non-quad case.

Tested-by: Jonas Bonn <jonas@norrbonn.se>

/Jonas

> 
> Thanks,
> ta
> 
>   drivers/mtd/spi-nor/spi-nor.c | 116 ++++++++++++++++++++++++++++++++++++++----
>   include/linux/mtd/spi-nor.h   |   1 +
>   2 files changed, 106 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index c0a8837c0575..af9ac7f09cc2 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1636,6 +1636,92 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
>   	return 0;
>   }
>   
> +/**
> + * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
> + * @nor:        pointer to a 'struct spi_nor'
> + *
> + * Read-modify-write function that clears the Block Protection bits from the
> + * Status Register without affecting other bits.
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +static int spi_nor_clear_sr_bp(struct spi_nor *nor)
> +{
> +	int ret;
> +	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +	ret = read_sr(nor);
> +	if (ret < 0) {
> +		dev_err(nor->dev, "error while reading status register\n");
> +		return ret;
> +	}
> +
> +	write_enable(nor);
> +
> +	ret = write_sr(nor, ret & ~mask);
> +	if (ret) {
> +		dev_err(nor->dev, "write to status register failed\n");
> +		return ret;
> +	}
> +
> +	ret = spi_nor_wait_till_ready(nor);
> +	if (ret)
> +		dev_err(nor->dev, "timeout while writing status register\n");
> +	return ret;
> +}
> +
> +/**
> + * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
> + * bits on spansion flashes.
> + * @nor:        pointer to a 'struct spi_nor'
> + *
> + * Read-modify-write function that clears the Block Protection bits from the
> + * Status Register without affecting other bits. The function is tightly
> + * coupled with the spansion_quad_enable() function. Both assume that the Write
> + * Register with 16 bits, together with the Read Configuration Register (35h)
> + * instructions are supported
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
> +{
> +	int ret;
> +	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +	u8 sr_cr[2] = {0};
> +
> +	/* Check current Quad Enable bit value. */
> +	ret = read_cr(nor);
> +	if (ret < 0) {
> +		dev_err(nor->dev,
> +			"error while reading configuration register\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * When the configuration register QUAD bit CR[1] is 1, only
> +	 * the WRR command format with 16 data bits may be used.
> +	 */
> +	if (ret & CR_QUAD_EN_SPAN) {
> +		sr_cr[1] = ret;
> +
> +		ret = read_sr(nor);
> +		if (ret < 0) {
> +			dev_err(nor->dev,
> +				"error while reading status register\n");
> +			return ret;
> +		}
> +		sr_cr[0] = ret & ~mask;
> +
> +		ret = write_sr_cr(nor, sr_cr);
> +		if (ret)
> +			dev_err(nor->dev, "16-bit write register failed\n");
> +		return ret;
> +	}
> +
> +	/* If quad bit is not set, use 8-bit WRR command. */
> +	return spi_nor_clear_sr_bp(nor);
> +}
> +
>   /* Used when the "_ext_id" is two bytes at most */
>   #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
>   		.id = {							\
> @@ -3663,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
>   		default:
>   			/* Kept only for backward compatibility purpose. */
>   			params->quad_enable = spansion_quad_enable;
> +			if (nor->clear_sr_bp)
> +				nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
>   			break;
>   		}
>   
> @@ -3915,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
>   {
>   	int err;
>   
> -	/*
> -	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> -	 * with the software protection bits set
> -	 */
> -	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
> -	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
> -	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
> -	    nor->info->flags & SPI_NOR_HAS_LOCK) {
> -		write_enable(nor);
> -		write_sr(nor, 0);
> -		spi_nor_wait_till_ready(nor);
> +	if (nor->clear_sr_bp) {
> +		err = nor->clear_sr_bp(nor);
> +		if (err) {
> +			dev_err(nor->dev,
> +				"fail to clear block protection bits\n");
> +			return err;
> +		}




>   	}
>   
>   	if (nor->quad_enable) {
> @@ -4050,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>   	if (info->flags & SPI_S3AN)
>   		nor->flags |=  SNOR_F_READY_XSR_RDY;
>   
> +	/*
> +	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> +	 * with the software protection bits set.
> +	 */
> +	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
> +	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
> +	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
> +	    nor->info->flags & SPI_NOR_HAS_LOCK)
> +		nor->clear_sr_bp = spi_nor_clear_sr_bp;
> +
>   	/* Parse the Serial Flash Discoverable Parameters table. */
>   	ret = spi_nor_init_params(nor, &params);
>   	if (ret)
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index b3d360b0ee3d..566bd5010bc8 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -410,6 +410,7 @@ struct spi_nor {
>   	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
>   	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
>   	int (*quad_enable)(struct spi_nor *nor);
> +	int (*clear_sr_bp)(struct spi_nor *nor);
>   
>   	void *priv;
>   };
> 

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

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
  2019-06-10  6:24                                       ` Tudor.Ambarus
@ 2019-06-11  8:35                                         ` Geert Uytterhoeven
  -1 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-06-11  8:35 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: Marek Vasut, Marek Vasut, R, Vignesh, Jonas Bonn,
	David Woodhouse, Brian Norris, Miquel Raynal, Richard Weinberger,
	MTD Maling List, Linux Kernel Mailing List, Linux-Renesas

Hi Tudor,

On Mon, Jun 10, 2019 at 8:24 AM <Tudor.Ambarus@microchip.com> wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
>
> SPI memory devices from different manufacturers have widely
> different configurations for Status, Control and Configuration
> registers. JEDEC 216C defines a new map for these common register
> bits and their functions, and describes how the individual bits may
> be accessed for a specific device. For the JEDEC 216B compliant
> flashes, we can partially deduce Status and Configuration registers
> functions by inspecting the 16th DWORD of BFPT. Older flashes that
> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
> SPANSION) let the software decide how to interact with these registers.
>
> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
> in the bootloader. When this bit is set, only the Write Register
> WRR command format with 16 data bits may be used, WRR with 8 bits
> is not recognized and hence the error when trying to clear the block
> protection bits.
>
> Fix the above by using 16-bits WRR command when Quad bit is set.
>
> Backward compatibility should be fine. The newly introduced
> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
> spansion_quad_enable() function. Both assume that the Write Register
> with 16 bits, together with the Read Configuration Register (35h)
> instructions are supported.
>
> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
> Geert, Jonas,
>
> This patch is compile-tested only. I don't have the flash, I need your
> help for testing this.

Thanks, this revives access to the s25fl512s on Koelsch.

Fixes: dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region locking")
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>Hi Tudor,

Two questions below...

> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c

> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
> +{

[...]

> +        * When the configuration register QUAD bit CR[1] is 1, only
> +        * the WRR command format with 16 data bits may be used.

s/WRR/WRSR/?

> +        */
> +       if (ret & CR_QUAD_EN_SPAN) {
> +               sr_cr[1] = ret;
> +
> +               ret = read_sr(nor);
> +               if (ret < 0) {
> +                       dev_err(nor->dev,
> +                               "error while reading status register\n");
> +                       return ret;
> +               }
> +               sr_cr[0] = ret & ~mask;
> +
> +               ret = write_sr_cr(nor, sr_cr);
> +               if (ret)
> +                       dev_err(nor->dev, "16-bit write register failed\n");
> +               return ret;
> +       }
> +
> +       /* If quad bit is not set, use 8-bit WRR command. */

Likewise.

> +       return spi_nor_clear_sr_bp(nor);
> +}

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
@ 2019-06-11  8:35                                         ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-06-11  8:35 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: R, Vignesh, Richard Weinberger, Linux Kernel Mailing List,
	Linux-Renesas, Marek Vasut, Jonas Bonn, MTD Maling List,
	Miquel Raynal, Brian Norris, David Woodhouse, Marek Vasut

Hi Tudor,

On Mon, Jun 10, 2019 at 8:24 AM <Tudor.Ambarus@microchip.com> wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
>
> SPI memory devices from different manufacturers have widely
> different configurations for Status, Control and Configuration
> registers. JEDEC 216C defines a new map for these common register
> bits and their functions, and describes how the individual bits may
> be accessed for a specific device. For the JEDEC 216B compliant
> flashes, we can partially deduce Status and Configuration registers
> functions by inspecting the 16th DWORD of BFPT. Older flashes that
> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
> SPANSION) let the software decide how to interact with these registers.
>
> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
> in the bootloader. When this bit is set, only the Write Register
> WRR command format with 16 data bits may be used, WRR with 8 bits
> is not recognized and hence the error when trying to clear the block
> protection bits.
>
> Fix the above by using 16-bits WRR command when Quad bit is set.
>
> Backward compatibility should be fine. The newly introduced
> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
> spansion_quad_enable() function. Both assume that the Write Register
> with 16 bits, together with the Read Configuration Register (35h)
> instructions are supported.
>
> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
> Geert, Jonas,
>
> This patch is compile-tested only. I don't have the flash, I need your
> help for testing this.

Thanks, this revives access to the s25fl512s on Koelsch.

Fixes: dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region locking")
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>Hi Tudor,

Two questions below...

> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c

> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
> +{

[...]

> +        * When the configuration register QUAD bit CR[1] is 1, only
> +        * the WRR command format with 16 data bits may be used.

s/WRR/WRSR/?

> +        */
> +       if (ret & CR_QUAD_EN_SPAN) {
> +               sr_cr[1] = ret;
> +
> +               ret = read_sr(nor);
> +               if (ret < 0) {
> +                       dev_err(nor->dev,
> +                               "error while reading status register\n");
> +                       return ret;
> +               }
> +               sr_cr[0] = ret & ~mask;
> +
> +               ret = write_sr_cr(nor, sr_cr);
> +               if (ret)
> +                       dev_err(nor->dev, "16-bit write register failed\n");
> +               return ret;
> +       }
> +
> +       /* If quad bit is not set, use 8-bit WRR command. */

Likewise.

> +       return spi_nor_clear_sr_bp(nor);
> +}

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
  2019-06-10  6:24                                       ` Tudor.Ambarus
@ 2019-06-12 16:46                                         ` Vignesh Raghavendra
  -1 siblings, 0 replies; 62+ messages in thread
From: Vignesh Raghavendra @ 2019-06-12 16:46 UTC (permalink / raw)
  To: Tudor.Ambarus, geert, marek.vasut+renesas, marek.vasut, jonas
  Cc: dwmw2, computersforpeace, miquel.raynal, richard, linux-mtd,
	linux-kernel, linux-renesas-soc

Hi,

On 10-Jun-19 11:54 AM, Tudor.Ambarus@microchip.com wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> SPI memory devices from different manufacturers have widely
> different configurations for Status, Control and Configuration
> registers. JEDEC 216C defines a new map for these common register
> bits and their functions, and describes how the individual bits may
> be accessed for a specific device. For the JEDEC 216B compliant
> flashes, we can partially deduce Status and Configuration registers
> functions by inspecting the 16th DWORD of BFPT. Older flashes that
> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
> SPANSION) let the software decide how to interact with these registers.
> 
> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
> in the bootloader. When this bit is set, only the Write Register
> WRR command format with 16 data bits may be used, WRR with 8 bits
> is not recognized and hence the error when trying to clear the block
> protection bits.
> 

I see above text in s25fl512s datasheet[1] as well. So the patch is
indeed needed:

Reviewed-by: Vignesh Raghavendra <vigneshr@ti.com>

Also, I was able to reproduce above scenario with TI's K2G EVM with
s25fl512s flash and can confirm that this patch fixes the issue:

Tested-by: Vignesh Raghavendra <vigneshr@ti.com>

Regards
Vignesh

[1] https://www.cypress.com/file/177971/download 9.3.7 Write Registers
> Fix the above by using 16-bits WRR command when Quad bit is set.
> 
> Backward compatibility should be fine. The newly introduced
> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
> spansion_quad_enable() function. Both assume that the Write Register
> with 16 bits, together with the Read Configuration Register (35h)
> instructions are supported.
> 
> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
> Geert, Jonas,
> 
> This patch is compile-tested only. I don't have the flash, I need your
> help for testing this.
> 
> Thanks,
> ta
> 
>  drivers/mtd/spi-nor/spi-nor.c | 116 ++++++++++++++++++++++++++++++++++++++----
>  include/linux/mtd/spi-nor.h   |   1 +
>  2 files changed, 106 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index c0a8837c0575..af9ac7f09cc2 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1636,6 +1636,92 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
>  	return 0;
>  }
>  
> +/**
> + * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
> + * @nor:        pointer to a 'struct spi_nor'
> + *
> + * Read-modify-write function that clears the Block Protection bits from the
> + * Status Register without affecting other bits.
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +static int spi_nor_clear_sr_bp(struct spi_nor *nor)
> +{
> +	int ret;
> +	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +	ret = read_sr(nor);
> +	if (ret < 0) {
> +		dev_err(nor->dev, "error while reading status register\n");
> +		return ret;
> +	}
> +
> +	write_enable(nor);
> +
> +	ret = write_sr(nor, ret & ~mask);
> +	if (ret) {
> +		dev_err(nor->dev, "write to status register failed\n");
> +		return ret;
> +	}
> +
> +	ret = spi_nor_wait_till_ready(nor);
> +	if (ret)
> +		dev_err(nor->dev, "timeout while writing status register\n");
> +	return ret;
> +}
> +
> +/**
> + * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
> + * bits on spansion flashes.
> + * @nor:        pointer to a 'struct spi_nor'
> + *
> + * Read-modify-write function that clears the Block Protection bits from the
> + * Status Register without affecting other bits. The function is tightly
> + * coupled with the spansion_quad_enable() function. Both assume that the Write
> + * Register with 16 bits, together with the Read Configuration Register (35h)
> + * instructions are supported
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
> +{
> +	int ret;
> +	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +	u8 sr_cr[2] = {0};
> +
> +	/* Check current Quad Enable bit value. */
> +	ret = read_cr(nor);
> +	if (ret < 0) {
> +		dev_err(nor->dev,
> +			"error while reading configuration register\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * When the configuration register QUAD bit CR[1] is 1, only
> +	 * the WRR command format with 16 data bits may be used.
> +	 */
> +	if (ret & CR_QUAD_EN_SPAN) {
> +		sr_cr[1] = ret;
> +
> +		ret = read_sr(nor);
> +		if (ret < 0) {
> +			dev_err(nor->dev,
> +				"error while reading status register\n");
> +			return ret;
> +		}
> +		sr_cr[0] = ret & ~mask;
> +
> +		ret = write_sr_cr(nor, sr_cr);
> +		if (ret)
> +			dev_err(nor->dev, "16-bit write register failed\n");
> +		return ret;
> +	}
> +
> +	/* If quad bit is not set, use 8-bit WRR command. */
> +	return spi_nor_clear_sr_bp(nor);
> +}
> +
>  /* Used when the "_ext_id" is two bytes at most */
>  #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
>  		.id = {							\
> @@ -3663,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
>  		default:
>  			/* Kept only for backward compatibility purpose. */
>  			params->quad_enable = spansion_quad_enable;
> +			if (nor->clear_sr_bp)
> +				nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
>  			break;
>  		}
>  
> @@ -3915,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
>  {
>  	int err;
>  
> -	/*
> -	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> -	 * with the software protection bits set
> -	 */
> -	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
> -	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
> -	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
> -	    nor->info->flags & SPI_NOR_HAS_LOCK) {
> -		write_enable(nor);
> -		write_sr(nor, 0);
> -		spi_nor_wait_till_ready(nor);
> +	if (nor->clear_sr_bp) {
> +		err = nor->clear_sr_bp(nor);
> +		if (err) {
> +			dev_err(nor->dev,
> +				"fail to clear block protection bits\n");
> +			return err;
> +		}
>  	}
>  
>  	if (nor->quad_enable) {
> @@ -4050,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  	if (info->flags & SPI_S3AN)
>  		nor->flags |=  SNOR_F_READY_XSR_RDY;
>  
> +	/*
> +	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> +	 * with the software protection bits set.
> +	 */
> +	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
> +	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
> +	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
> +	    nor->info->flags & SPI_NOR_HAS_LOCK)
> +		nor->clear_sr_bp = spi_nor_clear_sr_bp;
> +
>  	/* Parse the Serial Flash Discoverable Parameters table. */
>  	ret = spi_nor_init_params(nor, &params);
>  	if (ret)
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index b3d360b0ee3d..566bd5010bc8 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -410,6 +410,7 @@ struct spi_nor {
>  	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
>  	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
>  	int (*quad_enable)(struct spi_nor *nor);
> +	int (*clear_sr_bp)(struct spi_nor *nor);
>  
>  	void *priv;
>  };
> 

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
@ 2019-06-12 16:46                                         ` Vignesh Raghavendra
  0 siblings, 0 replies; 62+ messages in thread
From: Vignesh Raghavendra @ 2019-06-12 16:46 UTC (permalink / raw)
  To: Tudor.Ambarus, geert, marek.vasut+renesas, marek.vasut, jonas
  Cc: richard, linux-kernel, linux-renesas-soc, linux-mtd,
	miquel.raynal, computersforpeace, dwmw2

Hi,

On 10-Jun-19 11:54 AM, Tudor.Ambarus@microchip.com wrote:
> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> SPI memory devices from different manufacturers have widely
> different configurations for Status, Control and Configuration
> registers. JEDEC 216C defines a new map for these common register
> bits and their functions, and describes how the individual bits may
> be accessed for a specific device. For the JEDEC 216B compliant
> flashes, we can partially deduce Status and Configuration registers
> functions by inspecting the 16th DWORD of BFPT. Older flashes that
> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
> SPANSION) let the software decide how to interact with these registers.
> 
> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
> in the bootloader. When this bit is set, only the Write Register
> WRR command format with 16 data bits may be used, WRR with 8 bits
> is not recognized and hence the error when trying to clear the block
> protection bits.
> 

I see above text in s25fl512s datasheet[1] as well. So the patch is
indeed needed:

Reviewed-by: Vignesh Raghavendra <vigneshr@ti.com>

Also, I was able to reproduce above scenario with TI's K2G EVM with
s25fl512s flash and can confirm that this patch fixes the issue:

Tested-by: Vignesh Raghavendra <vigneshr@ti.com>

Regards
Vignesh

[1] https://www.cypress.com/file/177971/download 9.3.7 Write Registers
> Fix the above by using 16-bits WRR command when Quad bit is set.
> 
> Backward compatibility should be fine. The newly introduced
> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
> spansion_quad_enable() function. Both assume that the Write Register
> with 16 bits, together with the Read Configuration Register (35h)
> instructions are supported.
> 
> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> ---
> Geert, Jonas,
> 
> This patch is compile-tested only. I don't have the flash, I need your
> help for testing this.
> 
> Thanks,
> ta
> 
>  drivers/mtd/spi-nor/spi-nor.c | 116 ++++++++++++++++++++++++++++++++++++++----
>  include/linux/mtd/spi-nor.h   |   1 +
>  2 files changed, 106 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index c0a8837c0575..af9ac7f09cc2 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1636,6 +1636,92 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
>  	return 0;
>  }
>  
> +/**
> + * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
> + * @nor:        pointer to a 'struct spi_nor'
> + *
> + * Read-modify-write function that clears the Block Protection bits from the
> + * Status Register without affecting other bits.
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +static int spi_nor_clear_sr_bp(struct spi_nor *nor)
> +{
> +	int ret;
> +	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +
> +	ret = read_sr(nor);
> +	if (ret < 0) {
> +		dev_err(nor->dev, "error while reading status register\n");
> +		return ret;
> +	}
> +
> +	write_enable(nor);
> +
> +	ret = write_sr(nor, ret & ~mask);
> +	if (ret) {
> +		dev_err(nor->dev, "write to status register failed\n");
> +		return ret;
> +	}
> +
> +	ret = spi_nor_wait_till_ready(nor);
> +	if (ret)
> +		dev_err(nor->dev, "timeout while writing status register\n");
> +	return ret;
> +}
> +
> +/**
> + * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
> + * bits on spansion flashes.
> + * @nor:        pointer to a 'struct spi_nor'
> + *
> + * Read-modify-write function that clears the Block Protection bits from the
> + * Status Register without affecting other bits. The function is tightly
> + * coupled with the spansion_quad_enable() function. Both assume that the Write
> + * Register with 16 bits, together with the Read Configuration Register (35h)
> + * instructions are supported
> + *
> + * Return: 0 on success, -errno otherwise.
> + */
> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
> +{
> +	int ret;
> +	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
> +	u8 sr_cr[2] = {0};
> +
> +	/* Check current Quad Enable bit value. */
> +	ret = read_cr(nor);
> +	if (ret < 0) {
> +		dev_err(nor->dev,
> +			"error while reading configuration register\n");
> +		return ret;
> +	}
> +
> +	/*
> +	 * When the configuration register QUAD bit CR[1] is 1, only
> +	 * the WRR command format with 16 data bits may be used.
> +	 */
> +	if (ret & CR_QUAD_EN_SPAN) {
> +		sr_cr[1] = ret;
> +
> +		ret = read_sr(nor);
> +		if (ret < 0) {
> +			dev_err(nor->dev,
> +				"error while reading status register\n");
> +			return ret;
> +		}
> +		sr_cr[0] = ret & ~mask;
> +
> +		ret = write_sr_cr(nor, sr_cr);
> +		if (ret)
> +			dev_err(nor->dev, "16-bit write register failed\n");
> +		return ret;
> +	}
> +
> +	/* If quad bit is not set, use 8-bit WRR command. */
> +	return spi_nor_clear_sr_bp(nor);
> +}
> +
>  /* Used when the "_ext_id" is two bytes at most */
>  #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
>  		.id = {							\
> @@ -3663,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
>  		default:
>  			/* Kept only for backward compatibility purpose. */
>  			params->quad_enable = spansion_quad_enable;
> +			if (nor->clear_sr_bp)
> +				nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
>  			break;
>  		}
>  
> @@ -3915,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
>  {
>  	int err;
>  
> -	/*
> -	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> -	 * with the software protection bits set
> -	 */
> -	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
> -	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
> -	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
> -	    nor->info->flags & SPI_NOR_HAS_LOCK) {
> -		write_enable(nor);
> -		write_sr(nor, 0);
> -		spi_nor_wait_till_ready(nor);
> +	if (nor->clear_sr_bp) {
> +		err = nor->clear_sr_bp(nor);
> +		if (err) {
> +			dev_err(nor->dev,
> +				"fail to clear block protection bits\n");
> +			return err;
> +		}
>  	}
>  
>  	if (nor->quad_enable) {
> @@ -4050,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
>  	if (info->flags & SPI_S3AN)
>  		nor->flags |=  SNOR_F_READY_XSR_RDY;
>  
> +	/*
> +	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
> +	 * with the software protection bits set.
> +	 */
> +	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
> +	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
> +	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
> +	    nor->info->flags & SPI_NOR_HAS_LOCK)
> +		nor->clear_sr_bp = spi_nor_clear_sr_bp;
> +
>  	/* Parse the Serial Flash Discoverable Parameters table. */
>  	ret = spi_nor_init_params(nor, &params);
>  	if (ret)
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index b3d360b0ee3d..566bd5010bc8 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -410,6 +410,7 @@ struct spi_nor {
>  	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
>  	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
>  	int (*quad_enable)(struct spi_nor *nor);
> +	int (*clear_sr_bp)(struct spi_nor *nor);
>  
>  	void *priv;
>  };
> 

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

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
  2019-06-11  8:35                                         ` Geert Uytterhoeven
@ 2019-06-19 15:47                                           ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-06-19 15:47 UTC (permalink / raw)
  To: geert
  Cc: marek.vasut+renesas, marek.vasut, vigneshr, jonas, dwmw2,
	computersforpeace, miquel.raynal, richard, linux-mtd,
	linux-kernel, linux-renesas-soc

Hi, Geert,

On 06/11/2019 11:35 AM, Geert Uytterhoeven wrote:
> Hi Tudor,
> 
> On Mon, Jun 10, 2019 at 8:24 AM <Tudor.Ambarus@microchip.com> wrote:
>> From: Tudor Ambarus <tudor.ambarus@microchip.com>
>>
>> SPI memory devices from different manufacturers have widely
>> different configurations for Status, Control and Configuration
>> registers. JEDEC 216C defines a new map for these common register
>> bits and their functions, and describes how the individual bits may
>> be accessed for a specific device. For the JEDEC 216B compliant
>> flashes, we can partially deduce Status and Configuration registers
>> functions by inspecting the 16th DWORD of BFPT. Older flashes that
>> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
>> SPANSION) let the software decide how to interact with these registers.
>>
>> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
>> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
>> in the bootloader. When this bit is set, only the Write Register
>> WRR command format with 16 data bits may be used, WRR with 8 bits
>> is not recognized and hence the error when trying to clear the block
>> protection bits.
>>
>> Fix the above by using 16-bits WRR command when Quad bit is set.
>>
>> Backward compatibility should be fine. The newly introduced
>> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
>> spansion_quad_enable() function. Both assume that the Write Register
>> with 16 bits, together with the Read Configuration Register (35h)
>> instructions are supported.
>>
>> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
>> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
>> ---
>> Geert, Jonas,
>>
>> This patch is compile-tested only. I don't have the flash, I need your
>> help for testing this.
> 
> Thanks, this revives access to the s25fl512s on Koelsch.
> 
> Fixes: dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region locking")

I didn't add the Fixes tag because this commit helped us discover a case that
has not been taken into consideration before. It didn't introduce a bug, but
rather revealed one. However, it's not the time to walk over this thin line, so
I'll add it, thanks!

> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>Hi Tudor,
> 
> Two questions below...
> 
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
> 
>> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
>> +{
> 
> [...]
> 
>> +        * When the configuration register QUAD bit CR[1] is 1, only
>> +        * the WRR command format with 16 data bits may be used.
> 
> s/WRR/WRSR/?

S25FL512S named it "Write Registers" command and chose the "WRR" acronym.
JESD216D names it "Write Register" command and doesn't suggest an acronym. I'll
s/"WRR"/"Write Register command", to use the JESD216D naming and avoid confusion.

I also forgot to describe int (*clear_sr_bp), v2 will follow. Will keep the R-b
and T-b tags since I'll just update comments.

ta

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
@ 2019-06-19 15:47                                           ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-06-19 15:47 UTC (permalink / raw)
  To: geert
  Cc: vigneshr, richard, linux-kernel, linux-renesas-soc, marek.vasut,
	jonas, linux-mtd, miquel.raynal, computersforpeace, dwmw2,
	marek.vasut+renesas

Hi, Geert,

On 06/11/2019 11:35 AM, Geert Uytterhoeven wrote:
> Hi Tudor,
> 
> On Mon, Jun 10, 2019 at 8:24 AM <Tudor.Ambarus@microchip.com> wrote:
>> From: Tudor Ambarus <tudor.ambarus@microchip.com>
>>
>> SPI memory devices from different manufacturers have widely
>> different configurations for Status, Control and Configuration
>> registers. JEDEC 216C defines a new map for these common register
>> bits and their functions, and describes how the individual bits may
>> be accessed for a specific device. For the JEDEC 216B compliant
>> flashes, we can partially deduce Status and Configuration registers
>> functions by inspecting the 16th DWORD of BFPT. Older flashes that
>> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
>> SPANSION) let the software decide how to interact with these registers.
>>
>> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
>> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
>> in the bootloader. When this bit is set, only the Write Register
>> WRR command format with 16 data bits may be used, WRR with 8 bits
>> is not recognized and hence the error when trying to clear the block
>> protection bits.
>>
>> Fix the above by using 16-bits WRR command when Quad bit is set.
>>
>> Backward compatibility should be fine. The newly introduced
>> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
>> spansion_quad_enable() function. Both assume that the Write Register
>> with 16 bits, together with the Read Configuration Register (35h)
>> instructions are supported.
>>
>> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
>> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
>> ---
>> Geert, Jonas,
>>
>> This patch is compile-tested only. I don't have the flash, I need your
>> help for testing this.
> 
> Thanks, this revives access to the s25fl512s on Koelsch.
> 
> Fixes: dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region locking")

I didn't add the Fixes tag because this commit helped us discover a case that
has not been taken into consideration before. It didn't introduce a bug, but
rather revealed one. However, it's not the time to walk over this thin line, so
I'll add it, thanks!

> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>Hi Tudor,
> 
> Two questions below...
> 
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
> 
>> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
>> +{
> 
> [...]
> 
>> +        * When the configuration register QUAD bit CR[1] is 1, only
>> +        * the WRR command format with 16 data bits may be used.
> 
> s/WRR/WRSR/?

S25FL512S named it "Write Registers" command and chose the "WRR" acronym.
JESD216D names it "Write Register" command and doesn't suggest an acronym. I'll
s/"WRR"/"Write Register command", to use the JESD216D naming and avoid confusion.

I also forgot to describe int (*clear_sr_bp), v2 will follow. Will keep the R-b
and T-b tags since I'll just update comments.

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

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

* [PATCH v2 1/2] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
  2019-06-19 15:47                                           ` Tudor.Ambarus
@ 2019-06-19 17:26                                             ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-06-19 17:26 UTC (permalink / raw)
  To: geert, marek.vasut+renesas, marek.vasut, vigneshr, jonas, miquel.raynal
  Cc: dwmw2, computersforpeace, richard, linux-mtd, linux-kernel,
	linux-renesas-soc, Tudor.Ambarus

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

SPI memory devices from different manufacturers have widely
different configurations for Status, Control and Configuration
registers. JEDEC 216C defines a new map for these common register
bits and their functions, and describes how the individual bits may
be accessed for a specific device. For the JEDEC 216B compliant
flashes, we can partially deduce Status and Configuration registers
functions by inspecting the 16th DWORD of BFPT. Older flashes that
don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
SPANSION) let the software decide how to interact with these registers.

The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
uncovered a probe error for s25fl512s, when the Quad Enable bit CR[1]
was set to one in the bootloader. When this bit is one, only the Write
Status (01h) command with two data byts may be used, the 01h command with
one data byte is not recognized and hence the error when trying to clear
the block protection bits.

Fix the above by using the Write Status (01h) command with two data bytes
when the Quad Enable bit is one.

Backward compatibility should be fine. The newly introduced
spi_nor_spansion_clear_sr_bp() is tightly coupled with the
spansion_quad_enable() function. Both assume that the Write Register
with 16 bits, together with the Read Configuration Register (35h)
instructions are supported.

Fixes: dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region locking")
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Tested-by: Jonas Bonn <jonas@norrbonn.se>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Vignesh Raghavendra <vigneshr@ti.com>
Tested-by: Vignesh Raghavendra <vigneshr@ti.com>
---
- add Fixes tag. Collect R-b and T-b tags
- update comments regarding the Write Register command. Looks like
  JESD216D uses the "Write Status (01h) command" terminology. Use it.
- add description for int (*clear_sr_bp)(struct spi_nor *nor);

 drivers/mtd/spi-nor/spi-nor.c | 119 ++++++++++++++++++++++++++++++++++++++----
 include/linux/mtd/spi-nor.h   |   3 ++
 2 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 73172d7f512b..0c2ec1c21434 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1636,6 +1636,95 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	return 0;
 }
 
+/**
+ * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_clear_sr_bp(struct spi_nor *nor)
+{
+	int ret;
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	ret = read_sr(nor);
+	if (ret < 0) {
+		dev_err(nor->dev, "error while reading status register\n");
+		return ret;
+	}
+
+	write_enable(nor);
+
+	ret = write_sr(nor, ret & ~mask);
+	if (ret) {
+		dev_err(nor->dev, "write to status register failed\n");
+		return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		dev_err(nor->dev, "timeout while writing status register\n");
+	return ret;
+}
+
+/**
+ * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
+ * bits on spansion flashes.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits. The function is tightly
+ * coupled with the spansion_quad_enable() function. Both assume that the Write
+ * Register with 16 bits, together with the Read Configuration Register (35h)
+ * instructions are supported.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
+{
+	int ret;
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+	u8 sr_cr[2] = {0};
+
+	/* Check current Quad Enable bit value. */
+	ret = read_cr(nor);
+	if (ret < 0) {
+		dev_err(nor->dev,
+			"error while reading configuration register\n");
+		return ret;
+	}
+
+	/*
+	 * When the configuration register Quad Enable bit is one, only the
+	 * Write Status (01h) command with two data bytes may be used.
+	 */
+	if (ret & CR_QUAD_EN_SPAN) {
+		sr_cr[1] = ret;
+
+		ret = read_sr(nor);
+		if (ret < 0) {
+			dev_err(nor->dev,
+				"error while reading status register\n");
+			return ret;
+		}
+		sr_cr[0] = ret & ~mask;
+
+		ret = write_sr_cr(nor, sr_cr);
+		if (ret)
+			dev_err(nor->dev, "16-bit write register failed\n");
+		return ret;
+	}
+
+	/*
+	 * If the Quad Enable bit is zero, use the Write Status (01h) command
+	 * with one data byte.
+	 */
+	return spi_nor_clear_sr_bp(nor);
+}
+
 /* Used when the "_ext_id" is two bytes at most */
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
 		.id = {							\
@@ -3660,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
 		default:
 			/* Kept only for backward compatibility purpose. */
 			params->quad_enable = spansion_quad_enable;
+			if (nor->clear_sr_bp)
+				nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
 			break;
 		}
 
@@ -3912,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
 {
 	int err;
 
-	/*
-	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
-	 * with the software protection bits set
-	 */
-	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
-	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
-	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-	    nor->info->flags & SPI_NOR_HAS_LOCK) {
-		write_enable(nor);
-		write_sr(nor, 0);
-		spi_nor_wait_till_ready(nor);
+	if (nor->clear_sr_bp) {
+		err = nor->clear_sr_bp(nor);
+		if (err) {
+			dev_err(nor->dev,
+				"fail to clear block protection bits\n");
+			return err;
+		}
 	}
 
 	if (nor->quad_enable) {
@@ -4047,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (info->flags & SPI_S3AN)
 		nor->flags |=  SNOR_F_READY_XSR_RDY;
 
+	/*
+	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
+	 * with the software protection bits set.
+	 */
+	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
+	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
+	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
+	    nor->info->flags & SPI_NOR_HAS_LOCK)
+		nor->clear_sr_bp = spi_nor_clear_sr_bp;
+
 	/* Parse the Serial Flash Discoverable Parameters table. */
 	ret = spi_nor_init_params(nor, &params);
 	if (ret)
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index b3d360b0ee3d..9f57cdfcc93d 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -373,6 +373,8 @@ struct flash_info;
  * @flash_unlock:	[FLASH-SPECIFIC] unlock a region of the SPI NOR
  * @flash_is_locked:	[FLASH-SPECIFIC] check if a region of the SPI NOR is
  * @quad_enable:	[FLASH-SPECIFIC] enables SPI NOR quad mode
+ * @clear_sr_bp:	[FLASH-SPECIFIC] clears the Block Protection Bits from
+ *			the SPI NOR Status Register.
  *			completely locked
  * @priv:		the private data
  */
@@ -410,6 +412,7 @@ struct spi_nor {
 	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 	int (*quad_enable)(struct spi_nor *nor);
+	int (*clear_sr_bp)(struct spi_nor *nor);
 
 	void *priv;
 };
-- 
2.9.5


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

* [PATCH v2 1/2] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
@ 2019-06-19 17:26                                             ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-06-19 17:26 UTC (permalink / raw)
  To: geert, marek.vasut+renesas, marek.vasut, vigneshr, jonas, miquel.raynal
  Cc: Tudor.Ambarus, richard, linux-kernel, linux-renesas-soc,
	linux-mtd, computersforpeace, dwmw2

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

SPI memory devices from different manufacturers have widely
different configurations for Status, Control and Configuration
registers. JEDEC 216C defines a new map for these common register
bits and their functions, and describes how the individual bits may
be accessed for a specific device. For the JEDEC 216B compliant
flashes, we can partially deduce Status and Configuration registers
functions by inspecting the 16th DWORD of BFPT. Older flashes that
don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
SPANSION) let the software decide how to interact with these registers.

The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
uncovered a probe error for s25fl512s, when the Quad Enable bit CR[1]
was set to one in the bootloader. When this bit is one, only the Write
Status (01h) command with two data byts may be used, the 01h command with
one data byte is not recognized and hence the error when trying to clear
the block protection bits.

Fix the above by using the Write Status (01h) command with two data bytes
when the Quad Enable bit is one.

Backward compatibility should be fine. The newly introduced
spi_nor_spansion_clear_sr_bp() is tightly coupled with the
spansion_quad_enable() function. Both assume that the Write Register
with 16 bits, together with the Read Configuration Register (35h)
instructions are supported.

Fixes: dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region locking")
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Tested-by: Jonas Bonn <jonas@norrbonn.se>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Vignesh Raghavendra <vigneshr@ti.com>
Tested-by: Vignesh Raghavendra <vigneshr@ti.com>
---
- add Fixes tag. Collect R-b and T-b tags
- update comments regarding the Write Register command. Looks like
  JESD216D uses the "Write Status (01h) command" terminology. Use it.
- add description for int (*clear_sr_bp)(struct spi_nor *nor);

 drivers/mtd/spi-nor/spi-nor.c | 119 ++++++++++++++++++++++++++++++++++++++----
 include/linux/mtd/spi-nor.h   |   3 ++
 2 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 73172d7f512b..0c2ec1c21434 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1636,6 +1636,95 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	return 0;
 }
 
+/**
+ * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_clear_sr_bp(struct spi_nor *nor)
+{
+	int ret;
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+	ret = read_sr(nor);
+	if (ret < 0) {
+		dev_err(nor->dev, "error while reading status register\n");
+		return ret;
+	}
+
+	write_enable(nor);
+
+	ret = write_sr(nor, ret & ~mask);
+	if (ret) {
+		dev_err(nor->dev, "write to status register failed\n");
+		return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		dev_err(nor->dev, "timeout while writing status register\n");
+	return ret;
+}
+
+/**
+ * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
+ * bits on spansion flashes.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits. The function is tightly
+ * coupled with the spansion_quad_enable() function. Both assume that the Write
+ * Register with 16 bits, together with the Read Configuration Register (35h)
+ * instructions are supported.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
+{
+	int ret;
+	u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+	u8 sr_cr[2] = {0};
+
+	/* Check current Quad Enable bit value. */
+	ret = read_cr(nor);
+	if (ret < 0) {
+		dev_err(nor->dev,
+			"error while reading configuration register\n");
+		return ret;
+	}
+
+	/*
+	 * When the configuration register Quad Enable bit is one, only the
+	 * Write Status (01h) command with two data bytes may be used.
+	 */
+	if (ret & CR_QUAD_EN_SPAN) {
+		sr_cr[1] = ret;
+
+		ret = read_sr(nor);
+		if (ret < 0) {
+			dev_err(nor->dev,
+				"error while reading status register\n");
+			return ret;
+		}
+		sr_cr[0] = ret & ~mask;
+
+		ret = write_sr_cr(nor, sr_cr);
+		if (ret)
+			dev_err(nor->dev, "16-bit write register failed\n");
+		return ret;
+	}
+
+	/*
+	 * If the Quad Enable bit is zero, use the Write Status (01h) command
+	 * with one data byte.
+	 */
+	return spi_nor_clear_sr_bp(nor);
+}
+
 /* Used when the "_ext_id" is two bytes at most */
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
 		.id = {							\
@@ -3660,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
 		default:
 			/* Kept only for backward compatibility purpose. */
 			params->quad_enable = spansion_quad_enable;
+			if (nor->clear_sr_bp)
+				nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
 			break;
 		}
 
@@ -3912,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
 {
 	int err;
 
-	/*
-	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
-	 * with the software protection bits set
-	 */
-	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
-	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
-	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-	    nor->info->flags & SPI_NOR_HAS_LOCK) {
-		write_enable(nor);
-		write_sr(nor, 0);
-		spi_nor_wait_till_ready(nor);
+	if (nor->clear_sr_bp) {
+		err = nor->clear_sr_bp(nor);
+		if (err) {
+			dev_err(nor->dev,
+				"fail to clear block protection bits\n");
+			return err;
+		}
 	}
 
 	if (nor->quad_enable) {
@@ -4047,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (info->flags & SPI_S3AN)
 		nor->flags |=  SNOR_F_READY_XSR_RDY;
 
+	/*
+	 * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
+	 * with the software protection bits set.
+	 */
+	if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
+	    JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
+	    JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
+	    nor->info->flags & SPI_NOR_HAS_LOCK)
+		nor->clear_sr_bp = spi_nor_clear_sr_bp;
+
 	/* Parse the Serial Flash Discoverable Parameters table. */
 	ret = spi_nor_init_params(nor, &params);
 	if (ret)
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index b3d360b0ee3d..9f57cdfcc93d 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -373,6 +373,8 @@ struct flash_info;
  * @flash_unlock:	[FLASH-SPECIFIC] unlock a region of the SPI NOR
  * @flash_is_locked:	[FLASH-SPECIFIC] check if a region of the SPI NOR is
  * @quad_enable:	[FLASH-SPECIFIC] enables SPI NOR quad mode
+ * @clear_sr_bp:	[FLASH-SPECIFIC] clears the Block Protection Bits from
+ *			the SPI NOR Status Register.
  *			completely locked
  * @priv:		the private data
  */
@@ -410,6 +412,7 @@ struct spi_nor {
 	int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 	int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
 	int (*quad_enable)(struct spi_nor *nor);
+	int (*clear_sr_bp)(struct spi_nor *nor);
 
 	void *priv;
 };
-- 
2.9.5

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

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

* [PATCH v2 2/2] mtd: spi-nor: fix description for int (*flash_is_locked)()
  2019-06-19 17:26                                             ` Tudor.Ambarus
@ 2019-06-19 17:26                                               ` Tudor.Ambarus
  -1 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-06-19 17:26 UTC (permalink / raw)
  To: geert, marek.vasut+renesas, marek.vasut, vigneshr, jonas, miquel.raynal
  Cc: dwmw2, computersforpeace, richard, linux-mtd, linux-kernel,
	linux-renesas-soc, Tudor.Ambarus

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

The description was interleaved.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
v2: new patch

 include/linux/mtd/spi-nor.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 9f57cdfcc93d..c4c2c5971284 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -372,10 +372,10 @@ struct flash_info;
  * @flash_lock:		[FLASH-SPECIFIC] lock a region of the SPI NOR
  * @flash_unlock:	[FLASH-SPECIFIC] unlock a region of the SPI NOR
  * @flash_is_locked:	[FLASH-SPECIFIC] check if a region of the SPI NOR is
+ *			completely locked
  * @quad_enable:	[FLASH-SPECIFIC] enables SPI NOR quad mode
  * @clear_sr_bp:	[FLASH-SPECIFIC] clears the Block Protection Bits from
  *			the SPI NOR Status Register.
- *			completely locked
  * @priv:		the private data
  */
 struct spi_nor {
-- 
2.9.5


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

* [PATCH v2 2/2] mtd: spi-nor: fix description for int (*flash_is_locked)()
@ 2019-06-19 17:26                                               ` Tudor.Ambarus
  0 siblings, 0 replies; 62+ messages in thread
From: Tudor.Ambarus @ 2019-06-19 17:26 UTC (permalink / raw)
  To: geert, marek.vasut+renesas, marek.vasut, vigneshr, jonas, miquel.raynal
  Cc: Tudor.Ambarus, richard, linux-kernel, linux-renesas-soc,
	linux-mtd, computersforpeace, dwmw2

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

The description was interleaved.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
v2: new patch

 include/linux/mtd/spi-nor.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 9f57cdfcc93d..c4c2c5971284 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -372,10 +372,10 @@ struct flash_info;
  * @flash_lock:		[FLASH-SPECIFIC] lock a region of the SPI NOR
  * @flash_unlock:	[FLASH-SPECIFIC] unlock a region of the SPI NOR
  * @flash_is_locked:	[FLASH-SPECIFIC] check if a region of the SPI NOR is
+ *			completely locked
  * @quad_enable:	[FLASH-SPECIFIC] enables SPI NOR quad mode
  * @clear_sr_bp:	[FLASH-SPECIFIC] clears the Block Protection Bits from
  *			the SPI NOR Status Register.
- *			completely locked
  * @priv:		the private data
  */
 struct spi_nor {
-- 
2.9.5

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

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
  2019-06-19 15:47                                           ` Tudor.Ambarus
@ 2019-06-19 18:51                                             ` Geert Uytterhoeven
  -1 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-06-19 18:51 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: Marek Vasut, Marek Vasut, R, Vignesh, Jonas Bonn,
	David Woodhouse, Brian Norris, Miquel Raynal, Richard Weinberger,
	MTD Maling List, Linux Kernel Mailing List, Linux-Renesas

Hi Tudor,

On Wed, Jun 19, 2019 at 5:47 PM <Tudor.Ambarus@microchip.com> wrote:
> On 06/11/2019 11:35 AM, Geert Uytterhoeven wrote:
> > On Mon, Jun 10, 2019 at 8:24 AM <Tudor.Ambarus@microchip.com> wrote:
> >> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> >>
> >> SPI memory devices from different manufacturers have widely
> >> different configurations for Status, Control and Configuration
> >> registers. JEDEC 216C defines a new map for these common register
> >> bits and their functions, and describes how the individual bits may
> >> be accessed for a specific device. For the JEDEC 216B compliant
> >> flashes, we can partially deduce Status and Configuration registers
> >> functions by inspecting the 16th DWORD of BFPT. Older flashes that
> >> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
> >> SPANSION) let the software decide how to interact with these registers.
> >>
> >> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
> >> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
> >> in the bootloader. When this bit is set, only the Write Register
> >> WRR command format with 16 data bits may be used, WRR with 8 bits
> >> is not recognized and hence the error when trying to clear the block
> >> protection bits.
> >>
> >> Fix the above by using 16-bits WRR command when Quad bit is set.
> >>
> >> Backward compatibility should be fine. The newly introduced
> >> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
> >> spansion_quad_enable() function. Both assume that the Write Register
> >> with 16 bits, together with the Read Configuration Register (35h)
> >> instructions are supported.
> >>
> >> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> >> ---
> >> Geert, Jonas,
> >>
> >> This patch is compile-tested only. I don't have the flash, I need your
> >> help for testing this.
> >
> > Thanks, this revives access to the s25fl512s on Koelsch.
> >
> > Fixes: dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region locking")
>
> I didn't add the Fixes tag because this commit helped us discover a case that
> has not been taken into consideration before. It didn't introduce a bug, but
> rather revealed one. However, it's not the time to walk over this thin line, so
> I'll add it, thanks!

Good. Fixes also serves as an indicator that if dcb4b22eeaf44f91 is
backported to stable, the "fix" must be backported, too.

> > Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>Hi Tudor,
> >
> > Two questions below...
> >
> >> --- a/drivers/mtd/spi-nor/spi-nor.c
> >> +++ b/drivers/mtd/spi-nor/spi-nor.c
> >
> >> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
> >> +{
> >
> > [...]
> >
> >> +        * When the configuration register QUAD bit CR[1] is 1, only
> >> +        * the WRR command format with 16 data bits may be used.
> >
> > s/WRR/WRSR/?
>
> S25FL512S named it "Write Registers" command and chose the "WRR" acronym.
> JESD216D names it "Write Register" command and doesn't suggest an acronym. I'll
> s/"WRR"/"Write Register command", to use the JESD216D naming and avoid confusion.
>
> I also forgot to describe int (*clear_sr_bp), v2 will follow. Will keep the R-b
> and T-b tags since I'll just update comments.

OK. Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes
@ 2019-06-19 18:51                                             ` Geert Uytterhoeven
  0 siblings, 0 replies; 62+ messages in thread
From: Geert Uytterhoeven @ 2019-06-19 18:51 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: R, Vignesh, Richard Weinberger, Linux Kernel Mailing List,
	Linux-Renesas, Marek Vasut, Jonas Bonn, MTD Maling List,
	Miquel Raynal, Brian Norris, David Woodhouse, Marek Vasut

Hi Tudor,

On Wed, Jun 19, 2019 at 5:47 PM <Tudor.Ambarus@microchip.com> wrote:
> On 06/11/2019 11:35 AM, Geert Uytterhoeven wrote:
> > On Mon, Jun 10, 2019 at 8:24 AM <Tudor.Ambarus@microchip.com> wrote:
> >> From: Tudor Ambarus <tudor.ambarus@microchip.com>
> >>
> >> SPI memory devices from different manufacturers have widely
> >> different configurations for Status, Control and Configuration
> >> registers. JEDEC 216C defines a new map for these common register
> >> bits and their functions, and describes how the individual bits may
> >> be accessed for a specific device. For the JEDEC 216B compliant
> >> flashes, we can partially deduce Status and Configuration registers
> >> functions by inspecting the 16th DWORD of BFPT. Older flashes that
> >> don't declare the SFDP tables (SPANSION FL512SAIFG1 311QQ063 A ©11
> >> SPANSION) let the software decide how to interact with these registers.
> >>
> >> The commit dcb4b22eeaf4 ("spi-nor: s25fl512s supports region locking")
> >> uncovered a probe error for s25fl512s, when the QUAD bit CR[1] was set
> >> in the bootloader. When this bit is set, only the Write Register
> >> WRR command format with 16 data bits may be used, WRR with 8 bits
> >> is not recognized and hence the error when trying to clear the block
> >> protection bits.
> >>
> >> Fix the above by using 16-bits WRR command when Quad bit is set.
> >>
> >> Backward compatibility should be fine. The newly introduced
> >> spi_nor_spansion_clear_sr_bp() is tightly coupled with the
> >> spansion_quad_enable() function. Both assume that the Write Register
> >> with 16 bits, together with the Read Configuration Register (35h)
> >> instructions are supported.
> >>
> >> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> >> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> >> ---
> >> Geert, Jonas,
> >>
> >> This patch is compile-tested only. I don't have the flash, I need your
> >> help for testing this.
> >
> > Thanks, this revives access to the s25fl512s on Koelsch.
> >
> > Fixes: dcb4b22eeaf44f91 ("spi-nor: s25fl512s supports region locking")
>
> I didn't add the Fixes tag because this commit helped us discover a case that
> has not been taken into consideration before. It didn't introduce a bug, but
> rather revealed one. However, it's not the time to walk over this thin line, so
> I'll add it, thanks!

Good. Fixes also serves as an indicator that if dcb4b22eeaf44f91 is
backported to stable, the "fix" must be backported, too.

> > Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>Hi Tudor,
> >
> > Two questions below...
> >
> >> --- a/drivers/mtd/spi-nor/spi-nor.c
> >> +++ b/drivers/mtd/spi-nor/spi-nor.c
> >
> >> +static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
> >> +{
> >
> > [...]
> >
> >> +        * When the configuration register QUAD bit CR[1] is 1, only
> >> +        * the WRR command format with 16 data bits may be used.
> >
> > s/WRR/WRSR/?
>
> S25FL512S named it "Write Registers" command and chose the "WRR" acronym.
> JESD216D names it "Write Register" command and doesn't suggest an acronym. I'll
> s/"WRR"/"Write Register command", to use the JESD216D naming and avoid confusion.
>
> I also forgot to describe int (*clear_sr_bp), v2 will follow. Will keep the R-b
> and T-b tags since I'll just update comments.

OK. Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

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

end of thread, other threads:[~2019-06-19 18:51 UTC | newest]

Thread overview: 62+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-20  7:16 [PATCH v4 0/3] spi-nor block protection Jonas Bonn
2019-03-20  7:16 ` [PATCH v4 1/3] spi-nor: always respect write-protect input Jonas Bonn
2019-03-20  7:16 ` [PATCH v4 2/3] spi-nor: s25fl512s supports region locking Jonas Bonn
2019-03-20  7:39   ` Tudor.Ambarus
2019-03-21 16:48   ` Tudor.Ambarus
2019-05-07  9:53   ` Geert Uytterhoeven
2019-05-07  9:53     ` Geert Uytterhoeven
2019-05-07 10:42     ` Tudor.Ambarus
2019-05-07 10:42       ` Tudor.Ambarus
2019-05-07 10:50       ` Geert Uytterhoeven
2019-05-07 10:50         ` Geert Uytterhoeven
2019-05-07 11:13         ` Jonas Bonn
2019-05-07 11:13           ` Jonas Bonn
2019-05-07 12:52           ` Geert Uytterhoeven
2019-05-07 12:52             ` Geert Uytterhoeven
2019-05-07 13:15             ` Tudor.Ambarus
2019-05-07 13:15               ` Tudor.Ambarus
2019-05-07 13:18               ` Tudor.Ambarus
2019-05-07 13:18                 ` Tudor.Ambarus
2019-05-07 13:25               ` Tudor.Ambarus
2019-05-07 13:25                 ` Tudor.Ambarus
2019-05-07 14:33                 ` Geert Uytterhoeven
2019-05-07 14:33                   ` Geert Uytterhoeven
2019-05-08 10:44                   ` Tudor.Ambarus
2019-05-08 10:44                     ` Tudor.Ambarus
2019-05-08 13:11                     ` Geert Uytterhoeven
2019-05-08 13:11                       ` Geert Uytterhoeven
2019-05-08 14:23                       ` Tudor.Ambarus
2019-05-08 14:23                         ` Tudor.Ambarus
2019-05-08 17:00                         ` Geert Uytterhoeven
2019-05-08 17:00                           ` Geert Uytterhoeven
2019-05-09  6:55                           ` Tudor.Ambarus
2019-05-09  6:55                             ` Tudor.Ambarus
2019-05-09  9:11                             ` Geert Uytterhoeven
2019-05-09  9:11                               ` Geert Uytterhoeven
2019-05-09 10:31                               ` Tudor.Ambarus
2019-05-09 10:31                                 ` Tudor.Ambarus
2019-05-09 11:12                                 ` Geert Uytterhoeven
2019-05-09 11:12                                   ` Geert Uytterhoeven
2019-05-22 15:49                                   ` Tudor.Ambarus
2019-05-22 15:49                                     ` Tudor.Ambarus
2019-06-10  6:24                                     ` [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes Tudor.Ambarus
2019-06-10  6:24                                       ` Tudor.Ambarus
2019-06-10  9:28                                       ` Jonas Bonn
2019-06-10  9:28                                         ` Jonas Bonn
2019-06-11  8:35                                       ` Geert Uytterhoeven
2019-06-11  8:35                                         ` Geert Uytterhoeven
2019-06-19 15:47                                         ` Tudor.Ambarus
2019-06-19 15:47                                           ` Tudor.Ambarus
2019-06-19 17:26                                           ` [PATCH v2 1/2] " Tudor.Ambarus
2019-06-19 17:26                                             ` Tudor.Ambarus
2019-06-19 17:26                                             ` [PATCH v2 2/2] mtd: spi-nor: fix description for int (*flash_is_locked)() Tudor.Ambarus
2019-06-19 17:26                                               ` Tudor.Ambarus
2019-06-19 18:51                                           ` [PATCH] mtd: spi-nor: use 16-bit WRR command when QE is set on spansion flashes Geert Uytterhoeven
2019-06-19 18:51                                             ` Geert Uytterhoeven
2019-06-12 16:46                                       ` Vignesh Raghavendra
2019-06-12 16:46                                         ` Vignesh Raghavendra
2019-05-09 15:57                                 ` [PATCH v4 2/3] spi-nor: s25fl512s supports region locking Vignesh Raghavendra
2019-05-09 15:57                                   ` Vignesh Raghavendra
2019-03-20  7:16 ` [PATCH v4 3/3] spi-nor: allow setting the BPNV (default locked) bit Jonas Bonn
2019-04-02  5:27   ` Vignesh Raghavendra
2019-05-01  4:42     ` [PATCH v5 1/1] spi-nor: allow setting the BPNV (powerup lock) bit Jonas Bonn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.