linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 1/3] mtd: spi-nor: support dumping sfdp tables
@ 2021-03-12 19:05 Michael Walle
  2021-03-12 19:05 ` [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size Michael Walle
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Michael Walle @ 2021-03-12 19:05 UTC (permalink / raw)
  To: linux-kernel, linux-mtd
  Cc: Tudor Ambarus, Pratyush Yadav, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Michael Walle

Add the possibility to dump the SFDP data of a flash device.

More and more flash devices share the same flash ID and we need per device
fixups. Usually, these fixups differentiate flashes by looking at
differences in the SFDP data. Determining the difference is only possible
if we have the SFDP data for all the flashes which share a flash ID. This
will lay the foundation to dump the whole SFDP data of a flash device.

This is even more important, because some datasheets doesn't even contain
the SFDP data. Fixups for these kind of flashes are nearly impossible to
do.

I envision having a database of all the SFDP data for the flashes we
support and make it a requirement to submit it when a new flash is added.
This might or might not have legal implications. Thus I'd start with having
that database private to the SPI NOR maintainers.

There are two ways to provide access to the SFDP data:
 (1) We just read the SFDP data once and cache it
 (2) Any userspace access will always read the SFDP data

I choose (2) because it isn't as invasive as (1). The current SFDP code
reads the SFDP data only partially and only the part which are actually
used. Using (1) would mean to change that behavior.

Michael Walle (3):
  mtd: spi-nor: sfdp: remember sfdp_size
  mtd: spi-nor: sfdp: fix spi_nor_read_sfdp()
  mtd: spi-nor: add sysfs and SFDP support

 drivers/mtd/spi-nor/Makefile |  2 +-
 drivers/mtd/spi-nor/core.c   |  5 +++
 drivers/mtd/spi-nor/core.h   |  3 ++
 drivers/mtd/spi-nor/sfdp.c   | 24 +++++++++++-
 drivers/mtd/spi-nor/sfdp.h   |  2 +
 drivers/mtd/spi-nor/sysfs.c  | 73 ++++++++++++++++++++++++++++++++++++
 include/linux/mtd/spi-nor.h  |  1 +
 7 files changed, 107 insertions(+), 3 deletions(-)
 create mode 100644 drivers/mtd/spi-nor/sysfs.c

-- 
2.20.1


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

* [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size
  2021-03-12 19:05 [RFC PATCH 1/3] mtd: spi-nor: support dumping sfdp tables Michael Walle
@ 2021-03-12 19:05 ` Michael Walle
  2021-03-16 10:42   ` Pratyush Yadav
  2021-03-12 19:05 ` [RFC PATCH 2/3] mtd: spi-nor: sfdp: fix spi_nor_read_sfdp() Michael Walle
  2021-03-12 19:05 ` [RFC PATCH 3/3] mtd: spi-nor: add sysfs and SFDP support Michael Walle
  2 siblings, 1 reply; 11+ messages in thread
From: Michael Walle @ 2021-03-12 19:05 UTC (permalink / raw)
  To: linux-kernel, linux-mtd
  Cc: Tudor Ambarus, Pratyush Yadav, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Michael Walle

Save the sftp_size in the spi_nor struct so we can use it to dump the
SFDP table without parsing the headers again.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/mtd/spi-nor/sfdp.c  | 12 ++++++++++++
 include/linux/mtd/spi-nor.h |  1 +
 2 files changed, 13 insertions(+)

diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
index 25142ec4737b..b1814afefc33 100644
--- a/drivers/mtd/spi-nor/sfdp.c
+++ b/drivers/mtd/spi-nor/sfdp.c
@@ -16,6 +16,7 @@
 	(((p)->parameter_table_pointer[2] << 16) | \
 	 ((p)->parameter_table_pointer[1] <<  8) | \
 	 ((p)->parameter_table_pointer[0] <<  0))
+#define SFDP_PARAM_HEADER_PARAM_LEN(p) ((p)->length * 4)
 
 #define SFDP_BFPT_ID		0xff00	/* Basic Flash Parameter Table */
 #define SFDP_SECTOR_MAP_ID	0xff81	/* Sector Map Table */
@@ -1263,6 +1264,7 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
 	struct sfdp_parameter_header *param_headers = NULL;
 	struct sfdp_header header;
 	struct device *dev = nor->dev;
+	size_t param_max_offset;
 	size_t psize;
 	int i, err;
 
@@ -1285,6 +1287,9 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
 	    bfpt_header->major != SFDP_JESD216_MAJOR)
 		return -EINVAL;
 
+	nor->sfdp_size = SFDP_PARAM_HEADER_PTP(bfpt_header) +
+			 SFDP_PARAM_HEADER_PARAM_LEN(bfpt_header);
+
 	/*
 	 * Allocate memory then read all parameter headers with a single
 	 * Read SFDP command. These parameter headers will actually be parsed
@@ -1311,6 +1316,13 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
 		}
 	}
 
+	for (i = 0; i < header.nph; i++) {
+		param_header = &param_headers[i];
+		param_max_offset = SFDP_PARAM_HEADER_PTP(param_header) +
+				   SFDP_PARAM_HEADER_PARAM_LEN(param_header);
+		nor->sfdp_size = max(nor->sfdp_size, param_max_offset);
+	}
+
 	/*
 	 * Check other parameter headers to get the latest revision of
 	 * the basic flash parameter table.
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index a0d572855444..a58118b8b002 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -404,6 +404,7 @@ struct spi_nor {
 	bool			sst_write_second;
 	u32			flags;
 	enum spi_nor_cmd_ext	cmd_ext_type;
+	size_t			sfdp_size;
 
 	const struct spi_nor_controller_ops *controller_ops;
 
-- 
2.20.1


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

* [RFC PATCH 2/3] mtd: spi-nor: sfdp: fix spi_nor_read_sfdp()
  2021-03-12 19:05 [RFC PATCH 1/3] mtd: spi-nor: support dumping sfdp tables Michael Walle
  2021-03-12 19:05 ` [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size Michael Walle
@ 2021-03-12 19:05 ` Michael Walle
  2021-03-16 11:04   ` Pratyush Yadav
  2021-03-12 19:05 ` [RFC PATCH 3/3] mtd: spi-nor: add sysfs and SFDP support Michael Walle
  2 siblings, 1 reply; 11+ messages in thread
From: Michael Walle @ 2021-03-12 19:05 UTC (permalink / raw)
  To: linux-kernel, linux-mtd
  Cc: Tudor Ambarus, Pratyush Yadav, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Michael Walle

If spi_nor_read_sfdp() is used after probe, we have to set read_proto
and the read dirmap.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/mtd/spi-nor/sfdp.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
index b1814afefc33..47634ec9b899 100644
--- a/drivers/mtd/spi-nor/sfdp.c
+++ b/drivers/mtd/spi-nor/sfdp.c
@@ -179,19 +179,27 @@ static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr,
 			     size_t len, void *buf)
 {
 	u8 addr_width, read_opcode, read_dummy;
+	struct spi_mem_dirmap_desc *rdesc;
+	enum spi_nor_protocol read_proto;
 	int ret;
 
 	read_opcode = nor->read_opcode;
+	read_proto = nor->read_proto;
+	rdesc = nor->dirmap.rdesc;
 	addr_width = nor->addr_width;
 	read_dummy = nor->read_dummy;
 
 	nor->read_opcode = SPINOR_OP_RDSFDP;
+	nor->read_proto = SNOR_PROTO_1_1_1;
+	nor->dirmap.rdesc = NULL;
 	nor->addr_width = 3;
 	nor->read_dummy = 8;
 
 	ret = spi_nor_read_raw(nor, addr, len, buf);
 
 	nor->read_opcode = read_opcode;
+	nor->read_proto = read_proto;
+	nor->dirmap.rdesc = rdesc;
 	nor->addr_width = addr_width;
 	nor->read_dummy = read_dummy;
 
-- 
2.20.1


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

* [RFC PATCH 3/3] mtd: spi-nor: add sysfs and SFDP support
  2021-03-12 19:05 [RFC PATCH 1/3] mtd: spi-nor: support dumping sfdp tables Michael Walle
  2021-03-12 19:05 ` [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size Michael Walle
  2021-03-12 19:05 ` [RFC PATCH 2/3] mtd: spi-nor: sfdp: fix spi_nor_read_sfdp() Michael Walle
@ 2021-03-12 19:05 ` Michael Walle
  2 siblings, 0 replies; 11+ messages in thread
From: Michael Walle @ 2021-03-12 19:05 UTC (permalink / raw)
  To: linux-kernel, linux-mtd
  Cc: Tudor Ambarus, Pratyush Yadav, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Michael Walle

Add support to dump the SFDP table. Not all flashes list their SFDP
table contents in their datasheet. So having that is useful. It might
also be helpful in bug reports from users.

The idea behind the sysfs module is also to have raw access to the SPI
NOR flash device registers, which can also be useful for debugging.

Signed-off-by: Michael Walle <michael@walle.cc>
---
 drivers/mtd/spi-nor/Makefile |  2 +-
 drivers/mtd/spi-nor/core.c   |  5 +++
 drivers/mtd/spi-nor/core.h   |  3 ++
 drivers/mtd/spi-nor/sfdp.c   |  4 +-
 drivers/mtd/spi-nor/sfdp.h   |  2 +
 drivers/mtd/spi-nor/sysfs.c  | 73 ++++++++++++++++++++++++++++++++++++
 6 files changed, 86 insertions(+), 3 deletions(-)
 create mode 100644 drivers/mtd/spi-nor/sysfs.c

diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index 653923896205..aff308f75987 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 
-spi-nor-objs			:= core.o sfdp.o
+spi-nor-objs			:= core.o sfdp.o sysfs.o
 spi-nor-objs			+= atmel.o
 spi-nor-objs			+= catalyst.o
 spi-nor-objs			+= eon.o
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 4a315cb1c4db..2eaf4ba8c0f3 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3707,6 +3707,10 @@ static int spi_nor_probe(struct spi_mem *spimem)
 	if (ret)
 		return ret;
 
+	ret = spi_nor_sysfs_create(nor);
+	if (ret)
+		return ret;
+
 	return mtd_device_register(&nor->mtd, data ? data->parts : NULL,
 				   data ? data->nr_parts : 0);
 }
@@ -3716,6 +3720,7 @@ static int spi_nor_remove(struct spi_mem *spimem)
 	struct spi_nor *nor = spi_mem_get_drvdata(spimem);
 
 	spi_nor_restore(nor);
+	spi_nor_sysfs_remove(nor);
 
 	/* Clean up MTD stuff. */
 	return mtd_device_unregister(&nor->mtd);
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 4a3f7f150b5d..43c0d6eaf679 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -478,4 +478,7 @@ static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
 	return mtd->priv;
 }
 
