linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] MTD: SST SPI-NOR fixes
@ 2020-09-11 14:47 Marco Felsch
  2020-09-11 14:47 ` [PATCH 1/3] mtd: spi-nor: sst: fix write support for SST_WRITE marked devices Marco Felsch
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Marco Felsch @ 2020-09-11 14:47 UTC (permalink / raw)
  To: tudor.ambarus, miquel.raynal, richard, vigneshr, sergei.shtylyov,
	boris.brezillon, michael, j.neuschaefer
  Cc: linux-mtd, kernel, linux-kernel

Hi,

Patch 1-2: write path fixes
The sst write path is completely broken since v5.7-rc1 and in rare cases
since the support of the sst_write() function (49aac4aec53c).

Patch 3: cleanup

I've tested my patches with a small test app to ensure writes starting
on an odd address and with dd to test even start addresses. My dut was
an public available imx6q-sabrelite (rev.D).
Other testers are welcome :)

Regards,
  Marco

Marco Felsch (3):
  mtd: spi-nor: sst: fix write support for SST_WRITE marked devices
  mtd: spi-nor: sst: add missing write_enable
  mtd: spi-nor: sst: move sst_write_second to local driver

 drivers/mtd/spi-nor/core.c  | 15 +++++++++------
 drivers/mtd/spi-nor/sst.c   | 15 +++++++++++----
 include/linux/mtd/spi-nor.h |  2 --
 3 files changed, 20 insertions(+), 12 deletions(-)

-- 
2.20.1


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

* [PATCH 1/3] mtd: spi-nor: sst: fix write support for SST_WRITE marked devices
  2020-09-11 14:47 [PATCH 0/3] MTD: SST SPI-NOR fixes Marco Felsch
@ 2020-09-11 14:47 ` Marco Felsch
  2020-09-14 12:00   ` Vignesh Raghavendra
  2020-09-11 14:47 ` [PATCH 2/3] mtd: spi-nor: sst: add missing write_enable Marco Felsch
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Marco Felsch @ 2020-09-11 14:47 UTC (permalink / raw)
  To: tudor.ambarus, miquel.raynal, richard, vigneshr, sergei.shtylyov,
	boris.brezillon, michael, j.neuschaefer
  Cc: linux-mtd, kernel, linux-kernel

The sst write support for devices using the special SST_WRITE routine
is broken since commit commit df5c21002cf4 ("mtd: spi-nor: use spi-mem
dirmap API") because the spi_nor_create_write_dirmap() function checks
SPINOR_OP_AAI_WP and sst_write_second. These checks are not valid during
probe. The check seems also to be broken since the "op->addr.nbytes = 0"
causes the devm_spi_mem_dirmap_create() function to return
PTR_ERR(-EINVAL) and the probe() function will fail.

It seems that the commit only copy'n'pasted the existing logic. Use the
correct SST_WRITE flag and return 0 to fix both issues.

Fixes: df5c21002cf4 ("mtd: spi-nor: use spi-mem dirmap API")
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/mtd/spi-nor/core.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 65eff4ce6ab1..31869ac245a8 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3289,15 +3289,21 @@ static int spi_nor_create_write_dirmap(struct spi_nor *nor)
 	};
 	struct spi_mem_op *op = &info.op_tmpl;
 
+	/*
+	 * Most SST SPI-NOR's have a special write routine.which should so
+	 * dirmap.wdesc is not supported for these.
+	 */
+	if (nor->info->flags & SST_WRITE) {
+		nor->dirmap.wdesc = NULL;
+		return 0;
+	}
+
 	/* get transfer protocols. */
 	op->cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);
 	op->addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);
 	op->dummy.buswidth = op->addr.buswidth;
 	op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
 
-	if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
-		op->addr.nbytes = 0;
-
 	nor->dirmap.wdesc = devm_spi_mem_dirmap_create(nor->dev, nor->spimem,
 						       &info);
 	return PTR_ERR_OR_ZERO(nor->dirmap.wdesc);
