Dear Community,
I'd like to ask for two QSPI specific issues:
1. In the current Linux kernel driver - there is a comment regarding the QSPI working in "IP Command Read" mode:
Linux source code: drivers/mtd/spi-nor/fsl-quadspi.c (v4.19-rc4) - Bootlin
It states that on Vybrid it is broken and shall not be used. Could anybody from HW design team comment on it?
2. When I do use AHB mode to read data from two SPI-NOR memories connected to QSPI0 bus (individual mode), only 64 bytes are read correctly. The original Linux driver though wants to read 128 bytes:
Linux source code: drivers/mtd/spi-nor/fsl-quadspi.c (v4.19-rc4) - Bootlin
What is the recommended size for AHB memory transfer size for QSPI?
Thanks in advance,
Łukasz
Solved! Go to Solution.
Hi Edward,
As pointed out by Fabio Estevam on the Linux-mtd mailing list - I had an error in the dts file:
- n25q128a13_2: flash@1 {
+ n25q128a13_2: flash@2 {
compatible = "n25q128a13", "jedec,spi-nor";
#address-cells = <1>;
#size-cells = <1>;
spi-max-frequency = <66000000>;
spi-rx-bus-width = <2>;
- reg = <1>;
+ reg = <2>;
};
The reg=<2> needs to be set to have the second SPI-NOR correctly served (as it is connected to CS.0).
From the dt-bindings:
"Required SPI slave node properties:
- reg: There are two buses (A and B) with two chip selects each.
This encodes to which bus and CS the flash is connected:
<0>: Bus A, CS 0
<1>: Bus A, CS 1
<2>: Bus B, CS 0
<3>: Bus B, CS 1"
I by mistake had the 'reg' set to 1.
(What is _very_ strange the reg=1 worked with the old driver ..... ).
Big thanks for your help.
I'm going to close this topic as new driver for Vybrid works (tested with: tests-spi/spi_nor_quadspi_test.sh at master · lmajewski/tests-spi · GitHub ) and the comment about HW issue was related to the old driver.
Does it mean that Vybrid QSPI is broken in new kernels? If so, then the SoC should be soon abandoned (with retirement of v4.4) - no support from Linux kernel.
Hi Krzysztof,
I don't know the exact plans of NXP for Vybrid SoC support. Definitely it is used by the industry and it would be a pity if it would be removed from the Linux kernel as it is not not maintained anymore.
As of 5.2 kernel it is not functional - the QSPI driver is broken and for example the CAAM module is not supported at all in either vendor or mainline Linux kernel.
This post is here for more than 10 months here without any reply. I've even filled a bug report and posted it to linux-mtd [1], but no reply so far.
Best regards,
Łukasz
[1] - [imx][vybrid][qspi] Regression notification - vybrid vf610 QUADSPI - BK4 board
Fixes for old driver: [RFC/RFT,v1,0/9] mtd: fsl: quadspi: Fixes for fsl-quadspi.c driver (vybrid HW) - Patchwork
Hi,
I wonder this thread is somewhat alive. I saw it previously but didn't think these questions were serious.
1. IP read is not practical for data reads, only to be used when reading status of flash write, chip ID etc. Of course HW works well, so perhaps Linux driver is broken.
2. Question is little weird. In AHB mode you read kilobytes and megabytes. If you mean AHB buffer size specified in command LUT, 128 bytes (32 x 32bit words) in bare metal works perfectly well. So again, perhaps something in Linux driver is broken.
It depends on how fragmented are your reads, as well on cache hits and misses. For sequential read top size is the best. For fragmented: say you execute from QSPI (AHB of course), you read few instruction from one AHB buffer frame and need to jump to another buffer frame. Reading 128 bytes at once while you need only 20 bytes from specific AHB frame you waste time on unused bytes read. Cache won't remember unused lines, so next time jumping back to previous frame whole frame will be re-read from QSPI again. Reducing bytes to read could be faster, but reading smaller amounts you waste time on sending frame address to QSPI memory. Optimal value may be lower than 128.
Hi Edward,
1. IP read is not practical for data reads, only to be used when reading status of flash write, chip ID etc. Of course HW works well, so perhaps Linux driver is broken.
From the very beginning the post was related to Linux kernel driver.
The link in the original message points me to the following comment:
/*
* The IC guy suggests we use the "AHB Command Read" which is faster * then the "IP Command Read". (What's more is * that there is a bug in * the "IP Command Read" in the Vybrid.)
*/
I was just curious what is the bug as NXP employee wrote this comment when he added the code. For my setup there is indeed an issue described in those patches:
[RFC/RFT,v1,2/9] mtd: qspi: Provide quirk to read only half of RX buffer (NXP's vybrid) - Patchwork
2. Question is little weird. In AHB mode you read kilobytes and megabytes. If you mean AHB buffer size specified in command LUT, 128 bytes (32 x 32bit words) in bare metal works perfectly well. So again, perhaps something in Linux driver is broken.
Do you run Linux on Vybrid or somethig smaller/lighter (like some RTOS) ?
- What is the recommended size for AHB memory transfer size for QSPI?
It depends on how fragmented are your reads, as well on cache hits and misses. For sequential read top size is the best. For fragmented: say you execute from QSPI (AHB of course), you read few instruction from one AHB buffer frame and need to jump to another buffer frame. Reading 128 bytes at once while you need only 20 bytes from specific AHB frame you waste time on unused bytes read. Cache won't remember unused lines, so next time jumping back to previous frame whole frame will be re-read from QSPI again. Reducing bytes to read could be faster, but reading smaller amounts you waste time on sending frame address to QSPI memory. Optimal value may be lower than 128.
What is the transfer size for your application? From the above I deduce that it is 128B ? And I don't care (for now) about the performance as I cannot read 256B (with dd on /dev/mtdX) without reading some consecutive 0xFFs (on the old fsl-quadspi.c driver).
[RFC/RFT,v1,2/9] mtd: qspi: Provide quirk to read only half of RX buffer (NXP's vybrid) - Patchwork
Perhaps it matters, in contrast to code mentioned in this patchwork, I use 0 in BUF3CR.ADATSZ and specify AHB transfer size in commands LUT. From RM:
"AHB data transfer size: Defines the data transfer size in 8 Bytes of an AHB triggered access to serial
flash. When ADATSZ = 0, the data size mentioned the sequence pointed to by the SEQID field overrides
this value. SW should ensure that this transfer size is not greater than the size of this buffer."
And regarding 2nd patchwork, no issues with memories aligned back to back, no holes in between. I wonder how memories alignment should matter reading just 256 bytes!?! Perhaps patchwork is about parallel setup? Still no problems with aligned address blocks.
I use QSPI on Vybrid in bare metal app. I've tried QSPI from Linux without issues, kernel from Toradex, some v4.4.x I think, perhaps older, not sure.
Yes, 128. I'm sure I did read + verify whole Tower board QSPI memory from Linux quite long ago, not using it though since NAND is enough for our Linux application.
Hi,
just tried reproducing Vybrid Tower board QSPI read from Linux. It reads just fine using dd. Kernel v4.4 from here
http://git.toradex.com/cgit/linux-toradex.git/log/?h=toradex_vf_4.4
, of course QSPI should made enabled in kernel config, relevant QSPI DTS excerpts:
&qspi0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qspi0>;
status = "okay";
flash0: s25fl128s@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
compatible = "spansion,s25fl128s", "jedec,spi-nor";
spi-max-frequency = <29000000>;
};
flash1: s25fl128s@1 {
reg = <2>;
#address-cells = <1>;
#size-cells = <1>;
compatible = "spansion,s25fl128s", "jedec,spi-nor";
spi-max-frequency = <29000000>;
};
};
&iomuxc {
vf610-twr {
pinctrl_qspi0: qspi0grp {
fsl,pins = <
/*VF610_PAD_PTB6__QSPI0_QPCS1_A*/
/*VF610_PAD_PTB7__QSPI0_B_QPCS1*/
VF610_PAD_PTD0__QSPI0_A_QSCK 0x30C2
VF610_PAD_PTD1__QSPI0_A_CS0 0x30C2
VF610_PAD_PTD2__QSPI0_A_DATA3 0x30C3
VF610_PAD_PTD3__QSPI0_A_DATA2 0x30C3
VF610_PAD_PTD4__QSPI0_A_DATA1 0x30C3
VF610_PAD_PTD5__QSPI0_A_DATA0 0x30C3
VF610_PAD_PTD7__QSPI0_B_QSCK 0x30C2
VF610_PAD_PTD8__QSPI0_B_CS0 0x30C2
VF610_PAD_PTD9__QSPI0_B_DATA3 0x30C3
VF610_PAD_PTD10__QSPI0_B_DATA2 0x30C3
VF610_PAD_PTD11__QSPI0_B_DATA1 0x30C3
VF610_PAD_PTD12__QSPI0_B_DATA0 0x30C3
/*VF610_PAD_PTD13__QSPI0_B_DQS*/
>;
Regards,
Edward
Hi Edward,
As pointed out by Fabio Estevam on the Linux-mtd mailing list - I had an error in the dts file:
- n25q128a13_2: flash@1 {
+ n25q128a13_2: flash@2 {
compatible = "n25q128a13", "jedec,spi-nor";
#address-cells = <1>;
#size-cells = <1>;
spi-max-frequency = <66000000>;
spi-rx-bus-width = <2>;
- reg = <1>;
+ reg = <2>;
};
The reg=<2> needs to be set to have the second SPI-NOR correctly served (as it is connected to CS.0).
From the dt-bindings:
"Required SPI slave node properties:
- reg: There are two buses (A and B) with two chip selects each.
This encodes to which bus and CS the flash is connected:
<0>: Bus A, CS 0
<1>: Bus A, CS 1
<2>: Bus B, CS 0
<3>: Bus B, CS 1"
I by mistake had the 'reg' set to 1.
(What is _very_ strange the reg=1 worked with the old driver ..... ).
Big thanks for your help.
I'm going to close this topic as new driver for Vybrid works (tested with: tests-spi/spi_nor_quadspi_test.sh at master · lmajewski/tests-spi · GitHub ) and the comment about HW issue was related to the old driver.
I would _really_ appreciate a reply from NXP employee on this issue.
Thanks in advance,
Łukasz
Could anyone from NXP reply on this issue?
Thanks in advance,
Łukasz