+int spi_nor_sysfs_create(struct spi_nor *nor);
+void spi_nor_sysfs_remove(struct spi_nor *nor);
+
 #endif /* __LINUX_MTD_SPI_NOR_INTERNAL_H */
diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
index 47634ec9b899..62e58f14c197 100644
--- a/drivers/mtd/spi-nor/sfdp.c
+++ b/drivers/mtd/spi-nor/sfdp.c
@@ -219,8 +219,8 @@ static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr,
  * Return: -ENOMEM if kmalloc() fails, the return code of spi_nor_read_sfdp()
  *          otherwise.
  */
-static int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr,
-					size_t len, void *buf)
+int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr,
+				 size_t len, void *buf)
 {
 	void *dma_safe_buf;
 	int ret;
diff --git a/drivers/mtd/spi-nor/sfdp.h b/drivers/mtd/spi-nor/sfdp.h
index 89152ae1cf3e..11ce208e0cd7 100644
--- a/drivers/mtd/spi-nor/sfdp.h
+++ b/drivers/mtd/spi-nor/sfdp.h
@@ -109,5 +109,7 @@ struct sfdp_parameter_header {
 
 int spi_nor_parse_sfdp(struct spi_nor *nor,
 		       struct spi_nor_flash_parameter *params);
+int spi_nor_read_sfdp_dma_unsafe(struct spi_nor *nor, u32 addr,
+				 size_t len, void *buf);
 
 #endif /* __LINUX_MTD_SFDP_H */
diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c
new file mode 100644
index 000000000000..53641f964a2c
--- /dev/null
+++ b/drivers/mtd/spi-nor/sysfs.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/mtd/spi-nor.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
+#include <linux/sysfs.h>
+
+#include "core.h"
+
+static ssize_t sfdp_read(struct file *filp, struct kobject *kobj,
+			 struct bin_attribute *bin_attr, char *buf,
+			 loff_t off, size_t count)
+{
+	struct spi_device *spi = to_spi_device(kobj_to_dev(kobj));
+	struct spi_mem *spimem = spi_get_drvdata(spi);
+	struct spi_nor *nor = spi_mem_get_drvdata(spimem);
+	int ret;
+
+	ret = spi_nor_lock_and_prep(nor);
+	if (ret)
+		return ret;
+
+	if (off >= nor->sfdp_size) {
+		ret = 0;
+	} else {
+		if (off + count > nor->sfdp_size)
+			count = nor->sfdp_size - off;
+
+		ret = spi_nor_read_sfdp_dma_unsafe(nor, off, count, buf);
+		if (ret < 0)
+			ret = -EIO;
+		else
+			ret = count;
+	}
+
+	spi_nor_unlock_and_unprep(nor);
+	return ret;
+}
+static BIN_ATTR_RO(sfdp, PAGE_SIZE);
+
+static struct bin_attribute *spi_nor_sysfs_bin_entries[] = {
+	&bin_attr_sfdp,
+	NULL
+};
+
+static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj,
+					    struct bin_attribute *attr, int n)
+{
+	struct spi_device *spi = to_spi_device(kobj_to_dev(kobj));
+	struct spi_mem *spimem = spi_get_drvdata(spi);
+	struct spi_nor *nor = spi_mem_get_drvdata(spimem);
+
+	if (attr == &bin_attr_sfdp && !nor->sfdp_size)
+		return 0;
+
+	return 0400;
+}
+
+static struct attribute_group spi_nor_sysfs_attr_group = {
+	.name		= NULL,
+	.is_bin_visible	= spi_nor_sysfs_is_bin_visible,
+	.bin_attrs	= spi_nor_sysfs_bin_entries,
+};
+
+int spi_nor_sysfs_create(struct spi_nor *nor)
+{
+	return sysfs_create_group(&nor->dev->kobj, &spi_nor_sysfs_attr_group);
+}
+
+void spi_nor_sysfs_remove(struct spi_nor *nor)
+{
+	sysfs_remove_group(&nor->dev->kobj, &spi_nor_sysfs_attr_group);
+}
-- 
2.20.1


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

* Re: [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size
  2021-03-12 19:05 ` [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size Michael Walle
@ 2021-03-16 10:42   ` Pratyush Yadav
  2021-03-16 11:01     ` Michael Walle
  0 siblings, 1 reply; 11+ messages in thread
From: Pratyush Yadav @ 2021-03-16 10:42 UTC (permalink / raw)
  To: Michael Walle
  Cc: linux-kernel, linux-mtd, Tudor Ambarus, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra

On 12/03/21 08:05PM, Michael Walle wrote:
> Save the sftp_size in the spi_nor struct so we can use it to dump the
> SFDP table without parsing the headers again.
> 
> Signed-off-by: Michael Walle <michael@walle.cc>
> ---
>  drivers/mtd/spi-nor/sfdp.c  | 12 ++++++++++++
>  include/linux/mtd/spi-nor.h |  1 +
>  2 files changed, 13 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
> index 25142ec4737b..b1814afefc33 100644
> --- a/drivers/mtd/spi-nor/sfdp.c
> +++ b/drivers/mtd/spi-nor/sfdp.c
> @@ -16,6 +16,7 @@
>  	(((p)->parameter_table_pointer[2] << 16) | \
>  	 ((p)->parameter_table_pointer[1] <<  8) | \
>  	 ((p)->parameter_table_pointer[0] <<  0))
> +#define SFDP_PARAM_HEADER_PARAM_LEN(p) ((p)->length * 4)
>  
>  #define SFDP_BFPT_ID		0xff00	/* Basic Flash Parameter Table */
>  #define SFDP_SECTOR_MAP_ID	0xff81	/* Sector Map Table */
> @@ -1263,6 +1264,7 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
>  	struct sfdp_parameter_header *param_headers = NULL;
>  	struct sfdp_header header;
>  	struct device *dev = nor->dev;
> +	size_t param_max_offset;
>  	size_t psize;
>  	int i, err;
>  
> @@ -1285,6 +1287,9 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
>  	    bfpt_header->major != SFDP_JESD216_MAJOR)
>  		return -EINVAL;
>  
> +	nor->sfdp_size = SFDP_PARAM_HEADER_PTP(bfpt_header) +
> +			 SFDP_PARAM_HEADER_PARAM_LEN(bfpt_header);
> +
>  	/*
>  	 * Allocate memory then read all parameter headers with a single
>  	 * Read SFDP command. These parameter headers will actually be parsed
> @@ -1311,6 +1316,13 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
>  		}
>  	}
>  
> +	for (i = 0; i < header.nph; i++) {
> +		param_header = &param_headers[i];
> +		param_max_offset = SFDP_PARAM_HEADER_PTP(param_header) +
> +				   SFDP_PARAM_HEADER_PARAM_LEN(param_header);
> +		nor->sfdp_size = max(nor->sfdp_size, param_max_offset);
> +	}
> +

I don't see any mention in the SFDP spec (JESD216D-01) that parameter 
tables have to be contiguous. In fact, it says that "Parameter tables 
may be located anywhere in the SFDP space. They do not need to 
immediately follow the parameter headers". But I guess we can just say 
the sysfs entry exports the entire SFDP space instead of just the tables 
so that is OK.

This patch looks good to me other than the small nitpick that we can 
merge this loop and the one below that tries to find the latest BFPT 
version.

>  	/*
>  	 * Check other parameter headers to get the latest revision of
>  	 * the basic flash parameter table.
> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
> index a0d572855444..a58118b8b002 100644
> --- a/include/linux/mtd/spi-nor.h
> +++ b/include/linux/mtd/spi-nor.h
> @@ -404,6 +404,7 @@ struct spi_nor {
>  	bool			sst_write_second;
>  	u32			flags;
>  	enum spi_nor_cmd_ext	cmd_ext_type;
> +	size_t			sfdp_size;

Documentation for this variable missing.

>  
>  	const struct spi_nor_controller_ops *controller_ops;
>  
> -- 
> 2.20.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size
  2021-03-16 10:42   ` Pratyush Yadav
@ 2021-03-16 11:01     ` Michael Walle
  2021-03-16 11:06       ` Pratyush Yadav
  0 siblings, 1 reply; 11+ messages in thread
From: Michael Walle @ 2021-03-16 11:01 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: linux-kernel, linux-mtd, Tudor Ambarus, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra

Hi Pratyush,

Am 2021-03-16 11:42, schrieb Pratyush Yadav:
> On 12/03/21 08:05PM, Michael Walle wrote:
>> Save the sftp_size in the spi_nor struct so we can use it to dump the
>> SFDP table without parsing the headers again.
>> 
>> Signed-off-by: Michael Walle <michael@walle.cc>
>> ---
>>  drivers/mtd/spi-nor/sfdp.c  | 12 ++++++++++++
>>  include/linux/mtd/spi-nor.h |  1 +
>>  2 files changed, 13 insertions(+)
>> 
>> diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
>> index 25142ec4737b..b1814afefc33 100644
>> --- a/drivers/mtd/spi-nor/sfdp.c
>> +++ b/drivers/mtd/spi-nor/sfdp.c
>> @@ -16,6 +16,7 @@
>>  	(((p)->parameter_table_pointer[2] << 16) | \
>>  	 ((p)->parameter_table_pointer[1] <<  8) | \
>>  	 ((p)->parameter_table_pointer[0] <<  0))
>> +#define SFDP_PARAM_HEADER_PARAM_LEN(p) ((p)->length * 4)
>> 
>>  #define SFDP_BFPT_ID		0xff00	/* Basic Flash Parameter Table */
>>  #define SFDP_SECTOR_MAP_ID	0xff81	/* Sector Map Table */
>> @@ -1263,6 +1264,7 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
>>  	struct sfdp_parameter_header *param_headers = NULL;
>>  	struct sfdp_header header;
>>  	struct device *dev = nor->dev;
>> +	size_t param_max_offset;
>>  	size_t psize;
>>  	int i, err;
>> 
>> @@ -1285,6 +1287,9 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
>>  	    bfpt_header->major != SFDP_JESD216_MAJOR)
>>  		return -EINVAL;
>> 
>> +	nor->sfdp_size = SFDP_PARAM_HEADER_PTP(bfpt_header) +
>> +			 SFDP_PARAM_HEADER_PARAM_LEN(bfpt_header);
>> +
>>  	/*
>>  	 * Allocate memory then read all parameter headers with a single
>>  	 * Read SFDP command. These parameter headers will actually be 
>> parsed
>> @@ -1311,6 +1316,13 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
>>  		}
>>  	}
>> 
>> +	for (i = 0; i < header.nph; i++) {
>> +		param_header = &param_headers[i];
>> +		param_max_offset = SFDP_PARAM_HEADER_PTP(param_header) +
>> +				   SFDP_PARAM_HEADER_PARAM_LEN(param_header);
>> +		nor->sfdp_size = max(nor->sfdp_size, param_max_offset);
>> +	}
>> +
> 
> I don't see any mention in the SFDP spec (JESD216D-01) that parameter
> tables have to be contiguous.

ch. 6.1, fig.10 looks like all the headers come after the initial SFDP
header. If that wasn't the case, how would you find the headers then?

Also ch. 6.3
"""All subsequent parameter headers need to be contiguous and may be
specified..."""

> In fact, it says that "Parameter tables
> may be located anywhere in the SFDP space. They do not need to
> immediately follow the parameter headers".

The tables itself, yes, but not the headers for the tables.

> But I guess we can just say
> the sysfs entry exports the entire SFDP space instead of just the 
> tables
> so that is OK.
> 
> This patch looks good to me other than the small nitpick that we can
> merge this loop and the one below that tries to find the latest BFPT
> version.

btw. I've also added an export for the jedec id and the flash name to
this patch, which will be included in the next version.

>>  	/*
>>  	 * Check other parameter headers to get the latest revision of
>>  	 * the basic flash parameter table.
>> diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
>> index a0d572855444..a58118b8b002 100644
>> --- a/include/linux/mtd/spi-nor.h
>> +++ b/include/linux/mtd/spi-nor.h
>> @@ -404,6 +404,7 @@ struct spi_nor {
>>  	bool			sst_write_second;
>>  	u32			flags;
>>  	enum spi_nor_cmd_ext	cmd_ext_type;
>> +	size_t			sfdp_size;
> 
> Documentation for this variable missing.
> 
>> 
>>  	const struct spi_nor_controller_ops *controller_ops;
>> 
>> --
>> 2.20.1
>> 

-- 
-michael

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

* Re: [RFC PATCH 2/3] mtd: spi-nor: sfdp: fix spi_nor_read_sfdp()
  2021-03-12 19:05 ` [RFC PATCH 2/3] mtd: spi-nor: sfdp: fix spi_nor_read_sfdp() Michael Walle
@ 2021-03-16 11:04   ` Pratyush Yadav
  2021-03-16 11:15     ` Michael Walle
  0 siblings, 1 reply; 11+ messages in thread
From: Pratyush Yadav @ 2021-03-16 11:04 UTC (permalink / raw)
  To: Michael Walle
  Cc: linux-kernel, linux-mtd, Tudor Ambarus, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra

On 12/03/21 08:05PM, Michael Walle wrote:
> If spi_nor_read_sfdp() is used after probe, we have to set read_proto
> and the read dirmap.
> 
> Signed-off-by: Michael Walle <michael@walle.cc>
> ---
>  drivers/mtd/spi-nor/sfdp.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
> index b1814afefc33..47634ec9b899 100644
> --- a/drivers/mtd/spi-nor/sfdp.c
> +++ b/drivers/mtd/spi-nor/sfdp.c
> @@ -179,19 +179,27 @@ static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr,
>  			     size_t len, void *buf)
>  {
>  	u8 addr_width, read_opcode, read_dummy;
> +	struct spi_mem_dirmap_desc *rdesc;
> +	enum spi_nor_protocol read_proto;
>  	int ret;
>  
>  	read_opcode = nor->read_opcode;
> +	read_proto = nor->read_proto;
> +	rdesc = nor->dirmap.rdesc;
>  	addr_width = nor->addr_width;
>  	read_dummy = nor->read_dummy;
>  
>  	nor->read_opcode = SPINOR_OP_RDSFDP;
> +	nor->read_proto = SNOR_PROTO_1_1_1;
> +	nor->dirmap.rdesc = NULL;
>  	nor->addr_width = 3;
>  	nor->read_dummy = 8;

NACK. You can't assume the device is still in 1S-1S-1S mode after probe. 
For example, the s28hs512t flash is switched to 8D-8D-8D mode by the 
time the probe finishes so this would be an invalid command. Same for 
any flash that goes into a stateful mode.

And you can't even keep using nor->read_proto to read SFDP because the 
Read SFDP command might not be supported in all modes. xSPI spec 
(JESD251) says that the Read SFDP command is optional in 8D-8D-8D mode. 

I think the best approach for this would be to cache the entire SFDP 
table at parse time. This obviously comes with a memory overhead but I 
don't think it would be too big. For example, the sfdp table on 
s28hs512t is 491 bytes and it has 6 tables. Anyway, if the memory usage 
is too much of a problem we can put the feature behind a config.

>  
>  	ret = spi_nor_read_raw(nor, addr, len, buf);
>  
>  	nor->read_opcode = read_opcode;
> +	nor->read_proto = read_proto;
> +	nor->dirmap.rdesc = rdesc;
>  	nor->addr_width = addr_width;
>  	nor->read_dummy = read_dummy;
>  
> -- 
> 2.20.1
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size
  2021-03-16 11:01     ` Michael Walle
@ 2021-03-16 11:06       ` Pratyush Yadav
  2021-03-16 11:22         ` Michael Walle
  0 siblings, 1 reply; 11+ messages in thread
From: Pratyush Yadav @ 2021-03-16 11:06 UTC (permalink / raw)
  To: Michael Walle
  Cc: linux-kernel, linux-mtd, Tudor Ambarus, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra

On 16/03/21 12:01PM, Michael Walle wrote:
> Hi Pratyush,
> 
> Am 2021-03-16 11:42, schrieb Pratyush Yadav:
> > On 12/03/21 08:05PM, Michael Walle wrote:
> > > Save the sftp_size in the spi_nor struct so we can use it to dump the
> > > SFDP table without parsing the headers again.
> > > 
> > > Signed-off-by: Michael Walle <michael@walle.cc>
> > > ---
> > >  drivers/mtd/spi-nor/sfdp.c  | 12 ++++++++++++
> > >  include/linux/mtd/spi-nor.h |  1 +
> > >  2 files changed, 13 insertions(+)
> > > 
> > > diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
> > > index 25142ec4737b..b1814afefc33 100644
> > > --- a/drivers/mtd/spi-nor/sfdp.c
> > > +++ b/drivers/mtd/spi-nor/sfdp.c
> > > @@ -16,6 +16,7 @@
> > >  	(((p)->parameter_table_pointer[2] << 16) | \
> > >  	 ((p)->parameter_table_pointer[1] <<  8) | \
> > >  	 ((p)->parameter_table_pointer[0] <<  0))
> > > +#define SFDP_PARAM_HEADER_PARAM_LEN(p) ((p)->length * 4)
> > > 
> > >  #define SFDP_BFPT_ID		0xff00	/* Basic Flash Parameter Table */
> > >  #define SFDP_SECTOR_MAP_ID	0xff81	/* Sector Map Table */
> > > @@ -1263,6 +1264,7 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
> > >  	struct sfdp_parameter_header *param_headers = NULL;
> > >  	struct sfdp_header header;
> > >  	struct device *dev = nor->dev;
> > > +	size_t param_max_offset;
> > >  	size_t psize;
> > >  	int i, err;
> > > 
> > > @@ -1285,6 +1287,9 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
> > >  	    bfpt_header->major != SFDP_JESD216_MAJOR)
> > >  		return -EINVAL;
> > > 
> > > +	nor->sfdp_size = SFDP_PARAM_HEADER_PTP(bfpt_header) +
> > > +			 SFDP_PARAM_HEADER_PARAM_LEN(bfpt_header);
> > > +
> > >  	/*
> > >  	 * Allocate memory then read all parameter headers with a single
> > >  	 * Read SFDP command. These parameter headers will actually be
> > > parsed
> > > @@ -1311,6 +1316,13 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
> > >  		}
> > >  	}
> > > 
> > > +	for (i = 0; i < header.nph; i++) {
> > > +		param_header = &param_headers[i];
> > > +		param_max_offset = SFDP_PARAM_HEADER_PTP(param_header) +
> > > +				   SFDP_PARAM_HEADER_PARAM_LEN(param_header);
> > > +		nor->sfdp_size = max(nor->sfdp_size, param_max_offset);
> > > +	}
> > > +
> > 
> > I don't see any mention in the SFDP spec (JESD216D-01) that parameter
> > tables have to be contiguous.
> 
> ch. 6.1, fig.10 looks like all the headers come after the initial SFDP
> header. If that wasn't the case, how would you find the headers then?
> 
> Also ch. 6.3
> """All subsequent parameter headers need to be contiguous and may be
> specified..."""
> 
> > In fact, it says that "Parameter tables
> > may be located anywhere in the SFDP space. They do not need to
> > immediately follow the parameter headers".
> 
> The tables itself, yes, but not the headers for the tables.

Yes, I was talking about the tables and not the headers. There might be 
holes in the SFDP space but I don't think it would be a problem.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [RFC PATCH 2/3] mtd: spi-nor: sfdp: fix spi_nor_read_sfdp()
  2021-03-16 11:04   ` Pratyush Yadav
@ 2021-03-16 11:15     ` Michael Walle
  2021-03-16 13:15       ` Pratyush Yadav
  0 siblings, 1 reply; 11+ messages in thread
From: Michael Walle @ 2021-03-16 11:15 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: linux-kernel, linux-mtd, Tudor Ambarus, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra

Am 2021-03-16 12:04, schrieb Pratyush Yadav:
> On 12/03/21 08:05PM, Michael Walle wrote:
>> If spi_nor_read_sfdp() is used after probe, we have to set read_proto
>> and the read dirmap.
>> 
>> Signed-off-by: Michael Walle <michael@walle.cc>
>> ---
>>  drivers/mtd/spi-nor/sfdp.c | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>> 
>> diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
>> index b1814afefc33..47634ec9b899 100644
>> --- a/drivers/mtd/spi-nor/sfdp.c
>> +++ b/drivers/mtd/spi-nor/sfdp.c
>> @@ -179,19 +179,27 @@ static int spi_nor_read_sfdp(struct spi_nor 
>> *nor, u32 addr,
>>  			     size_t len, void *buf)
>>  {
>>  	u8 addr_width, read_opcode, read_dummy;
>> +	struct spi_mem_dirmap_desc *rdesc;
>> +	enum spi_nor_protocol read_proto;
>>  	int ret;
>> 
>>  	read_opcode = nor->read_opcode;
>> +	read_proto = nor->read_proto;
>> +	rdesc = nor->dirmap.rdesc;
>>  	addr_width = nor->addr_width;
>>  	read_dummy = nor->read_dummy;
>> 
>>  	nor->read_opcode = SPINOR_OP_RDSFDP;
>> +	nor->read_proto = SNOR_PROTO_1_1_1;
>> +	nor->dirmap.rdesc = NULL;
>>  	nor->addr_width = 3;
>>  	nor->read_dummy = 8;
> 
> NACK. You can't assume the device is still in 1S-1S-1S mode after 
> probe.
> For example, the s28hs512t flash is switched to 8D-8D-8D mode by the
> time the probe finishes so this would be an invalid command. Same for
> any flash that goes into a stateful mode.

I see.

> And you can't even keep using nor->read_proto to read SFDP because the
> Read SFDP command might not be supported in all modes. xSPI spec
> (JESD251) says that the Read SFDP command is optional in 8D-8D-8D mode.
> 
> I think the best approach for this would be to cache the entire SFDP
> table at parse time. This obviously comes with a memory overhead but I
> don't think it would be too big. For example, the sfdp table on
> s28hs512t is 491 bytes and it has 6 tables. Anyway, if the memory usage
> is too much of a problem we can put the feature behind a config.

I don't like to have it a config option, because then, if you really
need it, i.e. some user has an unknown flash, it might not be there.

The next question would be, should I leave the current parsing code
as is or should I also change that to use the sftp data cache. I'd
prefer to leave it as is.

-michael

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

* Re: [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size
  2021-03-16 11:06       ` Pratyush Yadav
@ 2021-03-16 11:22         ` Michael Walle
  0 siblings, 0 replies; 11+ messages in thread
From: Michael Walle @ 2021-03-16 11:22 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: linux-kernel, linux-mtd, Tudor Ambarus, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra

Am 2021-03-16 12:06, schrieb Pratyush Yadav:
> On 16/03/21 12:01PM, Michael Walle wrote:
>> Hi Pratyush,
>> 
>> Am 2021-03-16 11:42, schrieb Pratyush Yadav:
>> > On 12/03/21 08:05PM, Michael Walle wrote:
>> > > Save the sftp_size in the spi_nor struct so we can use it to dump the
>> > > SFDP table without parsing the headers again.
>> > >
>> > > Signed-off-by: Michael Walle <michael@walle.cc>
>> > > ---
>> > >  drivers/mtd/spi-nor/sfdp.c  | 12 ++++++++++++
>> > >  include/linux/mtd/spi-nor.h |  1 +
>> > >  2 files changed, 13 insertions(+)
>> > >
>> > > diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
>> > > index 25142ec4737b..b1814afefc33 100644
>> > > --- a/drivers/mtd/spi-nor/sfdp.c
>> > > +++ b/drivers/mtd/spi-nor/sfdp.c
>> > > @@ -16,6 +16,7 @@
>> > >  	(((p)->parameter_table_pointer[2] << 16) | \
>> > >  	 ((p)->parameter_table_pointer[1] <<  8) | \
>> > >  	 ((p)->parameter_table_pointer[0] <<  0))
>> > > +#define SFDP_PARAM_HEADER_PARAM_LEN(p) ((p)->length * 4)
>> > >
>> > >  #define SFDP_BFPT_ID		0xff00	/* Basic Flash Parameter Table */
>> > >  #define SFDP_SECTOR_MAP_ID	0xff81	/* Sector Map Table */
>> > > @@ -1263,6 +1264,7 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
>> > >  	struct sfdp_parameter_header *param_headers = NULL;
>> > >  	struct sfdp_header header;
>> > >  	struct device *dev = nor->dev;
>> > > +	size_t param_max_offset;
>> > >  	size_t psize;
>> > >  	int i, err;
>> > >
>> > > @@ -1285,6 +1287,9 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
>> > >  	    bfpt_header->major != SFDP_JESD216_MAJOR)
>> > >  		return -EINVAL;
>> > >
>> > > +	nor->sfdp_size = SFDP_PARAM_HEADER_PTP(bfpt_header) +
>> > > +			 SFDP_PARAM_HEADER_PARAM_LEN(bfpt_header);
>> > > +
>> > >  	/*
>> > >  	 * Allocate memory then read all parameter headers with a single
>> > >  	 * Read SFDP command. These parameter headers will actually be
>> > > parsed
>> > > @@ -1311,6 +1316,13 @@ int spi_nor_parse_sfdp(struct spi_nor *nor,
>> > >  		}
>> > >  	}
>> > >
>> > > +	for (i = 0; i < header.nph; i++) {
>> > > +		param_header = &param_headers[i];
>> > > +		param_max_offset = SFDP_PARAM_HEADER_PTP(param_header) +
>> > > +				   SFDP_PARAM_HEADER_PARAM_LEN(param_header);
>> > > +		nor->sfdp_size = max(nor->sfdp_size, param_max_offset);
>> > > +	}
>> > > +
>> >
>> > I don't see any mention in the SFDP spec (JESD216D-01) that parameter
>> > tables have to be contiguous.
>> 
>> ch. 6.1, fig.10 looks like all the headers come after the initial SFDP
>> header. If that wasn't the case, how would you find the headers then?
>> 
>> Also ch. 6.3
>> """All subsequent parameter headers need to be contiguous and may be
>> specified..."""
>> 
>> > In fact, it says that "Parameter tables
>> > may be located anywhere in the SFDP space. They do not need to
>> > immediately follow the parameter headers".
>> 
>> The tables itself, yes, but not the headers for the tables.
> 
> Yes, I was talking about the tables and not the headers. There might be
> holes in the SFDP space but I don't think it would be a problem.

Ah, ok. Well basically I'm assuming that the holes will returning some
sane values. Or you could dump the space together with a mask. But that
is overkill ;)

-michael

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

* Re: [RFC PATCH 2/3] mtd: spi-nor: sfdp: fix spi_nor_read_sfdp()
  2021-03-16 11:15     ` Michael Walle
@ 2021-03-16 13:15       ` Pratyush Yadav
  0 siblings, 0 replies; 11+ messages in thread
From: Pratyush Yadav @ 2021-03-16 13:15 UTC (permalink / raw)
  To: Michael Walle
  Cc: linux-kernel, linux-mtd, Tudor Ambarus, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra

On 16/03/21 12:15PM, Michael Walle wrote:
> Am 2021-03-16 12:04, schrieb Pratyush Yadav:
> > On 12/03/21 08:05PM, Michael Walle wrote:
> > > If spi_nor_read_sfdp() is used after probe, we have to set read_proto
> > > and the read dirmap.
> > > 
> > > Signed-off-by: Michael Walle <michael@walle.cc>
> > > ---
> > >  drivers/mtd/spi-nor/sfdp.c | 8 ++++++++
> > >  1 file changed, 8 insertions(+)
> > > 
> > > diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
> > > index b1814afefc33..47634ec9b899 100644
> > > --- a/drivers/mtd/spi-nor/sfdp.c
> > > +++ b/drivers/mtd/spi-nor/sfdp.c
> > > @@ -179,19 +179,27 @@ static int spi_nor_read_sfdp(struct spi_nor
> > > *nor, u32 addr,
> > >  			     size_t len, void *buf)
> > >  {
> > >  	u8 addr_width, read_opcode, read_dummy;
> > > +	struct spi_mem_dirmap_desc *rdesc;
> > > +	enum spi_nor_protocol read_proto;
> > >  	int ret;
> > > 
> > >  	read_opcode = nor->read_opcode;
> > > +	read_proto = nor->read_proto;
> > > +	rdesc = nor->dirmap.rdesc;
> > >  	addr_width = nor->addr_width;
> > >  	read_dummy = nor->read_dummy;
> > > 
> > >  	nor->read_opcode = SPINOR_OP_RDSFDP;
> > > +	nor->read_proto = SNOR_PROTO_1_1_1;
> > > +	nor->dirmap.rdesc = NULL;
> > >  	nor->addr_width = 3;
> > >  	nor->read_dummy = 8;
> > 
> > NACK. You can't assume the device is still in 1S-1S-1S mode after probe.
> > For example, the s28hs512t flash is switched to 8D-8D-8D mode by the
> > time the probe finishes so this would be an invalid command. Same for
> > any flash that goes into a stateful mode.
> 
> I see.
> 
> > And you can't even keep using nor->read_proto to read SFDP because the
> > Read SFDP command might not be supported in all modes. xSPI spec
> > (JESD251) says that the Read SFDP command is optional in 8D-8D-8D mode.
> > 
> > I think the best approach for this would be to cache the entire SFDP
> > table at parse time. This obviously comes with a memory overhead but I
> > don't think it would be too big. For example, the sfdp table on
> > s28hs512t is 491 bytes and it has 6 tables. Anyway, if the memory usage
> > is too much of a problem we can put the feature behind a config.
> 
> I don't like to have it a config option, because then, if you really
> need it, i.e. some user has an unknown flash, it might not be there.

Right. Then let's hope people don't mind us using up an extra half 
kilobyte or so.

> 
> The next question would be, should I leave the current parsing code
> as is or should I also change that to use the sftp data cache. I'd
> prefer to leave it as is.

For this series its fine if you leave it as is. But eventually it would 
be a good idea to convert all SFDP parsers to use the cache to reduce 
the number of SFDP reads and potentially speed up flash initialization a 
bit.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

end of thread, other threads:[~2021-03-16 13:16 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-12 19:05 [RFC PATCH 1/3] mtd: spi-nor: support dumping sfdp tables Michael Walle
2021-03-12 19:05 ` [RFC PATCH 1/3] mtd: spi-nor: sfdp: remember sfdp_size Michael Walle
2021-03-16 10:42   ` Pratyush Yadav
2021-03-16 11:01     ` Michael Walle
2021-03-16 11:06       ` Pratyush Yadav
2021-03-16 11:22         ` Michael Walle
2021-03-12 19:05 ` [RFC PATCH 2/3] mtd: spi-nor: sfdp: fix spi_nor_read_sfdp() Michael Walle
2021-03-16 11:04   ` Pratyush Yadav
2021-03-16 11:15     ` Michael Walle
2021-03-16 13:15       ` Pratyush Yadav
2021-03-12 19:05 ` [RFC PATCH 3/3] mtd: spi-nor: add sysfs and SFDP support Michael Walle

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