-- 
2.20.1


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

* [PATCH 2/3] mtd: spi-nor: sst: add missing write_enable
  2020-09-11 14:47 [PATCH 0/3] MTD: SST SPI-NOR fixes Marco Felsch
  2020-09-11 14:47 ` [PATCH 1/3] mtd: spi-nor: sst: fix write support for SST_WRITE marked devices Marco Felsch
@ 2020-09-11 14:47 ` Marco Felsch
  2020-09-11 14:47 ` [PATCH 3/3] mtd: spi-nor: sst: move sst_write_second to local driver Marco Felsch
  2020-11-24 20:35 ` [PATCH 0/3] MTD: SST SPI-NOR fixes Michael Auchter
  3 siblings, 0 replies; 7+ messages in thread
From: Marco Felsch @ 2020-09-11 14:47 UTC (permalink / raw)
  To: tudor.ambarus, miquel.raynal, richard, vigneshr, sergei.shtylyov,
	boris.brezillon, michael, j.neuschaefer
  Cc: linux-mtd, kernel, linux-kernel

According the datasheet [1] the WEL is automatically reset after the
Byte-Program instruction completion. So if we program the device with
byte-size set to 32 and starting from an odd address only the first and
the last byte is written. Fix this by (re-)anble the write support for
the first SPINOR_OP_AAI_WP sequence.

[1] http://ww1.microchip.com/downloads/en/DeviceDoc/20005044C.pdf;
    "4.3.2 WRITE ENABLE LATCH (WEL)"

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/mtd/spi-nor/sst.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
index e0af6d25d573..644252e27a2a 100644
--- a/drivers/mtd/spi-nor/sst.c
+++ b/drivers/mtd/spi-nor/sst.c
@@ -79,6 +79,13 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 	/* Write out most of the data here. */
 	for (; actual < len - 1; actual += 2) {
+		/* Enable write support if odd address was written before */
+		if (actual == 1) {
+			ret = spi_nor_write_enable(nor);
+			if (ret)
+				goto out;
+		}
+
 		nor->program_opcode = SPINOR_OP_AAI_WP;
 
 		/* write two bytes. */
-- 
2.20.1


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

* [PATCH 3/3] mtd: spi-nor: sst: move sst_write_second to local driver
  2020-09-11 14:47 [PATCH 0/3] MTD: SST SPI-NOR fixes Marco Felsch
  2020-09-11 14:47 ` [PATCH 1/3] mtd: spi-nor: sst: fix write support for SST_WRITE marked devices Marco Felsch
  2020-09-11 14:47 ` [PATCH 2/3] mtd: spi-nor: sst: add missing write_enable Marco Felsch
@ 2020-09-11 14:47 ` Marco Felsch
  2020-11-24 20:35 ` [PATCH 0/3] MTD: SST SPI-NOR fixes Michael Auchter
  3 siblings, 0 replies; 7+ messages in thread
From: Marco Felsch @ 2020-09-11 14:47 UTC (permalink / raw)
  To: tudor.ambarus, miquel.raynal, richard, vigneshr, sergei.shtylyov,
	boris.brezillon, michael, j.neuschaefer
  Cc: linux-mtd, kernel, linux-kernel

Don't mess the spi-nor core with details only relating to this specific
device. Handle the addr_width locally and drop the sst related stuff
from the spi-nor core to clean it up.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
 drivers/mtd/spi-nor/core.c  |  3 ---
 drivers/mtd/spi-nor/sst.c   | 10 ++++++----
 include/linux/mtd/spi-nor.h |  2 --
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 31869ac245a8..fabd8ca4e801 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -173,9 +173,6 @@ static ssize_t spi_nor_spimem_write_data(struct spi_nor *nor, loff_t to,
 	op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);
 	op.data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
 
-	if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
-		op.addr.nbytes = 0;
-
 	if (spi_nor_spimem_bounce(nor, &op))
 		memcpy(nor->bouncebuf, buf, op.data.nbytes);
 
diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
index 644252e27a2a..7ca7e1a13511 100644
--- a/drivers/mtd/spi-nor/sst.c
+++ b/drivers/mtd/spi-nor/sst.c
@@ -58,10 +58,9 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 	if (ret)
 		goto out;
 
-	nor->sst_write_second = false;
-
 	/* Start write from odd address. */
 	if (to % 2) {
+		nor->addr_width = 3;
 		nor->program_opcode = SPINOR_OP_BP;
 
 		/* write one byte. */
@@ -86,6 +85,8 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 				goto out;
 		}
 
+		/* Send address only once for each AAI_WP cycle */
+		nor->addr_width = (actual > 1) ? 0 : 3;
 		nor->program_opcode = SPINOR_OP_AAI_WP;
 
 		/* write two bytes. */
@@ -97,9 +98,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		if (ret)
 			goto out;
 		to += 2;
-		nor->sst_write_second = true;
 	}
