Enable access to SPI NOR flash on Samsung Snow board
Subsystems (7)
cover Enable access to SPI NOR flash on Samsung Snow board
Hello,
this patch series makes it possible to access the SPI NOR flash in the Samsung XE303 'Snow' Chromebook.
Unfortunately not all issues are resolved. To work around an issue with the pl330 dma engine I respun the patch for limiting transfer size in m25p80 driver.
As the flash does not contain any sane filesystem and is only likely to be accessed with mtd_debug or similar tool the limit of the dma engine is easily reached. Filesystems using shorter data transfers are less likely to be affected.
Thanks
Michal
Michal Suchanek (11):
ARM: dt: Add SPI CS on Samsung Snow board.
mtd: spi-nor: Add GD25LQ32C 1.8V SPI NOR flash ID
mtd: add debug prints to mtdpart partition parser.
mtd: ofpart: do not fail probe when no partitions exist
mtd: mtdpart: Do not fail mtd probe when parsing partitions fails.
mtd: spi-nor: rework spi nor read and write.
mtd: spi-nor: rework write loop
MTD: m25p80: Add option to limit SPI transfer size.
dma: pl330: fix wording in mcbufsz message
spi: add more debug prints in s3c64xx
dt: Exynos: add Snow SPI NOR node.
.../devicetree/bindings/mtd/jedec,spi-nor.txt | 6 ++ arch/arm/boot/dts/exynos5250-snow.dts | 15 +++- drivers/dma/pl330.c | 4 +- drivers/mtd/devices/m25p80.c | 57 +++++++++++---- drivers/mtd/mtdpart.c | 9 ++- drivers/mtd/ofpart.c | 4 +- drivers/mtd/spi-nor/fsl-quadspi.c | 29 ++++---- drivers/mtd/spi-nor/spi-nor.c | 80 ++++++++++++---------- drivers/spi/spi-s3c64xx.c | 30 ++++++++ include/linux/mtd/spi-nor.h | 8 +-- 10 files changed, 166 insertions(+), 76 deletions(-)
Signature · 1 line
2.1.4
PATCH 1/11 ARM: dt: Add SPI CS on Samsung Snow board.
Although there is only one choice of chipselect it is necessary to specify it. The driver cannot claim the gpio otherwise.
--- arch/arm/boot/dts/exynos5250-snow.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/boot/dts/exynos5250-snow.dts +2 -1
@@ -687,9 +687,10 @@ }; &spi_1 { - status = "okay"; samsung,spi-src-clk = <0>; num-cs = <1>; + cs-gpios = <&gpa2 5 0>; + status = "okay"; }; &usbdrd_dwc3 {
Signature · 1 line
2.1.4
Re: [PATCH 01/11] ARM: dt: Add SPI CS on Samsung Snow board.
Quoted 7 lines · Michal Suchanek
Although there is only one choice of chipselect it is necessary to specify it. The driver cannot claim the gpio otherwise.
Signed-off-by Michal Suchanek <[email protected]>--- arch/arm/boot/dts/exynos5250-snow.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Best regards,
Krzysztof
A message that is not in the archive (sent off-list or not yet received): d47abe28c751b54b839d9340269a2c06a6e23a6c.1433364398.git.hramrach-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Krzysztof Kozlowski
Acked-byRe: [PATCH 01/11] ARM: dt: Add SPI CS on Samsung Snow board.
Quoted 7 lines · Michal Suchanek
Although there is only one choice of chipselect it is necessary to specify it. The driver cannot claim the gpio otherwise.
Signed-off-by Michal Suchanek <[email protected]>--- arch/arm/boot/dts/exynos5250-snow.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Best regards,
Krzysztof
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/11] ARM: dt: Add SPI CS on Samsung Snow board.
In reply to Michal SuchanekQuoted 7 lines · Michal Suchanek
Although there is only one choice of chipselect it is necessary to specify it. The driver cannot claim the gpio otherwise.
Signed-off-by Michal Suchanek <[email protected]>--- arch/arm/boot/dts/exynos5250-snow.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
Best regards,
Krzysztof
Re: [PATCH 01/11] ARM: dt: Add SPI CS on Samsung Snow board.
In reply to Michal SuchanekHello Michal,
Quoted 13 lines · Michal Suchanek
Although there is only one choice of chipselect it is necessary to specify it. The driver cannot claim the gpio otherwise.
Signed-off-by Michal Suchanek <[email protected]>--- arch/arm/boot/dts/exynos5250-snow.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)arch/arm/boot/dts/exynos5250-snow.dts +0
-0
arch/arm/boot/dts/exynos5250-snow.dts line 693
Quoted 8 lines
arch/arm/boot/dts/exynos5250-snow.dts +2
-1@@ -687,9 +687,10 @@ }; &spi_1 { - status = "okay"; samsung,spi-src-clk = <0>; num-cs = <1>; + cs-gpios = <&gpa2 5 0>; + status = "okay";
Why are you changing the position of the status property? AFAIK the convention is to have this property at the beginning of the device node.
Best regards,
Javier
PATCH 2/11 mtd: spi-nor: Add GD25LQ32C 1.8V SPI NOR flash ID
In reply to Michal SuchanekThis 1.8V SPI NOR flash is found on ARM Chromebook XE303C and reads something like 25LQ32VIG in the middle.
--- drivers/mtd/spi-nor/spi-nor.c | 1 + 1 file changed, 1 insertion(+)
drivers/mtd/spi-nor/spi-nor.c +1 -0
@@ -552,6 +552,7 @@ static const struct spi_device_id spi_nor_ids[] = {/* GigaDevice */ { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) }, + { "gd25lq32c", INFO(0xc86016, 0, 64 * 1024, 64, SECT_4K) }, { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) }, { "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, SECT_4K) },
Signature · 1 line
2.1.4
PATCH 3/11 mtd: add debug prints to mtdpart partition parser.
In reply to Michal SuchanekThe probe of a mtd device can fail when a partition parser returns error. The failure due to partition parsing can be quite mysterious when multiple partitioning schemes are comiled in and any of them can fail the probe.
Add debug prints which show what parsers were tried and what they returned.
--- drivers/mtd/mtdpart.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/mtd/mtdpart.c +4 -0
@@ -759,12 +759,16 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, types = default_mtd_part_types;for ( ; ret <=0 && *types; types++) { +pr_debug ("Parsing partitions %s on %s" , *types, master->name); parser =get_partition_parser (*types);if (!parser && !request_module ("%s" , *types)) parser =get_partition_parser (*types); +pr_debug ("%s got parser %s" , master->name, + parser ? parser->name :NULL );if (!parser)continue ; ret = (*parser->parse_fn)(master, pparts, data); +pr_debug ("%s parser %s: %i" , master->name, parser->name, ret);put_partition_parser (parser);if (ret >0 ) { printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
Signature · 1 line
2.1.4
PATCH 4/11 mtd: ofpart: do not fail probe when no partitions exist
In reply to Michal SuchanekOn Exynos it is necessary to set SPI controller parameters that apply to a SPI slave in a DT subnode of the slave device. The ofpart code returns an error when there are subnodes of the SPI flash but no partitions are found. Change this condition to a warning so that flash without partitions can be accessed on Exynos.
--- drivers/mtd/ofpart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mtd/ofpart.c +2 -2
@@ -94,10 +94,10 @@ static int parse_ofpart_partitions(struct mtd_info *master,if (!i) {of_node_put (pp); -pr_err ("No valid partition found on %s\n" , node->full_name); +pr_warn ("No valid partition found on %s\n" , node->full_name);kfree (*pparts); *pparts =NULL ; -return -EINVAL ; +return 0 ; }return nr_parts;
Signature · 1 line
2.1.4
Re: [PATCH 04/11] mtd: ofpart: do not fail probe when no partitions exist
Quoted 5 lines · Michal Suchanek
On Exynos it is necessary to set SPI controller parameters that apply to a SPI slave in a DT subnode of the slave device. The ofpart code returns an error when there are subnodes of the SPI flash but no partitions are found. Change this condition to a warning so that flash without partitions can be accessed on Exynos.
I have to admit the rationale for this patch is not very clear to me, sorry. Can you please explain this a bit more ?
Best regards,
Marek Vasut
Re: [PATCH 04/11] mtd: ofpart: do not fail probe when no partitions exist
Quoted 9 lines · Marek Vasut
Quoted 5 lines · Michal Suchanek
On Exynos it is necessary to set SPI controller parameters that apply to a SPI slave in a DT subnode of the slave device. The ofpart code returns an error when there are subnodes of the SPI flash but no partitions are found. Change this condition to a warning so that flash without partitions can be accessed on Exynos.
I have to admit the rationale for this patch is not very clear to me, sorry. Can you please explain this a bit more ?
This is how the DT entry for SPI slave looks with s3c64xx:
flash: m25p80 at 0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <40000000>;
linux,max_tx_len = <65536>;
m25p,fast-read;
controller-data {
samsung,spi-feedback-delay = <0>;
};
};this is example of flash partitions:
flash at 0 {
#address-cells = <1>;
#size-cells = <1>;
partition at 0 {
label = "u-boot";
reg = <0x0000000 0x100000>;
read-only;
};
uimage at 100000 {
reg = <0x0100000 0x200000>;
};
};The parser ignores any flash without subnodes and returns 0 (no partititon). When there is a subnode it assumes the flash is partitioned and tries to parse the subnodes as partitions. When there are subnodes and none parses as partition an error is returned. As shown above it is valid to have subnodes on unpartitioned flash.
When an error is returned from a partition parser the mtdpart code passes on this error to the flash probe function and the proble of the flash fails.
Thanks
Michal
Re: [PATCH 04/11] mtd: ofpart: do not fail probe when no partitions exist
Quoted 11 lines · Michal Suchanek
Quoted 9 lines · Marek Vasut
Quoted 5 lines · Michal Suchanek
On Exynos it is necessary to set SPI controller parameters that apply to a SPI slave in a DT subnode of the slave device. The ofpart code returns an error when there are subnodes of the SPI flash but no partitions are found. Change this condition to a warning so that flash without partitions can be accessed on Exynos.
I have to admit the rationale for this patch is not very clear to me, sorry. Can you please explain this a bit more ?
Quoted 8 lines
This is how the DT entry for SPI slave looks with s3c64xx:
flash: m25p80 at 0 { #address-cells = <1>; #size-cells = <1>; compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; linux,max_tx_len = <65536>;
SIDENOTE: I thought this was actually added by your patch #8 in this series. The underscores in the name of the property are not really consistent with the rest of the names.
Quoted 28 lines
m25p,fast-read; controller-data { samsung,spi-feedback-delay = <0>; }; };this is example of flash partitions:
flash at 0 { #address-cells = <1>; #size-cells = <1>; partition at 0 { label = "u-boot"; reg = <0x0000000 0x100000>; read-only; }; uimage at 100000 { reg = <0x0100000 0x200000>; }; };The parser ignores any flash without subnodes and returns 0 (no partititon). When there is a subnode it assumes the flash is partitioned and tries to parse the subnodes as partitions. When there are subnodes and none parses as partition an error is returned. As shown above it is valid to have subnodes on unpartitioned flash.
Quoted 3 lines
When an error is returned from a partition parser the mtdpart code passes on this error to the flash probe function and the proble of the flash fails.
What does /proc/mtd tell you when you have no partitions defined in the DT ? It should provide you with the entire MTD device and the code shouldn't even try to parse any OF partitions, since you don't have any.
Best regards,
Marek Vasut
Re: [PATCH 04/11] mtd: ofpart: do not fail probe when no partitions exist
Quoted 53 lines · Marek Vasut
Quoted 11 lines · Michal Suchanek
Quoted 9 lines · Marek Vasut
Quoted 5 lines · Michal Suchanek
On Exynos it is necessary to set SPI controller parameters that apply to a SPI slave in a DT subnode of the slave device. The ofpart code returns an error when there are subnodes of the SPI flash but no partitions are found. Change this condition to a warning so that flash without partitions can be accessed on Exynos.
I have to admit the rationale for this patch is not very clear to me, sorry. Can you please explain this a bit more ?
Quoted 8 lines
This is how the DT entry for SPI slave looks with s3c64xx:
flash: m25p80 at 0 { #address-cells = <1>; #size-cells = <1>; compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; linux,max_tx_len = <65536>;SIDENOTE: I thought this was actually added by your patch #8 in this series. The underscores in the name of the property are not really consistent with the rest of the names.
Quoted 28 lines
m25p,fast-read; controller-data { samsung,spi-feedback-delay = <0>; }; };this is example of flash partitions:
flash at 0 { #address-cells = <1>; #size-cells = <1>; partition at 0 { label = "u-boot"; reg = <0x0000000 0x100000>; read-only; }; uimage at 100000 { reg = <0x0100000 0x200000>; }; };The parser ignores any flash without subnodes and returns 0 (no partititon). When there is a subnode it assumes the flash is partitioned and tries to parse the subnodes as partitions. When there are subnodes and none parses as partition an error is returned. As shown above it is valid to have subnodes on unpartitioned flash.
Quoted 8 lines
Quoted 3 lines
When an error is returned from a partition parser the mtdpart code passes on this error to the flash probe function and the proble of the flash fails.
What does
/proc/mtdtell you when you have no partitions defined in the DT ? It should provide you with the entire MTD device and the code shouldn't even try to parse any OF partitions, since you don't have any.
mtdinfo shows I have no mtd devices and the log shows that probe failed unless I patch the kernel.
When there is *support* for of partitions the ofparser is run on mtd probe. If it fails because it considers
Quoted 3 lines
Quoted 3 lines
controller-data { samsung,spi-feedback-delay = <0>; };
an invalid partition and does not find any valid partition the probe fails.
There are two problems here
1) the above is not invalid. It just is not a partition. The parser should not fail seeing this
2) the mtd probe should not fail when a partition parser fails and should present the unpartitioned device
Both are addressed in separate patches.
Thanks
Michal
Re: [PATCH 04/11] mtd: ofpart: do not fail probe when no partitions exist
Quoted 79 lines · Michal Suchanek
Quoted 63 lines · Marek Vasut
Quoted 14 lines · Michal Suchanek
Quoted 9 lines · Marek Vasut
Quoted 5 lines · Michal Suchanek
On Exynos it is necessary to set SPI controller parameters that apply to a SPI slave in a DT subnode of the slave device. The ofpart code returns an error when there are subnodes of the SPI flash but no partitions are found. Change this condition to a warning so that flash without partitions can be accessed on Exynos.
I have to admit the rationale for this patch is not very clear to me, sorry. Can you please explain this a bit more ?
This is how the DT entry for SPI slave looks with s3c64xx:
flash: m25p80 at 0 {Quoted 6 lines
#address-cells = <1>; #size-cells = <1>; compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; linux,max_tx_len = <65536>;SIDENOTE: I thought this was actually added by your patch #8 in this series. The underscores in the name of the property are not really consistent with the rest of the names.
Quoted 37 lines
m25p,fast-read; controller-data { samsung,spi-feedback-delay = <0>; }; };this is example of flash partitions:
flash at 0 {#address-cells = <1>; #size-cells = <1>; partition at 0 { label = "u-boot"; reg = <0x0000000 0x100000>; read-only; }; uimage at 100000 { reg = <0x0100000 0x200000>; };};
The parser ignores any flash without subnodes and returns 0 (no partititon). When there is a subnode it assumes the flash is partitioned and tries to parse the subnodes as partitions. When there are subnodes and none parses as partition an error is returned. As shown above it is valid to have subnodes on unpartitioned flash.
Quoted 8 lines
Quoted 3 lines
When an error is returned from a partition parser the mtdpart code passes on this error to the flash probe function and the proble of the flash fails.
What does
/proc/mtdtell you when you have no partitions defined in the DT ? It should provide you with the entire MTD device and the code shouldn't even try to parse any OF partitions, since you don't have any.mtdinfo shows I have no mtd devices and the log shows that probe failed unless I patch the kernel.
When there is *support* for of partitions the ofparser is run on mtd probe. If it fails because it considers
Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
controller-data { samsung,spi-feedback-delay = <0>; };an invalid partition and does not find any valid partition the probe fails.
OK, now it has become clearer to me, thanks!
Quoted 4 lines
There are two problems here
1) the above is not invalid. It just is not a partition. The parser should not fail seeing this
The parser should complain verbosely and ignore this I guess ?
Quoted 2 lines
2) the mtd probe should not fail when a partition parser fails and should present the unpartitioned device
OK
Quoted 5 lines
Both are addressed in separate patches.
Thanks
Michal
Re: [PATCH 04/11] mtd: ofpart: do not fail probe when no partitions exist
In reply to Michal SuchanekQuoted 5 lines · Michal Suchanek
On Exynos it is necessary to set SPI controller parameters that apply to a SPI slave in a DT subnode of the slave device. The ofpart code returns an error when there are subnodes of the SPI flash but no partitions are found. Change this condition to a warning so that flash without partitions can be accessed on Exynos.
So judging by the subsequent discussion, you're looking at handling nodes like this:
flash at ... {
compatible = "m25p80";
...
controller-data {
samsung,spi-feedback-delay = <0>;
};
};Now, I'm not a real fan of this controller-data node in the first place (did that binding get reviewed?). But this is especially bad since we now have collisions on what to do with subnodes that don't have a compatible property. By legacy, ofpart has already claimed ownership of subnodes of an MTD node, where the subnode does not have a compatible property. See Documentation/devicetree/bindings/mtd/partition.txt:
"NOTE: if the sub-node has a compatible string, then it is not a partition."
So it seems the natural solution is to just define a proper compatibile property for this subnode, and ofpart.c will naturally handle this. See:
commit e79265ba6bdb31437bd4c3e7911950f9d1262a07
Author: Josh Wu <[email protected]> Date: Mon Aug 5 19:14:38 2013 +0800
mtd: ofpart: add compatible check for child nodes
Brian
Quoted 25 lines
Signed-off-by Michal Suchanek <[email protected]>--- drivers/mtd/ofpart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/mtd/ofpart.c +2
-2@@ -94,10 +94,10 @@ static int parse_ofpart_partitions(struct mtd_info *master,if (!i) {of_node_put (pp); -pr_err ("No valid partition found on %s\n" , node->full_name); +pr_warn ("No valid partition found on %s\n" , node->full_name);kfree (*pparts); *pparts =NULL ; -return -EINVAL ; +return 0 ; }return nr_parts;Signature · 1 line
2.1.4
PATCH 5/11 mtd: mtdpart: Do not fail mtd probe when parsing partitions fails.
In reply to Michal SuchanekDue to wrong assumption in ofpart ofpart fails on Exynos on SPI chips with no partitions because the subnode containing controller data confuses the ofpart parser.
Thus compiling in ofpart support automatically fails probing any SPI NOR flash without partitions on Exynos. Compiling in a partitioning scheme should not cause probe of otherwise valid device to fail.
Remove that failure possibility.
--- drivers/mtd/mtdpart.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/mtd/mtdpart.c +2 -3
@@ -743,7 +743,6 @@ static const char * const default_mtd_part_types[] = {* partitions parsed out by the first parser. * * This function may return: -* o a negative error code in case of failure * o zero if no partitions were found * o a positive number of found partitions, in which case on exit @pparts will * point to an array containing this number of &struct mtd_info objects.
@@ -773,10 +772,10 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,if (ret >0 ) {printk (KERN_NOTICE "%d %s partitions found on MTD device %s\n" , ret, parser->name, master->name); -break ; +return ret; } } -return ret; +return 0 ; }int mtd_is_partition (const struct mtd_info *mtd)
Signature · 1 line
2.1.4
PATCH 6/11 mtd: spi-nor: rework spi nor read and write.
In reply to Michal SuchanekThe spi_nor read and write functions pass thru the mtd retlen to the chip-specific read and write function. This makes it difficult to check for errors in read and write functions and these errors are not checked. This leads to silent data corruption.
This patch styles the chip-specific read and write function as unix read(2) and write(2) and updates the retlen in the spi-nor generic driver.
This also makes it possible to check for write errors. When pl330 fails to transfer the flash data over SPI I get I/O error instead of 4M of zeroes.
I do not have sst and fsl hardware to test with.
--- drivers/mtd/devices/m25p80.c | 33 ++++++++++++++--------- drivers/mtd/spi-nor/fsl-quadspi.c | 29 ++++++++++---------- drivers/mtd/spi-nor/spi-nor.c | 57 ++++++++++++++++++++++++++++----------- include/linux/mtd/spi-nor.h | 8 +++--- 4 files changed, 81 insertions(+), 46 deletions(-)
drivers/mtd/devices/m25p80.c +21 -12
@@ -75,14 +75,15 @@ static int m25p80_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len,return spi_write (spi, flash->command, len +1 ); } -static void m25p80_write (struct spi_nor *nor,loff_t to,size_t len, -size_t *retlen,const u_char *buf) +static ssize_t m25p80_write (struct spi_nor *nor,loff_t to,size_t len, +const u_char *buf) {struct m25p *flash = nor->priv;struct spi_device *spi = flash->spi;struct spi_transfer t[2 ] = {};struct spi_message m;int cmd_sz =m25p_cmdsz (nor); +ssize_t ret;spi_message_init (&m);
@@ -100,9 +101,14 @@ static void m25p80_write(struct spi_nor *nor, loff_t to, size_t len, t[1 ].len = len;spi_message_add_tail (&t[1 ], &m); -spi_sync (spi, &m); + ret =spi_sync (spi, &m); +if (ret) +return ret; - *retlen += m.actual_length - cmd_sz; + ret = m.actual_length - cmd_sz; +if (ret <0 ) +return -EIO ; +return ret; }static inline unsigned int m25p80_rx_nbits (struct spi_nor *nor)
@@ -121,14 +127,15 @@ static inline unsigned int m25p80_rx_nbits(struct spi_nor *nor)* Read an address range from the nor chip. The address range * may be any size provided it is within the physical boundaries. */ -static int m25p80_read (struct spi_nor *nor,loff_t from,size_t len, -size_t *retlen,u_char *buf) +static ssize_t m25p80_read (struct spi_nor *nor,loff_t from,size_t len, +u_char *buf) {struct m25p *flash = nor->priv;struct spi_device *spi = flash->spi;struct spi_transfer t[2 ];struct spi_message m;unsigned int dummy = nor->read_dummy; +ssize_t ret;/* convert the dummy cycles to the number of bytes */ dummy /=8 ;
@@ -148,10 +155,14 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len, t[1 ].len = len;spi_message_add_tail (&t[1 ], &m); -spi_sync (spi, &m); + ret =spi_sync (spi, &m); +if (ret) +return ret; - *retlen = m.actual_length -m25p_cmdsz (nor) - dummy; -return 0 ; + ret = m.actual_length -m25p_cmdsz (nor) - dummy; +if (ret <0 ) +return -EIO ; +return ret; }static int m25p80_erase (struct spi_nor *nor,loff_t offset)
@@ -165,9 +176,7 @@ static int m25p80_erase(struct spi_nor *nor, loff_t offset) flash->command[0 ] = nor->erase_opcode;m25p_addr2cmd (nor, offset, flash->command); -spi_write (flash->spi, flash->command,m25p_cmdsz (nor)); - -return 0 ; +return spi_write (flash->spi, flash->command,m25p_cmdsz (nor)); }/*
drivers/mtd/spi-nor/fsl-quadspi.c +15 -14
@@ -525,9 +525,9 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q)writel (reg, q->iobase +QUADSPI_MCR ); } -static int fsl_qspi_nor_write (struct fsl_qspi *q,struct spi_nor *nor, +static ssize_t fsl_qspi_nor_write (struct fsl_qspi *q,struct spi_nor *nor,u8 opcode,unsigned int to,u32 *txbuf, -unsigned count,size_t *retlen) +unsigned count) {int ret, i, j;u32 tmp;
@@ -549,8 +549,8 @@ static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,/* Trigger it */ ret =fsl_qspi_runcmd (q, opcode, to, count); -if (ret ==0 && retlen) - *retlen += count; +if (ret ==0 ) +return count;return ret; }
@@ -703,7 +703,9 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len, }else if (len >0 ) { ret =fsl_qspi_nor_write (q, nor, opcode,0 , - (u32 *)buf, len,NULL ); + (u32 *)buf, len); +if (ret >0 ) +return 0 ; }else {dev_err (q->dev,"invalid cmd %d\n" , opcode); ret = -EINVAL ;
@@ -712,20 +714,20 @@ static int fsl_qspi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len,return ret; } -static void fsl_qspi_write (struct spi_nor *nor,loff_t to, -size_t len,size_t *retlen,const u_char *buf) +static ssize_t fsl_qspi_write (struct spi_nor *nor,loff_t to, +size_t len,const u_char *buf) {struct fsl_qspi *q = nor->priv; - -fsl_qspi_nor_write (q, nor, nor->program_opcode, to, - (u32 *)buf, len, retlen); +ssize_t ret =fsl_qspi_nor_write (q, nor, nor->program_opcode, to, + (u32 *)buf, len);/* invalid the data in the AHB buffer. */ fsl_qspi_invalid (q); +return ret; } -static int fsl_qspi_read (struct spi_nor *nor,loff_t from, -size_t len,size_t *retlen,u_char *buf) +static ssize_t fsl_qspi_read (struct spi_nor *nor,loff_t from, +size_t len,u_char *buf) {struct fsl_qspi *q = nor->priv;u8 cmd = nor->read_opcode;
@@ -736,8 +738,7 @@ static int fsl_qspi_read(struct spi_nor *nor, loff_t from,/* Read out the data directly from the AHB buffer.*/ memcpy (buf, q->ahb_base + q->chip_base_addr + from, len); - *retlen += len; -return 0 ; +return len; }static int fsl_qspi_erase (struct spi_nor *nor,loff_t offs)
drivers/mtd/spi-nor/spi-nor.c +41 -16
115 lines not on this page · raw message
include/linux/mtd/spi-nor.h +4 -4
@@ -185,10 +185,10 @@ struct spi_nor {int (*write_reg)(struct spi_nor *nor,u8 opcode,u8 *buf,int len,int write_enable); -int (*read)(struct spi_nor *nor,loff_t from, -size_t len,size_t *retlen,u_char *read_buf); -void (*write)(struct spi_nor *nor,loff_t to, -size_t len,size_t *retlen,const u_char *write_buf); +ssize_t (*read)(struct spi_nor *nor,loff_t from, +size_t len,u_char *read_buf); +ssize_t (*write)(struct spi_nor *nor,loff_t to, +size_t len,const u_char *write_buf);int (*erase)(struct spi_nor *nor,loff_t offs);int (*flash_lock)(struct spi_nor *nor,loff_t ofs,uint64_t len);
Signature · 1 line
2.1.4
PATCH 7/11 mtd: spi-nor: rework write loop
In reply to Michal SuchanekThe write loop assumes that what is passed to write() is what gets written. When write() writes less than page size at once data is dropped on the floor. Check the amount of data writen.
--- drivers/mtd/spi-nor/spi-nor.c | 48 ++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 33 deletions(-)
drivers/mtd/spi-nor/spi-nor.c +15 -33
@@ -823,7 +823,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { struct spi_nor *nor = mtd_to_spi_nor(mtd); -u32 page_offset, page_size, i; +size_t page_offset, page_remain, i;int ret;dev_dbg (nor->dev,"to 0x%08x, len %zd\n" , (u32 )to, len);
@@ -832,45 +832,27 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,if (ret)return ret; -write_enable (nor); - - page_offset = to & (nor->page_size -1 ); +for (i =0 ; i < len; ) { +int written; -/* do all the bytes fit onto one page? */ -if (page_offset + len <= nor->page_size) { - ret = nor->write (nor, to, len, buf); -if (ret <0 ) - goto write_err; - *retlen += ret; - }else { + page_offset = to & (nor->page_size -1 );/* the size of data remaining on the first page */ - page_size = nor->page_size - page_offset; - nor->write (nor, to, page_size, buf); + page_remain =min_t (size_t, + nor->page_size - page_offset, len - i); + +write_enable (nor); + ret = nor->write (nor, to + i, page_remain, buf + i);if (ret <0 ) goto write_err; - *retlen += ret; - -/* write everything in nor->page_size chunks */ -for (i = ret; i < len; ) { - page_size = len - i; -if (page_size > nor->page_size) - page_size = nor->page_size; - - ret =spi_nor_wait_till_ready (nor); -if (ret) - goto write_err; + written = ret; -write_enable (nor); - - ret = nor->write (nor, to + i, page_size, buf + i); -if (ret <0 ) - goto write_err; - *retlen += ret; - i += ret; - } + ret =spi_nor_wait_till_ready (nor); +if (ret) + goto write_err; + *retlen += written; + i += written; } - ret =spi_nor_wait_till_ready (nor); write_err:spi_nor_unlock_and_unprep (nor,SPI_NOR_OPS_WRITE );return ret;
Signature · 1 line
2.1.4
PATCH 8/11 MTD: m25p80: Add option to limit SPI transfer size.
In reply to Michal SuchanekOn sunxi the SPI controller currently does not have DMA support and fails any transfer larger than 63 bytes.
On Exynos the pl330 DMA controller fails any transfer larger than 64kb when using slower speed like 40MHz and any transfer larger than 128bytes when running at 133MHz.
The best thing is that in both cases the controller can just lock up and never finish potentially leaving the hardware in unusable state.
So it is required that the m25p80 driver actively prevents doing transfers that are too large for the current driver state on a particular piece of hardware.
--
Update commit message and documentation text.
--- .../devicetree/bindings/mtd/jedec,spi-nor.txt | 6 ++++++ drivers/mtd/devices/m25p80.c | 24 ++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +6 -0
@@ -19,6 +19,12 @@ Optional properties: all chips and support for it can not be detected at runtime. Refer to your chips' datasheet to check if this is supported by your chip. +- linux,max_tx_len : With some SPI controller drivers possible transfer size is + limited. This may be hardware or driver bug. + Transfer data in chunks no larger than this value. + Using this option may severely degrade performance and + possibly flash memory life when max_tx_len is smaller than + flash page size (typically 256 bytes) Example:
drivers/mtd/devices/m25p80.c +22 -2
@@ -26,12 +26,14 @@#include <linux/spi/spi.h> #include <linux/spi/flash.h> #include <linux/mtd/spi-nor.h> +#include <linux/of_platform.h> #define MAX_CMD_SIZE 6struct m25p {struct spi_device *spi;struct spi_nor spi_nor;struct mtd_info mtd; +size_t max_tx_len;u8 command[MAX_CMD_SIZE ]; };
@@ -98,7 +100,10 @@ static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,spi_message_add_tail (&t[0 ], &m); t[1 ].tx_buf = buf; - t[1 ].len = len; +if (flash->max_tx_len) + t[1 ].len =min (len, flash->max_tx_len); +else + t[1 ].len = len;spi_message_add_tail (&t[1 ], &m); ret =spi_sync (spi, &m);
@@ -152,7 +157,10 @@ static ssize_t m25p80_read(struct spi_nor *nor, loff_t from, size_t len, t[1 ].rx_buf = buf; t[1 ].rx_nbits =m25p80_rx_nbits (nor); - t[1 ].len = len; +if (flash->max_tx_len) + t[1 ].len =min (len, flash->max_tx_len); +else + t[1 ].len = len;spi_message_add_tail (&t[1 ], &m); ret =spi_sync (spi, &m);
@@ -242,6 +250,18 @@ static int m25p_probe(struct spi_device *spi)return ret; ppdata.of_node = spi->dev.of_node; +if (spi->dev.of_node) { +int result =of_property_read_u32 (spi->dev.of_node, +"linux,max_tx_len" , + &flash->max_tx_len); + +if (result) + flash->max_tx_len =0 ; +else +dev_info (&spi->dev, +"Using maximum transfer length %u\n" , + flash->max_tx_len); + } return mtd_device_parse_register(&flash->mtd, NULL, &ppdata, data ? data->parts : NULL,
Signature · 1 line
2.1.4
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 6 lines · Michal Suchanek
On sunxi the SPI controller currently does not have DMA support and fails any transfer larger than 63 bytes.
On Exynos the pl330 DMA controller fails any transfer larger than 64kb when using slower speed like 40MHz and any transfer larger than 128bytes when running at 133MHz.
This smells more like some corruption of the data on the bus or something even more obscure.
Quoted 31 lines
The best thing is that in both cases the controller can just lock up and never finish potentially leaving the hardware in unusable state.
So it is required that the m25p80 driver actively prevents doing transfers that are too large for the current driver state on a particular piece of hardware.
Signed-off-by Michal Suchanek <[email protected]>--
Update commit message and documentation text.
--- .../devicetree/bindings/mtd/jedec,spi-nor.txt | 6 ++++++ drivers/mtd/devices/m25p80.c | 24++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-)
(quoted diff) +0
-0
b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txtindex 2bee681..4e63ae8 100644Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +0
-0@@ -19,6 +19,12 @@ Optional properties: all chips and support for it can not be detected atruntime. Refer to your chips' datasheet to check if this is supported by your chip.
+- linux,max_tx_len : With some SPI controller drivers possible transfer size is + limited. This may be hardware or driver bug.Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +2
-0+ Transfer data in chunks no larger than this value. + Using this option may severely degrade performance and + possibly flash memory life when max_tx_len is
Quoted 1 line
smaller than + flash page size (typically 256 bytes)
Will we need similar patch for all other SPI slave drivers, like SPI NAND ?
Best regards,
Marek Vasut
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 10 lines · Marek Vasut
Quoted 6 lines · Michal Suchanek
On sunxi the SPI controller currently does not have DMA support and fails any transfer larger than 63 bytes.
On Exynos the pl330 DMA controller fails any transfer larger than 64kb when using slower speed like 40MHz and any transfer larger than 128bytes when running at 133MHz.
This smells more like some corruption of the data on the bus or something even more obscure.
If the data was corrupted you would get corrupted data and not transfer failure. AFAIK there is no checksum or anything. I actually do get corrupted data when I use wrong feedback delay setting.
Quoted 27 lines
Quoted 27 lines
The best thing is that in both cases the controller can just lock up and never finish potentially leaving the hardware in unusable state.
So it is required that the m25p80 driver actively prevents doing transfers that are too large for the current driver state on a particular piece of hardware.
Signed-off-by Michal Suchanek <[email protected]>--
Update commit message and documentation text.
--- .../devicetree/bindings/mtd/jedec,spi-nor.txt | 6 ++++++ drivers/mtd/devices/m25p80.c | 24++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-)
(quoted diff) +0
-0
b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txtindex 2bee681..4e63ae8 100644Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +0
-0@@ -19,6 +19,12 @@ Optional properties: all chips and support for it can not be detected atruntime. Refer to your chips' datasheet to check if this is supported by your chip.
Quoted 8 lines
Quoted 6 lines
+- linux,max_tx_len : With some SPI controller drivers possible transfer size is + limited. This may be hardware or driver bug.Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +2
-0+ Transfer data in chunks no larger than this value. + Using this option may severely degrade performance and + possibly flash memory life when max_tx_len issmaller than + flash page size (typically 256 bytes)
Will we need similar patch for all other SPI slave drivers, like SPI NAND ?
Probably. Some SPI slave drivers already do have similar option. In general it cannot be expected that you can reliably transfer arbitrarily large data over SPI it seems. However, if the nand driver transfers data a page at a time it should be fine.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 9 lines · Michal Suchanek
Quoted 8 lines · Marek Vasut
Quoted 6 lines · Michal Suchanek
On sunxi the SPI controller currently does not have DMA support and fails any transfer larger than 63 bytes.
On Exynos the pl330 DMA controller fails any transfer larger than 64kb when using slower speed like 40MHz and any transfer larger than 128bytes when running at 133MHz.
Quoted 6 lines
Quoted 2 lines
This smells more like some corruption of the data on the bus or something even more obscure.
If the data was corrupted you would get corrupted data and not transfer failure. AFAIK there is no checksum or anything. I actually do get corrupted data when I use wrong feedback delay setting.
OK
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
The best thing is that in both cases the controller can just lock up and never finish potentially leaving the hardware in unusable state.
[...]
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +0
-0@@ -19,6 +19,12 @@ Optional properties: all chips and support for it can not be detected atruntime. Refer to your chips' datasheet to check if this is supported by your chip.
+- linux,max_tx_len : With some SPI controller drivers possible transfer size is + limited. This may be hardware or driver bug. + Transfer data in chunks no larger than thisvalue. +
Using this option may severely degrade performance and
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
+ possibly flash memory life when
max_tx_lenis
smaller than + flash page size (typically 256 bytes)Will we need similar patch for all other SPI slave drivers, like SPI NAND ?
Probably. Some SPI slave drivers already do have similar option.
So the SPI device drivers are implementing workarounds for buggy SPI hosts, even if those SPI devices themselves don't suffer from such limitations. Yes, this seems like the seriously wrong thing to do.
Quoted 2 lines
In general it cannot be expected that you can reliably transfer arbitrarily large data over SPI it seems.
This is what should be expected because this is how the bus is supposed to work in fact. You can transfer an arbitrary amount of data over SPI bus.
If some driver has a limitation, it's that (bus, dma) driver which needs to implement a fix or a workaround.
Quoted 2 lines
However, if the nand driver transfers data a page at a time it should be fine.
... until someone issues multi-block read, in which case it all falls down like a house of cards. It is impossible to build a reliable system on "should" and similar assumptions ; the driver must be solid.
Best regards,
Marek Vasut
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
In reply to Michal SuchanekQuoted 2 lines · Michal Suchanek
On sunxi the SPI controller currently does not have DMA support and fails any transfer larger than 63 bytes.
This is a driver limitation, not a hardware limitation.
Quoted 3 lines
On Exynos the pl330 DMA controller fails any transfer larger than 64kb when using slower speed like 40MHz and any transfer larger than 128bytes when running at 133MHz.
This may be a driver bug.
Quoted 6 lines
The best thing is that in both cases the controller can just lock up and never finish potentially leaving the hardware in unusable state.
So it is required that the m25p80 driver actively prevents doing transfers that are too large for the current driver state on a particular piece of hardware.
OK.
Quoted 15 lines
Signed-off-by Michal Suchanek <[email protected]>--
Update commit message and documentation text.
--- .../devicetree/bindings/mtd/jedec,spi-nor.txt | 6 ++++++ drivers/mtd/devices/m25p80.c | 24 ++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-)Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +0
-0
Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt Optional properties: · line 27
Quoted 9 lines
Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +6
-0@@ -19,6 +19,12 @@ Optional properties: all chips and support for it can not be detected at runtime. Refer to your chips' datasheet to check if this is supported by your chip. +- linux,max_tx_len : With some SPI controller drivers possible transfer size is + limited. This may be hardware or driver bug. + Transfer data in chunks no larger than this value. + Using this option may severely degrade performance and + possibly flash memory life when max_tx_len is smaller than + flash page size (typically 256 bytes)
DT describes the hardware, not buggy drivers.
So IMHO this doesn't belong in DT, but it can be a field in struct spi_master.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 19 lines · Geert Uytterhoeven
Quoted 2 lines · Michal Suchanek
On sunxi the SPI controller currently does not have DMA support and fails any transfer larger than 63 bytes.
This is a driver limitation, not a hardware limitation.
Quoted 3 lines
On Exynos the pl330 DMA controller fails any transfer larger than 64kb when using slower speed like 40MHz and any transfer larger than 128bytes when running at 133MHz.
This may be a driver bug.
Quoted 6 lines
The best thing is that in both cases the controller can just lock up and never finish potentially leaving the hardware in unusable state.
So it is required that the m25p80 driver actively prevents doing transfers that are too large for the current driver state on a particular piece of hardware.
Quoted 7 lines
OK.
DT describes the hardware, not buggy drivers.
So IMHO this doesn't belong in DT, but it can be a field in struct
spi_master.
Unfortunately, this cannot be a field in struct spi_master. The value can and does vary with device configuration and device configuration is only available in DT.
For example, on the Snow board one working configuration is
40MHz spi bus speed, feedback delay 0 and maximum transfer size 64k.
Another working configuration is 133MHz bus speed, feedback delay 3, and maximum transfer size 128 bytes.
You might want to try to run the bus at 60MHz or 80MHz and then the values would probably again be different.
The first two values are set in DT so the logical place for setting the third is also in DT.
Otherwise you would need some in-kernel table of these settings.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 7 lines · Michal Suchanek
You might want to try to run the bus at 60MHz or 80MHz and then the values would probably again be different.
The first two values are set in DT so the logical place for setting the third is also in DT.
Otherwise you would need some in-kernel table of these settings.
Or a formula.
Thanks,
Richard
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 11 lines · Richard Cochran
Quoted 7 lines · Michal Suchanek
You might want to try to run the bus at 60MHz or 80MHz and then the values would probably again be different.
The first two values are set in DT so the logical place for setting the third is also in DT.
Otherwise you would need some in-kernel table of these settings.
Or a formula.
This formula probably needs to take into account
- the unknown reason for the pl330 to fail transfer
- the device transfer speed and transfer phase as set in DT
- possibly device-specific latency and board-specific trace design
and assembly tolerances
Seriously, until I have at least a vague idea why the transfer fails I am not comfortable pulling some formula out of thin air and pretending I have a working patch.
On the other hand, a parameter you can set in the DT and which comes with a suggested value which can be tuned depending on the system seems more viable.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 8 lines · Michal Suchanek
Quoted 7 lines · Richard Cochran
Quoted 6 lines · Michal Suchanek
You might want to try to run the bus at 60MHz or 80MHz and then the values would probably again be different.
The first two values are set in DT so the logical place for setting the third is also in DT.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
Otherwise you would need some in-kernel table of these settings.
Or a formula.
This formula probably needs to take into account
- the unknown reason for the pl330 to fail transfer
Shouldn't that be fixed at the PL330 level ? This looks like fixing a problem at the wrong place :)
Quoted 3 lines
- the device transfer speed and transfer phase as set in DT
- possibly device-specific latency and board-specific trace design
and assembly tolerances
If the design is broken, then cap the speed as for normal SPI device.
Quoted 7 lines
Seriously, until I have at least a vague idea why the transfer fails I am not comfortable pulling some formula out of thin air and pretending I have a working patch.
On the other hand, a parameter you can set in the DT and which comes with a suggested value which can be tuned depending on the system seems more viable.
The problem is, if you add a new DT binding, you'd have to support it forever, no matter how bad idea that binding turned out to be.
Best regards,
Marek Vasut
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Hi Michal,
Quoted 2 lines · Marek Vasut
The problem is, if you add a new DT binding, you'd have to support it forever, no matter how bad idea that binding turned out to be.
Agreed, and a solid NAK to this patch. I could have sworn I gave such a response when this was originally being discussed a month ago.
AFAICT, you have one of two general approaches available to you:
1. Fix up the SPI driver so that it knows how to break large SPI transfers up into smaller segments that its constituent hardware (DMA controllers, fast clocks, etc.) can handle.
2. Utilize/create a parameter within the SPI subsystem to communicate that the SPI master has a limited max transfer size (notably: NOT a per-device DT property, but a SPI API property), and modify SPI device drivers (like m25p80) to honor it. Mark Brown seemed open to this, and I thought he suggested it somewhere.
It is most definitely wrong to put this information solely in the slave device DT (i.e., for the flash), when it is not a property of the flash device at all. It's a property of the SPI master and/or its clocks and DMA controllers.
Brian
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 1 line · Brian Norris
Hi Michal,
Hi all,
Quoted 12 lines · Marek Vasut
Quoted 2 lines
The problem is, if you add a new DT binding, you'd have to support it forever, no matter how bad idea that binding turned out to be.
Agreed, and a solid NAK to this patch. I could have sworn I gave such a response when this was originally being discussed a month ago.
AFAICT, you have one of two general approaches available to you:
1. Fix up the SPI driver so that it knows how to break large SPI transfers up into smaller segments that its constituent hardware (DMA controllers, fast clocks, etc.) can handle.
I think this might actually be easier -- just do a transfer where you don't toggle CS and just stops the clock at the last bit, then do another (multiple) transfers which don't toggle CS at all, then finally do a transfer which toggles a CS at the end. This should be pretty trivial to do and I think for example spi-mxs.c does this.
Best regards,
Marek Vasut
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 4 lines · Marek Vasut
Quoted 3 lines · Brian Norris
1. Fix up the SPI driver so that it knows how to break large SPI transfers up into smaller segments that its constituent hardware (DMA controllers, fast clocks, etc.) can handle.
BTW, Mark Brown already commented on this approach:
http://lists.infradead.org/pipermail/linux-mtd/2015-May/059364.html
I quote:
| With modern drivers using transfer_one() where we have control of the | chip select we do also have the ability to add support to the core for | chopping large transfers up into smaller ones that the hardware can | handle transparently. That won't for everything though since it depends | on us being able to manually control the chip select which not all | hardware can do.
Quoted 4 lines
I think this might actually be easier -- just do a transfer where you don't toggle CS and just stops the clock at the last bit, then do another (multiple) transfers which don't toggle CS at all, then finally do a transfer which toggles a CS at the end.
Sounds OK to me. And as Mark noted, this could probably be done in the core. I suppose Mark could suggest whether the most expedient path is to hack the buggy driver to do this, or whether reworking the SPI core to have the appropriate spi_master field(s) (and caveats) to support this.
Quoted 2 lines
This should be pretty trivial
to do and I think for examplespi-mxs.cdoes this.
I don't think spi-mxs.c really does this; it chooses between PIO and DMA based on length, but with either option, it runs through each SPI transfer in one go. You might be confused by the fact that this driver implements ->transfer_one_message instead of ->transfer_one, so it has to loop through all transfers in the message.
(IIUC, spi-mxs.c could easily be rewritten to use ->transfer, and some of that not-too-complicated boilerplate could be killed off.)
Brian
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 23 lines · Brian Norris
Quoted 4 lines · Marek Vasut
Quoted 3 lines · Brian Norris
1. Fix up the SPI driver so that it knows how to break large SPI transfers up into smaller segments that its constituent hardware (DMA controllers, fast clocks, etc.) can handle.
BTW, Mark Brown already commented on this approach:
http://lists.infradead.org/pipermail/linux-mtd/2015-May/059364.html
I quote:
| With modern drivers using transfer_one() where we have control of the | chip select we do also have the ability to add support to the core for | chopping large transfers up into smaller ones that the hardware can | handle transparently. That won't for everything though since it depends | on us being able to manually control the chip select which not all | hardware can do. |Quoted 4 lines
I think this might actually be easier -- just do a transfer where you don't toggle CS and just stops the clock at the last bit, then do another (multiple) transfers which don't toggle CS at all, then finally do a transfer which toggles a CS at the end.
Quoted 4 lines
Sounds OK to me. And as Mark noted, this could probably be done in the core. I suppose Mark could suggest whether the most expedient path is to hack the buggy driver to do this, or whether reworking the SPI core to have the appropriate
spi_masterfield(s) (and caveats) to support this.
Yep, agreed.
Quoted 8 lines
Quoted 2 lines
This should be pretty trivial
to do and I think for examplespi-mxs.cdoes this.I don't think
spi-mxs.creally does this; it chooses between PIO and DMA based on length, but with either option, it runs through each SPI transfer in one go. You might be confused by the fact that this driver implements ->transfer_one_message instead of ->transfer_one, so it has to loop through all transfers in the message.
It does chop up the DMA transfers between multiple runs of the DMA engine IIRC. But it does so within the driver, which apparently is not the way to go :)
Quoted 2 lines
(IIUC,
spi-mxs.ccould easily be rewritten to use ->transfer, and some of that not-too-complicated boilerplate could be killed off.)
Most likely, yes.
Best regards,
Marek Vasut
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
In reply to Brian NorrisHello,
Quoted 15 lines · Brian Norris
Hi Michal,
Quoted 2 lines · Marek Vasut
The problem is, if you add a new DT binding, you'd have to support it forever, no matter how bad idea that binding turned out to be.
Agreed, and a solid NAK to this patch. I could have sworn I gave such a response when this was originally being discussed a month ago.
AFAICT, you have one of two general approaches available to you:
1. Fix up the SPI driver so that it knows how to break large SPI transfers up into smaller segments that its constituent hardware (DMA controllers, fast clocks, etc.) can handle.
Quoted 5 lines
2. Utilize/create a parameter within the SPI subsystem to communicate that the SPI master has a limited max transfer size (notably: NOT a per-device DT property, but a SPI API property), and modify SPI device drivers (like m25p80) to honor it. Mark Brown seemed open to this, and I thought he suggested it somewhere.
It is not known what exactly is limited here.
It seems that the pl330 fails but it is not possible to transfer that much data over the spi bus in one go without the help of the pl330.
With either approach the limit depends on the SPI transfer settings which are known the the SPI driver. The pl330 driver is oblivious to these because it just transfers data from one port to another port and has no idea that the port is wired to SPI in the SoC.
On the other hand, AFAICT the SPI driver only allocates a DMA channel which it receives through DT binding and is oblivious to the fact the DMA channel lives on a pl330. It could probably determine that the channel is indeed driven by a pl330. I don't think it's a great idea to add device-specific handling to a generic dmaengine driver or a dmaengine-spiecific handling to a SPI driver.
It's technically possible to pass SPI transfer parameters to the dmaengine driver prior to transfer and the dmaengine could impose some limitation based on those parameters. However, generalising this to drivers other than SPI might be problematic. Should this interface also handle i2c parameters, VE parameters, audio parameters, ethernet parameters, etc?
In the DT you have the information that this particular device is connected to a Samsung SPI controller connected to a pl330 dma engine.
Quoted 5 lines
It is most definitely wrong to put this information solely in the slave device DT (i.e., for the flash), when it is not a property of the flash device at all. It's a property of the SPI master and/or its clocks and DMA controllers.
However, the clocks are set by the parameters of the device, not the parameters of the master. So the limitation applies for the master with the settings of the particular slave device. Different slave settings do impose different master limitations.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 41 lines · Michal Suchanek
Hello,
Quoted 15 lines · Brian Norris
Hi Michal,
Quoted 2 lines · Marek Vasut
The problem is, if you add a new DT binding, you'd have to support it forever, no matter how bad idea that binding turned out to be.
Agreed, and a solid NAK to this patch. I could have sworn I gave such a response when this was originally being discussed a month ago.
AFAICT, you have one of two general approaches available to you:
1. Fix up the SPI driver so that it knows how to break large SPI transfers up into smaller segments that its constituent hardware (DMA controllers, fast clocks, etc.) can handle.
Quoted 5 lines
2. Utilize/create a parameter within the SPI subsystem to communicate that the SPI master has a limited max transfer size (notably: NOT a per-device DT property, but a SPI API property), and modify SPI device drivers (like m25p80) to honor it. Mark Brown seemed open to this, and I thought he suggested it somewhere.
It is not known what exactly is limited here.
It seems that the pl330 fails but it is not possible to transfer that much data over the spi bus in one go without the help of the pl330.
With either approach the limit depends on the SPI transfer settings which are known the the SPI driver. The pl330 driver is oblivious to these because it just transfers data from one port to another port and has no idea that the port is wired to SPI in the SoC.
On the other hand, AFAICT the SPI driver only allocates a DMA channel which it receives through DT binding and is oblivious to the fact the DMA channel lives on a pl330. It could probably determine that the channel is indeed driven by a pl330. I don't think it's a great idea to add device-specific handling to a generic dmaengine driver or a dmaengine-spiecific handling to a SPI driver.
Quoted 6 lines
It's technically possible to pass SPI transfer parameters to the dmaengine driver prior to transfer and the dmaengine could impose some limitation based on those parameters. However, generalising this to drivers other than SPI might be problematic. Should this interface also handle i2c parameters, VE parameters, audio parameters, ethernet parameters, etc?
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by dma_get_slave_caps(chan, &caps)
And we add max_length as one more parameter to existing set
Also all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Let me know if this idea is okay, I can push the dmaengine bits...
Thanks
Signature · 1 line
~Vinod
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Hello,
Quoted 54 lines · Vinod Koul
Quoted 41 lines · Michal Suchanek
Hello,
Quoted 15 lines · Brian Norris
Hi Michal,
Quoted 2 lines · Marek Vasut
The problem is, if you add a new DT binding, you'd have to support it forever, no matter how bad idea that binding turned out to be.
Agreed, and a solid NAK to this patch. I could have sworn I gave such a response when this was originally being discussed a month ago.
AFAICT, you have one of two general approaches available to you:
1. Fix up the SPI driver so that it knows how to break large SPI transfers up into smaller segments that its constituent hardware (DMA controllers, fast clocks, etc.) can handle.
Quoted 5 lines
2. Utilize/create a parameter within the SPI subsystem to communicate that the SPI master has a limited max transfer size (notably: NOT a per-device DT property, but a SPI API property), and modify SPI device drivers (like m25p80) to honor it. Mark Brown seemed open to this, and I thought he suggested it somewhere.
It is not known what exactly is limited here.
It seems that the pl330 fails but it is not possible to transfer that much data over the spi bus in one go without the help of the pl330.
With either approach the limit depends on the SPI transfer settings which are known the the SPI driver. The pl330 driver is oblivious to these because it just transfers data from one port to another port and has no idea that the port is wired to SPI in the SoC.
On the other hand, AFAICT the SPI driver only allocates a DMA channel which it receives through DT binding and is oblivious to the fact the DMA channel lives on a pl330. It could probably determine that the channel is indeed driven by a pl330. I don't think it's a great idea to add device-specific handling to a generic dmaengine driver or a dmaengine-spiecific handling to a SPI driver.
Quoted 6 lines
It's technically possible to pass SPI transfer parameters to the dmaengine driver prior to transfer and the dmaengine could impose some limitation based on those parameters. However, generalising this to drivers other than SPI might be problematic. Should this interface also handle i2c parameters, VE parameters, audio parameters, ethernet parameters, etc?
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
Quoted 9 lines
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 13 lines · Michal Suchanek
Quoted 13 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 6 lines
Quoted 1 line
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Signature · 1 line
~Vinod
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 16 lines · Vinod Koul
Quoted 15 lines · Michal Suchanek
Quoted 14 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Let me know if this idea is okay, I can push the dmaengine bits...
Quoted 8 lines
Quoted 4 lines
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
However, if this was not tied to the particular slave setting picked in the current DT a formula would be needed that translates arbitrary client settings to transfer size limit and there would be need to somehow get the client settings to the formula in the dmaengine driver.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 27 lines · Michal Suchanek
Quoted 21 lines · Vinod Koul
Quoted 13 lines · Michal Suchanek
Quoted 13 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 6 lines
Quoted 1 line
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
Quoted 4 lines
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Quoted 4 lines
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
This looks more like a signal integrity issue though.
Quoted 9 lines
However, if this was not tied to the particular slave setting picked in the current DT a formula would be needed that translates arbitrary client settings to transfer size limit and there would be need to somehow get the client settings to the formula in the dmaengine driver.
Thanks
Michal
Best regards,
Marek Vasut
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 28 lines · Marek Vasut
Quoted 27 lines · Michal Suchanek
Quoted 25 lines · Vinod Koul
Quoted 13 lines · Michal Suchanek
Quoted 13 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 6 lines
Quoted 1 line
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Quoted 7 lines
Quoted 4 lines
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
This looks more like a signal integrity issue though.
It certainly does on the surface. However, when wrong data is delivered over the SPI bus (such as when I use wrong phase setting) the SPI controller happily delivers wrong data over PIO.
The failure I am seeing is that the pl330 DMA program which repeatedly waits for data from the SPI controller never finishes the read loop and does not signal the interrupt. It seems it also leaves some data in a FIFO somewhere so next command on the flash returns garbage and fails.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 40 lines · Michal Suchanek
Quoted 28 lines · Marek Vasut
Quoted 27 lines · Michal Suchanek
Quoted 25 lines · Vinod Koul
Quoted 13 lines · Michal Suchanek
Quoted 13 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 6 lines
Quoted 1 line
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Quoted 6 lines
Quoted 4 lines
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
This looks more like a signal integrity issue though.
It certainly does on the surface. However, when wrong data is delivered over the SPI bus (such as when I use wrong phase setting) the SPI controller happily delivers wrong data over PIO.
Quoted 5 lines
The failure I am seeing is that the pl330 DMA program which repeatedly waits for data from the SPI controller never finishes the read loop and does not signal the interrupt. It seems it also leaves some data in a FIFO somewhere so next command on the flash returns garbage and fails.
I observed something similar on MXS (mx28) SPI block. Do you use mixed PIO/DMA mode perhaps ? Do you have the option to connect a bus analyzer? I can probably offer you some tools, I'm in Prague ...
Best regards,
Marek Vasut
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 41 lines · Marek Vasut
Quoted 40 lines · Michal Suchanek
Quoted 28 lines · Marek Vasut
Quoted 27 lines · Michal Suchanek
Quoted 25 lines · Vinod Koul
Quoted 13 lines · Michal Suchanek
Quoted 13 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 6 lines
Quoted 1 line
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Quoted 6 lines
Quoted 4 lines
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
This looks more like a signal integrity issue though.
It certainly does on the surface. However, when wrong data is delivered over the SPI bus (such as when I use wrong phase setting) the SPI controller happily delivers wrong data over PIO.
Quoted 8 lines
Quoted 5 lines
The failure I am seeing is that the pl330 DMA program which repeatedly waits for data from the SPI controller never finishes the read loop and does not signal the interrupt. It seems it also leaves some data in a FIFO somewhere so next command on the flash returns garbage and fails.
I observed something similar on MXS (mx28) SPI block. Do you use mixed PIO/DMA mode perhaps ?
The SPI driver uses PIO for short transfers and DMA for transfers longer than the controller FIFO. This seems to be the standard way to do things.It works flawlessly so long as submitting overly long DMA programs is avoided.
Quoted 2 lines
Do you have the option to connect a bus analyzer? I can probably offer you some tools, I'm in Prague ...
The flash chip is accessible when removing the bottom cover. It is VSOP8 package slightly lower than SOP8 so attaching clips to it might be a bit problematic. That's the only accessible part. Everything other than SPI is inside the SoC.
Since SPI has no verification whatsoever the chip might be completely dead and you can still read fine all zeroes or all ones when attempting a read from it. I observed this behaviour when I used a flash chip in a socket and it was not firmly seated. It was with a different SPI controller, though.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 51 lines · Michal Suchanek
Quoted 50 lines · Marek Vasut
Quoted 48 lines · Michal Suchanek
Quoted 31 lines · Marek Vasut
Quoted 30 lines · Michal Suchanek
Quoted 28 lines · Vinod Koul
Quoted 14 lines · Michal Suchanek
Quoted 14 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 8 lines
Quoted 2 lines
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Quoted 6 lines
Quoted 4 lines
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
This looks more like a signal integrity issue though.
It certainly does on the surface. However, when wrong data is delivered over the SPI bus (such as when I use wrong phase setting) the SPI controller happily delivers wrong data over PIO.
The failure I am seeing is that the pl330 DMA program which repeatedly waits for data from the SPI controller never finishes the read loop and does not signal the interrupt. It seems it also leaves some data in a FIFO somewhere so next command on the flash returns garbage and fails.
Quoted 7 lines
Quoted 2 lines
I observed something similar on MXS (mx28) SPI block. Do you use mixed PIO/DMA mode perhaps ?
The SPI driver uses PIO for short transfers and DMA for transfers longer than the controller FIFO. This seems to be the standard way to do things.It works flawlessly so long as submitting overly long DMA programs is avoided.
Can you try doing JUST DMA, no PIO ? I remember seeing some bus synchronisation issues when I did mixed PIO/DMA on the MXS and it was nasty to track down. Just give pure DMA a go to see if the thing stabilizes somehow.
Quoted 7 lines
Quoted 2 lines
Do you have the option to connect a bus analyzer? I can probably offer you some tools, I'm in Prague ...
The flash chip is accessible when removing the bottom cover. It is VSOP8 package slightly lower than SOP8 so attaching clips to it might be a bit problematic. That's the only accessible part. Everything other than SPI is inside the SoC.
That might be doable, though you might want to try the above thing first.
Quoted 5 lines
Since SPI has no verification whatsoever the chip might be completely dead and you can still read fine all zeroes or all ones when attempting a read from it. I observed this behaviour when I used a flash chip in a socket and it was not firmly seated. It was with a different SPI controller, though.
You should run into issues as soon as the SPI NOR framework tries to read status register, no ?
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 55 lines · Marek Vasut
Quoted 54 lines · Michal Suchanek
Quoted 52 lines · Marek Vasut
Quoted 43 lines · Michal Suchanek
Quoted 31 lines · Marek Vasut
Quoted 30 lines · Michal Suchanek
Quoted 28 lines · Vinod Koul
Quoted 14 lines · Michal Suchanek
Quoted 14 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 8 lines
Quoted 2 lines
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Quoted 6 lines
Quoted 4 lines
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
This looks more like a signal integrity issue though.
It certainly does on the surface. However, when wrong data is delivered over the SPI bus (such as when I use wrong phase setting) the SPI controller happily delivers wrong data over PIO.
Quoted 5 lines
The failure I am seeing is that the pl330 DMA program which repeatedly waits for data from the SPI controller never finishes the read loop and does not signal the interrupt. It seems it also leaves some data in a FIFO somewhere so next command on the flash returns garbage and fails.
I observed something similar on MXS (mx28) SPI block. Do you use mixed PIO/DMA mode perhaps ?
Quoted 8 lines
Quoted 4 lines
The SPI driver uses PIO for short transfers and DMA for transfers longer than the controller FIFO. This seems to be the standard way to do things.It works flawlessly so long as submitting overly long DMA programs is avoided.
Can you try doing JUST DMA, no PIO ? I remember seeing some bus synchronisation issues when I did mixed PIO/DMA on the MXS and it was nasty to track down. Just give pure DMA a go to see if the thing stabilizes somehow.
It's probably slower to set up DMA for 2-byte commands but it might work nonetheless.
I will give it a go.
Quoted 11 lines
Quoted 8 lines
Quoted 3 lines
Do you have the option to connect a bus analyzer? I can probably offer you some tools, I'm in Prague ...
The flash chip is accessible when removing the bottom cover. It is VSOP8 package slightly lower than SOP8 so attaching clips to it might be a bit problematic. That's the only accessible part. Everything other than SPI is inside the SoC.
That might be doable, though you might want to try the above thing first.
Quoted 8 lines
Quoted 5 lines
Since SPI has no verification whatsoever the chip might be completely dead and you can still read fine all zeroes or all ones when attempting a read from it. I observed this behaviour when I used a flash chip in a socket and it was not firmly seated. It was with a different SPI controller, though.
You should run into issues as soon as the SPI NOR framework tries to read status register, no ?
Yes, when the DMA transfer fails the next command fails due to garbage lying around. However, you can unload the SPI NOR driver, load spidev driver, and read enough garbage to empty the fifos. Then the flash identifies as normal again and you can access it.
When the flash is not seated properly and acts autistic you get all 0xff or all 0 back whatever you send to it, obvously. The identification by the SPI NOR driver fails then.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 62 lines · Michal Suchanek
Quoted 61 lines · Marek Vasut
Quoted 59 lines · Michal Suchanek
Quoted 45 lines · Marek Vasut
Quoted 44 lines · Michal Suchanek
Quoted 31 lines · Marek Vasut
Quoted 30 lines · Michal Suchanek
Quoted 28 lines · Vinod Koul
Quoted 14 lines · Michal Suchanek
Quoted 14 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 8 lines
Quoted 2 lines
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Quoted 7 lines
Quoted 5 lines
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
This looks more like a signal integrity issue though.
It certainly does on the surface. However, when wrong data is delivered over the SPI bus (such as when I use wrong phase setting) the SPI controller happily delivers wrong data over PIO.
Quoted 8 lines
Quoted 5 lines
The failure I am seeing is that the pl330 DMA program which repeatedly waits for data from the SPI controller never finishes the read loop and does not signal the interrupt. It seems it also leaves some data in a FIFO somewhere so next command on the flash returns garbage and fails.
I observed something similar on MXS (mx28) SPI block. Do you use mixed PIO/DMA mode perhaps ?
The SPI driver uses PIO for short transfers and DMA for transfers longer than the controller FIFO. This seems to be the standard way to do things.It works flawlessly so long as submitting overly long DMA programs is avoided.
Quoted 7 lines
Quoted 4 lines
Can you try doing JUST DMA, no PIO ? I remember seeing some bus synchronisation issues when I did mixed PIO/DMA on the MXS and it was nasty to track down. Just give pure DMA a go to see if the thing stabilizes somehow.
It's probably slower to set up DMA for 2-byte commands but it might work nonetheless.
It is, the overhead will be considerable. It might help the stability though. I'm really looking forward to the results!
Quoted 18 lines
I will give it a go.
Quoted 16 lines
Quoted 7 lines
Quoted 2 lines
Do you have the option to connect a bus analyzer? I can probably offer you some tools, I'm in Prague ...
The flash chip is accessible when removing the bottom cover. It is VSOP8 package slightly lower than SOP8 so attaching clips to it might be a bit problematic. That's the only accessible part. Everything other than SPI is inside the SoC.
That might be doable, though you might want to try the above thing first.
Quoted 5 lines
Since SPI has no verification whatsoever the chip might be completely dead and you can still read fine all zeroes or all ones when attempting a read from it. I observed this behaviour when I used a flash chip in a socket and it was not firmly seated. It was with a different SPI controller, though.
Quoted 7 lines
Quoted 2 lines
You should run into issues as soon as the SPI NOR framework tries to read status register, no ?
Yes, when the DMA transfer fails the next command fails due to garbage lying around. However, you can unload the SPI NOR driver, load spidev driver, and read enough garbage to empty the fifos. Then the flash identifies as normal again and you can access it.
Yikes :(
Quoted 7 lines
When the flash is not seated properly and acts autistic you get all
0xffor all 0 back whatever you send to it, obvously. The identification by the SPI NOR driver fails then.Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 68 lines · Marek Vasut
Quoted 67 lines · Michal Suchanek
Quoted 65 lines · Marek Vasut
Quoted 52 lines · Michal Suchanek
Quoted 51 lines · Marek Vasut
Quoted 49 lines · Michal Suchanek
Quoted 31 lines · Marek Vasut
Quoted 30 lines · Michal Suchanek
Quoted 28 lines · Vinod Koul
Quoted 14 lines · Michal Suchanek
Quoted 14 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 8 lines
Quoted 2 lines
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Quoted 7 lines
Quoted 5 lines
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
This looks more like a signal integrity issue though.
It certainly does on the surface. However, when wrong data is delivered over the SPI bus (such as when I use wrong phase setting) the SPI controller happily delivers wrong data over PIO.
The failure I am seeing is that the pl330 DMA program which repeatedly waits for data from the SPI controller never finishes the read loop and does not signal the interrupt. It seems it also leaves some data in a FIFO somewhere so next command on the flash returns garbage and fails.
Quoted 7 lines
Quoted 2 lines
I observed something similar on MXS (mx28) SPI block. Do you use mixed PIO/DMA mode perhaps ?
The SPI driver uses PIO for short transfers and DMA for transfers longer than the controller FIFO. This seems to be the standard way to do things.It works flawlessly so long as submitting overly long DMA programs is avoided.
Can you try doing JUST DMA, no PIO ? I remember seeing some bus synchronisation issues when I did mixed PIO/DMA on the MXS and it was nasty to track down. Just give pure DMA a go to see if the thing stabilizes somehow.
Quoted 6 lines
Quoted 2 lines
It's probably slower to set up DMA for 2-byte commands but it might work nonetheless.
It is, the overhead will be considerable. It might help the stability though. I'm really looking forward to the results!
Hello,
this does not quite work.
My test with spidev:
# ./spinor /dev/spidev1.0 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60 Sending 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff ff ff ff c8 15 c8 15 c8 15 c8 15 c8 15 c8 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60
I receive correct ID but spi-nor complains it does not know ID 00 c8 60. IIRC garbage should be sent only at the time command is transferred so only one byte of garbage should be received. Also the garbage tends to be the last state of the data output - all 0 or all 1.
So it seems using DMA for all transfers including 1-byte commands results in (some?) received data getting an extra 00 prefix.
[ 26.702690] spi spi1.0: setup mode 0, 8 bits/w, 40000000 Hz max --> 0 [ 26.703474] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 26.703534] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed 40000000 [ 26.703543] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: using dma [ 26.703568] dma-pl330 121b0000.pdma: setting up request on thread 1 [ 26.703576] bc041200: DMAMOV CCR 0x800201 [ 26.703585] bc041206: DMAMOV SAR 0x6e151280 [ 26.703593] bc04120c: DMAMOV DAR 0x12d30018 [ 26.703601] bc041212: DMAWFPS 5 [ 26.703609] bc041214: DMALDA [ 26.703615] bc041215: DMASTPS 5 [ 26.703625] bc041217: DMAFLUSHP 5 [ 26.703636] bc041219: DMASEV 1 [ 26.703645] bc04121b: DMAEND [ 26.703668] dma-pl330 121b0000.pdma: event signalled on thread id 1 [ 26.703690] spi_master spi1: wait_for_dma: waiting for 100ms transferring 1bytes at 40000000Hz [ 26.703699] spi_master spi1: wait_for_dma: waited 0 ms [ 26.703711] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed 40000000 [ 26.703718] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: using dma [ 26.703728] dma-pl330 121b0000.pdma: setting up request on thread 0 [ 26.703733] bc041000: DMAMOV CCR 0x804200 [ 26.703742] bc041006: DMAMOV SAR 0x12d3001c [ 26.703749] bc04100c: DMAMOV DAR 0x6e151281 [ 26.703755] bc041012: DMALP_1 5 [ 26.703763] bc041014: DMAWFPS 4 [ 26.703769] bc041016: DMALDPS 4 [ 26.703775] bc041018: DMASTA [ 26.703781] bc041019: DMAFLUSHP 4 [ 26.703787] bc04101b: DMALPENDA_1 bjmpto_7 [ 26.703795] bc04101d: DMASEV 0 [ 26.703801] bc04101f: DMAEND [ 26.703815] spi_master spi1: wait_for_dma: waiting for 100ms transferring 6bytes at 40000000Hz [ 26.703820] dma-pl330 121b0000.pdma: event signalled on thread id 0 [ 26.703837] spi_master spi1: wait_for_dma: waited 0 ms [ 26.703866] m25p80 spi1.0: unrecognized JEDEC id bytes: 00, c8, 60 [ 26.703885] m25p80: probe of spi1.0 failed with error -2 [ 26.703905] s3c64xx-spi 12d30000.spi: registered child spi1.0
[ 65.079159] spi spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 65.079343] spidev spi1.0: buggy DT: spidev listed directly in DT [ 65.079350] ------------[ cut here ]------------ [ 65.079362] WARNING: CPU: 1 PID: 3951 at /scratch/build/linux/drivers/spi/spidev.c:717 spidev_probe+0x1d4/0x1f0() [ 65.079367] Modules linked in: ipv6 [ 65.079383] CPU: 1 PID: 3951 Comm: cat Not tainted 4.2.0-rc3-00167-ged73574 #43 [ 65.079389] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) [ 65.079406] [<c00168bc>] (unwind_backtrace) from [<c0012fc4>] (show_stack+0x10/0x14) [ 65.079417] [<c0012fc4>] (show_stack) from [<c066fea8>] (dump_stack+0x84/0xc4) [ 65.079428] [<c066fea8>] (dump_stack) from [<c00299a0>] (warn_slowpath_common+0x84/0xb4) [ 65.079437] [<c00299a0>] (warn_slowpath_common) from [<c0029a6c>] (warn_slowpath_null+0x1c/0x24) [ 65.079446] [<c0029a6c>] (warn_slowpath_null) from [<c03f38a4>] (spidev_probe+0x1d4/0x1f0) [ 65.079457] [<c03f38a4>] (spidev_probe) from [<c03f1258>] (spi_drv_probe+0x50/0x74) [ 65.079468] [<c03f1258>] (spi_drv_probe) from [<c03a885c>] (driver_probe_device+0x1fc/0x43c) [ 65.079480] [<c03a885c>] (driver_probe_device) from [<c03a6a94>] (bus_for_each_drv+0x64/0x98) [ 65.079489] [<c03a6a94>] (bus_for_each_drv) from [<c03a8588>] (__device_attach+0x8c/0x108) [ 65.079498] [<c03a8588>] (__device_attach) from [<c03a7b08>] (bus_probe_device+0x84/0x8c) [ 65.079506] [<c03a7b08>] (bus_probe_device) from [<c03a5cb0>] (device_add+0x414/0x5a4) [ 65.079514] [<c03a5cb0>] (device_add) from [<c03f187c>] (spi_add_device+0x94/0x16c) [ 65.079524] [<c03f187c>] (spi_add_device) from [<c03f1d08>] (of_register_spi_device+0x234/0x2fc) [ 65.079532] [<c03f1d08>] (of_register_spi_device) from [<c03f3350>] (of_spi_notify+0x88/0xd0) [ 65.079542] [<c03f3350>] (of_spi_notify) from [<c0043170>] (notifier_call_chain+0x44/0x84) [ 65.079552] [<c0043170>] (notifier_call_chain) from [<c00434cc>] (__blocking_notifier_call_chain+0x48/0x60) [ 65.079561] [<c00434cc>] (__blocking_notifier_call_chain) from [<c00434fc>] (blocking_notifier_call_chain+0x18/0x20) [ 65.079572] [<c00434fc>] (blocking_notifier_call_chain) from [<c0508350>] (__of_changeset_entry_notify+0x84/0xe0) [ 65.079581] [<c0508350>] (__of_changeset_entry_notify) from [<c0508c08>] (of_changeset_apply+0x78/0x140) [ 65.079591] [<c0508c08>] (of_changeset_apply) from [<c050d5c8>] (of_overlay_create+0x300/0x490) [ 65.079601] [<c050d5c8>] (of_overlay_create) from [<c050d790>] (of_overlay_create_store+0x38/0x50) [ 65.079611] [<c050d790>] (of_overlay_create_store) from [<c01375d4>] (kernfs_fop_write+0xb8/0x19c) [ 65.079622] [<c01375d4>] (kernfs_fop_write) from [<c00daae8>] (__vfs_write+0x20/0xd8) [ 65.079631] [<c00daae8>] (__vfs_write) from [<c00db308>] (vfs_write+0x90/0x164) [ 65.079639] [<c00db308>] (vfs_write) from [<c00dbb30>] (SyS_write+0x44/0x9c) [ 65.079647] [<c00dbb30>] (SyS_write) from [<c0010100>] (ret_fast_syscall+0x0/0x3c) [ 65.079654] ---[ end trace 4cf0fad6e5c33d55 ]--- [ 65.079957] s3c64xx-spi 12d30000.spi: registered child spi1.0 [ 91.215230] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 91.215242] spidev spi1.0: spi mode 0 [ 91.215276] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 91.215282] spidev spi1.0: msb first [ 91.215314] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 91.215319] spidev spi1.0: 0 bits per word [ 91.215351] spidev spi1.0: setup mode 0, 8 bits/w, 1000000 Hz max --> 0 [ 91.215424] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 91.215460] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed 1000000 [ 91.215467] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 91.215500] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: using dma [ 91.215515] dma-pl330 121b0000.pdma: setting up request on thread 1 [ 91.215520] bc041200: DMAMOV CCR 0x800201 [ 91.215526] bc041206: DMAMOV SAR 0x6d842000 [ 91.215532] bc04120c: DMAMOV DAR 0x12d30018 [ 91.215538] bc041212: DMAWFPS 5 [ 91.215543] bc041214: DMALDA [ 91.215548] bc041215: DMASTPS 5 [ 91.215553] bc041217: DMAFLUSHP 5 [ 91.215558] bc041219: DMASEV 1 [ 91.215563] bc04121b: DMAEND [ 91.215577] dma-pl330 121b0000.pdma: setting up request on thread 0 [ 91.215581] bc041000: DMAMOV CCR 0x804200 [ 91.215586] bc041006: DMAMOV SAR 0x12d3001c [ 91.215592] bc04100c: DMAMOV DAR 0x6d845000 [ 91.215597] bc041012: DMAWFPS 4 [ 91.215602] bc041014: DMALDPS 4 [ 91.215607] bc041016: DMASTA [ 91.215612] bc041017: DMAFLUSHP 4 [ 91.215617] bc041019: DMASEV 0 [ 91.215622] bc04101b: DMAEND [ 91.215632] dma-pl330 121b0000.pdma: event signalled on thread id 1 [ 91.215646] spi_master spi1: wait_for_dma: waiting for 100ms transferring 1bytes at 1000000Hz [ 91.215650] dma-pl330 121b0000.pdma: event signalled on thread id 0 [ 91.215680] spi_master spi1: wait_for_dma: waited 0 ms [ 91.215803] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 91.215836] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed 1000000 [ 91.215844] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 91.215878] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: using dma [ 91.215887] dma-pl330 121b0000.pdma: setting up request on thread 1[ 91.215891] bc041200: DMAMOV CCR 0x800201 [ 91.215898] bc041206: DMAMOV SAR 0x6d842000 [ 91.215903] bc04120c: DMAMOV DAR 0x12d30018 [ 91.215909] bc041212: DMALP_1 1 [ 91.215914] bc041214: DMAWFPS 5 [ 91.215920] bc041216: DMALDA [ 91.215925] bc041217: DMASTPS 5 [ 91.215931] bc041219: DMAFLUSHP 5 [ 91.215936] bc04121b: DMALPENDA_1 bjmpto_7 [ 91.215948] bc04121d: DMASEV 1 [ 91.215959] bc04121f: DMAEND [ 91.215974] dma-pl330 121b0000.pdma: setting up request on thread 0 [ 91.215978] bc041000: DMAMOV CCR 0x804200 [ 91.215984] bc041006: DMAMOV SAR 0x12d3001c [ 91.215989] bc04100c: DMAMOV DAR 0x6d845000 [ 91.215994] bc041012: DMALP_1 1 [ 91.216000] bc041014: DMAWFPS 4 [ 91.216005] bc041016: DMALDPS 4 [ 91.216014] bc041018: DMASTA [ 91.216023] bc041019: DMAFLUSHP 4 [ 91.216028] bc04101b: DMALPENDA_1 bjmpto_7 [ 91.216033] bc04101d: DMASEV 0 [ 91.216038] bc04101f: DMAEND [ 91.216050] spi_master spi1: wait_for_dma: waiting for 100ms transferring 2bytes at 1000000Hz [ 91.216055] dma-pl330 121b0000.pdma: event signalled on thread id 1 [ 91.216064] dma-pl330 121b0000.pdma: event signalled on thread id 0 [ 91.216579] spi_master spi1: wait_for_dma: waited 0 ms [ 91.216655] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 91.216678] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed 1000000 [ 91.216684] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 91.216716] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: using dma [ 91.216726] dma-pl330 121b0000.pdma: setting up request on thread 1 [ 91.216730] bc041200: DMAMOV CCR 0x800201 [ 91.216736] bc041206: DMAMOV SAR 0x6d842000 [ 91.216741] bc04120c: DMAMOV DAR 0x12d30018 [ 91.216747] bc041212: DMALP_1 3 [ 91.216752] bc041214: DMAWFPS 5 [ 91.216757] bc041216: DMALDA [ 91.216762] bc041217: DMASTPS 5 [ 91.216767] bc041219: DMAFLUSHP 5 [ 91.216772] bc04121b: DMALPENDA_1 bjmpto_7 [ 91.216777] bc04121d: DMASEV 1 [ 91.216782] bc04121f: DMAEND [ 91.216794] dma-pl330 121b0000.pdma: setting up request on thread 0 [ 91.216797] bc041000: DMAMOV CCR 0x804200 [ 91.216803] bc041006: DMAMOV SAR 0x12d3001c [ 91.216808] bc04100c: DMAMOV DAR 0x6d845000 [ 91.216813] bc041012: DMALP_1 3 [ 91.216818] bc041014: DMAWFPS 4 [ 91.216823] bc041016: DMALDPS 4 [ 91.216828] bc041018: DMASTA [ 91.216833] bc041019: DMAFLUSHP 4 [ 91.216838] bc04101b: DMALPENDA_1 bjmpto_7 [ 91.216844] bc04101d: DMASEV 0 [ 91.216849] bc04101f: DMAEND [ 91.216860] spi_master spi1: wait_for_dma: waiting for 100ms transferring 4bytes at 1000000Hz [ 91.216865] dma-pl330 121b0000.pdma: event signalled on thread id 1 [ 91.216891] dma-pl330 121b0000.pdma: event signalled on thread id 0 [ 91.216910] spi_master spi1: wait_for_dma: waited 0 ms
The parallel transfer of command and reply seems particualrly dodgy in this case.
I also managed to lock up the controller completely since there is some error passing the SPI speed somewhere :(
[ 1352.977530] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977540] spidev spi1.0: spi mode 0 [ 1352.977576] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977582] spidev spi1.0: msb first [ 1352.977614] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977620] spidev spi1.0: 0 bits per word [ 1352.977652] spidev spi1.0: setup mode 0, 8 bits/w, 2690588672 Hz max --> 0 [ 1352.977726] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977753] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed -1604378624 [ 1352.977760] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977781] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: using dma [ 1352.977797] dma-pl330 121b0000.pdma: setting up request on thread 1
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 101 lines · Michal Suchanek
Quoted 68 lines · Marek Vasut
Quoted 67 lines · Michal Suchanek
Quoted 65 lines · Marek Vasut
Quoted 52 lines · Michal Suchanek
Quoted 51 lines · Marek Vasut
Quoted 49 lines · Michal Suchanek
Quoted 31 lines · Marek Vasut
Quoted 30 lines · Michal Suchanek
Quoted 28 lines · Vinod Koul
Quoted 14 lines · Michal Suchanek
Quoted 14 lines
Or alternatively we could publish the limitations of the channel using capabilities so SPI knows I have a dmaengine channel and it can transfer max N length transfers so would be able to break rather than guessing it or coding in DT. Yes it may come from DT but that should be dmaengine driver rather than client driver :)
This can be done by
dma_get_slave_caps(chan, &caps)And we add
max_lengthas one more parameter to existing setAlso all this could be handled in generic SPI-dmaengine layer so that individual drivers don't have to code it in
Quoted 8 lines
Quoted 2 lines
Let me know if this idea is okay, I can push the dmaengine bits...
It would be ok if there was a fixed limit. However, the limit depends on SPI slave settings. Presumably for other buses using the dmaengine the limit would depend on the bus or slave settings as well. I do not see a sane way of passing this all the way to the dmaengine driver.
I don't see why this should be client (SPI) dependent. The max length supported is a dmaengine constraint, typically flowing from max blocks/length it can transfer. Know this limit can allow clients to split transfers.
Quoted 7 lines
Quoted 5 lines
In practice on the board I have the maximum transfer length before it fails depends on SPI bus speed which is set up per slave. I did not try searching the space of possible settings thorougly and settled for a setting that gives reasonable speed and transfer length.
This looks more like a signal integrity issue though.
It certainly does on the surface. However, when wrong data is delivered over the SPI bus (such as when I use wrong phase setting) the SPI controller happily delivers wrong data over PIO.
The failure I am seeing is that the pl330 DMA program which repeatedly waits for data from the SPI controller never finishes the read loop and does not signal the interrupt. It seems it also leaves some data in a FIFO somewhere so next command on the flash returns garbage and fails.
Quoted 7 lines
Quoted 2 lines
I observed something similar on MXS (mx28) SPI block. Do you use mixed PIO/DMA mode perhaps ?
The SPI driver uses PIO for short transfers and DMA for transfers longer than the controller FIFO. This seems to be the standard way to do things.It works flawlessly so long as submitting overly long DMA programs is avoided.
Can you try doing JUST DMA, no PIO ? I remember seeing some bus synchronisation issues when I did mixed PIO/DMA on the MXS and it was nasty to track down. Just give pure DMA a go to see if the thing stabilizes somehow.
Quoted 6 lines
Quoted 2 lines
It's probably slower to set up DMA for 2-byte commands but it might work nonetheless.
It is, the overhead will be considerable. It might help the stability though. I'm really looking forward to the results!
Hello,
this does not quite work.
My test with spidev:
# ./spinor /dev/spidev1.0 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60 Sending 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff ff ff ff c8 15 c8 15 c8 15 c8 15 c8 15 c8 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60I receive correct ID but spi-nor complains it does not know ID 00 c8 60. IIRC garbage should be sent only at the time command is transferred so only one byte of garbage should be received. Also the garbage tends to be the last state of the data output - all 0 or all 1.
So it seems using DMA for all transfers including 1-byte commands results in (some?) received data getting an extra 00 prefix.I also managed to lock up the controller completely since there is some error passing the SPI speed somewhere :(
Quoted 15 lines
[ 1352.977530] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977540] spidev spi1.0: spi mode 0 [ 1352.977576] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977582] spidev spi1.0: msb first [ 1352.977614] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977620] spidev spi1.0: 0 bits per word [ 1352.977652] spidev spi1.0: setup mode 0, 8 bits/w, 2690588672 Hz max --> 0 [ 1352.977726] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977753] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed -1604378624 [ 1352.977760] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977781] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: using dma [ 1352.977797] dma-pl330 121b0000.pdma: setting up request on thread 1
Hmm, on a second thought it probably works as expected more or less.
The nonsensical value was passed from application and there is no guard against that.
Since I don't do PIO the controller remains locked up indefinitely.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
On Thursday, July 23, 2015 at 07:03:47 PM, Michal Suchanek wrote:
Hi!
[...]
Quoted 48 lines
Quoted 45 lines
Quoted 5 lines
Quoted 2 lines
It's probably slower to set up DMA for 2-byte commands but it might work nonetheless.
It is, the overhead will be considerable. It might help the stability though. I'm really looking forward to the results!
Hello,
this does not quite work.
My test with spidev:
# ./spinor /dev/spidev1.0 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60 Sending 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff ff ff ff c8 15 c8 15 c8 15 c8 15 c8 15 c8 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60I receive correct ID but spi-nor complains it does not know ID 00 c8 60. IIRC garbage should be sent only at the time command is transferred so only one byte of garbage should be received. Also the garbage tends to be the last state of the data output - all 0 or all 1.
So it seems using DMA for all transfers including 1-byte commands results in (some?) received data getting an extra 00 prefix.I also managed to lock up the controller completely since there is some error passing the SPI speed somewhere :(
[ 1352.977530] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977540] spidev spi1.0: spi mode 0 [ 1352.977576] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977582] spidev spi1.0: msb first [ 1352.977614] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977620] spidev spi1.0: 0 bits per word [ 1352.977652] spidev spi1.0: setup mode 0, 8 bits/w, 2690588672 Hz max --> 0 [ 1352.977726] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977753] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed -1604378624 [ 1352.977760] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977781] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: usingQuoted 2 lines
dma [ 1352.977797] dma-pl330 121b0000.pdma: setting up request on thread 1
Quoted 6 lines
Hmm, on a second thought it probably works as expected more or less.
The nonsensical value was passed from application and there is no guard against that.
Since I don't do PIO the controller remains locked up indefinitely.
I have to admit, I don't quite understand the above. I also don't quite know what your spidev test does. Can you possibly just bind a regular SPI NOR driver and run mtdtests to see if it is stable ?
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 56 lines · Marek Vasut
On Thursday, July 23, 2015 at 07:03:47 PM, Michal Suchanek wrote:
Hi!
[...]
Quoted 50 lines
Quoted 45 lines
Quoted 5 lines
Quoted 2 lines
It's probably slower to set up DMA for 2-byte commands but it might work nonetheless.
It is, the overhead will be considerable. It might help the stability though. I'm really looking forward to the results!
Hello,
this does not quite work.
My test with spidev:
# ./spinor /dev/spidev1.0 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60 Sending 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff ff ff ff c8 15 c8 15 c8 15 c8 15 c8 15 c8 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60I receive correct ID but spi-nor complains it does not know ID 00 c8 60. IIRC garbage should be sent only at the time command is transferred so only one byte of garbage should be received. Also the garbage tends to be the last state of the data output - all 0 or all 1.
So it seems using DMA for all transfers including 1-byte commands results in (some?) received data getting an extra 00 prefix.I also managed to lock up the controller completely since there is some error passing the SPI speed somewhere :(
[ 1352.977530] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977540] spidev spi1.0: spi mode 0 [ 1352.977576] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977582] spidev spi1.0: msb first [ 1352.977614] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977620] spidev spi1.0: 0 bits per word [ 1352.977652] spidev spi1.0: setup mode 0, 8 bits/w, 2690588672 Hz max --> 0 [ 1352.977726] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977753] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed -1604378624 [ 1352.977760] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977781] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: usingQuoted 2 lines
dma [ 1352.977797] dma-pl330 121b0000.pdma: setting up request on thread 1
Hmm, on a second thought it probably works as expected more or less.
Quoted 7 lines
Quoted 4 lines
The nonsensical value was passed from application and there is no guard against that.
Since I don't do PIO the controller remains locked up indefinitely.
I have to admit, I don't quite understand the above. I also don't quite know what your spidev test does.
It does a full duplex transfer sending what is printed and printing what is received.
Quoted 2 lines
Can you possibly just bind a regular SPI NOR driver and run mtdtests to see if it is stable ?
I can if I use PIO for short transfers. Using DMA for all transfers results in the received data prefixed with 00 so the NOR flash identification fails. Admittedly I have no idea what the flash memory actually contains so if all DMA reads were always prefixed with 00 I could not tell. I vaguely recall reading the whole content and parsing the
I can probably make the minimum length for DMA configurable so I can fall back to PIO when the controler locks up. It seems setting up a PIO transfer makes it work again.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
In reply to Marek VasutQuoted 56 lines · Marek Vasut
On Thursday, July 23, 2015 at 07:03:47 PM, Michal Suchanek wrote:
Hi!
[...]
Quoted 50 lines
Quoted 45 lines
Quoted 5 lines
Quoted 2 lines
It's probably slower to set up DMA for 2-byte commands but it might work nonetheless.
It is, the overhead will be considerable. It might help the stability though. I'm really looking forward to the results!
Hello,
this does not quite work.
My test with spidev:
# ./spinor /dev/spidev1.0 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60 Sending 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff ff ff ff c8 15 c8 15 c8 15 c8 15 c8 15 c8 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60I receive correct ID but spi-nor complains it does not know ID 00 c8 60. IIRC garbage should be sent only at the time command is transferred so only one byte of garbage should be received. Also the garbage tends to be the last state of the data output - all 0 or all 1.
So it seems using DMA for all transfers including 1-byte commands results in (some?) received data getting an extra 00 prefix.I also managed to lock up the controller completely since there is some error passing the SPI speed somewhere :(
[ 1352.977530] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977540] spidev spi1.0: spi mode 0 [ 1352.977576] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977582] spidev spi1.0: msb first [ 1352.977614] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977620] spidev spi1.0: 0 bits per word [ 1352.977652] spidev spi1.0: setup mode 0, 8 bits/w, 2690588672 Hz max --> 0 [ 1352.977726] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977753] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed -1604378624 [ 1352.977760] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977781] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: usingQuoted 2 lines
dma [ 1352.977797] dma-pl330 121b0000.pdma: setting up request on thread 1
Hmm, on a second thought it probably works as expected more or less.
Quoted 8 lines
Quoted 4 lines
The nonsensical value was passed from application and there is no guard against that.
Since I don't do PIO the controller remains locked up indefinitely.
I have to admit, I don't quite understand the above. I also don't quite know what your spidev test does. Can you possibly just bind a regular SPI NOR driver and run mtdtests to see if it is stable ?
Ok, so here is some summary.
I have a NOR flash attached to a s3c64xx SPI controller with 64byte fifo and a pl330 dma controller.
Normally DMA controller is used for transfers that do not fit into the FIFO.
I tried adding the flash memory ID to the spi-nor driver table and adding a DT node for it.
The flash is rated at 120MHz so I used that speed but the ID was bit-shifted and identification failed. There is DT property samsung,spi-feedback-delay for addressing this and at 120MHz it must be 2 or 3 on this board. 40MHz works with default value 0.
The next step after identification worked was to try reading the flash content. For this the DMA controller is used because data is transferred in blocks larger than 64 bytes. When reading the whole 4MB flash the transfer failed silently. I got a 4MB file of all ones or all zeroes.
It turns out that
- the pl330 locks up when transfering large amount of data.
Specifically, the maximum power of 2 sized transfer at 120MHz is 128 bytes and 64k at 40MHz. Transferring more than this results in the pl330 locking up and never signalling completion of the transfer. Data is left in FIFO which causes subsequent commands to fail since garbage is returned instead of command reply. Also subsequent read may cause I/O error or or return an empty page depending on the garbage around.
- the I/O errors are not checked in spi-nor at all which leads to silent data corruption.
On a suggestion that this may improve reliability I changed the s3c64xx driver to use DMA for all transfers. This caused identification to fail in spin-nor because the ID was prefixed with extra 00 byte. Testing with spidev confirmed that everything is prefixed with extra 00. Also when the DMA controller locked up no transfers were possible anymore. When DMA was not used for sending commands the controller would recover on next command. I made the option to always use DMA configurable and it turns out that the returned data is prefixed with 00 only when no transfer without DMA was ever made. Loading the spi-nor driver with the dma-only option off and then with dma-only option on results in correct operation. Only loading the dma-only driver first causes the 00 prefix.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 89 lines · Michal Suchanek
Quoted 57 lines · Marek Vasut
On Thursday, July 23, 2015 at 07:03:47 PM, Michal Suchanek wrote:
Hi!
[...]
Quoted 51 lines
Quoted 46 lines
Quoted 5 lines
Quoted 2 lines
It's probably slower to set up DMA for 2-byte commands but it might work nonetheless.
It is, the overhead will be considerable. It might help the stability though. I'm really looking forward to the results!
Hello,
this does not quite work.
My test with spidev:
# ./spinor /dev/spidev1.0 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60 Sending 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff ff ff ff c8 15 c8 15 c8 15 c8 15 c8 15 c8 Sending 9f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Received 00 ff c8 60 16 c8 60 16 c8 60 16 c8 60 16 c8 60I receive correct ID but spi-nor complains it does not know ID 00 c8
60. IIRC garbage should be sent only at the time command is transferred so only one byte of garbage should be received. Also the garbage tends to be the last state of the data output - all 0 or all 1.
So it seems using DMA for all transfers including 1-byte commands results in (some?) received data getting an extra 00 prefix.I also managed to lock up the controller completely since there is some error passing the SPI speed somewhere :(
[ 1352.977530] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977540] spidev spi1.0: spi mode 0 [ 1352.977576] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977582] spidev spi1.0: msb first [ 1352.977614] spidev spi1.0: setup mode 0, 8 bits/w, 80000000 Hz max --> 0 [ 1352.977620] spidev spi1.0: 0 bits per word [ 1352.977652] spidev spi1.0: setup mode 0, 8 bits/w, 2690588672 Hz max --> 0 [ 1352.977726] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977753] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: xfer bpw 8 speed -1604378624 [ 1352.977760] spi_master spi1: s3c64xx_spi_config: clk_from_cmu 1 src_clk sclk_spi1 mode bpw 8 [ 1352.977781] spi_master spi1: spi1.0 s3c64xx_spi_transfer_one: usingQuoted 2 lines
dma [ 1352.977797] dma-pl330 121b0000.pdma: setting up request on thread 1
Hmm, on a second thought it probably works as expected more or less.
Quoted 8 lines
Quoted 4 lines
The nonsensical value was passed from application and there is no guard against that.
Since I don't do PIO the controller remains locked up indefinitely.
I have to admit, I don't quite understand the above. I also don't quite know what your spidev test does. Can you possibly just bind a regular SPI NOR driver and run mtdtests to see if it is stable ?
Ok, so here is some summary.
I have a NOR flash attached to a s3c64xx SPI controller with 64byte fifo and a pl330 dma controller.
Normally DMA controller is used for transfers that do not fit into the FIFO.
I tried adding the flash memory ID to the spi-nor driver table and adding a DT node for it.
The flash is rated at 120MHz so I used that speed but the ID was bit-shifted and identification failed. There is DT property samsung,spi-feedback-delay for addressing this and at 120MHz it must be 2 or 3 on this board. 40MHz works with default value 0.
The next step after identification worked was to try reading the flash content. For this the DMA controller is used because data is transferred in blocks larger than 64 bytes. When reading the whole 4MB flash the transfer failed silently. I got a 4MB file of all ones or all zeroes.
Quoted 6 lines
It turns out that
- the pl330 locks up when transfering large amount of data.
Specifically, the maximum power of 2 sized transfer at 120MHz is 128 bytes and 64k at 40MHz. Transferring more than this results in the pl330 locking up and never signalling completion of the transfer.
Hypothesis:
I think this might just be that the controller didn't catch all the inbound clock ticks and thus counted less inbound data than it was set up to receive. The controller thus waits for more data.
Quoted 4 lines
Data
is left in FIFO which causes subsequent commands to fail since garbage is returned instead of command reply. Also subsequent read may cause I/O error or or return an empty page depending on the garbage around.
So the driver for the DMA controller might need to be augmented to handle this case -- add a timeout and in case DMA times out, drain the FIFO to make sure subsequent transfers do not fail.
Quoted 8 lines
- the I/O errors are not checked in spi-nor at all which leads to silent data corruption.
On a suggestion that this may improve reliability I changed the s3c64xx driver to use DMA for all transfers. This caused identification to fail in spin-nor because the ID was prefixed with extra 00 byte. Testing with spidev confirmed that everything is prefixed with extra 00.
The determinism of this is in fact excellent news.
Quoted 8 lines
Also when the DMA controller locked up no
transfers were possible anymore. When DMA was not used for sending commands the controller would recover on next command. I made the option to always use DMA configurable and it turns out that the returned data is prefixed with 00 only when no transfer without DMA was ever made. Loading the spi-nor driver with the dma-only option off and then with dma-only option on results in correct operation. Only loading the dma-only driver first causes the 00 prefix.
Can we conclude that the PIO codepath somehow programs a register somewhere which gets rid of this 0x00 prefix ? If so, this should then also be part of the DMA codepath, or even better, this should be set in probe() somewhere.
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 33 lines · Marek Vasut
Quoted 25 lines · Michal Suchanek
Quoted 2 lines · Marek Vasut
On Thursday, July 23, 2015 at 07:03:47 PM, Michal Suchanek wrote:
Ok, so here is some summary.
I have a NOR flash attached to a s3c64xx SPI controller with 64byte fifo and a pl330 dma controller.
Normally DMA controller is used for transfers that do not fit into the FIFO.
I tried adding the flash memory ID to the spi-nor driver table and adding a DT node for it.
The flash is rated at 120MHz so I used that speed but the ID was bit-shifted and identification failed. There is DT property samsung,spi-feedback-delay for addressing this and at 120MHz it must be 2 or 3 on this board. 40MHz works with default value 0.
The next step after identification worked was to try reading the flash content. For this the DMA controller is used because data is transferred in blocks larger than 64 bytes. When reading the whole 4MB flash the transfer failed silently. I got a 4MB file of all ones or all zeroes.
Quoted 6 lines
It turns out that
- the pl330 locks up when transfering large amount of data.
Specifically, the maximum power of 2 sized transfer at 120MHz is 128 bytes and 64k at 40MHz. Transferring more than this results in the pl330 locking up and never signalling completion of the transfer.
Quoted 4 lines
Hypothesis:
I think this might just be that the controller didn't catch all the inbound clock ticks and thus counted less inbound data than it was set up to receive. The controller thus waits for more data.
The flash chip can transfer data as long as you keep the clock going, especially when you transfer 64k off a 4M flash.
The read command is bound just by stopping the clock. There is always more data to be had.
Quoted 9 lines
Quoted 5 lines
Data
is left in FIFO which causes subsequent commands to fail since garbage is returned instead of command reply. Also subsequent read may cause I/O error or or return an empty page depending on the garbage around.So the driver for the DMA controller might need to be augmented to handle this case -- add a timeout and in case DMA times out, drain the FIFO to make sure subsequent transfers do not fail.
There is no way to add timeout in the DMA driver since it does not know the SPI clock.
The timeout is handled by the SPI driver and it should be possible to augment it to drain the FIFO when DMA fails so long as FIFO level is readable somewhere.
Quoted 21 lines
Quoted 9 lines
- the I/O errors are not checked in spi-nor at all which leads to silent data corruption.
On a suggestion that this may improve reliability I changed the s3c64xx driver to use DMA for all transfers. This caused identification to fail in spin-nor because the ID was prefixed with extra 00 byte. Testing with spidev confirmed that everything is prefixed with extra 00.
The determinism of this is in fact excellent news.
Quoted 8 lines
Also when the DMA controller locked up no
transfers were possible anymore. When DMA was not used for sending commands the controller would recover on next command. I made the option to always use DMA configurable and it turns out that the returned data is prefixed with 00 only when no transfer without DMA was ever made. Loading the spi-nor driver with the dma-only option off and then with dma-only option on results in correct operation. Only loading the dma-only driver first causes the 00 prefix.
Quoted 3 lines
Can we conclude that the PIO codepath somehow programs a register somewhere which gets rid of this
0x00prefix ? If so, this should then also be part of the DMA codepath, or even better, this should be set inprobe()somewhere.
Yes, it looks like it.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 39 lines · Michal Suchanek
Quoted 29 lines · Marek Vasut
Quoted 28 lines · Michal Suchanek
Quoted 1 line · Marek Vasut
On Thursday, July 23, 2015 at 07:03:47 PM, Michal Suchanek wrote:
Ok, so here is some summary.
I have a NOR flash attached to a s3c64xx SPI controller with 64byte fifo and a pl330 dma controller.
Normally DMA controller is used for transfers that do not fit into the FIFO.
I tried adding the flash memory ID to the spi-nor driver table and adding a DT node for it.
The flash is rated at 120MHz so I used that speed but the ID was bit-shifted and identification failed. There is DT property samsung,spi-feedback-delay for addressing this and at 120MHz it must be 2 or 3 on this board. 40MHz works with default value 0.
The next step after identification worked was to try reading the flash content. For this the DMA controller is used because data is transferred in blocks larger than 64 bytes. When reading the whole 4MB flash the transfer failed silently. I got a 4MB file of all ones or all zeroes.
It turns out that
- the pl330 locks up when transfering large amount of data.
Quoted 8 lines
Quoted 3 lines
Specifically, the maximum power of 2 sized transfer at 120MHz is 128 bytes and 64k at 40MHz. Transferring more than this results in the pl330 locking up and never signalling completion of the transfer.
Hypothesis:
I think this might just be that the controller didn't catch all the inbound clock ticks and thus counted less inbound data than it was set up to receive. The controller thus waits for more data.
Quoted 5 lines
The flash chip can transfer data as long as you keep the clock going, especially when you transfer 64k off a 4M flash.
The read command is bound just by stopping the clock. There is always more data to be had.
Sure, if you keep clocking the chip, the data will keep going. Is the chip being clocked ?
Doesn't the PL330 have some kind of a counter register where you can check how much data were received so far ? That should be sufficient to verify this hypothesis of mine.
Quoted 9 lines
Quoted 8 lines
Quoted 4 lines
Data
is left in FIFO which causes subsequent commands to fail since garbage is returned instead of command reply. Also subsequent read may cause I/O error or or return an empty page depending on the garbage around.So the driver for the DMA controller might need to be augmented to handle this case -- add a timeout and in case DMA times out, drain the FIFO to make sure subsequent transfers do not fail.
Quoted 6 lines
There is no way to add timeout in the DMA driver since it does not know the SPI clock.
The timeout is handled by the SPI driver and it should be possible to augment it to drain the FIFO when DMA fails so long as FIFO level is readable somewhere.
If the DMA doesn't complete in certain amount of time, it should time out I'd say. Don't you think ?
Quoted 20 lines
Quoted 20 lines
Quoted 8 lines
- the I/O errors are not checked in spi-nor at all which leads to silent data corruption.
On a suggestion that this may improve reliability I changed the s3c64xx driver to use DMA for all transfers. This caused identification to fail in spin-nor because the ID was prefixed with extra 00 byte. Testing with spidev confirmed that everything is prefixed with extra 00.
The determinism of this is in fact excellent news.
Quoted 8 lines
Also when the DMA controller locked up no
transfers were possible anymore. When DMA was not used for sending commands the controller would recover on next command. I made the option to always use DMA configurable and it turns out that the returned data is prefixed with 00 only when no transfer without DMA was ever made. Loading the spi-nor driver with the dma-only option off and then with dma-only option on results in correct operation. Only loading the dma-only driver first causes the 00 prefix.
Quoted 6 lines
Quoted 4 lines
Can we conclude that the PIO codepath somehow programs a register somewhere which gets rid of this
0x00prefix ? If so, this should then also be part of the DMA codepath, or even better, this should be set inprobe()somewhere.Yes, it looks like it.
Did you find what this could be please ?
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 40 lines · Marek Vasut
Quoted 39 lines · Michal Suchanek
Quoted 37 lines · Marek Vasut
Quoted 24 lines · Michal Suchanek
Quoted 1 line · Marek Vasut
On Thursday, July 23, 2015 at 07:03:47 PM, Michal Suchanek wrote:
Ok, so here is some summary.
I have a NOR flash attached to a s3c64xx SPI controller with 64byte fifo and a pl330 dma controller.
Normally DMA controller is used for transfers that do not fit into the FIFO.
I tried adding the flash memory ID to the spi-nor driver table and adding a DT node for it.
The flash is rated at 120MHz so I used that speed but the ID was bit-shifted and identification failed. There is DT property samsung,spi-feedback-delay for addressing this and at 120MHz it must be 2 or 3 on this board. 40MHz works with default value 0.
The next step after identification worked was to try reading the flash content. For this the DMA controller is used because data is transferred in blocks larger than 64 bytes. When reading the whole 4MB flash the transfer failed silently. I got a 4MB file of all ones or all zeroes.
Quoted 7 lines
It turns out that
- the pl330 locks up when transfering large amount of data.
Specifically, the maximum power of 2 sized transfer at 120MHz is 128 bytes and 64k at 40MHz. Transferring more than this results in the pl330 locking up and never signalling completion of the transfer.
Hypothesis:
I think this might just be that the controller didn't catch all the inbound clock ticks and thus counted less inbound data than it was set up to receive. The controller thus waits for more data.
Quoted 8 lines
Quoted 5 lines
The flash chip can transfer data as long as you keep the clock going, especially when you transfer 64k off a 4M flash.
The read command is bound just by stopping the clock. There is always more data to be had.
Sure, if you keep clocking the chip, the data will keep going. Is the chip being clocked ?
There is always data. Like in whenever you want to read SPI data you sample the input pin and watever you sample is data so far as SPI bus is concerned.
Quoted 4 lines
Doesn't the PL330 have some kind of a counter register where you can check how much data were received so far ? That should be sufficient to verify this hypothesis of mine.
Could check that, yes. Maybe I could read the counter in a function which dmaengine client uses to tear down the dma transfer.
On a related note I enabled more prints on the spidev test program.
I have code that tests maximum transfer size up to the 4k spidev limit and it can transfer full 4k buffer of NOPs at 80MHz.
The recieved data is all ones except a 00 at the start. So it looks like read-only transfers fail but full-duplex sort of work. And it reproduces the 00 prefix that was seen in the dma-only setup in otherwise working setup :-S
An attempt to read a page of data using the fast-read command fails with timeout.
Quoted 13 lines
Quoted 13 lines
Quoted 9 lines
Quoted 5 lines
Data
is left in FIFO which causes subsequent commands to fail since garbage is returned instead of command reply. Also subsequent read may cause I/O error or or return an empty page depending on the garbage around.So the driver for the DMA controller might need to be augmented to handle this case -- add a timeout and in case DMA times out, drain the FIFO to make sure subsequent transfers do not fail.
There is no way to add timeout in the DMA driver since it does not know the SPI clock.
Quoted 6 lines
Quoted 3 lines
The timeout is handled by the SPI driver and it should be possible to augment it to drain the FIFO when DMA fails so long as FIFO level is readable somewhere.
If the DMA doesn't complete in certain amount of time, it should time out I'd say. Don't you think ?
No. The DMA driver has no idea if the transfer is at 133MHz, 40MHz, 1MHz, 1kHz, whatever.
On the other hand, adding a flush_fifo in the SPI driver after DMA failure allows probing the chip reliably by realoding the driver even just after a failed transfer.
Quoted 21 lines
Quoted 21 lines
Quoted 21 lines
Quoted 9 lines
- the I/O errors are not checked in spi-nor at all which leads to silent data corruption.
On a suggestion that this may improve reliability I changed the s3c64xx driver to use DMA for all transfers. This caused identification to fail in spin-nor because the ID was prefixed with extra 00 byte. Testing with spidev confirmed that everything is prefixed with extra 00.
The determinism of this is in fact excellent news.
Quoted 8 lines
Also when the DMA controller locked up no
transfers were possible anymore. When DMA was not used for sending commands the controller would recover on next command. I made the option to always use DMA configurable and it turns out that the returned data is prefixed with 00 only when no transfer without DMA was ever made. Loading the spi-nor driver with the dma-only option off and then with dma-only option on results in correct operation. Only loading the dma-only driver first causes the 00 prefix.
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Can we conclude that the PIO codepath somehow programs a register somewhere which gets rid of this
0x00prefix ? If so, this should then also be part of the DMA codepath, or even better, this should be set inprobe()somewhere.Yes, it looks like it.
Did you find what this could be please ?
The suspicious function is enable_datapath in the s3c64xx driver. There is even a comment about keeping the clock going on half-duplex transfers.
I did not get to dissecting it so far.
Thanks
Michal
Re: [PATCH 08/11] MTD: m25p80: Add option to limit SPI transfer size.
Quoted 47 lines · Michal Suchanek
Quoted 46 lines · Marek Vasut
Quoted 44 lines · Michal Suchanek
Quoted 29 lines · Marek Vasut
Quoted 28 lines · Michal Suchanek
Quoted 1 line · Marek Vasut
On Thursday, July 23, 2015 at 07:03:47 PM, Michal Suchanek wrote:
Ok, so here is some summary.
I have a NOR flash attached to a s3c64xx SPI controller with 64byte fifo and a pl330 dma controller.
Normally DMA controller is used for transfers that do not fit into the FIFO.
I tried adding the flash memory ID to the spi-nor driver table and adding a DT node for it.
The flash is rated at 120MHz so I used that speed but the ID was bit-shifted and identification failed. There is DT property samsung,spi-feedback-delay for addressing this and at 120MHz it must be 2 or 3 on this board. 40MHz works with default value 0.
The next step after identification worked was to try reading the flash content. For this the DMA controller is used because data is transferred in blocks larger than 64 bytes. When reading the whole 4MB flash the transfer failed silently. I got a 4MB file of all ones or all zeroes.
It turns out that
- the pl330 locks up when transfering large amount of data.
Quoted 8 lines
Quoted 3 lines
Specifically, the maximum power of 2 sized transfer at 120MHz is 128 bytes and 64k at 40MHz. Transferring more than this results in the pl330 locking up and never signalling completion of the transfer.
Hypothesis:
I think this might just be that the controller didn't catch all the inbound clock ticks and thus counted less inbound data than it was set up to receive. The controller thus waits for more data.The flash chip can transfer data as long as you keep the clock going, especially when you transfer 64k off a 4M flash.
The read command is bound just by stopping the clock. There is always more data to be had.
Quoted 6 lines
Quoted 2 lines
Sure, if you keep clocking the chip, the data will keep going. Is the chip being clocked ?
There is always data. Like in whenever you want to read SPI data you sample the input pin and watever you sample is data so far as SPI bus is concerned.
Aren't you forgetting that the data are synchronous to the clock which you (your SPI block) generate ?
Quoted 6 lines
Quoted 3 lines
Doesn't the PL330 have some kind of a counter register where you can check how much data were received so far ? That should be sufficient to verify this hypothesis of mine.
Could check that, yes. Maybe I could read the counter in a function which dmaengine client uses to tear down the dma transfer.
Might be a good idea. Check if the register is stuck for too long and then zap the transfer.
Quoted 5 lines
On a related note I enabled more prints on the spidev test program.
I have code that tests maximum transfer size up to the 4k spidev limit and it can transfer full 4k buffer of NOPs at 80MHz.
Quoted 7 lines
The recieved data is all ones except a 00 at the start. So it looks like read-only transfers fail but full-duplex sort of work. And it reproduces the 00 prefix that was seen in the dma-only setup in otherwise working setup :-S
An attempt to read a page of data using the fast-read command fails with timeout.
It would be a good idea to detail what your program exactly does on the bus (like, "my program sends 3 bytes of data 0xf0 0x0b 0xar and then receives 60 bytes of data"). Maybe I'm lost, but your test is really not clear.
Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 9 lines
Quoted 5 lines
Data
is left in FIFO which causes subsequent commands to fail since garbage is returned instead of command reply. Also subsequent read may cause I/O error or or return an empty page depending on the garbage around.So the driver for the DMA controller might need to be augmented to handle this case -- add a timeout and in case DMA times out, drain the FIFO to make sure subsequent transfers do not fail.
There is no way to add timeout in the DMA driver since it does not know the SPI clock.
The timeout is handled by the SPI driver and it should be possible to augment it to drain the FIFO when DMA fails so long as FIFO level is readable somewhere.
Quoted 5 lines
Quoted 2 lines
If the DMA doesn't complete in certain amount of time, it should time out I'd say. Don't you think ?
No. The DMA driver has no idea if the transfer is at 133MHz, 40MHz, 1MHz, 1kHz, whatever.
That's not really important, is it ? If the transfer doesn't finish in, say, 1 second, and it is a 4096b transfer, then it is most likely timeout.
Quoted 3 lines
On the other hand, adding a
flush_fifoin the SPI driver after DMA failure allows probing the chip reliably by realoding the driver even just after a failed transfer.
OK
Quoted 27 lines
Quoted 27 lines
Quoted 26 lines
Quoted 20 lines
Quoted 8 lines
- the I/O errors are not checked in spi-nor at all which leads to silent data corruption.
On a suggestion that this may improve reliability I changed the s3c64xx driver to use DMA for all transfers. This caused identification to fail in spin-nor because the ID was prefixed with extra 00 byte. Testing with spidev confirmed that everything is prefixed with extra 00.
The determinism of this is in fact excellent news.
Quoted 8 lines
Also when the DMA controller locked up no
transfers were possible anymore. When DMA was not used for sending commands the controller would recover on next command. I made the option to always use DMA configurable and it turns out that the returned data is prefixed with 00 only when no transfer without DMA was ever made. Loading the spi-nor driver with the dma-only option off and then with dma-only option on results in correct operation. Only loading the dma-only driver first causes the 00 prefix.Quoted 4 lines
Can we conclude that the PIO codepath somehow programs a register somewhere which gets rid of this
0x00prefix ? If so, this should then also be part of the DMA codepath, or even better, this should be set inprobe()somewhere.Yes, it looks like it.
Quoted 7 lines
Quoted 1 line
Did you find what this could be please ?
The suspicious function is
enable_datapathin the s3c64xx driver. There is even a comment about keeping the clock going on half-duplex transfers.I did not get to dissecting it so far.
Good luck!
PATCH 9/11 dma: pl330: fix wording in mcbufsz message
In reply to Michal SuchanekThe kernel is not trying to increase mcbufsz. It suggests you should try doing so. Also print the calculated required size of mcbufsz.
--- drivers/dma/pl330.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/dma/pl330.c +2 -2
@@ -1436,8 +1436,8 @@ static int pl330_submit_req(struct pl330_thread *thrd, goto xfer_exit;if (ret > pl330->mcbufsz /2 ) { -dev_info (pl330->ddma.dev,"%s:%d Trying increasing mcbufsz\n" , - __func__, __LINE__); +dev_info (pl330->ddma.dev,"%s:%d Try increasing mcbufsz (%i/%i)\n" , + __func__, __LINE__, ret, pl330->mcbufsz /2 ); ret = -ENOMEM ; goto xfer_exit; }
Signature · 1 line
2.1.4
Re: [PATCH 09/11] dma: pl330: fix wording in mcbufsz message
Quoted 4 lines · Michal Suchanek
The kernel is not trying to increase mcbufsz. It suggests you should try doing so. Also print the calculated required size of mcbufsz.
Signed-off-by Michal Suchanek <[email protected]>
Looks good:
Best regards,
Krzysztof
Re: [PATCH 09/11] dma: pl330: fix wording in mcbufsz message
In reply to Michal SuchanekQuoted 4 lines · Michal Suchanek
The kernel is not trying to increase mcbufsz. It suggests you should try doing so. Also print the calculated required size of mcbufsz.
Signed-off-by Michal Suchanek <[email protected]>
Looks good:
Best regards,
Krzysztof
Re: [PATCH 09/11] dma: pl330: fix wording in mcbufsz message
In reply to Michal SuchanekQuoted 2 lines · Michal Suchanek
The kernel is not trying to increase mcbufsz. It suggests you should try doing so. Also print the calculated required size of mcbufsz.
pls use right subsystem name in the patches
I have applied this now
Signature · 1 line
~Vinod
PATCH 10/11 spi: add more debug prints in s3c64xx
In reply to Michal SuchanekThe SPI NOR transfers mysteriously fail so add more debug prints about SPI transactions.
--- drivers/spi/spi-s3c64xx.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
drivers/spi/spi-s3c64xx.c +30 -0
@@ -18,6 +18,7 @@#include <linux/interrupt.h> #include <linux/delay.h> #include <linux/clk.h> +#include <linux/clk-provider.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/platform_device.h>
@@ -469,6 +470,7 @@ static int wait_for_dma(struct s3c64xx_spi_driver_data *sdd, {void __iomem *regs = sdd->regs;unsigned long val; +unsigned long start, end;u32 status;int ms;
@@ -477,8 +479,20 @@ static int wait_for_dma(struct s3c64xx_spi_driver_data *sdd, ms +=10 ;/* some tolerance */ ms *=10 ; +pr_debug ("%s %s %s waiting for %ims transferring %zubytes@%iHz" , + __func__, sdd->pdev ?dev_name (&sdd->pdev->dev) :NULL , +dev_name (&sdd->master->dev), + ms, xfer->len, sdd->cur_speed); + val =msecs_to_jiffies (ms) +10 ; + start = jiffies; val =wait_for_completion_timeout (&sdd->xfer_completion, val); + end = jiffies; + +pr_debug ("%s %s %s waited %u ms" , + __func__, sdd->pdev ?dev_name (&sdd->pdev->dev) :NULL , +dev_name (&sdd->master->dev), +jiffies_to_msecs (end - start));/* * If the previous xfer was completed within timeout, then
@@ -577,6 +591,14 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)void __iomem *regs = sdd->regs;u32 val; +pr_debug ("%s %s %s clk_from_cmu %i src_clk %s mode%s%s bpw %i" , + __func__, sdd->pdev ?dev_name (&sdd->pdev->dev) :NULL , +dev_name (&sdd->master->dev), sdd->port_conf->clk_from_cmu, + sdd->src_clk ?__clk_get_name (sdd->src_clk) :NULL , + (sdd->cur_mode &SPI_CPOL ) ?" SPI_CPOL" :"" , + (sdd->cur_mode &SPI_CPHA ) ?" SPI_CPHA" :"" , + sdd->cur_bpw); +/* Disable Clock */ if (sdd->port_conf->clk_from_cmu) {clk_disable_unprepare (sdd->src_clk);
@@ -679,6 +701,10 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,unsigned long flags;int use_dma; +pr_debug ("%s %s %s %s xfer bpw %i speed %i" , + __func__, sdd->pdev ?dev_name (&sdd->pdev->dev) :NULL , +dev_name (&master->dev),dev_name (&spi->dev), + xfer->bits_per_word, xfer->speed_hz);reinit_completion (&sdd->xfer_completion);/* Only BPW and Speed may change across transfers */
@@ -697,6 +723,10 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master, (sdd->rx_dma.ch && sdd->tx_dma.ch && (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1)))) use_dma =1 ; +pr_debug ("%s %s %s %s %susing dma" , + __func__, sdd->pdev ?dev_name (&sdd->pdev->dev) :NULL , +dev_name (&master->dev),dev_name (&spi->dev), + use_dma ?"" :"not " );spin_lock_irqsave (&sdd->lock, flags);
Signature · 1 line
2.1.4
Re: [PATCH 10/11] spi: add more debug prints in s3c64xx
Quoted 4 lines · Michal Suchanek
The SPI NOR transfers mysteriously fail so add more debug prints about SPI transactions.
Signed-off-by Michal Suchanek <[email protected]>
dev_dbg() and friends would certainly be nicer here.
Best regards,
Marek Vasut
Mark Brown
maintainerRe: [PATCH 10/11] spi: add more debug prints in s3c64xx
In reply to Michal SuchanekQuoted 2 lines · Michal Suchanek
The SPI NOR transfers mysteriously fail so add more debug prints about SPI transactions.
Please try to only send patches to relevant people - the list of recipients for this is so large that it only barely fits on a single screen in my mail client.
Also for this patch (which just adds some trace) there isn't any clear reason for it to be sent as part of the series at all, it doesn't help deliver the functionality and doesn't depend on the rest of the series.
drivers/spi/spi-s3c64xx.c line 21
Quoted 7 lines
drivers/spi/spi-s3c64xx.c +1
-0@@ -18,6 +18,7 @@#include <linux/interrupt.h> #include <linux/delay.h> #include <linux/clk.h> +#include <linux/clk-provider.h>
Whatever you're doing here this indicates that there's a very big abstraction problem going on.
drivers/spi/spi-s3c64xx.c static int wait_for_dma(struct s3c64xx_spi_driver_data *sdd, · line 485
Quoted 4 lines
drivers/spi/spi-s3c64xx.c +4
-0+pr_debug ("%s %s %s waiting for %ims transferring %zubytes@%iHz" , + __func__, sdd->pdev ?dev_name (&sdd->pdev->dev) :NULL , +dev_name (&sdd->master->dev), + ms, xfer->len, sdd->cur_speed);
I'd say dev_dbg() but more generally this is just tracing things that
seem to be already covered by the trace points already present in the
core, the same goes for most of the rest of it. If there's things
missing from the existing trace it seems better to add to it.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150604/bcd71d7d/attachment.sig>
Re: [PATCH 10/11] spi: add more debug prints in s3c64xx
Quoted 10 lines · Mark Brown
drivers/spi/spi-s3c64xx.c line 21
Quoted 7 lines
drivers/spi/spi-s3c64xx.c +1
-0@@ -18,6 +18,7 @@#include <linux/interrupt.h> #include <linux/delay.h> #include <linux/clk.h> +#include <linux/clk-provider.h> Whatever you're doing here this indicates that there's a very big abstraction problem going on.
I guess it's needed for __clk_get_name(), which can be avoided by using the "%pC" printf format specifier instead.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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
Mark Brown
maintainerRe: [PATCH 10/11] spi: add more debug prints in s3c64xx
Quoted 12 lines · Geert Uytterhoeven
Quoted 10 lines · Mark Brown
drivers/spi/spi-s3c64xx.c line 21
Quoted 7 lines
drivers/spi/spi-s3c64xx.c +1
-0@@ -18,6 +18,7 @@#include <linux/interrupt.h> #include <linux/delay.h> #include <linux/clk.h> +#include <linux/clk-provider.h> Whatever you're doing here this indicates that there's a very big abstraction problem going on.
Quoted 2 lines
I guess it's needed for
__clk_get_name(), which can be avoided by using the "%pC" printf format specifier instead.
Right, or by adding an externally usable API - the point is that using
internal functions in a client driver is a big red flag.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150604/64516a5f/attachment-0001.sig>
Re: [PATCH 10/11] spi: add more debug prints in s3c64xx
In reply to Mark BrownHello,
Quoted 11 lines · Mark Brown
Quoted 2 lines · Michal Suchanek
The SPI NOR transfers mysteriously fail so add more debug prints about SPI transactions.
Please try to only send patches to relevant people - the list of recipients for this is so large that it only barely fits on a single screen in my mail client.
Also for this patch (which just adds some trace) there isn't any clear reason for it to be sent as part of the series at all, it doesn't help deliver the functionality and doesn't depend on the rest of the series.
I used this patch to add missing information to dmesg output so I could diagnose the SPI failures so I think it is relevant.
The failure is reported by the s3c64xx but the root cause is pl330 not finishing a DMA transfer.
It is non-obvious that this is the issue. The information that a call to pl330 failed is only available in the s3c64xx driver and not SPI core so I think there is no reasonable way to debug this issue other than adding prints in s3c64xx. This issue is not completely resolved or even well tested (I have only single board to test with) so these prints remain relevant in my view.
Quoted 11 lines
drivers/spi/spi-s3c64xx.c line 21
Quoted 8 lines
drivers/spi/spi-s3c64xx.c +1
-0@@ -18,6 +18,7 @@#include <linux/interrupt.h> #include <linux/delay.h> #include <linux/clk.h> +#include <linux/clk-provider.h> Whatever you're doing here this indicates that there's a very big abstraction problem going on.
I wanted to print a clock name in case the information was relevant for the issue at hand.
To print a clock name you AFAICT need this header. I think this is an abstraction problem in the clock framework. Fixing the abstraction problem with clock framework would only grow the list of recipients which is already so long you complain about it.
It turns out that in this case the clock was not at fault so I did not need the clock name in the end.
Quoted 10 lines
drivers/spi/spi-s3c64xx.c static int wait_for_dma(struct s3c64xx_spi_driver_data *sdd, · line 485
Quoted 5 lines
drivers/spi/spi-s3c64xx.c +4
-0+pr_debug ("%s %s %s waiting for %ims transferring %zubytes@%iHz" , + __func__, sdd->pdev ?dev_name (&sdd->pdev->dev) :NULL , +dev_name (&sdd->master->dev), + ms, xfer->len, sdd->cur_speed);I'd say
dev_dbg()but more generally this is just tracing things that seem to be already covered by the trace points already present in the core, the same goes for most of the rest of it. If there's things missing from the existing trace it seems better to add to it.
There is master and slave device involved but it's certainly possible to use dev_dbg on one of them and pass the other as string.
Thanks
Michal
Mark Brown
maintainerRe: [PATCH 10/11] spi: add more debug prints in s3c64xx
Quoted 8 lines · Michal Suchanek
Quoted 3 lines · Mark Brown
Also for this patch (which just adds some trace) there isn't any clear reason for it to be sent as part of the series at all, it doesn't help deliver the functionality and doesn't depend on the rest of the series.
I used this patch to add missing information to dmesg output so I could diagnose the SPI failures so I think it is relevant.
The fact that you used this to debug problems is not relevant to any fix you might have developed for those problems; the fix can be explained without needing to know how you got there. Similarly the debugging is hopefully useful in general without needing to know which particular problem prompted it's creation.
Quoted 4 lines
To print a clock name you AFAICT need this header. I think this is an abstraction problem in the clock framework. Fixing the abstraction problem with clock framework would only grow the list of recipients which is already so long you complain about it.
This is a bit of a warning sign that the series isn't very focused.
It's also just not good practice, sending patches with obvious problems
(especially obvious problems that aren't clearly flagged up as something
temporary) will frustrate reviewers and can often lead to other issues
being obscured.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150604/f2edb94c/attachment.sig>
Re: [PATCH 10/11] spi: add more debug prints in s3c64xx
Quoted 7 lines · Mark Brown
Quoted 5 lines · Michal Suchanek
Quoted 3 lines · Mark Brown
Also for this patch (which just adds some trace) there isn't any clear reason for it to be sent as part of the series at all, it doesn't help deliver the functionality and doesn't depend on the rest of the series.
Quoted 8 lines
Quoted 2 lines
I used this patch to add missing information to dmesg output so I could diagnose the SPI failures so I think it is relevant.
The fact that you used this to debug problems is not relevant to any fix you might have developed for those problems; the fix can be explained without needing to know how you got there. Similarly the debugging is hopefully useful in general without needing to know which particular problem prompted it's creation.
Yes, this patch should be meaningful on its own.
The ultimate purpose of this patch series is to make the SPI NOR flash chip usable on boards of which I have 1 sample. If the results on boards other than mine happen to be different the debug prints will be useful for users of this flash chip.
There is no code interdependency with the other patches so if it's preferred I can send patches like this separately.
Quoted 11 lines
Quoted 5 lines
To print a clock name you AFAICT need this header. I think this is an abstraction problem in the clock framework. Fixing the abstraction problem with clock framework would only grow the list of recipients which is already so long you complain about it.
This is a bit of a warning sign that the series isn't very focused. It's also just not good practice, sending patches with obvious problems (especially obvious problems that aren't clearly flagged up as something temporary) will frustrate reviewers and can often lead to other issues being obscured.
As has been pointed out public interface already exists for getting the clock name so the issue here is cosmetic.
Thanks
Michal
Mark Brown
maintainerRe: [PATCH 10/11] spi: add more debug prints in s3c64xx
Quoted 2 lines · Michal Suchanek
There is no code interdependency with the other patches so if it's preferred I can send patches like this separately.
Yes, that's better practice.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150604/0ad5f1a4/attachment.sig>
PATCH 11/11 dt: Exynos: add Snow SPI NOR node.
In reply to Michal SuchanekThe Snow has onboard SPI NOR flash which contains the bootloader.
Add DT node for this flash chip. The flash is rated 133MHz but the pl330 controller can transfer only up to 128 bytes at this speed so use more conservative settings. Even at 40MHz pl330 can transfer at most 64k with the current driver.
--- arch/arm/boot/dts/exynos5250-snow.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+)
arch/arm/boot/dts/exynos5250-snow.dts +12 -0
@@ -691,6 +691,18 @@ num-cs = <1>; cs-gpios = <&gpa2 5 0>; status = "okay"; + flash: m25p80 at 0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + linux,max_tx_len = <65536>; + m25p,fast-read; + controller-data { + samsung,spi-feedback-delay = <0>; + }; + }; }; &usbdrd_dwc3 {
Signature · 1 line
2.1.4
Re: [PATCH 11/11] dt: Exynos: add Snow SPI NOR node.
Quoted 17 lines · Michal Suchanek
The Snow has onboard SPI NOR flash which contains the bootloader.
Add DT node for this flash chip. The flash is rated 133MHz but the pl330 controller can transfer only up to 128 bytes at this speed so use more conservative settings. Even at 40MHz pl330 can transfer at most 64k with the current driver.
Signed-off-by Michal Suchanek <[email protected]>--- arch/arm/boot/dts/exynos5250-snow.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+)arch/arm/boot/dts/exynos5250-snow.dts +0
-0
arch/arm/boot/dts/exynos5250-snow.dts line 694
Quoted 4 lines
arch/arm/boot/dts/exynos5250-snow.dts +1
-0@@ -691,6 +691,18 @@ num-cs = <1>; cs-gpios = <&gpa2 5 0>; status = "okay"; + flash: m25p80 at 0 {
The indentation looks odd. This should be at the same level as "status".
arch/arm/boot/dts/exynos5250-snow.dts line 699
Quoted 5 lines
arch/arm/boot/dts/exynos5250-snow.dts +5
-0+ #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>;
So actually you wanted 133 MHz but as a workaround for DMA issue you use 40 MHz, right? Could you add here a small TODO note in comment about it?
Best regards,
Krzysztof
Re: [PATCH 11/11] dt: Exynos: add Snow SPI NOR node.
Quoted 28 lines · Krzysztof Kozlowski
Quoted 18 lines · Michal Suchanek
The Snow has onboard SPI NOR flash which contains the bootloader.
Add DT node for this flash chip. The flash is rated 133MHz but the pl330 controller can transfer only up to 128 bytes at this speed so use more conservative settings. Even at 40MHz pl330 can transfer at most 64k with the current driver.
Signed-off-by Michal Suchanek <[email protected]>---
arch/arm/boot/dts/exynos5250-snow.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+)(quoted diff) +0
-0
b/arch/arm/boot/dts/exynos5250-snow.dtsindex 1fa72cf..38e4cda 100644arch/arm/boot/dts/exynos5250-snow.dts line 696
Quoted 6 lines
arch/arm/boot/dts/exynos5250-snow.dts +1
-0@@ -691,6 +691,18 @@ num-cs = <1>; cs-gpios = <&gpa2 5 0>; status = "okay"; + flash: m25p80 at 0 {The indentation looks odd. This should be at the same level as "status".
Quoted 8 lines
arch/arm/boot/dts/exynos5250-snow.dts line 699
Quoted 5 lines
arch/arm/boot/dts/exynos5250-snow.dts +5
-0+ #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>;So actually you wanted 133 MHz but as a workaround for DMA issue you use 40 MHz, right? Could you add here a small TODO note in comment about it?
I disagree. There is a problem, the problem should actually be analyzed and fixed, not just postponed with some TODO nonsense.
Best regards,
Marek Vasut
Re: [PATCH 11/11] dt: Exynos: add Snow SPI NOR node.
Quoted 38 lines · Marek Vasut
Quoted 28 lines · Krzysztof Kozlowski
Quoted 18 lines · Michal Suchanek
The Snow has onboard SPI NOR flash which contains the bootloader.
Add DT node for this flash chip. The flash is rated 133MHz but the pl330 controller can transfer only up to 128 bytes at this speed so use more conservative settings. Even at 40MHz pl330 can transfer at most 64k with the current driver.
Signed-off-by Michal Suchanek <[email protected]>---
arch/arm/boot/dts/exynos5250-snow.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+)(quoted diff) +0
-0
b/arch/arm/boot/dts/exynos5250-snow.dtsindex 1fa72cf..38e4cda 100644arch/arm/boot/dts/exynos5250-snow.dts line 696
Quoted 6 lines
arch/arm/boot/dts/exynos5250-snow.dts +1
-0@@ -691,6 +691,18 @@ num-cs = <1>; cs-gpios = <&gpa2 5 0>; status = "okay"; + flash: m25p80 at 0 {The indentation looks odd. This should be at the same level as "status".
Quoted 8 lines
arch/arm/boot/dts/exynos5250-snow.dts line 699
Quoted 5 lines
arch/arm/boot/dts/exynos5250-snow.dts +5
-0+ #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>;So actually you wanted 133 MHz but as a workaround for DMA issue you use 40 MHz, right? Could you add here a small TODO note in comment about it?
Quoted 2 lines
I disagree. There is a problem, the problem should actually be analyzed and fixed, not just postponed with some TODO nonsense.
Of course, that would be preferable if submitter has time. But OTOH slow SPI is probably better than no SPI at all, and debugging this can be nasty. I think that TODO is suitable.
Pavel
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
A message that is not in the archive (sent off-list or not yet received): 3234c12c90eabbeeb6d33604a324231937e309ec.1433364398.git.hramrach-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Re: [PATCH 11/11] dt: Exynos: add Snow SPI NOR node.
Quoted 17 lines · Michal Suchanek
The Snow has onboard SPI NOR flash which contains the bootloader.
Add DT node for this flash chip. The flash is rated 133MHz but the pl330 controller can transfer only up to 128 bytes at this speed so use more conservative settings. Even at 40MHz pl330 can transfer at most 64k with the current driver.
Signed-off-by Michal Suchanek <[email protected]>--- arch/arm/boot/dts/exynos5250-snow.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+)arch/arm/boot/dts/exynos5250-snow.dts +0
-0
arch/arm/boot/dts/exynos5250-snow.dts line 694
Quoted 4 lines
arch/arm/boot/dts/exynos5250-snow.dts +1
-0@@ -691,6 +691,18 @@ num-cs = <1>; cs-gpios = <&gpa2 5 0>; status = "okay"; + flash: m25p80@0 {
The indentation looks odd. This should be at the same level as "status".
arch/arm/boot/dts/exynos5250-snow.dts line 699
Quoted 5 lines
arch/arm/boot/dts/exynos5250-snow.dts +5
-0+ #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>;
So actually you wanted 133 MHz but as a workaround for DMA issue you use 40 MHz, right? Could you add here a small TODO note in comment about it?
Best regards,
Krzysztof
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 1 line · Michal Suchanek
Hello,
Hi,
Quoted 6 lines
this patch series makes it possible to access the SPI NOR flash in the Samsung XE303 'Snow' Chromebook.
Unfortunately not all issues are resolved. To work around an issue with the pl330 dma engine I respun the patch for limiting transfer size in m25p80 driver.
Looks like fixing a bug at the wrong place to me ...
Quoted 4 lines
As the flash does not contain any sane filesystem and is only likely to be accessed with
mtd_debugor similar tool the limit of the dma engine is easily reached. Filesystems using shorter data transfers are less likely to be affected.
Sounds like the DMA engine driver should be fixed.
Best regards,
Marek Vasut
Quoted 12 lines · Marek Vasut
Quoted 1 line · Michal Suchanek
Hello,
Hi,
Quoted 6 lines
this patch series makes it possible to access the SPI NOR flash in the Samsung XE303 'Snow' Chromebook.
Unfortunately not all issues are resolved. To work around an issue with the pl330 dma engine I respun the patch for limiting transfer size in m25p80 driver.
Quoted 8 lines
Looks like fixing a bug at the wrong place to me ...
Quoted 4 lines
As the flash does not contain any sane filesystem and is only likely to be accessed with
mtd_debugor similar tool the limit of the dma engine is easily reached. Filesystems using shorter data transfers are less likely to be affected.Sounds like the DMA engine driver should be fixed.
I looked at the pl330 datasheet and don't see anything obviusly wrong with the pl330 driver in Linux.
Ideally it would be fixed but I have no idea what's wrong with it.
Thanks
Michal
Quoted 20 lines · Michal Suchanek
Quoted 19 lines · Marek Vasut
Quoted 1 line · Michal Suchanek
Hello,
Hi,
Quoted 6 lines
this patch series makes it possible to access the SPI NOR flash in the Samsung XE303 'Snow' Chromebook.
Unfortunately not all issues are resolved. To work around an issue with the pl330 dma engine I respun the patch for limiting transfer size in m25p80 driver.
Looks like fixing a bug at the wrong place to me ...
Quoted 4 lines
As the flash does not contain any sane filesystem and is only likely to be accessed with
mtd_debugor similar tool the limit of the dma engine is easily reached. Filesystems using shorter data transfers are less likely to be affected.
Quoted 6 lines
Quoted 1 line
Sounds like the DMA engine driver should be fixed.
I looked at the pl330 datasheet and don't see anything obviusly wrong with the pl330 driver in Linux.
Ideally it would be fixed but I have no idea what's wrong with it.
Ask maybe Catalin from ARM to help you -- he might be able to point you to the right hardware guy.
Best regards,
Marek Vasut