-	nor->sst_write_second = false;
 
 	ret = spi_nor_write_disable(nor);
 	if (ret)
@@ -115,6 +114,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		if (ret)
 			goto out;
 
+		nor->addr_width = 3;
 		nor->program_opcode = SPINOR_OP_BP;
 		ret = spi_nor_write_data(nor, to, 1, buf + actual);
 		if (ret < 0)
@@ -129,6 +129,8 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 		ret = spi_nor_write_disable(nor);
 	}
 out:
+	/* Set to default in case no trailing bytes are written */
+	nor->addr_width = 3;
 	*retlen += actual;
 	spi_nor_unlock_and_unprep(nor);
 	return ret;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 60bac2c0ec45..4368c0c41fda 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -343,7 +343,6 @@ struct spi_nor_flash_parameter;
  * @read_opcode:	the read opcode
  * @read_dummy:		the dummy needed by the read operation
  * @program_opcode:	the program opcode
- * @sst_write_second:	used by the SST write operation
  * @flags:		flag options for the current SPI NOR (SNOR_F_*)
  * @read_proto:		the SPI protocol for read operations
  * @write_proto:	the SPI protocol for write operations
@@ -374,7 +373,6 @@ struct spi_nor {
 	enum spi_nor_protocol	read_proto;
 	enum spi_nor_protocol	write_proto;
 	enum spi_nor_protocol	reg_proto;
-	bool			sst_write_second;
 	u32			flags;
 
 	const struct spi_nor_controller_ops *controller_ops;
-- 
2.20.1


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

* Re: [PATCH 1/3] mtd: spi-nor: sst: fix write support for SST_WRITE marked devices
  2020-09-11 14:47 ` [PATCH 1/3] mtd: spi-nor: sst: fix write support for SST_WRITE marked devices Marco Felsch
@ 2020-09-14 12:00   ` Vignesh Raghavendra
  2020-09-16  9:36     ` Tudor.Ambarus
  0 siblings, 1 reply; 7+ messages in thread
From: Vignesh Raghavendra @ 2020-09-14 12:00 UTC (permalink / raw)
  To: Marco Felsch, tudor.ambarus, miquel.raynal, richard,
	sergei.shtylyov, boris.brezillon, michael, j.neuschaefer
  Cc: linux-mtd, kernel, linux-kernel



On 9/11/20 8:17 PM, Marco Felsch wrote:
> The sst write support for devices using the special SST_WRITE routine
> is broken since commit commit df5c21002cf4 ("mtd: spi-nor: use spi-mem
> dirmap API") because the spi_nor_create_write_dirmap() function checks
> SPINOR_OP_AAI_WP and sst_write_second. These checks are not valid during
> probe. The check seems also to be broken since the "op->addr.nbytes = 0"
> causes the devm_spi_mem_dirmap_create() function to return
> PTR_ERR(-EINVAL) and the probe() function will fail.
> 
> It seems that the commit only copy'n'pasted the existing logic. Use the
> correct SST_WRITE flag and return 0 to fix both issues.
> 
> Fixes: df5c21002cf4 ("mtd: spi-nor: use spi-mem dirmap API")
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
>  drivers/mtd/spi-nor/core.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 65eff4ce6ab1..31869ac245a8 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -3289,15 +3289,21 @@ static int spi_nor_create_write_dirmap(struct spi_nor *nor)
>  	};
>  	struct spi_mem_op *op = &info.op_tmpl;
>  
> +	/*
> +	 * Most SST SPI-NOR's have a special write routine.which should so

s/SPI-NOR/SPI NOR.

> +	 * dirmap.wdesc is not supported for these.

Or How about more readable version:

"Most SST flashes have special sequence for writing data to the flash
and therefore cannot support writes through direct mapping APIs."

> +	 */
> +	if (nor->info->flags & SST_WRITE) {
> +		nor->dirmap.wdesc = NULL;

nor->dirmap.wdesc is known to be NULL at this point. So no need to set
to NULL again.

> +		return 0;
> +	}
> +
>  	/* get transfer protocols. */
>  	op->cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);
>  	op->addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);
>  	op->dummy.buswidth = op->addr.buswidth;
>  	op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
>  
> -	if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
> -		op->addr.nbytes = 0;
> -
>  	nor->dirmap.wdesc = devm_spi_mem_dirmap_create(nor->dev, nor->spimem,
>  						       &info);
>  	return PTR_ERR_OR_ZERO(nor->dirmap.wdesc);
> 

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

* Re: [PATCH 1/3] mtd: spi-nor: sst: fix write support for SST_WRITE marked devices
  2020-09-14 12:00   ` Vignesh Raghavendra
@ 2020-09-16  9:36     ` Tudor.Ambarus
  0 siblings, 0 replies; 7+ messages in thread
From: Tudor.Ambarus @ 2020-09-16  9:36 UTC (permalink / raw)
  To: vigneshr, m.felsch, miquel.raynal, richard, sergei.shtylyov,
	boris.brezillon, michael, j.neuschaefer
  Cc: linux-mtd, kernel, linux-kernel

On 9/14/20 3:00 PM, Vignesh Raghavendra wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 9/11/20 8:17 PM, Marco Felsch wrote:
>> The sst write support for devices using the special SST_WRITE routine
>> is broken since commit commit df5c21002cf4 ("mtd: spi-nor: use spi-mem
>> dirmap API") because the spi_nor_create_write_dirmap() function checks
>> SPINOR_OP_AAI_WP and sst_write_second. These checks are not valid during
>> probe. The check seems also to be broken since the "op->addr.nbytes = 0"
>> causes the devm_spi_mem_dirmap_create() function to return
>> PTR_ERR(-EINVAL) and the probe() function will fail.
>>
>> It seems that the commit only copy'n'pasted the existing logic. Use the
>> correct SST_WRITE flag and return 0 to fix both issues.
>>
>> Fixes: df5c21002cf4 ("mtd: spi-nor: use spi-mem dirmap API")
>> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
>> ---
>>  drivers/mtd/spi-nor/core.c | 12 +++++++++---
>>  1 file changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
>> index 65eff4ce6ab1..31869ac245a8 100644
>> --- a/drivers/mtd/spi-nor/core.c
>> +++ b/drivers/mtd/spi-nor/core.c
>> @@ -3289,15 +3289,21 @@ static int spi_nor_create_write_dirmap(struct spi_nor *nor)
>>       };
>>       struct spi_mem_op *op = &info.op_tmpl;
>>
>> +     /*
>> +      * Most SST SPI-NOR's have a special write routine.which should so
> 
> s/SPI-NOR/SPI NOR.
> 
>> +      * dirmap.wdesc is not supported for these.
> 
> Or How about more readable version:
> 
> "Most SST flashes have special sequence for writing data to the flash
> and therefore cannot support writes through direct mapping APIs."
> 
>> +      */
>> +     if (nor->info->flags & SST_WRITE) {
>> +             nor->dirmap.wdesc = NULL;
> 
> nor->dirmap.wdesc is known to be NULL at this point. So no need to set
> to NULL again.
> 
>> +             return 0;
>> +     }
>> +
>>       /* get transfer protocols. */
>>       op->cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);
>>       op->addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);
>>       op->dummy.buswidth = op->addr.buswidth;
>>       op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
>>
>> -     if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
>> -             op->addr.nbytes = 0;
>> -
>>       nor->dirmap.wdesc = devm_spi_mem_dirmap_create(nor->dev, nor->spimem,
>>                                                      &info);
>>       return PTR_ERR_OR_ZERO(nor->dirmap.wdesc);
>>

With Vignesh's comments addressed, one can add:
Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>

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

* Re: [PATCH 0/3] MTD: SST SPI-NOR fixes
  2020-09-11 14:47 [PATCH 0/3] MTD: SST SPI-NOR fixes Marco Felsch
                   ` (2 preceding siblings ...)
  2020-09-11 14:47 ` [PATCH 3/3] mtd: spi-nor: sst: move sst_write_second to local driver Marco Felsch
@ 2020-11-24 20:35 ` Michael Auchter
  3 siblings, 0 replies; 7+ messages in thread
From: Michael Auchter @ 2020-11-24 20:35 UTC (permalink / raw)
  To: Marco Felsch
  Cc: tudor.ambarus, miquel.raynal, richard, vigneshr, sergei.shtylyov,
	boris.brezillon, michael, j.neuschaefer, linux-mtd, kernel,
	linux-kernel, joerg.hofrichter

Hello Marco,

On Fri, Sep 11, 2020 at 04:47:00PM +0200, Marco Felsch wrote:
> Hi,
> 
> Patch 1-2: write path fixes
> The sst write path is completely broken since v5.7-rc1 and in rare cases
> since the support of the sst_write() function (49aac4aec53c).
> 
> Patch 3: cleanup
> 
> I've tested my patches with a small test app to ensure writes starting
> on an odd address and with dd to test even start addresses. My dut was
> an public available imx6q-sabrelite (rev.D).
> Other testers are welcome :)
> 
> Regards,
>   Marco
> 
> Marco Felsch (3):
>   mtd: spi-nor: sst: fix write support for SST_WRITE marked devices
>   mtd: spi-nor: sst: add missing write_enable
>   mtd: spi-nor: sst: move sst_write_second to local driver
> 
>  drivers/mtd/spi-nor/core.c  | 15 +++++++++------
>  drivers/mtd/spi-nor/sst.c   | 15 +++++++++++----
>  include/linux/mtd/spi-nor.h |  2 --
>  3 files changed, 20 insertions(+), 12 deletions(-)
> 
> -- 
> 2.20.1

My colleague, Joerg, has validated that these patches fix an issue we
saw where performing multi-byte writes to a SST25VF016B would fail.

Tested-by: Joerg Hofrichter <joerg.hofrichter@ni.com>

Thanks,
 Michael

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

end of thread, other threads:[~2020-11-24 20:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-11 14:47 [PATCH 0/3] MTD: SST SPI-NOR fixes Marco Felsch
2020-09-11 14:47 ` [PATCH 1/3] mtd: spi-nor: sst: fix write support for SST_WRITE marked devices Marco Felsch
2020-09-14 12:00   ` Vignesh Raghavendra
2020-09-16  9:36     ` Tudor.Ambarus
2020-09-11 14:47 ` [PATCH 2/3] mtd: spi-nor: sst: add missing write_enable Marco Felsch
2020-09-11 14:47 ` [PATCH 3/3] mtd: spi-nor: sst: move sst_write_second to local driver Marco Felsch
2020-11-24 20:35 ` [PATCH 0/3] MTD: SST SPI-NOR fixes Michael Auchter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).