[v2,03/12] spi: Add a driver for the Freescale/NXP QuadSPI controller

Message ID 1530789310-16254-4-git-send-email-frieder.schrempf@exceet.de
State New
Delegated to: Boris Brezillon
Headers show
Series
  • Port the FSL QSPI driver to the SPI framework
Related show

Commit Message

Frieder Schrempf July 5, 2018, 11:14 a.m.
This driver is derived from the SPI NOR driver at
mtd/spi-nor/fsl-quadspi.c. It uses the new SPI memory interface
of the SPI framework to issue flash memory operations to up to
four connected flash chips (2 buses with 2 CS each).

The controller does not support generic SPI messages.

Signed-off-by: Frieder Schrempf <frieder.schrempf@exceet.de>
---
Changes in v2:

Comments

Frieder Schrempf Aug. 2, 2018, 1:09 p.m. | #1
Ping.

I'm not sure if my message below went out to you at all. At least I 
can't find it in the ML archive.

I still hope someone can help with the questions below.

Meanwhile for the second point I did some tests myself with one chip on 
each of the two buses and it worked fine with my latest v2 patches.
So I'm not sure at all why Yogesh has problems with his setup (two chips 
on the first bus).

Thanks,
Frieder

On 11.07.2018 14:13, Frieder Schrempf wrote:
> Hi guys from NXP,
> 
> we still have some issues/questions concerning the FSL QSPI IP, that 
> somehow block the new driver under the SPI memory framework [1].
> 
> If anyone of you could comment on these, or help finding solutions, this 
> would be very much appreciated.
> 
> 1. The SPI NOR driver was using a reset of the flash and AHB domain to 
> invalidate the AHB buffer [2]. But this needs quite a lot of time, so we 
> have a hack to use two regions in memory and switch between them 
> alternately to invalidate the cache [3]. As this is not so nice, do you 
> know of any other possibility to invalidate the flash?
> 
> 2. We tried to reuse the mapped memory to access different chips on 
> different CS, by switching the QUADSPI_SFA1AD, QUADSPI_SFA2AD, etc. 
> accordingly [4]. This doesn't work as expected, but Yogesh found out, 
> that it works with a fixed memory map for each CS and by adding a 
> ioremap(), as the SPI NOR driver does [5]. Can someone explain this 
> behavior and why the ioremap is needed?
> 
> 3. In case of a NOR page program operation, the driver is expected to 
> write the full page, even if it's larger than the TX buffer size. Boris 
> explained this here: [6].
> So we need to find a way of triggering a refill of the TX buffer by CPU 
> or DMA if possible.
> 
> Thank you in advance for your help,
> 
> Frieder
> 
> [1] https://patchwork.ozlabs.org/cover/939864/
> [2] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/mtd/spi-nor/fsl-quadspi.c?h=v4.18-rc4#n591 
> 
> [3] 
> https://github.com/fschrempf/linux/blob/fsl-qspi-next-2/drivers/spi/spi-fsl-qspi.c#L511 
> 
> [4] 
> https://github.com/fschrempf/linux/blob/fsl-qspi-next-2/drivers/spi/spi-fsl-qspi.c#L476 
> 
> [5] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/mtd/spi-nor/fsl-quadspi.c?h=v4.18-rc4#n906 
> 
> [6] https://patchwork.ozlabs.org/patch/928677/#1950278
Han Xu Aug. 2, 2018, 9:58 p.m. | #2
> -----Original Message-----
> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> Sent: Thursday, August 2, 2018 8:09 AM
> To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
> <fabio.estevam@nxp.com>; Prabhakar Kushwaha
> <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
> shawnguo@kernel.org
> Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com; linux-
> spi@vger.kernel.org; dwmw2@infradead.org;
> computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
> miquel.raynal@bootlin.com; broonie@kernel.org
> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> 
> Ping.
> 
> I'm not sure if my message below went out to you at all. At least I can't find it
> in the ML archive.
> 
> I still hope someone can help with the questions below.
> 
> Meanwhile for the second point I did some tests myself with one chip on
> each of the two buses and it worked fine with my latest v2 patches.
> So I'm not sure at all why Yogesh has problems with his setup (two chips on
> the first bus).

Tried to test the v2 patch set on i.MX6SX SDB board but get the memory map failure.

[    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for resource [mem 0x70000000-0x7fffffff]
[    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe failed
[    1.313922] fsl-quadspi: probe of 21e4000.qspi failed with error -12

This is the reason why dynamic ioremap added in previous driver, please refer to
 https://patchwork.ozlabs.org/patch/503655/

I cannot really test the functionality in this case, will get another platform without such issue and retry.

> 
> Thanks,
> Frieder
> 
> On 11.07.2018 14:13, Frieder Schrempf wrote:
> > Hi guys from NXP,
> >
> > we still have some issues/questions concerning the FSL QSPI IP, that
> > somehow block the new driver under the SPI memory framework [1].
> >
> > If anyone of you could comment on these, or help finding solutions,
> > this would be very much appreciated.
> >
> > 1. The SPI NOR driver was using a reset of the flash and AHB domain to
> > invalidate the AHB buffer [2]. But this needs quite a lot of time, so
> > we have a hack to use two regions in memory and switch between them
> > alternately to invalidate the cache [3]. As this is not so nice, do
> > you know of any other possibility to invalidate the flash?
> >
> > 2. We tried to reuse the mapped memory to access different chips on
> > different CS, by switching the QUADSPI_SFA1AD, QUADSPI_SFA2AD, etc.
> > accordingly [4]. This doesn't work as expected, but Yogesh found out,
> > that it works with a fixed memory map for each CS and by adding a
> > ioremap(), as the SPI NOR driver does [5]. Can someone explain this
> > behavior and why the ioremap is needed?
> >
> > 3. In case of a NOR page program operation, the driver is expected to
> > write the full page, even if it's larger than the TX buffer size.
> > Boris explained this here: [6].
> > So we need to find a way of triggering a refill of the TX buffer by
> > CPU or DMA if possible.
> >
> > Thank you in advance for your help,
> >
> > Frieder
> >
> > [1]
> >
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpat
> >
> chwork.ozlabs.org%2Fcover%2F939864%2F&amp;data=02%7C01%7Chan.xu
> %40nxp.
> >
> com%7C567dbf7050bc4b38dbea08d5f87925db%7C686ea1d3bc2b4c6fa92cd9
> 9c5c301
> >
> 635%7C0%7C0%7C636688121577481337&amp;sdata=d%2BRazwVOV0z0wJ%
> 2BHrOthM6a
> > 50W0o8omAUOQ%2F3Ji%2Fs6M%3D&amp;reserved=0
> > [2]
> > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> > .kernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Ftorvalds%2Flinux.g
> it%
> > 2Ftree%2Fdrivers%2Fmtd%2Fspi-nor%2Ffsl-quadspi.c%3Fh%3Dv4.18-
> rc4%23n59
> >
> 1&amp;data=02%7C01%7Chan.xu%40nxp.com%7C567dbf7050bc4b38dbea0
> 8d5f87925
> >
> db%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63668812157748
> 1337&amp
> > ;sdata=48yLzR8tBHRgLh1rN1Nw1L45%2FNCe4m6idmzvpbi5jpc%3D&amp;re
> served=0
> >
> > [3]
> > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> > hub.com%2Ffschrempf%2Flinux%2Fblob%2Ffsl-qspi-next-
> 2%2Fdrivers%2Fspi%2
> > Fspi-fsl-
> qspi.c%23L511&amp;data=02%7C01%7Chan.xu%40nxp.com%7C567dbf705
> >
> 0bc4b38dbea08d5f87925db%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%
> 7C0%7C6
> >
> 36688121577481337&amp;sdata=lf0Xwxr6RYrs5YHIIf9TO5RbyEgtr1qMus7p0
> vfUgh
> > c%3D&amp;reserved=0
> >
> > [4]
> > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> > hub.com%2Ffschrempf%2Flinux%2Fblob%2Ffsl-qspi-next-
> 2%2Fdrivers%2Fspi%2
> > Fspi-fsl-
> qspi.c%23L476&amp;data=02%7C01%7Chan.xu%40nxp.com%7C567dbf705
> >
> 0bc4b38dbea08d5f87925db%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%
> 7C0%7C6
> >
> 36688121577481337&amp;sdata=NYmMKaTsff7%2FZ%2BO7nRjnsIWDFDrAN
> dXZfgpn0H
> > b6Nmw%3D&amp;reserved=0
> >
> > [5]
> > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit
> > .kernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Ftorvalds%2Flinux.g
> it%
> > 2Ftree%2Fdrivers%2Fmtd%2Fspi-nor%2Ffsl-quadspi.c%3Fh%3Dv4.18-
> rc4%23n90
> >
> 6&amp;data=02%7C01%7Chan.xu%40nxp.com%7C567dbf7050bc4b38dbea0
> 8d5f87925
> >
> db%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63668812157748
> 1337&amp
> > ;sdata=BSLjT%2BlwxocGJT3eJ1pUIYxsrBP%2FCdSt0Mthb%2Bx3ySE%3D&am
> p;reserv
> > ed=0
> >
> > [6]
> >
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpat
> >
> chwork.ozlabs.org%2Fpatch%2F928677%2F%231950278&amp;data=02%7C0
> 1%7Chan
> > .xu%40nxp.com%7C567dbf7050bc4b38dbea08d5f87925db%7C686ea1d3bc
> 2b4c6fa92
> >
> cd99c5c301635%7C0%7C0%7C636688121577491349&amp;sdata=LPUHvPVnX
> Qvp7OfIl
> > yH26FADDXqJI7%2B%2FsUClsfrGx7k%3D&amp;reserved=0
Boris Brezillon Aug. 4, 2018, 1:37 p.m. | #3
Hi Han,

On Thu, 2 Aug 2018 21:58:48 +0000
Han Xu <han.xu@nxp.com> wrote:

> > -----Original Message-----
> > From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> > Sent: Thursday, August 2, 2018 8:09 AM
> > To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
> > <fabio.estevam@nxp.com>; Prabhakar Kushwaha
> > <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> > <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
> > shawnguo@kernel.org
> > Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com; linux-
> > spi@vger.kernel.org; dwmw2@infradead.org;
> > computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
> > miquel.raynal@bootlin.com; broonie@kernel.org
> > Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> > 
> > Ping.
> > 
> > I'm not sure if my message below went out to you at all. At least I can't find it
> > in the ML archive.
> > 
> > I still hope someone can help with the questions below.
> > 
> > Meanwhile for the second point I did some tests myself with one chip on
> > each of the two buses and it worked fine with my latest v2 patches.
> > So I'm not sure at all why Yogesh has problems with his setup (two chips on
> > the first bus).  
> 
> Tried to test the v2 patch set on i.MX6SX SDB board but get the memory map failure.
> 
> [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for resource [mem 0x70000000-0x7fffffff]
> [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe failed
> [    1.313922] fsl-quadspi: probe of 21e4000.qspi failed with error -12
> 
> This is the reason why dynamic ioremap added in previous driver, please refer to
>  https://patchwork.ozlabs.org/patch/503655/

We can reduce the size of the iomap to 2k * 4, since this is all we use
currently. Can you try to change the size of the ioremap call to 16k and
tell us if it works.

Unrelated to this issue, we still have 2 questions left unanswered:

1/ is there an easy way to invalidate AHB buffers? I mean, not
   something that implies a full reset + several milliseconds of delay
   after the reset. Right now we trick the caching logic by mapping a
   portion that is twice the size of the buffer and switching from one
   sub-portion to this other to trigger a real read on each read
   access, but that's hack-ish, and I'd be surprised if HW
   engineers hadn't planned for this "manual AHB buffer flush" case.

2/ if we use DMA, do you know what happens when the TX FIFO runs out
   of data while the TX request is not finished yet. In PIO mode, it
   seems the engine sends garbage on the bus when that happens, and we
   definitely don't want that.

While #1 is not blocking us, #2 is if we don't have those patches
[1][2] applied, and Marek wanted to be sure there was no other
ways to solve the "TX FIFO starvation" issue before considering these
changes. So that'd be great if someone from NXP could have a look/ask
around and give us answers to those 2 questions.

Thanks,

Boris

[1]http://patchwork.ozlabs.org/patch/928677/
[2]http://patchwork.ozlabs.org/patch/928678/
Frieder Schrempf Sept. 3, 2018, 9:02 a.m. | #4
Hi Han,

On 04.08.2018 15:37, Boris Brezillon wrote:
> Hi Han,
> 
> On Thu, 2 Aug 2018 21:58:48 +0000
> Han Xu <han.xu@nxp.com> wrote:
> 
>>> -----Original Message-----
>>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
>>> Sent: Thursday, August 2, 2018 8:09 AM
>>> To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
>>> <fabio.estevam@nxp.com>; Prabhakar Kushwaha
>>> <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
>>> <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
>>> shawnguo@kernel.org
>>> Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com; linux-
>>> spi@vger.kernel.org; dwmw2@infradead.org;
>>> computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
>>> miquel.raynal@bootlin.com; broonie@kernel.org
>>> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
>>>
>>> Ping.
>>>
>>> I'm not sure if my message below went out to you at all. At least I can't find it
>>> in the ML archive.
>>>
>>> I still hope someone can help with the questions below.
>>>
>>> Meanwhile for the second point I did some tests myself with one chip on
>>> each of the two buses and it worked fine with my latest v2 patches.
>>> So I'm not sure at all why Yogesh has problems with his setup (two chips on
>>> the first bus).
>>
>> Tried to test the v2 patch set on i.MX6SX SDB board but get the memory map failure.
>>
>> [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for resource [mem 0x70000000-0x7fffffff]
>> [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe failed
>> [    1.313922] fsl-quadspi: probe of 21e4000.qspi failed with error -12
>>
>> This is the reason why dynamic ioremap added in previous driver, please refer to
>>   https://patchwork.ozlabs.org/patch/503655/
> 
> We can reduce the size of the iomap to 2k * 4, since this is all we use
> currently. Can you try to change the size of the ioremap call to 16k and
> tell us if it works.

Were you able to test with the reduced iomap size?
It would be great to know if it works on your board.

Thanks,
Frieder

> 
> Unrelated to this issue, we still have 2 questions left unanswered:
> 
> 1/ is there an easy way to invalidate AHB buffers? I mean, not
>     something that implies a full reset + several milliseconds of delay
>     after the reset. Right now we trick the caching logic by mapping a
>     portion that is twice the size of the buffer and switching from one
>     sub-portion to this other to trigger a real read on each read
>     access, but that's hack-ish, and I'd be surprised if HW
>     engineers hadn't planned for this "manual AHB buffer flush" case.
> 
> 2/ if we use DMA, do you know what happens when the TX FIFO runs out
>     of data while the TX request is not finished yet. In PIO mode, it
>     seems the engine sends garbage on the bus when that happens, and we
>     definitely don't want that.
> 
> While #1 is not blocking us, #2 is if we don't have those patches
> [1][2] applied, and Marek wanted to be sure there was no other
> ways to solve the "TX FIFO starvation" issue before considering these
> changes. So that'd be great if someone from NXP could have a look/ask
> around and give us answers to those 2 questions.
> 
> Thanks,
> 
> Boris
> 
> [1]http://patchwork.ozlabs.org/patch/928677/
> [2]http://patchwork.ozlabs.org/patch/928678/
>
Yogesh Gaur Sept. 6, 2018, 11:11 a.m. | #5
Hi Boris,

> -----Original Message-----
> From: Boris Brezillon [mailto:boris.brezillon@bootlin.com]
> Sent: Saturday, August 4, 2018 7:07 PM
> To: Han Xu <han.xu@nxp.com>
> Cc: Frieder Schrempf <frieder.schrempf@exceet.de>; David Wolfe
> <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>; Prabhakar
> Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
> mtd@lists.infradead.org; linux-spi@vger.kernel.org; dwmw2@infradead.org;
> computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
> miquel.raynal@bootlin.com; broonie@kernel.org
> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> 
> Hi Han,
> 
> On Thu, 2 Aug 2018 21:58:48 +0000
> Han Xu <han.xu@nxp.com> wrote:
> 
> > > -----Original Message-----
> > > From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> > > Sent: Thursday, August 2, 2018 8:09 AM
> > > To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
> > > <fabio.estevam@nxp.com>; Prabhakar Kushwaha
> > > <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> > > <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
> > > shawnguo@kernel.org
> > > Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com;
> > > linux- spi@vger.kernel.org; dwmw2@infradead.org;
> > > computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
> > > miquel.raynal@bootlin.com; broonie@kernel.org
> > > Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> > >
> > > Ping.
> > >
> > > I'm not sure if my message below went out to you at all. At least I
> > > can't find it in the ML archive.
> > >
> > > I still hope someone can help with the questions below.
> > >
> > > Meanwhile for the second point I did some tests myself with one chip
> > > on each of the two buses and it worked fine with my latest v2 patches.
> > > So I'm not sure at all why Yogesh has problems with his setup (two
> > > chips on the first bus).
> >
> > Tried to test the v2 patch set on i.MX6SX SDB board but get the memory map
> failure.
> >
> > [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for resource [mem
> 0x70000000-0x7fffffff]
> > [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe failed
> > [    1.313922] fsl-quadspi: probe of 21e4000.qspi failed with error -12
> >
> > This is the reason why dynamic ioremap added in previous driver,
> > please refer to
> >
> > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpat
> >
> chwork.ozlabs.org%2Fpatch%2F503655%2F&amp;data=02%7C01%7Cyogeshnar
> ayan
> > .gaur%40nxp.com%7Caed89ff1b0ac4936acd408d5fa0f7303%7C686ea1d3bc2
> b4c6fa
> >
> 92cd99c5c301635%7C0%7C0%7C636689866643724038&amp;sdata=lZnBc0m%
> 2BOp8yY
> > JBFcNBEa2HSoNMhmJjeM9cIoGeVs0E%3D&amp;reserved=0
> 
> We can reduce the size of the iomap to 2k * 4, since this is all we use currently.
> Can you try to change the size of the ioremap call to 16k and tell us if it works.
> 
> Unrelated to this issue, we still have 2 questions left unanswered:
> 
> 1/ is there an easy way to invalidate AHB buffers? I mean, not
>    something that implies a full reset + several milliseconds of delay
>    after the reset. Right now we trick the caching logic by mapping a
>    portion that is twice the size of the buffer and switching from one
>    sub-portion to this other to trigger a real read on each read
>    access, but that's hack-ish, and I'd be surprised if HW
>    engineers hadn't planned for this "manual AHB buffer flush" case.
> 

I had a discussion with the HW IP owner, they said that IP command and AHB command are two separate sets of accessing method to flash. 
Memory coherency between IP and AHB command can't be maintained by the hardware.
So after every IP data write command (write, erase, write reg) AHB RX buffer needs to be flushed.

Software Reset is the safest way to achieve this. 
Adding of the delay in several millisecond after setting of the Reset Bits is too conservative, can be tried with the reduced value.

> 2/ if we use DMA, do you know what happens when the TX FIFO runs out
>    of data while the TX request is not finished yet. In PIO mode, it
>    seems the engine sends garbage on the bus when that happens, and we
>    definitely don't want that.

For this query, they have said TX FIFO is the max limit, if data send more than TX FIFO size then it would results in un-defined behavior and there would be data corruption.

--
Regards
Yogesh Gaur.

> 
> While #1 is not blocking us, #2 is if we don't have those patches [1][2] applied,
> and Marek wanted to be sure there was no other ways to solve the "TX FIFO
> starvation" issue before considering these changes. So that'd be great if
> someone from NXP could have a look/ask around and give us answers to those 2
> questions.
> 
> Thanks,
> 
> Boris
> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatc
> hwork.ozlabs.org%2Fpatch%2F928677%2F&amp;data=02%7C01%7Cyogeshnara
> yan.gaur%40nxp.com%7Caed89ff1b0ac4936acd408d5fa0f7303%7C686ea1d3bc
> 2b4c6fa92cd99c5c301635%7C0%7C0%7C636689866643724038&amp;sdata=Iw
> nETfWcL%2BmDkgFPgAjn73C33a877%2BsZz37qhUdLG0I%3D&amp;reserved=0
> [2]https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatc
> hwork.ozlabs.org%2Fpatch%2F928678%2F&amp;data=02%7C01%7Cyogeshnara
> yan.gaur%40nxp.com%7Caed89ff1b0ac4936acd408d5fa0f7303%7C686ea1d3bc
> 2b4c6fa92cd99c5c301635%7C0%7C0%7C636689866643724038&amp;sdata=thf
> I9yDC2epen9Zp18ekku%2FVLsjUIdX6EIPENBbY8xE%3D&amp;reserved=0
Boris Brezillon Sept. 6, 2018, 11:36 a.m. | #6
On Thu, 6 Sep 2018 11:11:57 +0000
Yogesh Narayan Gaur <yogeshnarayan.gaur@nxp.com> wrote:

> Hi Boris,
> 
> > -----Original Message-----
> > From: Boris Brezillon [mailto:boris.brezillon@bootlin.com]
> > Sent: Saturday, August 4, 2018 7:07 PM
> > To: Han Xu <han.xu@nxp.com>
> > Cc: Frieder Schrempf <frieder.schrempf@exceet.de>; David Wolfe
> > <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
> > Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> > <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
> > mtd@lists.infradead.org; linux-spi@vger.kernel.org;
> > dwmw2@infradead.org; computersforpeace@gmail.com;
> > marek.vasut@gmail.com; richard@nod.at; miquel.raynal@bootlin.com;
> > broonie@kernel.org Subject: Re: Questions about the Freescale/NXP
> > QuadSPI controller
> > 
> > Hi Han,
> > 
> > On Thu, 2 Aug 2018 21:58:48 +0000
> > Han Xu <han.xu@nxp.com> wrote:
> >   
> > > > -----Original Message-----
> > > > From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> > > > Sent: Thursday, August 2, 2018 8:09 AM
> > > > To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
> > > > <fabio.estevam@nxp.com>; Prabhakar Kushwaha
> > > > <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> > > > <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
> > > > shawnguo@kernel.org
> > > > Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com;
> > > > linux- spi@vger.kernel.org; dwmw2@infradead.org;
> > > > computersforpeace@gmail.com; marek.vasut@gmail.com;
> > > > richard@nod.at; miquel.raynal@bootlin.com; broonie@kernel.org
> > > > Subject: Re: Questions about the Freescale/NXP QuadSPI
> > > > controller
> > > >
> > > > Ping.
> > > >
> > > > I'm not sure if my message below went out to you at all. At
> > > > least I can't find it in the ML archive.
> > > >
> > > > I still hope someone can help with the questions below.
> > > >
> > > > Meanwhile for the second point I did some tests myself with one
> > > > chip on each of the two buses and it worked fine with my latest
> > > > v2 patches. So I'm not sure at all why Yogesh has problems with
> > > > his setup (two chips on the first bus).  
> > >
> > > Tried to test the v2 patch set on i.MX6SX SDB board but get the
> > > memory map  
> > failure.  
> > >
> > > [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for
> > > resource [mem  
> > 0x70000000-0x7fffffff]  
> > > [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe
> > > failed [    1.313922] fsl-quadspi: probe of 21e4000.qspi failed
> > > with error -12
> > >
> > > This is the reason why dynamic ioremap added in previous driver,
> > > please refer to
> > >
> > > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpat
> > >  
> > chwork.ozlabs.org%2Fpatch%2F503655%2F&amp;data=02%7C01%7Cyogeshnar
> > ayan  
> > > .gaur%40nxp.com%7Caed89ff1b0ac4936acd408d5fa0f7303%7C686ea1d3bc2  
> > b4c6fa  
> > >  
> > 92cd99c5c301635%7C0%7C0%7C636689866643724038&amp;sdata=lZnBc0m%
> > 2BOp8yY  
> > > JBFcNBEa2HSoNMhmJjeM9cIoGeVs0E%3D&amp;reserved=0  
> > 
> > We can reduce the size of the iomap to 2k * 4, since this is all we
> > use currently. Can you try to change the size of the ioremap call
> > to 16k and tell us if it works.
> > 
> > Unrelated to this issue, we still have 2 questions left unanswered:
> > 
> > 1/ is there an easy way to invalidate AHB buffers? I mean, not
> >    something that implies a full reset + several milliseconds of
> > delay after the reset. Right now we trick the caching logic by
> > mapping a portion that is twice the size of the buffer and
> > switching from one sub-portion to this other to trigger a real read
> > on each read access, but that's hack-ish, and I'd be surprised if HW
> >    engineers hadn't planned for this "manual AHB buffer flush" case.
> >   
> 
> I had a discussion with the HW IP owner, they said that IP command
> and AHB command are two separate sets of accessing method to flash.
> Memory coherency between IP and AHB command can't be maintained by
> the hardware. So after every IP data write command (write, erase,
> write reg) AHB RX buffer needs to be flushed.
> 
> Software Reset is the safest way to achieve this. 
> Adding of the delay in several millisecond after setting of the Reset
> Bits is too conservative, can be tried with the reduced value.

Do you know exactly how many cycles/nanoseconds we should wait? Is
there a status reg that says when the block is ready to be used again?

> 
> > 2/ if we use DMA, do you know what happens when the TX FIFO runs out
> >    of data while the TX request is not finished yet. In PIO mode, it
> >    seems the engine sends garbage on the bus when that happens, and
> > we definitely don't want that.  
> 
> For this query, they have said TX FIFO is the max limit, if data send
> more than TX FIFO size then it would results in un-defined behavior
> and there would be data corruption.

Okay.
Marek, I guess we have a good reason to accept patch [1] now.

[1]http://patchwork.ozlabs.org/patch/928677/
Yogesh Gaur Sept. 6, 2018, 12:22 p.m. | #7
Hi Boris,

> -----Original Message-----
> From: Boris Brezillon [mailto:boris.brezillon@bootlin.com]
> Sent: Thursday, September 6, 2018 5:06 PM
> To: Yogesh Narayan Gaur <yogeshnarayan.gaur@nxp.com>;
> marek.vasut@gmail.com
> Cc: Han Xu <han.xu@nxp.com>; Frieder Schrempf
> <frieder.schrempf@exceet.de>; David Wolfe <david.wolfe@nxp.com>; Fabio
> Estevam <fabio.estevam@nxp.com>; Prabhakar Kushwaha
> <prabhakar.kushwaha@nxp.com>; shawnguo@kernel.org; linux-
> mtd@lists.infradead.org; linux-spi@vger.kernel.org; dwmw2@infradead.org;
> computersforpeace@gmail.com; richard@nod.at; miquel.raynal@bootlin.com;
> broonie@kernel.org
> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> 
> On Thu, 6 Sep 2018 11:11:57 +0000
> Yogesh Narayan Gaur <yogeshnarayan.gaur@nxp.com> wrote:
> 
> > Hi Boris,
> >
> > > -----Original Message-----
> > > From: Boris Brezillon [mailto:boris.brezillon@bootlin.com]
> > > Sent: Saturday, August 4, 2018 7:07 PM
> > > To: Han Xu <han.xu@nxp.com>
> > > Cc: Frieder Schrempf <frieder.schrempf@exceet.de>; David Wolfe
> > > <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
> > > Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan
> Gaur
> > > <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
> > > mtd@lists.infradead.org; linux-spi@vger.kernel.org;
> > > dwmw2@infradead.org; computersforpeace@gmail.com;
> > > marek.vasut@gmail.com; richard@nod.at; miquel.raynal@bootlin.com;
> > > broonie@kernel.org Subject: Re: Questions about the Freescale/NXP
> > > QuadSPI controller
> > >
> > > Hi Han,
> > >
> > > On Thu, 2 Aug 2018 21:58:48 +0000
> > > Han Xu <han.xu@nxp.com> wrote:
> > >
> > > > > -----Original Message-----
> > > > > From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> > > > > Sent: Thursday, August 2, 2018 8:09 AM
> > > > > To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
> > > > > <fabio.estevam@nxp.com>; Prabhakar Kushwaha
> > > > > <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> > > > > <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
> > > > > shawnguo@kernel.org
> > > > > Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com;
> > > > > linux- spi@vger.kernel.org; dwmw2@infradead.org;
> > > > > computersforpeace@gmail.com; marek.vasut@gmail.com;
> > > > > richard@nod.at; miquel.raynal@bootlin.com; broonie@kernel.org
> > > > > Subject: Re: Questions about the Freescale/NXP QuadSPI
> > > > > controller
> > > > >
> > > > > Ping.
> > > > >
> > > > > I'm not sure if my message below went out to you at all. At
> > > > > least I can't find it in the ML archive.
> > > > >
> > > > > I still hope someone can help with the questions below.
> > > > >
> > > > > Meanwhile for the second point I did some tests myself with one
> > > > > chip on each of the two buses and it worked fine with my latest
> > > > > v2 patches. So I'm not sure at all why Yogesh has problems with
> > > > > his setup (two chips on the first bus).
> > > >
> > > > Tried to test the v2 patch set on i.MX6SX SDB board but get the
> > > > memory map
> > > failure.
> > > >
> > > > [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for
> > > > resource [mem
> > > 0x70000000-0x7fffffff]
> > > > [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe
> > > > failed [    1.313922] fsl-quadspi: probe of 21e4000.qspi failed
> > > > with error -12
> > > >
> > > > This is the reason why dynamic ioremap added in previous driver,
> > > > please refer to
> > > >
> > > > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2
> > > > Fpat
> > > >
> > >
> chwork.ozlabs.org%2Fpatch%2F503655%2F&amp;data=02%7C01%7Cyogeshnar
> > > ayan
> > > > .gaur%40nxp.com%7Caed89ff1b0ac4936acd408d5fa0f7303%7C686ea1d3
> bc2
> > > b4c6fa
> > > >
> > >
> 92cd99c5c301635%7C0%7C0%7C636689866643724038&amp;sdata=lZnBc0m%
> > > 2BOp8yY
> > > > JBFcNBEa2HSoNMhmJjeM9cIoGeVs0E%3D&amp;reserved=0
> > >
> > > We can reduce the size of the iomap to 2k * 4, since this is all we
> > > use currently. Can you try to change the size of the ioremap call to
> > > 16k and tell us if it works.
> > >
> > > Unrelated to this issue, we still have 2 questions left unanswered:
> > >
> > > 1/ is there an easy way to invalidate AHB buffers? I mean, not
> > >    something that implies a full reset + several milliseconds of
> > > delay after the reset. Right now we trick the caching logic by
> > > mapping a portion that is twice the size of the buffer and switching
> > > from one sub-portion to this other to trigger a real read on each
> > > read access, but that's hack-ish, and I'd be surprised if HW
> > >    engineers hadn't planned for this "manual AHB buffer flush" case.
> > >
> >
> > I had a discussion with the HW IP owner, they said that IP command and
> > AHB command are two separate sets of accessing method to flash.
> > Memory coherency between IP and AHB command can't be maintained by the
> > hardware. So after every IP data write command (write, erase, write
> > reg) AHB RX buffer needs to be flushed.
> >
> > Software Reset is the safest way to achieve this.
> > Adding of the delay in several millisecond after setting of the Reset
> > Bits is too conservative, can be tried with the reduced value.
> 
> Do you know exactly how many cycles/nanoseconds we should wait? Is there a
> status reg that says when the block is ready to be used again?
> 

There is no specific cycles being mentioned in document and this was the design issue to not having these bits as w1c or any reg which provides the status.
Needs to explicitly set the RESET bits, wait for some time and then reset the RESET bit with 0.
We need to come-out with nanosecond number with the experiment.

> >
> > > 2/ if we use DMA, do you know what happens when the TX FIFO runs out
> > >    of data while the TX request is not finished yet. In PIO mode, it
> > >    seems the engine sends garbage on the bus when that happens, and
> > > we definitely don't want that.
> >
> > For this query, they have said TX FIFO is the max limit, if data send
> > more than TX FIFO size then it would results in un-defined behavior
> > and there would be data corruption.
> 
> Okay.
> Marek, I guess we have a good reason to accept patch [1] now.

Thanks

Regards
Yogesh Gaur

> 
> [1]https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatc
> hwork.ozlabs.org%2Fpatch%2F928677%2F&amp;data=02%7C01%7Cyogeshnara
> yan.gaur%40nxp.com%7Cf8c6c7f0083c4ddf0e0708d613ecec3c%7C686ea1d3bc
> 2b4c6fa92cd99c5c301635%7C0%7C0%7C636718305631257433&amp;sdata=3sI
> wpOn4pXDNsqfPSpJqLXKerll%2BoJ1i%2FV3WMY9cx5s%3D&amp;reserved=0
Han Xu Sept. 12, 2018, 5:04 p.m. | #8
> -----Original Message-----
> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> Sent: Monday, September 3, 2018 4:02 AM
> To: Han Xu <han.xu@nxp.com>
> Cc: Boris Brezillon <boris.brezillon@bootlin.com>; David Wolfe
> <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
> Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan
> Gaur <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
> mtd@lists.infradead.org; linux-spi@vger.kernel.org; dwmw2@infradead.org;
> computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
> miquel.raynal@bootlin.com; broonie@kernel.org
> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> 
> Hi Han,
> 
> On 04.08.2018 15:37, Boris Brezillon wrote:
> > Hi Han,
> >
> > On Thu, 2 Aug 2018 21:58:48 +0000
> > Han Xu <han.xu@nxp.com> wrote:
> >
> >>> -----Original Message-----
> >>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> >>> Sent: Thursday, August 2, 2018 8:09 AM
> >>> To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
> >>> <fabio.estevam@nxp.com>; Prabhakar Kushwaha
> >>> <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> >>> <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
> >>> shawnguo@kernel.org
> >>> Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com;
> >>> linux- spi@vger.kernel.org; dwmw2@infradead.org;
> >>> computersforpeace@gmail.com; marek.vasut@gmail.com;
> richard@nod.at;
> >>> miquel.raynal@bootlin.com; broonie@kernel.org
> >>> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> >>>
> >>> Ping.
> >>>
> >>> I'm not sure if my message below went out to you at all. At least I
> >>> can't find it in the ML archive.
> >>>
> >>> I still hope someone can help with the questions below.
> >>>
> >>> Meanwhile for the second point I did some tests myself with one chip
> >>> on each of the two buses and it worked fine with my latest v2 patches.
> >>> So I'm not sure at all why Yogesh has problems with his setup (two
> >>> chips on the first bus).
> >>
> >> Tried to test the v2 patch set on i.MX6SX SDB board but get the memory
> map failure.
> >>
> >> [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for resource [mem
> 0x70000000-0x7fffffff]
> >> [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe failed
> >> [    1.313922] fsl-quadspi: probe of 21e4000.qspi failed with error -12
> >>
> >> This is the reason why dynamic ioremap added in previous driver, please
> refer to
> >>
> >>
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpa
> >>
> tchwork.ozlabs.org%2Fpatch%2F503655%2F&amp;data=02%7C01%7Chan.xu
> %40nx
> >>
> p.com%7C9f45a8b666d3478f065408d6117bf524%7C686ea1d3bc2b4c6fa92cd9
> 9c5c
> >>
> 301635%7C0%7C0%7C636715621426190473&amp;sdata=XWPfWe%2Fu2ePW
> mNPe179D0
> >> vjTp6eLp0%2FJRF2vRayDwug%3D&amp;reserved=0
> >
> > We can reduce the size of the iomap to 2k * 4, since this is all we
> > use currently. Can you try to change the size of the ioremap call to
> > 16k and tell us if it works.
> 
> Were you able to test with the reduced iomap size?
> It would be great to know if it works on your board.
> 
> Thanks,
> Frieder

Test the code on i.MX6SX sabreauto board with two micron n25q256a chips on two CS.
First issue found is __div0 kernel dump with these code
/* Max 64 dummy clock cycles supported */
if (op->dummy.nbytes * 8 / op->dummy.buswidth > 64)
dummy.buswidth was not set during read id.

Second issue is the second part failed to be probed, tried both buswidth 4 and buswidth 1.

[    1.364979] m25p80 spi5.0: found n25q256a, expected m25p80
[    1.370986] m25p80 spi5.0: n25q256a (32768 Kbytes)
[    1.381020] m25p80 spi5.1: unrecognized JEDEC id bytes: ff, ff, ff

These are the DT settings:
&qspi1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_qspi1_1>;
        status = "okay";

        flash0: n25q256a@0 {
        ¦       #address-cells = <1>;
        ¦       #size-cells = <1>;
        ¦       compatible = "micron,m25p80";
        ¦       spi-max-frequency = <29000000>;
                spi-rx-bus-width = <4>;
                spi-tx-bus-width = <4>;
        ¦       reg = <0>;
        };

        flash1: n25q256a@1 {
        ¦       #address-cells = <1>;
        ¦       #size-cells = <1>;
        ¦       compatible = "micron,m25p80";
        ¦       spi-max-frequency = <29000000>;
                spi-rx-bus-width = <4>;
                spi-tx-bus-width = <4>;
        ¦       reg = <1>;
        };
};

> 
> >
> > Unrelated to this issue, we still have 2 questions left unanswered:
> >
> > 1/ is there an easy way to invalidate AHB buffers? I mean, not
> >     something that implies a full reset + several milliseconds of delay
> >     after the reset. Right now we trick the caching logic by mapping a
> >     portion that is twice the size of the buffer and switching from one
> >     sub-portion to this other to trigger a real read on each read
> >     access, but that's hack-ish, and I'd be surprised if HW
> >     engineers hadn't planned for this "manual AHB buffer flush" case.
> >
> > 2/ if we use DMA, do you know what happens when the TX FIFO runs out
> >     of data while the TX request is not finished yet. In PIO mode, it
> >     seems the engine sends garbage on the bus when that happens, and we
> >     definitely don't want that.
> >
> > While #1 is not blocking us, #2 is if we don't have those patches
> > [1][2] applied, and Marek wanted to be sure there was no other ways to
> > solve the "TX FIFO starvation" issue before considering these changes.
> > So that'd be great if someone from NXP could have a look/ask around
> > and give us answers to those 2 questions.
> >
> > Thanks,
> >
> > Boris
> >
> >
> [1]https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fp
> >
> atchwork.ozlabs.org%2Fpatch%2F928677%2F&amp;data=02%7C01%7Chan.x
> u%40nx
> >
> p.com%7C9f45a8b666d3478f065408d6117bf524%7C686ea1d3bc2b4c6fa92cd9
> 9c5c3
> >
> 01635%7C0%7C0%7C636715621426190473&amp;sdata=p%2FJBfxNd2Swlmrrr
> H9Xk2R2
> > DDl%2BshfXdUoyXAy4bXBc%3D&amp;reserved=0
> >
> [2]https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fp
> >
> atchwork.ozlabs.org%2Fpatch%2F928678%2F&amp;data=02%7C01%7Chan.x
> u%40nx
> >
> p.com%7C9f45a8b666d3478f065408d6117bf524%7C686ea1d3bc2b4c6fa92cd9
> 9c5c3
> >
> 01635%7C0%7C0%7C636715621426190473&amp;sdata=xo2l3Ld3n9mkO5PTW
> 5DOqP7u0
> > %2Bgch0cXs7jEjHVokqQ%3D&amp;reserved=0
> >
Frieder Schrempf Sept. 12, 2018, 6:40 p.m. | #9
Hi Han,

On 12.09.2018 19:04, Han Xu wrote:
> 
> 
>> -----Original Message-----
>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
>> Sent: Monday, September 3, 2018 4:02 AM
>> To: Han Xu <han.xu@nxp.com>
>> Cc: Boris Brezillon <boris.brezillon@bootlin.com>; David Wolfe
>> <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
>> Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan
>> Gaur <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
>> mtd@lists.infradead.org; linux-spi@vger.kernel.org; dwmw2@infradead.org;
>> computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
>> miquel.raynal@bootlin.com; broonie@kernel.org
>> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
>>
>> Hi Han,
>>
>> On 04.08.2018 15:37, Boris Brezillon wrote:
>>> Hi Han,
>>>
>>> On Thu, 2 Aug 2018 21:58:48 +0000
>>> Han Xu <han.xu@nxp.com> wrote:
>>>
>>>>> -----Original Message-----
>>>>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
>>>>> Sent: Thursday, August 2, 2018 8:09 AM
>>>>> To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
>>>>> <fabio.estevam@nxp.com>; Prabhakar Kushwaha
>>>>> <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
>>>>> <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
>>>>> shawnguo@kernel.org
>>>>> Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com;
>>>>> linux- spi@vger.kernel.org; dwmw2@infradead.org;
>>>>> computersforpeace@gmail.com; marek.vasut@gmail.com;
>> richard@nod.at;
>>>>> miquel.raynal@bootlin.com; broonie@kernel.org
>>>>> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
>>>>>
>>>>> Ping.
>>>>>
>>>>> I'm not sure if my message below went out to you at all. At least I
>>>>> can't find it in the ML archive.
>>>>>
>>>>> I still hope someone can help with the questions below.
>>>>>
>>>>> Meanwhile for the second point I did some tests myself with one chip
>>>>> on each of the two buses and it worked fine with my latest v2 patches.
>>>>> So I'm not sure at all why Yogesh has problems with his setup (two
>>>>> chips on the first bus).
>>>>
>>>> Tried to test the v2 patch set on i.MX6SX SDB board but get the memory
>> map failure.
>>>>
>>>> [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for resource [mem
>> 0x70000000-0x7fffffff]
>>>> [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe failed
>>>> [    1.313922] fsl-quadspi: probe of 21e4000.qspi failed with error -12
>>>>
>>>> This is the reason why dynamic ioremap added in previous driver, please
>> refer to
>>>>
>>>>
>> https://smex12-5-en-ctp.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2femea01.safelinks.protection.outlook.com%2f%3furl%3dhttps%253A%252F%252Fpa&umid=d6cc1014-1848-42fb-92fd-9626d45c8050&auth=541e45255b6517100d80c2b1b80b6933b203c492-5aa8e1977a9db94300a9f61f5446e7a21b175f56
>>>>
>> tchwork.ozlabs.org%2Fpatch%2F503655%2F&amp;data=02%7C01%7Chan.xu
>> %40nx
>>>>
>> p.com%7C9f45a8b666d3478f065408d6117bf524%7C686ea1d3bc2b4c6fa92cd9
>> 9c5c
>>>>
>> 301635%7C0%7C0%7C636715621426190473&amp;sdata=XWPfWe%2Fu2ePW
>> mNPe179D0
>>>> vjTp6eLp0%2FJRF2vRayDwug%3D&amp;reserved=0
>>>
>>> We can reduce the size of the iomap to 2k * 4, since this is all we
>>> use currently. Can you try to change the size of the ioremap call to
>>> 16k and tell us if it works.
>>
>> Were you able to test with the reduced iomap size?
>> It would be great to know if it works on your board.
>>
>> Thanks,
>> Frieder
> 
> Test the code on i.MX6SX sabreauto board with two micron n25q256a chips on two CS.
> First issue found is __div0 kernel dump with these code
> /* Max 64 dummy clock cycles supported */
> if (op->dummy.nbytes * 8 / op->dummy.buswidth > 64)
> dummy.buswidth was not set during read id.

First, thank you for coming back to this and doing the test.
I'm currently not sure about the reason for this, but I guess Boris will 
figure it out easily ;)

> 
> Second issue is the second part failed to be probed, tried both buswidth 4 and buswidth 1.
> 
> [    1.364979] m25p80 spi5.0: found n25q256a, expected m25p80
> [    1.370986] m25p80 spi5.0: n25q256a (32768 Kbytes)
> [    1.381020] m25p80 spi5.1: unrecognized JEDEC id bytes: ff, ff, ff
> 
> These are the DT settings:
> &qspi1 {
>          pinctrl-names = "default";
>          pinctrl-0 = <&pinctrl_qspi1_1>;
>          status = "okay";
> 
>          flash0: n25q256a@0 {
>          ¦       #address-cells = <1>;
>          ¦       #size-cells = <1>;
>          ¦       compatible = "micron,m25p80";
>          ¦       spi-max-frequency = <29000000>;
>                  spi-rx-bus-width = <4>;
>                  spi-tx-bus-width = <4>;
>          ¦       reg = <0>;
>          };
> 
>          flash1: n25q256a@1 {
>          ¦       #address-cells = <1>;
>          ¦       #size-cells = <1>;
>          ¦       compatible = "micron,m25p80";
>          ¦       spi-max-frequency = <29000000>;
>                  spi-rx-bus-width = <4>;
>                  spi-tx-bus-width = <4>;
>          ¦       reg = <1>;
>          };
> };

First, I think you should add "jedec,spi-nor" to your compatible properties.

Second, are you sure, that the two chips are both on QSPIA using the two 
chip selects?
I have no schematics of the board, but if I look at the devicetree in 
the linux-imx kernel [1] it seems to me that one chip is on QSPIA CS0 
and the other on QSPIB CS0.
If this is the case, then you have to set reg = <2> for the second chip.

Thanks,
Frieder

[1] 
http://git.freescale.com/git/cgit.cgi/imx/linux-imx.git/tree/arch/arm/boot/dts/imx6sx-sabreauto.dts?h=imx_4.9.11_1.0.0_ga#n771

>>>
>>> Unrelated to this issue, we still have 2 questions left unanswered:
>>>
>>> 1/ is there an easy way to invalidate AHB buffers? I mean, not
>>>      something that implies a full reset + several milliseconds of delay
>>>      after the reset. Right now we trick the caching logic by mapping a
>>>      portion that is twice the size of the buffer and switching from one
>>>      sub-portion to this other to trigger a real read on each read
>>>      access, but that's hack-ish, and I'd be surprised if HW
>>>      engineers hadn't planned for this "manual AHB buffer flush" case.
>>>
>>> 2/ if we use DMA, do you know what happens when the TX FIFO runs out
>>>      of data while the TX request is not finished yet. In PIO mode, it
>>>      seems the engine sends garbage on the bus when that happens, and we
>>>      definitely don't want that.
>>>
>>> While #1 is not blocking us, #2 is if we don't have those patches
>>> [1][2] applied, and Marek wanted to be sure there was no other ways to
>>> solve the "TX FIFO starvation" issue before considering these changes.
>>> So that'd be great if someone from NXP could have a look/ask around
>>> and give us answers to those 2 questions.
>>>
>>> Thanks,
>>>
>>> Boris
Han Xu Sept. 12, 2018, 9:04 p.m. | #10
> -----Original Message-----
> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> Sent: Wednesday, September 12, 2018 1:41 PM
> To: Han Xu <han.xu@nxp.com>
> Cc: Boris Brezillon <boris.brezillon@bootlin.com>; David Wolfe
> <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
> Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan
> Gaur <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
> mtd@lists.infradead.org; linux-spi@vger.kernel.org; dwmw2@infradead.org;
> computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
> miquel.raynal@bootlin.com; broonie@kernel.org
> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> 
> Hi Han,
> 
> On 12.09.2018 19:04, Han Xu wrote:
> >
> >
> >> -----Original Message-----
> >> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> >> Sent: Monday, September 3, 2018 4:02 AM
> >> To: Han Xu <han.xu@nxp.com>
> >> Cc: Boris Brezillon <boris.brezillon@bootlin.com>; David Wolfe
> >> <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
> >> Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan
> Gaur
> >> <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
> >> mtd@lists.infradead.org; linux-spi@vger.kernel.org;
> >> dwmw2@infradead.org; computersforpeace@gmail.com;
> >> marek.vasut@gmail.com; richard@nod.at; miquel.raynal@bootlin.com;
> >> broonie@kernel.org
> >> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> >>
> >> Hi Han,
> >>
> >> On 04.08.2018 15:37, Boris Brezillon wrote:
> >>> Hi Han,
> >>>
> >>> On Thu, 2 Aug 2018 21:58:48 +0000
> >>> Han Xu <han.xu@nxp.com> wrote:
> >>>
> >>>>> -----Original Message-----
> >>>>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> >>>>> Sent: Thursday, August 2, 2018 8:09 AM
> >>>>> To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
> >>>>> <fabio.estevam@nxp.com>; Prabhakar Kushwaha
> >>>>> <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> >>>>> <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
> >>>>> shawnguo@kernel.org
> >>>>> Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com;
> >>>>> linux- spi@vger.kernel.org; dwmw2@infradead.org;
> >>>>> computersforpeace@gmail.com; marek.vasut@gmail.com;
> >> richard@nod.at;
> >>>>> miquel.raynal@bootlin.com; broonie@kernel.org
> >>>>> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> >>>>>
> >>>>> Ping.
> >>>>>
> >>>>> I'm not sure if my message below went out to you at all. At least
> >>>>> I can't find it in the ML archive.
> >>>>>
> >>>>> I still hope someone can help with the questions below.
> >>>>>
> >>>>> Meanwhile for the second point I did some tests myself with one
> >>>>> chip on each of the two buses and it worked fine with my latest v2
> patches.
> >>>>> So I'm not sure at all why Yogesh has problems with his setup (two
> >>>>> chips on the first bus).
> >>>>
> >>>> Tried to test the v2 patch set on i.MX6SX SDB board but get the
> >>>> memory
> >> map failure.
> >>>>
> >>>> [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for resource
> [mem
> >> 0x70000000-0x7fffffff]
> >>>> [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe failed
> >>>> [    1.313922] fsl-quadspi: probe of 21e4000.qspi failed with error -12
> >>>>
> >>>> This is the reason why dynamic ioremap added in previous driver,
> >>>> please
> >> refer to
> >>>>
> >>>>
> >>
> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsm
> >> ex12-5-en-
> ctp.trendmicro.com%3A443%2Fwis%2Fclicktime%2Fv1%2Fquery%3Fu
> >>
> rl%3Dhttps%253a%252f%252femea01.safelinks.protection.outlook.com%252
> f
> >> %253furl%253dhttps%25253A%25252F%25252Fpa%26umid%3Dd6cc1014-
> 1848-42fb
> >> -92fd-
> 9626d45c8050%26auth%3D541e45255b6517100d80c2b1b80b6933b203c492-
> >>
> 5aa8e1977a9db94300a9f61f5446e7a21b175f56&amp;data=02%7C01%7Chan.x
> u%40
> >>
> nxp.com%7C9d43e9b29a82419a36c408d618df3dc3%7C686ea1d3bc2b4c6fa92c
> d99c
> >>
> 5c301635%7C0%7C0%7C636723744426896223&amp;sdata=Y32I9H9adPn%2Bn
> lcICuV
> >> M8Uoozsig%2BM3F0rNAhkIF5ZE%3D&amp;reserved=0
> >>>>
> >>
> tchwork.ozlabs.org%2Fpatch%2F503655%2F&amp;data=02%7C01%7Chan.xu
> >> %40nx
> >>>>
> >>
> p.com%7C9f45a8b666d3478f065408d6117bf524%7C686ea1d3bc2b4c6fa92cd9
> >> 9c5c
> >>>>
> >>
> 301635%7C0%7C0%7C636715621426190473&amp;sdata=XWPfWe%2Fu2ePW
> >> mNPe179D0
> >>>> vjTp6eLp0%2FJRF2vRayDwug%3D&amp;reserved=0
> >>>
> >>> We can reduce the size of the iomap to 2k * 4, since this is all we
> >>> use currently. Can you try to change the size of the ioremap call to
> >>> 16k and tell us if it works.
> >>
> >> Were you able to test with the reduced iomap size?
> >> It would be great to know if it works on your board.
> >>
> >> Thanks,
> >> Frieder
> >
> > Test the code on i.MX6SX sabreauto board with two micron n25q256a chips
> on two CS.
> > First issue found is __div0 kernel dump with these code
> > /* Max 64 dummy clock cycles supported */ if (op->dummy.nbytes * 8 /
> > op->dummy.buswidth > 64) dummy.buswidth was not set during read id.
> 
> First, thank you for coming back to this and doing the test.
> I'm currently not sure about the reason for this, but I guess Boris will figure it
> out easily ;)
> 
> >
> > Second issue is the second part failed to be probed, tried both buswidth 4
> and buswidth 1.
> >
> > [    1.364979] m25p80 spi5.0: found n25q256a, expected m25p80
> > [    1.370986] m25p80 spi5.0: n25q256a (32768 Kbytes)
> > [    1.381020] m25p80 spi5.1: unrecognized JEDEC id bytes: ff, ff, ff
> >
> > These are the DT settings:
> > &qspi1 {
> >          pinctrl-names = "default";
> >          pinctrl-0 = <&pinctrl_qspi1_1>;
> >          status = "okay";
> >
> >          flash0: n25q256a@0 {
> >          ¦       #address-cells = <1>;
> >          ¦       #size-cells = <1>;
> >          ¦       compatible = "micron,m25p80";
> >          ¦       spi-max-frequency = <29000000>;
> >                  spi-rx-bus-width = <4>;
> >                  spi-tx-bus-width = <4>;
> >          ¦       reg = <0>;
> >          };
> >
> >          flash1: n25q256a@1 {
> >          ¦       #address-cells = <1>;
> >          ¦       #size-cells = <1>;
> >          ¦       compatible = "micron,m25p80";
> >          ¦       spi-max-frequency = <29000000>;
> >                  spi-rx-bus-width = <4>;
> >                  spi-tx-bus-width = <4>;
> >          ¦       reg = <1>;
> >          };
> > };
> 
> First, I think you should add "jedec,spi-nor" to your compatible properties.
> 
> Second, are you sure, that the two chips are both on QSPIA using the two
> chip selects?
> I have no schematics of the board, but if I look at the devicetree in the linux-
> imx kernel [1] it seems to me that one chip is on QSPIA CS0 and the other on
> QSPIB CS0.
> If this is the case, then you have to set reg = <2> for the second chip.

Yes, you are right, the second chip connects to QSPIB CS0, with the DT change, both of them work fine with __div0 issue workaround.

> 
> Thanks,
> Frieder
> 
> [1]
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fgit.f
> reescale.com%2Fgit%2Fcgit.cgi%2Fimx%2Flinux-
> imx.git%2Ftree%2Farch%2Farm%2Fboot%2Fdts%2Fimx6sx-
> sabreauto.dts%3Fh%3Dimx_4.9.11_1.0.0_ga%23n771&amp;data=02%7C01%
> 7Chan.xu%40nxp.com%7C9d43e9b29a82419a36c408d618df3dc3%7C686ea1d
> 3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C636723744426896223&amp;sdata
> =038DdgMLjO23Io3CTHoSVrJL2Ho%2BgxyHlx9%2BLMrLWkQ%3D&amp;reser
> ved=0
> 
> >>>
> >>> Unrelated to this issue, we still have 2 questions left unanswered:
> >>>
> >>> 1/ is there an easy way to invalidate AHB buffers? I mean, not
> >>>      something that implies a full reset + several milliseconds of delay
> >>>      after the reset. Right now we trick the caching logic by mapping a
> >>>      portion that is twice the size of the buffer and switching from one
> >>>      sub-portion to this other to trigger a real read on each read
> >>>      access, but that's hack-ish, and I'd be surprised if HW
> >>>      engineers hadn't planned for this "manual AHB buffer flush" case.
> >>>
> >>> 2/ if we use DMA, do you know what happens when the TX FIFO runs
> out
> >>>      of data while the TX request is not finished yet. In PIO mode, it
> >>>      seems the engine sends garbage on the bus when that happens, and
> we
> >>>      definitely don't want that.
> >>>
> >>> While #1 is not blocking us, #2 is if we don't have those patches
> >>> [1][2] applied, and Marek wanted to be sure there was no other ways
> >>> to solve the "TX FIFO starvation" issue before considering these changes.
> >>> So that'd be great if someone from NXP could have a look/ask around
> >>> and give us answers to those 2 questions.
> >>>
> >>> Thanks,
> >>>
> >>> Boris
Frieder Schrempf Sept. 13, 2018, 7 a.m. | #11
Hi Han,

On 12.09.2018 23:04, Han Xu wrote:
> 
> 
>> -----Original Message-----
>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
>> Sent: Wednesday, September 12, 2018 1:41 PM
>> To: Han Xu <han.xu@nxp.com>
>> Cc: Boris Brezillon <boris.brezillon@bootlin.com>; David Wolfe
>> <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
>> Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan
>> Gaur <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
>> mtd@lists.infradead.org; linux-spi@vger.kernel.org; dwmw2@infradead.org;
>> computersforpeace@gmail.com; marek.vasut@gmail.com; richard@nod.at;
>> miquel.raynal@bootlin.com; broonie@kernel.org
>> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
>>
>> Hi Han,
>>
>> On 12.09.2018 19:04, Han Xu wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
>>>> Sent: Monday, September 3, 2018 4:02 AM
>>>> To: Han Xu <han.xu@nxp.com>
>>>> Cc: Boris Brezillon <boris.brezillon@bootlin.com>; David Wolfe
>>>> <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
>>>> Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan
>> Gaur
>>>> <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
>>>> mtd@lists.infradead.org; linux-spi@vger.kernel.org;
>>>> dwmw2@infradead.org; computersforpeace@gmail.com;
>>>> marek.vasut@gmail.com; richard@nod.at; miquel.raynal@bootlin.com;
>>>> broonie@kernel.org
>>>> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
>>>>
>>>> Hi Han,
>>>>
>>>> On 04.08.2018 15:37, Boris Brezillon wrote:
>>>>> Hi Han,
>>>>>
>>>>> On Thu, 2 Aug 2018 21:58:48 +0000
>>>>> Han Xu <han.xu@nxp.com> wrote:
>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
>>>>>>> Sent: Thursday, August 2, 2018 8:09 AM
>>>>>>> To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
>>>>>>> <fabio.estevam@nxp.com>; Prabhakar Kushwaha
>>>>>>> <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
>>>>>>> <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
>>>>>>> shawnguo@kernel.org
>>>>>>> Cc: linux-mtd@lists.infradead.org; boris.brezillon@bootlin.com;
>>>>>>> linux- spi@vger.kernel.org; dwmw2@infradead.org;
>>>>>>> computersforpeace@gmail.com; marek.vasut@gmail.com;
>>>> richard@nod.at;
>>>>>>> miquel.raynal@bootlin.com; broonie@kernel.org
>>>>>>> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
>>>>>>>
>>>>>>> Ping.
>>>>>>>
>>>>>>> I'm not sure if my message below went out to you at all. At least
>>>>>>> I can't find it in the ML archive.
>>>>>>>
>>>>>>> I still hope someone can help with the questions below.
>>>>>>>
>>>>>>> Meanwhile for the second point I did some tests myself with one
>>>>>>> chip on each of the two buses and it worked fine with my latest v2
>> patches.
>>>>>>> So I'm not sure at all why Yogesh has problems with his setup (two
>>>>>>> chips on the first bus).
>>>>>>
>>>>>> Tried to test the v2 patch set on i.MX6SX SDB board but get the
>>>>>> memory
>>>> map failure.
>>>>>>
>>>>>> [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for resource
>> [mem
>>>> 0x70000000-0x7fffffff]
>>>>>> [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI probe failed
>>>>>> [    1.313922] fsl-quadspi: probe of 21e4000.qspi failed with error -12
>>>>>>
>>>>>> This is the reason why dynamic ioremap added in previous driver,
>>>>>> please
>>>> refer to
>>>>>>
>>>>>>
>>>>
>> https://smex12-5-en-ctp.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2femea01.safelinks.protection.outlook.com%2f%3furl%3dhttps%253A%252F%252Fsm&umid=aac77072-ee97-4b8a-b8b9-55765e276aec&auth=78a0452d0eda3018cc3487ba1bec995089e109a2-cefb4275e4aea35bf0c475f6bd6da9e9a8c877a0
>>>> ex12-5-en-
>> ctp.trendmicro.com%3A443%2Fwis%2Fclicktime%2Fv1%2Fquery%3Fu
>>>>
>> rl%3Dhttps%253a%252f%252femea01.safelinks.protection.outlook.com%252
>> f
>>>> %253furl%253dhttps%25253A%25252F%25252Fpa%26umid%3Dd6cc1014-
>> 1848-42fb
>>>> -92fd-
>> 9626d45c8050%26auth%3D541e45255b6517100d80c2b1b80b6933b203c492-
>>>>
>> 5aa8e1977a9db94300a9f61f5446e7a21b175f56&amp;data=02%7C01%7Chan.x
>> u%40
>>>>
>> nxp.com%7C9d43e9b29a82419a36c408d618df3dc3%7C686ea1d3bc2b4c6fa92c
>> d99c
>>>>
>> 5c301635%7C0%7C0%7C636723744426896223&amp;sdata=Y32I9H9adPn%2Bn
>> lcICuV
>>>> M8Uoozsig%2BM3F0rNAhkIF5ZE%3D&amp;reserved=0
>>>>>>
>>>>
>> tchwork.ozlabs.org%2Fpatch%2F503655%2F&amp;data=02%7C01%7Chan.xu
>>>> %40nx
>>>>>>
>>>>
>> p.com%7C9f45a8b666d3478f065408d6117bf524%7C686ea1d3bc2b4c6fa92cd9
>>>> 9c5c
>>>>>>
>>>>
>> 301635%7C0%7C0%7C636715621426190473&amp;sdata=XWPfWe%2Fu2ePW
>>>> mNPe179D0
>>>>>> vjTp6eLp0%2FJRF2vRayDwug%3D&amp;reserved=0
>>>>>
>>>>> We can reduce the size of the iomap to 2k * 4, since this is all we
>>>>> use currently. Can you try to change the size of the ioremap call to
>>>>> 16k and tell us if it works.
>>>>
>>>> Were you able to test with the reduced iomap size?
>>>> It would be great to know if it works on your board.
>>>>
>>>> Thanks,
>>>> Frieder
>>>
>>> Test the code on i.MX6SX sabreauto board with two micron n25q256a chips
>> on two CS.
>>> First issue found is __div0 kernel dump with these code
>>> /* Max 64 dummy clock cycles supported */ if (op->dummy.nbytes * 8 /
>>> op->dummy.buswidth > 64) dummy.buswidth was not set during read id.
>>
>> First, thank you for coming back to this and doing the test.
>> I'm currently not sure about the reason for this, but I guess Boris will figure it
>> out easily ;)

Ok, on a closer look it is obvious that the reason is this commit [1]. 
My last test was before this change, when dummy.buswidth was still set 
to 1 even if dummy.n_bytes is 0.
Now both are 0 and I need to handle this in the FSL QSPI driver.

>>
>>>
>>> Second issue is the second part failed to be probed, tried both buswidth 4
>> and buswidth 1.
>>>
>>> [    1.364979] m25p80 spi5.0: found n25q256a, expected m25p80
>>> [    1.370986] m25p80 spi5.0: n25q256a (32768 Kbytes)
>>> [    1.381020] m25p80 spi5.1: unrecognized JEDEC id bytes: ff, ff, ff
>>>
>>> These are the DT settings:
>>> &qspi1 {
>>>           pinctrl-names = "default";
>>>           pinctrl-0 = <&pinctrl_qspi1_1>;
>>>           status = "okay";
>>>
>>>           flash0: n25q256a@0 {
>>>           ¦       #address-cells = <1>;
>>>           ¦       #size-cells = <1>;
>>>           ¦       compatible = "micron,m25p80";
>>>           ¦       spi-max-frequency = <29000000>;
>>>                   spi-rx-bus-width = <4>;
>>>                   spi-tx-bus-width = <4>;
>>>           ¦       reg = <0>;
>>>           };
>>>
>>>           flash1: n25q256a@1 {
>>>           ¦       #address-cells = <1>;
>>>           ¦       #size-cells = <1>;
>>>           ¦       compatible = "micron,m25p80";
>>>           ¦       spi-max-frequency = <29000000>;
>>>                   spi-rx-bus-width = <4>;
>>>                   spi-tx-bus-width = <4>;
>>>           ¦       reg = <1>;
>>>           };
>>> };
>>
>> First, I think you should add "jedec,spi-nor" to your compatible properties.
>>
>> Second, are you sure, that the two chips are both on QSPIA using the two
>> chip selects?
>> I have no schematics of the board, but if I look at the devicetree in the linux-
>> imx kernel [1] it seems to me that one chip is on QSPIA CS0 and the other on
>> QSPIB CS0.
>> If this is the case, then you have to set reg = <2> for the second chip.
> 
> Yes, you are right, the second chip connects to QSPIB CS0, with the DT change, both of them work fine with __div0 issue workaround.

Ok, great. Thanks for your test.

As Yogesh reported problems with his LS1088ARDB board, where both chips 
are connected to QSPIA, I was hoping someone could confirm this by 
testing on a similar setup.

So if you have a board around, that uses this setup, it would be great 
if you can try on that. If not we have to find other ways to investigate 
this.

Thanks,
Frieder

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=9882b5375df532acb2c2399a90d882461112e612

> 
>>
>> Thanks,
>> Frieder
>>
>> [1]
>> https://smex12-5-en-ctp.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2femea01.safelinks.protection.outlook.com%2f%3furl%3dhttp%253A%252F%252Fgit.f&umid=aac77072-ee97-4b8a-b8b9-55765e276aec&auth=78a0452d0eda3018cc3487ba1bec995089e109a2-54ce7888db3c2cb56ff686a840c4d0fa657a3cdb
>> reescale.com%2Fgit%2Fcgit.cgi%2Fimx%2Flinux-
>> imx.git%2Ftree%2Farch%2Farm%2Fboot%2Fdts%2Fimx6sx-
>> sabreauto.dts%3Fh%3Dimx_4.9.11_1.0.0_ga%23n771&amp;data=02%7C01%
>> 7Chan.xu%40nxp.com%7C9d43e9b29a82419a36c408d618df3dc3%7C686ea1d
>> 3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C636723744426896223&amp;sdata
>> =038DdgMLjO23Io3CTHoSVrJL2Ho%2BgxyHlx9%2BLMrLWkQ%3D&amp;reser
>> ved=0
>>
>>>>>
>>>>> Unrelated to this issue, we still have 2 questions left unanswered:
>>>>>
>>>>> 1/ is there an easy way to invalidate AHB buffers? I mean, not
>>>>>       something that implies a full reset + several milliseconds of delay
>>>>>       after the reset. Right now we trick the caching logic by mapping a
>>>>>       portion that is twice the size of the buffer and switching from one
>>>>>       sub-portion to this other to trigger a real read on each read
>>>>>       access, but that's hack-ish, and I'd be surprised if HW
>>>>>       engineers hadn't planned for this "manual AHB buffer flush" case.
>>>>>
>>>>> 2/ if we use DMA, do you know what happens when the TX FIFO runs
>> out
>>>>>       of data while the TX request is not finished yet. In PIO mode, it
>>>>>       seems the engine sends garbage on the bus when that happens, and
>> we
>>>>>       definitely don't want that.
>>>>>
>>>>> While #1 is not blocking us, #2 is if we don't have those patches
>>>>> [1][2] applied, and Marek wanted to be sure there was no other ways
>>>>> to solve the "TX FIFO starvation" issue before considering these changes.
>>>>> So that'd be great if someone from NXP could have a look/ask around
>>>>> and give us answers to those 2 questions.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Boris
Lukasz Majewski Sept. 18, 2018, 10:42 p.m. | #12
Dear All,

Maybe I do jump a bit off topic here, but...

I've read through the following thread:
https://patchwork.ozlabs.org/patch/939885/

And it mentions some issues with reading AHB content (buffers) in
fsl-quadspi.c driver discovered when new QuadSPI driver was developed.

I do have a setup with qspi0 having two SPI memories connected (2x16
MiB), and I'm wondering if anybody has some more info regarding:

(What's more is that there is a bug in
 * the "IP Command Read" in the Vybrid.) found here:
https://elixir.bootlin.com/linux/v4.19-rc4/source/drivers/mtd/spi-nor/fsl-quadspi.c#L671

I've googled for some errata or known issues for vybryd's QSPI IP block
(vf610) but without luck so far ...

Thanks in advance,

> Hi Han,
> 
> On 12.09.2018 23:04, Han Xu wrote:
> > 
> >   
> >> -----Original Message-----
> >> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> >> Sent: Wednesday, September 12, 2018 1:41 PM
> >> To: Han Xu <han.xu@nxp.com>
> >> Cc: Boris Brezillon <boris.brezillon@bootlin.com>; David Wolfe
> >> <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
> >> Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan
> >> Gaur <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
> >> mtd@lists.infradead.org; linux-spi@vger.kernel.org;
> >> dwmw2@infradead.org; computersforpeace@gmail.com;
> >> marek.vasut@gmail.com; richard@nod.at; miquel.raynal@bootlin.com;
> >> broonie@kernel.org Subject: Re: Questions about the Freescale/NXP
> >> QuadSPI controller
> >>
> >> Hi Han,
> >>
> >> On 12.09.2018 19:04, Han Xu wrote:  
> >>>
> >>>  
> >>>> -----Original Message-----
> >>>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> >>>> Sent: Monday, September 3, 2018 4:02 AM
> >>>> To: Han Xu <han.xu@nxp.com>
> >>>> Cc: Boris Brezillon <boris.brezillon@bootlin.com>; David Wolfe
> >>>> <david.wolfe@nxp.com>; Fabio Estevam <fabio.estevam@nxp.com>;
> >>>> Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>; Yogesh Narayan  
> >> Gaur  
> >>>> <yogeshnarayan.gaur@nxp.com>; shawnguo@kernel.org; linux-
> >>>> mtd@lists.infradead.org; linux-spi@vger.kernel.org;
> >>>> dwmw2@infradead.org; computersforpeace@gmail.com;
> >>>> marek.vasut@gmail.com; richard@nod.at; miquel.raynal@bootlin.com;
> >>>> broonie@kernel.org
> >>>> Subject: Re: Questions about the Freescale/NXP QuadSPI controller
> >>>>
> >>>> Hi Han,
> >>>>
> >>>> On 04.08.2018 15:37, Boris Brezillon wrote:  
> >>>>> Hi Han,
> >>>>>
> >>>>> On Thu, 2 Aug 2018 21:58:48 +0000
> >>>>> Han Xu <han.xu@nxp.com> wrote:
> >>>>>  
> >>>>>>> -----Original Message-----
> >>>>>>> From: Frieder Schrempf [mailto:frieder.schrempf@exceet.de]
> >>>>>>> Sent: Thursday, August 2, 2018 8:09 AM
> >>>>>>> To: David Wolfe <david.wolfe@nxp.com>; Fabio Estevam
> >>>>>>> <fabio.estevam@nxp.com>; Prabhakar Kushwaha
> >>>>>>> <prabhakar.kushwaha@nxp.com>; Yogesh Narayan Gaur
> >>>>>>> <yogeshnarayan.gaur@nxp.com>; Han Xu <han.xu@nxp.com>;
> >>>>>>> shawnguo@kernel.org
> >>>>>>> Cc: linux-mtd@lists.infradead.org;
> >>>>>>> boris.brezillon@bootlin.com; linux- spi@vger.kernel.org;
> >>>>>>> dwmw2@infradead.org; computersforpeace@gmail.com;
> >>>>>>> marek.vasut@gmail.com;  
> >>>> richard@nod.at;  
> >>>>>>> miquel.raynal@bootlin.com; broonie@kernel.org
> >>>>>>> Subject: Re: Questions about the Freescale/NXP QuadSPI
> >>>>>>> controller
> >>>>>>>
> >>>>>>> Ping.
> >>>>>>>
> >>>>>>> I'm not sure if my message below went out to you at all. At
> >>>>>>> least I can't find it in the ML archive.
> >>>>>>>
> >>>>>>> I still hope someone can help with the questions below.
> >>>>>>>
> >>>>>>> Meanwhile for the second point I did some tests myself with
> >>>>>>> one chip on each of the two buses and it worked fine with my
> >>>>>>> latest v2  
> >> patches.  
> >>>>>>> So I'm not sure at all why Yogesh has problems with his setup
> >>>>>>> (two chips on the first bus).  
> >>>>>>
> >>>>>> Tried to test the v2 patch set on i.MX6SX SDB board but get the
> >>>>>> memory  
> >>>> map failure.  
> >>>>>>
> >>>>>> [    1.298633] fsl-quadspi 21e4000.qspi: ioremap failed for
> >>>>>> resource  
> >> [mem  
> >>>> 0x70000000-0x7fffffff]  
> >>>>>> [    1.307330] fsl-quadspi 21e4000.qspi: Freescale QuadSPI
> >>>>>> probe failed [    1.313922] fsl-quadspi: probe of 21e4000.qspi
> >>>>>> failed with error -12
> >>>>>>
> >>>>>> This is the reason why dynamic ioremap added in previous
> >>>>>> driver, please  
> >>>> refer to  
> >>>>>>
> >>>>>>  
> >>>>  
> >> https://smex12-5-en-ctp.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2femea01.safelinks.protection.outlook.com%2f%3furl%3dhttps%253A%252F%252Fsm&umid=aac77072-ee97-4b8a-b8b9-55765e276aec&auth=78a0452d0eda3018cc3487ba1bec995089e109a2-cefb4275e4aea35bf0c475f6bd6da9e9a8c877a0  
> >>>> ex12-5-en-  
> >> ctp.trendmicro.com%3A443%2Fwis%2Fclicktime%2Fv1%2Fquery%3Fu  
> >>>>  
> >> rl%3Dhttps%253a%252f%252femea01.safelinks.protection.outlook.com%252
> >> f  
> >>>> %253furl%253dhttps%25253A%25252F%25252Fpa%26umid%3Dd6cc1014-  
> >> 1848-42fb  
> >>>> -92fd-  
> >> 9626d45c8050%26auth%3D541e45255b6517100d80c2b1b80b6933b203c492-  
> >>>>  
> >> 5aa8e1977a9db94300a9f61f5446e7a21b175f56&amp;data=02%7C01%7Chan.x
> >> u%40  
> >>>>  
> >> nxp.com%7C9d43e9b29a82419a36c408d618df3dc3%7C686ea1d3bc2b4c6fa92c
> >> d99c  
> >>>>  
> >> 5c301635%7C0%7C0%7C636723744426896223&amp;sdata=Y32I9H9adPn%2Bn
> >> lcICuV  
> >>>> M8Uoozsig%2BM3F0rNAhkIF5ZE%3D&amp;reserved=0  
> >>>>>>  
> >>>>  
> >> tchwork.ozlabs.org%2Fpatch%2F503655%2F&amp;data=02%7C01%7Chan.xu  
> >>>> %40nx  
> >>>>>>  
> >>>>  
> >> p.com%7C9f45a8b666d3478f065408d6117bf524%7C686ea1d3bc2b4c6fa92cd9  
> >>>> 9c5c  
> >>>>>>  
> >>>>  
> >> 301635%7C0%7C0%7C636715621426190473&amp;sdata=XWPfWe%2Fu2ePW  
> >>>> mNPe179D0  
> >>>>>> vjTp6eLp0%2FJRF2vRayDwug%3D&amp;reserved=0  
> >>>>>
> >>>>> We can reduce the size of the iomap to 2k * 4, since this is
> >>>>> all we use currently. Can you try to change the size of the
> >>>>> ioremap call to 16k and tell us if it works.  
> >>>>
> >>>> Were you able to test with the reduced iomap size?
> >>>> It would be great to know if it works on your board.
> >>>>
> >>>> Thanks,
> >>>> Frieder  
> >>>
> >>> Test the code on i.MX6SX sabreauto board with two micron n25q256a
> >>> chips  
> >> on two CS.  
> >>> First issue found is __div0 kernel dump with these code
> >>> /* Max 64 dummy clock cycles supported */ if (op->dummy.nbytes *
> >>> 8 / op->dummy.buswidth > 64) dummy.buswidth was not set during
> >>> read id.  
> >>
> >> First, thank you for coming back to this and doing the test.
> >> I'm currently not sure about the reason for this, but I guess
> >> Boris will figure it out easily ;)  
> 
> Ok, on a closer look it is obvious that the reason is this commit
> [1]. My last test was before this change, when dummy.buswidth was
> still set to 1 even if dummy.n_bytes is 0.
> Now both are 0 and I need to handle this in the FSL QSPI driver.
> 
> >>  
> >>>
> >>> Second issue is the second part failed to be probed, tried both
> >>> buswidth 4  
> >> and buswidth 1.  
> >>>
> >>> [    1.364979] m25p80 spi5.0: found n25q256a, expected m25p80
> >>> [    1.370986] m25p80 spi5.0: n25q256a (32768 Kbytes)
> >>> [    1.381020] m25p80 spi5.1: unrecognized JEDEC id bytes: ff,
> >>> ff, ff
> >>>
> >>> These are the DT settings:
> >>> &qspi1 {
> >>>           pinctrl-names = "default";
> >>>           pinctrl-0 = <&pinctrl_qspi1_1>;
> >>>           status = "okay";
> >>>
> >>>           flash0: n25q256a@0 {
> >>>           ¦       #address-cells = <1>;
> >>>           ¦       #size-cells = <1>;
> >>>           ¦       compatible = "micron,m25p80";
> >>>           ¦       spi-max-frequency = <29000000>;
> >>>                   spi-rx-bus-width = <4>;
> >>>                   spi-tx-bus-width = <4>;
> >>>           ¦       reg = <0>;
> >>>           };
> >>>
> >>>           flash1: n25q256a@1 {
> >>>           ¦       #address-cells = <1>;
> >>>           ¦       #size-cells = <1>;
> >>>           ¦       compatible = "micron,m25p80";
> >>>           ¦       spi-max-frequency = <29000000>;
> >>>                   spi-rx-bus-width = <4>;
> >>>                   spi-tx-bus-width = <4>;
> >>>           ¦       reg = <1>;
> >>>           };
> >>> };  
> >>
> >> First, I think you should add "jedec,spi-nor" to your compatible
> >> properties.
> >>
> >> Second, are you sure, that the two chips are both on QSPIA using
> >> the two chip selects?
> >> I have no schematics of the board, but if I look at the devicetree
> >> in the linux- imx kernel [1] it seems to me that one chip is on
> >> QSPIA CS0 and the other on QSPIB CS0.
> >> If this is the case, then you have to set reg = <2> for the second
> >> chip.  
> > 
> > Yes, you are right, the second chip connects to QSPIB CS0, with the
> > DT change, both of them work fine with __div0 issue workaround.  
> 
> Ok, great. Thanks for your test.
> 
> As Yogesh reported problems with his LS1088ARDB board, where both
> chips are connected to QSPIA, I was hoping someone could confirm this
> by testing on a similar setup.
> 
> So if you have a board around, that uses this setup, it would be
> great if you can try on that. If not we have to find other ways to
> investigate this.
> 
> Thanks,
> Frieder
> 
> [1] 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit?id=9882b5375df532acb2c2399a90d882461112e612
> 
> >   
> >>
> >> Thanks,
> >> Frieder
> >>
> >> [1]
> >> https://smex12-5-en-ctp.trendmicro.com:443/wis/clicktime/v1/query?url=https%3a%2f%2femea01.safelinks.protection.outlook.com%2f%3furl%3dhttp%253A%252F%252Fgit.f&umid=aac77072-ee97-4b8a-b8b9-55765e276aec&auth=78a0452d0eda3018cc3487ba1bec995089e109a2-54ce7888db3c2cb56ff686a840c4d0fa657a3cdb
> >> reescale.com%2Fgit%2Fcgit.cgi%2Fimx%2Flinux-
> >> imx.git%2Ftree%2Farch%2Farm%2Fboot%2Fdts%2Fimx6sx-
> >> sabreauto.dts%3Fh%3Dimx_4.9.11_1.0.0_ga%23n771&amp;data=02%7C01%
> >> 7Chan.xu%40nxp.com%7C9d43e9b29a82419a36c408d618df3dc3%7C686ea1d
> >> 3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C636723744426896223&amp;sdata
> >> =038DdgMLjO23Io3CTHoSVrJL2Ho%2BgxyHlx9%2BLMrLWkQ%3D&amp;reser
> >> ved=0
> >>  
> >>>>>
> >>>>> Unrelated to this issue, we still have 2 questions left
> >>>>> unanswered:
> >>>>>
> >>>>> 1/ is there an easy way to invalidate AHB buffers? I mean, not
> >>>>>       something that implies a full reset + several
> >>>>> milliseconds of delay after the reset. Right now we trick the
> >>>>> caching logic by mapping a portion that is twice the size of
> >>>>> the buffer and switching from one sub-portion to this other to
> >>>>> trigger a real read on each read access, but that's hack-ish,
> >>>>> and I'd be surprised if HW engineers hadn't planned for this
> >>>>> "manual AHB buffer flush" case.
> >>>>>
> >>>>> 2/ if we use DMA, do you know what happens when the TX FIFO
> >>>>> runs  
> >> out  
> >>>>>       of data while the TX request is not finished yet. In PIO
> >>>>> mode, it seems the engine sends garbage on the bus when that
> >>>>> happens, and  
> >> we  
> >>>>>       definitely don't want that.
> >>>>>
> >>>>> While #1 is not blocking us, #2 is if we don't have those
> >>>>> patches [1][2] applied, and Marek wanted to be sure there was
> >>>>> no other ways to solve the "TX FIFO starvation" issue before
> >>>>> considering these changes. So that'd be great if someone from
> >>>>> NXP could have a look/ask around and give us answers to those 2
> >>>>> questions.
> >>>>>
> >>>>> Thanks,
> >>>>>
> >>>>> Boris  
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Frieder Schrempf Sept. 19, 2018, 6:49 a.m. | #13
Hi Lukasz,

On 19.09.2018 00:42, Lukasz Majewski wrote:
> Dear All,
> 
> Maybe I do jump a bit off topic here, but...
> 
> I've read through the following thread:
> https://patchwork.ozlabs.org/patch/939885/
> 
> And it mentions some issues with reading AHB content (buffers) in
> fsl-quadspi.c driver discovered when new QuadSPI driver was developed.

The only setup with two chips that is known to be problematic with the 
new driver, is when both chips are connected to the same bus (e.g. 
QSPIA) using separate chip selects.

Does your board use this kind of setup, or are the two chips connected 
two different buses (QSPIA and QSPIB)?

Have you tested the new driver? It would be great to receive some more 
feedback.

> I do have a setup with qspi0 having two SPI memories connected (2x16
> MiB), and I'm wondering if anybody has some more info regarding:
> 
> (What's more is that there is a bug in
>   * the "IP Command Read" in the Vybrid.) found here:
> https://elixir.bootlin.com/linux/v4.19-rc4/source/drivers/mtd/spi-nor/fsl-quadspi.c#L671
> 
> I've googled for some errata or known issues for vybryd's QSPI IP block
> (vf610) but without luck so far ...

Unfortunately I don't know the background for this comment. Is your 
board using VF610? Do you experience problems?

Regards,
Frieder
Lukasz Majewski Sept. 19, 2018, 11:02 a.m. | #14
Hi Frieder,

> Hi Lukasz,
> 
> On 19.09.2018 00:42, Lukasz Majewski wrote:
> > Dear All,
> > 
> > Maybe I do jump a bit off topic here, but...
> > 
> > I've read through the following thread:
> > https://patchwork.ozlabs.org/patch/939885/
> > 
> > And it mentions some issues with reading AHB content (buffers) in
> > fsl-quadspi.c driver discovered when new QuadSPI driver was
> > developed.  
> 
> The only setup with two chips that is known to be problematic with
> the new driver, is when both chips are connected to the same bus
> (e.g. QSPIA) using separate chip selects.

I'm using QSPI0 controller, with two memories connected to QSPI0_A and
QSPI0_B lines.

> 
> Does your board use this kind of setup, or are the two chips
> connected two different buses (QSPIA and QSPIB)?
> 
> Have you tested the new driver? It would be great to receive some
> more feedback.

I will check (test) this new driver. No problem.

> 
> > I do have a setup with qspi0 having two SPI memories connected (2x16
> > MiB), and I'm wondering if anybody has some more info regarding:
> > 
> > (What's more is that there is a bug in
> >   * the "IP Command Read" in the Vybrid.) found here:
> > https://elixir.bootlin.com/linux/v4.19-rc4/source/drivers/mtd/spi-nor/fsl-quadspi.c#L671
> > 
> > I've googled for some errata or known issues for vybryd's QSPI IP
> > block (vf610) but without luck so far ...  
> 
> Unfortunately I don't know the background for this comment.

The comment was added by some Freescale employee when the driver was
added to Linux (by Huang - CC'ed).

> Is your 
> board using VF610?

Yes, it uses vf610 (A5 + M4 cores).

> Do you experience problems?

I've already observed following issue:

For the current QSPI ML driver (fsl-quadspi.c - 4.19-rc3) only half
of the AHB buffer is valid. When I do read the whole one - I do see read
data corruption (on UBI or raw memory). 

This was pointed out in the patch:
https://patchwork.ozlabs.org/patch/675401/

Unfortunately, I did not found any info regarding this problem (in
NXP's errata or other doc).

I will check if this issue shows up on new patches.

Thanks in advance for your help.

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

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Huang Shijie Sept. 20, 2018, 1:17 a.m. | #15
On Wed, Sep 19, 2018 at 01:02:11PM +0200, Lukasz Majewski wrote:
> Hi Frieder,
> 
> > Hi Lukasz,
> > 
> > On 19.09.2018 00:42, Lukasz Majewski wrote:
> > > Dear All,
> > > 
> > > Maybe I do jump a bit off topic here, but...
> > > 
> > > I've read through the following thread:
> > > https://patchwork.ozlabs.org/patch/939885/
> > > 
> > > And it mentions some issues with reading AHB content (buffers) in
> > > fsl-quadspi.c driver discovered when new QuadSPI driver was
> > > developed.  
> > 
> > The only setup with two chips that is known to be problematic with
> > the new driver, is when both chips are connected to the same bus
> > (e.g. QSPIA) using separate chip selects.
> 
> I'm using QSPI0 controller, with two memories connected to QSPI0_A and
> QSPI0_B lines.
> 
> > 
> > Does your board use this kind of setup, or are the two chips
> > connected two different buses (QSPIA and QSPIB)?
> > 
> > Have you tested the new driver? It would be great to receive some
> > more feedback.
> 
> I will check (test) this new driver. No problem.
> 
> > 
> > > I do have a setup with qspi0 having two SPI memories connected (2x16
> > > MiB), and I'm wondering if anybody has some more info regarding:
> > > 
> > > (What's more is that there is a bug in
> > >   * the "IP Command Read" in the Vybrid.) found here:
> > > https://elixir.bootlin.com/linux/v4.19-rc4/source/drivers/mtd/spi-nor/fsl-quadspi.c#L671
> > > 
> > > I've googled for some errata or known issues for vybryd's QSPI IP
> > > block (vf610) but without luck so far ...  
> > 
> > Unfortunately I don't know the background for this comment.
> 
> The comment was added by some Freescale employee when the driver was
> added to Linux (by Huang - CC'ed).

I was told that there was a hardware bug in the vybryd when we use the "IP Command Read":
    If you use the "IP Command Read", you will not get the correct data.

So I added that comment.

I suggest that do not use the "IP Command Read" for vybryd.

Thanks
Huang Shijie

> 
> > Is your 
> > board using VF610?
> 
> Yes, it uses vf610 (A5 + M4 cores).
>
Lukasz Majewski Sept. 20, 2018, 3 p.m. | #16
Hi Frieder, 

> Hi Frieder,
> 
> > Hi Lukasz,
> > 
> > On 19.09.2018 00:42, Lukasz Majewski wrote:  
> > > Dear All,
> > > 
> > > Maybe I do jump a bit off topic here, but...
> > > 
> > > I've read through the following thread:
> > > https://patchwork.ozlabs.org/patch/939885/
> > > 
> > > And it mentions some issues with reading AHB content (buffers) in
> > > fsl-quadspi.c driver discovered when new QuadSPI driver was
> > > developed.    
> > 
> > The only setup with two chips that is known to be problematic with
> > the new driver, is when both chips are connected to the same bus
> > (e.g. QSPIA) using separate chip selects.  
> 
> I'm using QSPI0 controller, with two memories connected to QSPI0_A and
> QSPI0_B lines.
> 
> > 
> > Does your board use this kind of setup, or are the two chips
> > connected two different buses (QSPIA and QSPIB)?
> > 
> > Have you tested the new driver? It would be great to receive some
> > more feedback.  
> 
> I will check (test) this new driver. No problem.

I've ported your patch on v4.19-rc3.

I had to fix the "div0 issue" by adding:
if (op->dummy.buswidth && 
	(op->dummy.nbytes * 8 / op->dummy.buswidth > 64))

In fsl_qspi_supports_op() function.


Unfortunately, on Vybrid vf610 when testing I do see corruption of read
data from the mtd device:

~# hexdump aaa.img
0000000 464c eec0 baa5 c5ff 7b99 4dfb e0b6 8a2e
0000010 e98e 5265 683c a635 c069 e402 303f d936
0000020 c243 01a7 7064 fce8 e3a9 200a 7e85 28bc
0000030 4296 a30e 1bb4 88d4 b456 b4a6 f3aa 8cff
0000040 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000100

~# hexdump data_test.img
0000000 464c eec0 baa5 c5ff 7b99 4dfb e0b6 8a2e
0000010 e98e 5265 683c a635 c069 e402 303f d936
0000020 c243 01a7 7064 fce8 e3a9 200a 7e85 28bc
0000030 4296 a30e 1bb4 88d4 b456 b4a6 f3aa 8cff
0000040 01c9 462d 0a43 f893 0e42 67f1 57f0 787c
0000050 49c0 fb2a e514 e954 1d21 affa bac4 38f1
0000060 1ca5 ec46 77eb a854 285b 8e21 12d7 f377
0000070 b441 2baf ee33 596c 98b6 e71a c1cb 876c


Test case:
flash_erase /dev/mtd3 0 1
dd if=data_test.img of=/dev/mtd3
dd if=/dev/mtd3 of=aaa.img bs=1 count=256


From the code I see that the AHB buffer has 1024B. It is accessed in 8
bytes packs.

This seems like some cache or HW issue....

In the old driver, to fix this problem one needed to 
1. Reduce the RX fifo size from 128B to 64B

2. Disable (set to 0) the AHB transfer's BUF3CR ADATSZ field - the
transfer size is the same as in LUT.

(Original patch: https://patchwork.ozlabs.org/patch/675401/)


> 
> >   
> > > I do have a setup with qspi0 having two SPI memories connected
> > > (2x16 MiB), and I'm wondering if anybody has some more info
> > > regarding:
> > > 
> > > (What's more is that there is a bug in
> > >   * the "IP Command Read" in the Vybrid.) found here:
	^^^^^^^^^^^^^^^^^^^^^^^^ - It would be handy to have the exact
	explanation of this issue.

> > > https://elixir.bootlin.com/linux/v4.19-rc4/source/drivers/mtd/spi-nor/fsl-quadspi.c#L67
> > > 
> > > I've googled for some errata or known issues for vybryd's QSPI IP
> > > block (vf610) but without luck so far ...    
> > 
> > Unfortunately I don't know the background for this comment.  
> 
> The comment was added by some Freescale employee when the driver was
> added to Linux (by Huang - CC'ed).
> 
> > Is your 
> > board using VF610?  
> 
> Yes, it uses vf610 (A5 + M4 cores).
> 
> > Do you experience problems?  
> 
> I've already observed following issue:
> 
> For the current QSPI ML driver (fsl-quadspi.c - 4.19-rc3) only half
> of the AHB buffer is valid. When I do read the whole one - I do see
> read data corruption (on UBI or raw memory). 
> 
> This was pointed out in the patch:
> https://patchwork.ozlabs.org/patch/675401/
> 
> Unfortunately, I did not found any info regarding this problem (in
> NXP's errata or other doc).
> 
> I will check if this issue shows up on new patches.
> 
> Thanks in advance for your help.
> 
> > 
> > Regards,
> > Frieder
> > 
> > ______________________________________________________
> > Linux MTD discussion mailing list
> > http://lists.infradead.org/mailman/listinfo/linux-mtd/  
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Frieder Schrempf Sept. 20, 2018, 3:41 p.m. | #17
Hi Lukasz,

On 20.09.2018 17:00, Lukasz Majewski wrote:
> Hi Frieder,
> 
>> Hi Frieder,
>>
>>> Hi Lukasz,
>>>
>>> On 19.09.2018 00:42, Lukasz Majewski wrote:
>>>> Dear All,
>>>>
>>>> Maybe I do jump a bit off topic here, but...
>>>>
>>>> I've read through the following thread:
>>>> https://patchwork.ozlabs.org/patch/939885/
>>>>
>>>> And it mentions some issues with reading AHB content (buffers) in
>>>> fsl-quadspi.c driver discovered when new QuadSPI driver was
>>>> developed.
>>>
>>> The only setup with two chips that is known to be problematic with
>>> the new driver, is when both chips are connected to the same bus
>>> (e.g. QSPIA) using separate chip selects.
>>
>> I'm using QSPI0 controller, with two memories connected to QSPI0_A and
>> QSPI0_B lines.
>>
>>>
>>> Does your board use this kind of setup, or are the two chips
>>> connected two different buses (QSPIA and QSPIB)?
>>>
>>> Have you tested the new driver? It would be great to receive some
>>> more feedback.
>>
>> I will check (test) this new driver. No problem.
> 
> I've ported your patch on v4.19-rc3.
> 
> I had to fix the "div0 issue" by adding:
> if (op->dummy.buswidth &&
> 	(op->dummy.nbytes * 8 / op->dummy.buswidth > 64))
> 
> In fsl_qspi_supports_op() function.
> 
> 
> Unfortunately, on Vybrid vf610 when testing I do see corruption of read
> data from the mtd device:
> 
> ~# hexdump aaa.img
> 0000000 464c eec0 baa5 c5ff 7b99 4dfb e0b6 8a2e
> 0000010 e98e 5265 683c a635 c069 e402 303f d936
> 0000020 c243 01a7 7064 fce8 e3a9 200a 7e85 28bc
> 0000030 4296 a30e 1bb4 88d4 b456 b4a6 f3aa 8cff
> 0000040 ffff ffff ffff ffff ffff ffff ffff ffff
> *
> 0000100
> 
> ~# hexdump data_test.img
> 0000000 464c eec0 baa5 c5ff 7b99 4dfb e0b6 8a2e
> 0000010 e98e 5265 683c a635 c069 e402 303f d936
> 0000020 c243 01a7 7064 fce8 e3a9 200a 7e85 28bc
> 0000030 4296 a30e 1bb4 88d4 b456 b4a6 f3aa 8cff
> 0000040 01c9 462d 0a43 f893 0e42 67f1 57f0 787c
> 0000050 49c0 fb2a e514 e954 1d21 affa bac4 38f1
> 0000060 1ca5 ec46 77eb a854 285b 8e21 12d7 f377
> 0000070 b441 2baf ee33 596c 98b6 e71a c1cb 876c
> 
> 
> Test case:
> flash_erase /dev/mtd3 0 1
> dd if=data_test.img of=/dev/mtd3
> dd if=/dev/mtd3 of=aaa.img bs=1 count=256
> 
> 
>  From the code I see that the AHB buffer has 1024B. It is accessed in 8
> bytes packs.
> 
> This seems like some cache or HW issue....
> 
> In the old driver, to fix this problem one needed to
> 1. Reduce the RX fifo size from 128B to 64B
> 
> 2. Disable (set to 0) the AHB transfer's BUF3CR ADATSZ field - the
> transfer size is the same as in LUT.
> 
> (Original patch: https://patchwork.ozlabs.org/patch/675401/)

Thanks a lot for doing the test. It seems like Vybrid needs some special 
handling to work around this problem.
So this means the current driver has never worked for Vybrid, as the 
mentioned patch was never merged!?

As these issues seem to be specific to Vybrid and as they seem to exist 
in the current driver too, I would like to fix them after we have a 
first version of the new driver that works for the other platforms.

I hope we can figure out the other issues soon.

Thanks,
Frieder

> 
> 
>>
>>>    
>>>> I do have a setup with qspi0 having two SPI memories connected
>>>> (2x16 MiB), and I'm wondering if anybody has some more info
>>>> regarding:
>>>>
>>>> (What's more is that there is a bug in
>>>>    * the "IP Command Read" in the Vybrid.) found here:
> 	^^^^^^^^^^^^^^^^^^^^^^^^ - It would be handy to have the exact
> 	explanation of this issue.
> 
>>>> https://elixir.bootlin.com/linux/v4.19-rc4/source/drivers/mtd/spi-nor/fsl-quadspi.c#L67
>>>>
>>>> I've googled for some errata or known issues for vybryd's QSPI IP
>>>> block (vf610) but without luck so far ...
>>>
>>> Unfortunately I don't know the background for this comment.
>>
>> The comment was added by some Freescale employee when the driver was
>> added to Linux (by Huang - CC'ed).
>>
>>> Is your
>>> board using VF610?
>>
>> Yes, it uses vf610 (A5 + M4 cores).
>>
>>> Do you experience problems?
>>
>> I've already observed following issue:
>>
>> For the current QSPI ML driver (fsl-quadspi.c - 4.19-rc3) only half
>> of the AHB buffer is valid. When I do read the whole one - I do see
>> read data corruption (on UBI or raw memory).
>>
>> This was pointed out in the patch:
>> https://patchwork.ozlabs.org/patch/675401/
>>
>> Unfortunately, I did not found any info regarding this problem (in
>> NXP's errata or other doc).
>>
>> I will check if this issue shows up on new patches.
>>
>> Thanks in advance for your help.
>>
>>>
>>> Regards,
>>> Frieder
>>>
>>> ______________________________________________________
>>> Linux MTD discussion mailing list
>>> http://lists.infradead.org/mailman/listinfo/linux-mtd/
>>
>> Best regards,
>>
>> Lukasz Majewski
>>
>> --
>>
>> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
>> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
>> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> 
> 
> 
> 
> Best regards,
> 
> Lukasz Majewski
> 
> --
> 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
>
Lukasz Majewski Sept. 20, 2018, 8:37 p.m. | #18
Hi Frieder,

> Hi Lukasz,
> 
> On 20.09.2018 17:00, Lukasz Majewski wrote:
> > Hi Frieder,
> >   
> >> Hi Frieder,
> >>  
> >>> Hi Lukasz,
> >>>
> >>> On 19.09.2018 00:42, Lukasz Majewski wrote:  
> >>>> Dear All,
> >>>>
> >>>> Maybe I do jump a bit off topic here, but...
> >>>>
> >>>> I've read through the following thread:
> >>>> https://patchwork.ozlabs.org/patch/939885/
> >>>>
> >>>> And it mentions some issues with reading AHB content (buffers) in
> >>>> fsl-quadspi.c driver discovered when new QuadSPI driver was
> >>>> developed.  
> >>>
> >>> The only setup with two chips that is known to be problematic with
> >>> the new driver, is when both chips are connected to the same bus
> >>> (e.g. QSPIA) using separate chip selects.  
> >>
> >> I'm using QSPI0 controller, with two memories connected to QSPI0_A
> >> and QSPI0_B lines.
> >>  
> >>>
> >>> Does your board use this kind of setup, or are the two chips
> >>> connected two different buses (QSPIA and QSPIB)?
> >>>
> >>> Have you tested the new driver? It would be great to receive some
> >>> more feedback.  
> >>
> >> I will check (test) this new driver. No problem.  
> > 
> > I've ported your patch on v4.19-rc3.
> > 
> > I had to fix the "div0 issue" by adding:
> > if (op->dummy.buswidth &&
> > 	(op->dummy.nbytes * 8 / op->dummy.buswidth > 64))
> > 
> > In fsl_qspi_supports_op() function.
> > 
> > 
> > Unfortunately, on Vybrid vf610 when testing I do see corruption of
> > read data from the mtd device:
> > 
> > ~# hexdump aaa.img
> > 0000000 464c eec0 baa5 c5ff 7b99 4dfb e0b6 8a2e
> > 0000010 e98e 5265 683c a635 c069 e402 303f d936
> > 0000020 c243 01a7 7064 fce8 e3a9 200a 7e85 28bc
> > 0000030 4296 a30e 1bb4 88d4 b456 b4a6 f3aa 8cff
> > 0000040 ffff ffff ffff ffff ffff ffff ffff ffff
> > *
> > 0000100
> > 
> > ~# hexdump data_test.img
> > 0000000 464c eec0 baa5 c5ff 7b99 4dfb e0b6 8a2e
> > 0000010 e98e 5265 683c a635 c069 e402 303f d936
> > 0000020 c243 01a7 7064 fce8 e3a9 200a 7e85 28bc
> > 0000030 4296 a30e 1bb4 88d4 b456 b4a6 f3aa 8cff
> > 0000040 01c9 462d 0a43 f893 0e42 67f1 57f0 787c
> > 0000050 49c0 fb2a e514 e954 1d21 affa bac4 38f1
> > 0000060 1ca5 ec46 77eb a854 285b 8e21 12d7 f377
> > 0000070 b441 2baf ee33 596c 98b6 e71a c1cb 876c
> > 
> > 
> > Test case:
> > flash_erase /dev/mtd3 0 1
> > dd if=data_test.img of=/dev/mtd3
> > dd if=/dev/mtd3 of=aaa.img bs=1 count=256
> > 
> > 
> >  From the code I see that the AHB buffer has 1024B. It is accessed
> > in 8 bytes packs.
> > 
> > This seems like some cache or HW issue....
> > 
> > In the old driver, to fix this problem one needed to
> > 1. Reduce the RX fifo size from 128B to 64B
> > 
> > 2. Disable (set to 0) the AHB transfer's BUF3CR ADATSZ field - the
> > transfer size is the same as in LUT.
> > 
> > (Original patch: https://patchwork.ozlabs.org/patch/675401/)  
> 
> Thanks a lot for doing the test. It seems like Vybrid needs some
> special handling to work around this problem.

I'm not sure if it is special - it looks like there may be some HW
issue with Vybrid.

> So this means the current driver has never worked for Vybrid, as the 
> mentioned patch was never merged!?

At least on my setup. You cannot use MTD memory for anything as you
cannot read correctly data from it.

I'm wondering if any other vybrid users (with QSPI) also experience
such problems.

> 
> As these issues seem to be specific to Vybrid and as they seem to
> exist in the current driver too, I would like to fix them after we
> have a first version of the new driver that works for the other
> platforms.

It is fine for me - I hope that I will find solution soon (and rebase
it on top of your patch).

> 
> I hope we can figure out the other issues soon.

I would be very happy if anybody from NXP could look on this issue and
forward it to HW engineers for some insight.

(Vybryd has some old "chip errata document":
https://community.nxp.com/message/1059701 , but it mentions other issue
with QSPI).

> 
> Thanks,
> Frieder
> 
> > 
> >   
> >>  
> >>>      
> >>>> I do have a setup with qspi0 having two SPI memories connected
> >>>> (2x16 MiB), and I'm wondering if anybody has some more info
> >>>> regarding:
> >>>>
> >>>> (What's more is that there is a bug in
> >>>>    * the "IP Command Read" in the Vybrid.) found here:  
> > 	^^^^^^^^^^^^^^^^^^^^^^^^ - It would be handy to have the
> > exact explanation of this issue.
> >   
> >>>> https://elixir.bootlin.com/linux/v4.19-rc4/source/drivers/mtd/spi-nor/fsl-quadspi.c#L67
> >>>>
> >>>> I've googled for some errata or known issues for vybryd's QSPI IP
> >>>> block (vf610) but without luck so far ...  
> >>>
> >>> Unfortunately I don't know the background for this comment.  
> >>
> >> The comment was added by some Freescale employee when the driver
> >> was added to Linux (by Huang - CC'ed).
> >>  
> >>> Is your
> >>> board using VF610?  
> >>
> >> Yes, it uses vf610 (A5 + M4 cores).
> >>  
> >>> Do you experience problems?  
> >>
> >> I've already observed following issue:
> >>
> >> For the current QSPI ML driver (fsl-quadspi.c - 4.19-rc3) only half
> >> of the AHB buffer is valid. When I do read the whole one - I do see
> >> read data corruption (on UBI or raw memory).
> >>
> >> This was pointed out in the patch:
> >> https://patchwork.ozlabs.org/patch/675401/
> >>
> >> Unfortunately, I did not found any info regarding this problem (in
> >> NXP's errata or other doc).
> >>
> >> I will check if this issue shows up on new patches.
> >>
> >> Thanks in advance for your help.
> >>  
> >>>
> >>> Regards,
> >>> Frieder
> >>>
> >>> ______________________________________________________
> >>> Linux MTD discussion mailing list
> >>> http://lists.infradead.org/mailman/listinfo/linux-mtd/  
> >>
> >> Best regards,
> >>
> >> Lukasz Majewski
> >>
> >> --
> >>
> >> DENX Software Engineering GmbH,      Managing Director: Wolfgang
> >> Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell,
> >> Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email:
> >> wd@denx.de  
> > 
> > 
> > 
> > 
> > Best regards,
> > 
> > Lukasz Majewski
> > 
> > --
> > 
> > DENX Software Engineering GmbH,      Managing Director: Wolfgang
> > Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell,
> > Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email:
> > wd@denx.de 
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Lukasz Majewski Sept. 20, 2018, 10:13 p.m. | #19
Hi Frieder,

Please find some more comments regarding the new spi-fsl-qspi.c driver.

> Hi Lukasz,
> 
> On 20.09.2018 17:00, Lukasz Majewski wrote:
> > Hi Frieder,
> >   
> >> Hi Frieder,
> >>  
> >>> Hi Lukasz,
> >>>
> >>> On 19.09.2018 00:42, Lukasz Majewski wrote:  
> >>>> Dear All,
> >>>>
> >>>> Maybe I do jump a bit off topic here, but...
> >>>>
> >>>> I've read through the following thread:
> >>>> https://patchwork.ozlabs.org/patch/939885/
> >>>>
> >>>> And it mentions some issues with reading AHB content (buffers) in
> >>>> fsl-quadspi.c driver discovered when new QuadSPI driver was
> >>>> developed.  
> >>>
> >>> The only setup with two chips that is known to be problematic with
> >>> the new driver, is when both chips are connected to the same bus
> >>> (e.g. QSPIA) using separate chip selects.  
> >>
> >> I'm using QSPI0 controller, with two memories connected to QSPI0_A
> >> and QSPI0_B lines.
> >>  
> >>>
> >>> Does your board use this kind of setup, or are the two chips
> >>> connected two different buses (QSPIA and QSPIB)?
> >>>
> >>> Have you tested the new driver? It would be great to receive some
> >>> more feedback.  
> >>
> >> I will check (test) this new driver. No problem.  
> > 
> > I've ported your patch on v4.19-rc3.
> > 
> > I had to fix the "div0 issue" by adding:
> > if (op->dummy.buswidth &&
> > 	(op->dummy.nbytes * 8 / op->dummy.buswidth > 64))
> > 
> > In fsl_qspi_supports_op() function.
> > 
> > 
> > Unfortunately, on Vybrid vf610 when testing I do see corruption of
> > read data from the mtd device:
> > 
> > ~# hexdump aaa.img
> > 0000000 464c eec0 baa5 c5ff 7b99 4dfb e0b6 8a2e
> > 0000010 e98e 5265 683c a635 c069 e402 303f d936
> > 0000020 c243 01a7 7064 fce8 e3a9 200a 7e85 28bc
> > 0000030 4296 a30e 1bb4 88d4 b456 b4a6 f3aa 8cff
> > 0000040 ffff ffff ffff ffff ffff ffff ffff ffff
> > *
> > 0000100
> > 
> > ~# hexdump data_test.img
> > 0000000 464c eec0 baa5 c5ff 7b99 4dfb e0b6 8a2e
> > 0000010 e98e 5265 683c a635 c069 e402 303f d936
> > 0000020 c243 01a7 7064 fce8 e3a9 200a 7e85 28bc
> > 0000030 4296 a30e 1bb4 88d4 b456 b4a6 f3aa 8cff
> > 0000040 01c9 462d 0a43 f893 0e42 67f1 57f0 787c
> > 0000050 49c0 fb2a e514 e954 1d21 affa bac4 38f1
> > 0000060 1ca5 ec46 77eb a854 285b 8e21 12d7 f377
> > 0000070 b441 2baf ee33 596c 98b6 e71a c1cb 876c
> > 
> > 
> > Test case:
> > flash_erase /dev/mtd3 0 1
> > dd if=data_test.img of=/dev/mtd3
> > dd if=/dev/mtd3 of=aaa.img bs=1 count=256
> > 
> > 
> >  From the code I see that the AHB buffer has 1024B. It is accessed
> > in 8 bytes packs.
> > 
> > This seems like some cache or HW issue....
> > 
> > In the old driver, to fix this problem one needed to
> > 1. Reduce the RX fifo size from 128B to 64B
> > 
> > 2. Disable (set to 0) the AHB transfer's BUF3CR ADATSZ field - the
> > transfer size is the same as in LUT.
> > 
> > (Original patch: https://patchwork.ozlabs.org/patch/675401/)  
> 
> Thanks a lot for doing the test. It seems like Vybrid needs some
> special handling to work around this problem.
> So this means the current driver has never worked for Vybrid, as the 
> mentioned patch was never merged!?
> 
> As these issues seem to be specific to Vybrid and as they seem to
> exist in the current driver too, I would like to fix them after we
> have a first version of the new driver that works for the other
> platforms.
> 
> I hope we can figure out the other issues soon.
> 
> Thanks,
> Frieder
> 
> > 
> >   
> >>  
> >>>      
> >>>> I do have a setup with qspi0 having two SPI memories connected
> >>>> (2x16 MiB), and I'm wondering if anybody has some more info
> >>>> regarding:
> >>>>
> >>>> (What's more is that there is a bug in
> >>>>    * the "IP Command Read" in the Vybrid.) found here:  
> > 	^^^^^^^^^^^^^^^^^^^^^^^^ - It would be handy to have the
> > exact explanation of this issue.
> >   
> >>>> https://elixir.bootlin.com/linux/v4.19-rc4/source/drivers/mtd/spi-nor/fsl-quadspi.c#L671
       ^^^^^^^^^^^^ - [1]


I've looked a bit closer to the new spi-fsl-qspi.c driver and it looks
like it uses fsl_qspi_exec_op() and then calls fsl_qspi_do_op().

In the last function we setup the QUADSPI_IPCR register to initiate the
transfer between SPI-NOR and the internal RX buffer.

Please correct me if I'm wrong but it seems to me like we are using "IP
Command Read" approach here.

If this is true - what was the rationale to use it in the new driver, as
in the old one the "AHB Command Read" approach was recommended (i.e.
faster) [1]?

To be even more problematic the info in link [1] states that on vybrid
there is a bug on the "IP Command Read" HW block and it should be
avoided.

> >>>>
> >>>> I've googled for some errata or known issues for vybryd's QSPI IP
> >>>> block (vf610) but without luck so far ...  
> >>>
> >>> Unfortunately I don't know the background for this comment.  
> >>
> >> The comment was added by some Freescale employee when the driver
> >> was added to Linux (by Huang - CC'ed).
> >>  
> >>> Is your
> >>> board using VF610?  
> >>
> >> Yes, it uses vf610 (A5 + M4 cores).
> >>  
> >>> Do you experience problems?  
> >>
> >> I've already observed following issue:
> >>
> >> For the current QSPI ML driver (fsl-quadspi.c - 4.19-rc3) only half
> >> of the AHB buffer is valid. When I do read the whole one - I do see
> >> read data corruption (on UBI or raw memory).
> >>
> >> This was pointed out in the patch:
> >> https://patchwork.ozlabs.org/patch/675401/
> >>
> >> Unfortunately, I did not found any info regarding this problem (in
> >> NXP's errata or other doc).
> >>
> >> I will check if this issue shows up on new patches.
> >>
> >> Thanks in advance for your help.
> >>  
> >>>
> >>> Regards,
> >>> Frieder
> >>>
> >>> ______________________________________________________
> >>> Linux MTD discussion mailing list
> >>> http://lists.infradead.org/mailman/listinfo/linux-mtd/  
> >>
> >> Best regards,
> >>
> >> Lukasz Majewski
> >>
> >> --
> >>
> >> DENX Software Engineering GmbH,      Managing Director: Wolfgang
> >> Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell,
> >> Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email:
> >> wd@denx.de  
> > 
> > 
> > 
> > 
> > Best regards,
> > 
> > Lukasz Majewski
> > 
> > --
> > 
> > DENX Software Engineering GmbH,      Managing Director: Wolfgang
> > Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell,
> > Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email:
> > wd@denx.de 
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de

Patch

==============
* Add Yogesh Gaur and Suresh Gupta as authors
* Use GENMASK() for generating bitmasks
* Use callback functions for read/write of registers
* Attach the seq variable to the selected CS
* Avoid using conditional in read/write loop
* Avoid infinite loop and use a timeout instead
* Return error pointer when allocation in fsl_qspi_get_name() fails
* Remove redundant iounmap()
* Put suspend()/resume() in struct dev_pm_ops instead of struct platform_driver

 drivers/spi/Kconfig        |  11 +
 drivers/spi/Makefile       |   1 +
 drivers/spi/spi-fsl-qspi.c | 954 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 966 insertions(+)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index ad5d68e..5e95ffc 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -251,6 +251,17 @@  config SPI_FSL_LPSPI
 	help
 	  This enables Freescale i.MX LPSPI controllers in master mode.
 
+config SPI_FSL_QSPI
+	tristate "Freescale QSPI controller"
+	depends on ARCH_MXC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  This enables support for the Quad SPI controller in master mode.
+	  Up to four flash chips can be connected on two buses with two
+	  chipselects each.
+	  This controller does not support generic SPI messages. It only
+	  supports the high-level SPI memory interface.
+
 config SPI_GPIO
 	tristate "GPIO-based bitbanging SPI Master"
 	depends on GPIOLIB || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index cb1f437..a8f7fda 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -43,6 +43,7 @@  obj-$(CONFIG_SPI_FSL_DSPI)		+= spi-fsl-dspi.o
 obj-$(CONFIG_SPI_FSL_LIB)		+= spi-fsl-lib.o
 obj-$(CONFIG_SPI_FSL_ESPI)		+= spi-fsl-espi.o
 obj-$(CONFIG_SPI_FSL_LPSPI)		+= spi-fsl-lpspi.o
+obj-$(CONFIG_SPI_FSL_QSPI)		+= spi-fsl-qspi.o
 obj-$(CONFIG_SPI_FSL_SPI)		+= spi-fsl-spi.o
 obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o
 obj-$(CONFIG_SPI_IMG_SPFI)		+= spi-img-spfi.o
diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c
new file mode 100644
index 0000000..3e17209
--- /dev/null
+++ b/drivers/spi/spi-fsl-qspi.c
@@ -0,0 +1,954 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Freescale QuadSPI driver.
+ *
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2018 Bootlin
+ * Copyright (C) 2018 Exceet Electronics GmbH
+ *
+ * Transition to SPI MEM interface:
+ * Author:
+ *     Boris Brezillion <boris.brezillon@bootlin.com>
+ *     Frieder Schrempf <frieder.schrempf@exceet.de>
+ *     Yogesh Gaur <yogeshnarayan.gaur@nxp.com>
+ *     Suresh Gupta <suresh.gupta@nxp.com>
+ *
+ * Based on the original fsl-quadspi.c spi-nor driver:
+ * Author: Freescale Semiconductor, Inc.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/sizes.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
+
+/*
+ * The driver only uses one single LUT entry, that is updated on
+ * each call of exec_op(). Index 0 is preset at boot with a basic
+ * read operation, so let's use the last entry (15).
+ */
+#define	SEQID_LUT			15
+
+/* Registers used by the driver */
+#define QUADSPI_MCR			0x00
+#define QUADSPI_MCR_RESERVED_MASK	GENMASK(19, 16)
+#define QUADSPI_MCR_MDIS_MASK		BIT(14)
+#define QUADSPI_MCR_CLR_TXF_MASK	BIT(11)
+#define QUADSPI_MCR_CLR_RXF_MASK	BIT(10)
+#define QUADSPI_MCR_DDR_EN_MASK		BIT(7)
+#define QUADSPI_MCR_END_CFG_MASK	GENMASK(3, 2)
+#define QUADSPI_MCR_SWRSTHD_MASK	BIT(1)
+#define QUADSPI_MCR_SWRSTSD_MASK	BIT(0)
+
+#define QUADSPI_IPCR			0x08
+#define QUADSPI_IPCR_SEQID_SHIFT	24
+
+#define QUADSPI_BUF3CR			0x1c
+#define QUADSPI_BUF3CR_ALLMST_MASK	BIT(31)
+#define QUADSPI_BUF3CR_ADATSZ_SHIFT	8
+#define QUADSPI_BUF3CR_ADATSZ_MASK	(0xFF << QUADSPI_BUF3CR_ADATSZ_SHIFT)
+
+#define QUADSPI_BFGENCR			0x20
+#define QUADSPI_BFGENCR_SEQID_SHIFT	12
+
+#define QUADSPI_BUF0IND			0x30
+#define QUADSPI_BUF1IND			0x34
+#define QUADSPI_BUF2IND			0x38
+#define QUADSPI_SFAR			0x100
+
+#define QUADSPI_SMPR			0x108
+#define QUADSPI_SMPR_DDRSMP_MASK	GENMASK(18, 16)
+#define QUADSPI_SMPR_FSDLY_MASK		BIT(6)
+#define QUADSPI_SMPR_FSPHS_MASK		BIT(5)
+#define QUADSPI_SMPR_HSENA_MASK		BIT(0)
+
+#define QUADSPI_RBCT			0x110
+#define QUADSPI_RBCT_WMRK_MASK		GENMASK(4, 0)
+#define QUADSPI_RBCT_RXBRD_USEIPS	BIT(8)
+
+#define QUADSPI_TBDR			0x154
+
+#define QUADSPI_SR			0x15c
+#define QUADSPI_SR_IP_ACC_MASK		BIT(1)
+#define QUADSPI_SR_AHB_ACC_MASK		BIT(2)
+
+#define QUADSPI_FR			0x160
+#define QUADSPI_FR_TFF_MASK		BIT(0)
+
+#define QUADSPI_SPTRCLR			0x16c
+#define QUADSPI_SPTRCLR_IPPTRC		BIT(8)
+#define QUADSPI_SPTRCLR_BFPTRC		BIT(0)
+
+#define QUADSPI_SFA1AD			0x180
+#define QUADSPI_SFA2AD			0x184
+#define QUADSPI_SFB1AD			0x188
+#define QUADSPI_SFB2AD			0x18c
+#define QUADSPI_RBDR(x)			(0x200 + ((x) * 4))
+
+#define QUADSPI_LUTKEY			0x300
+#define QUADSPI_LUTKEY_VALUE		0x5AF05AF0
+
+#define QUADSPI_LCKCR			0x304
+#define QUADSPI_LCKER_LOCK		BIT(0)
+#define QUADSPI_LCKER_UNLOCK		BIT(1)
+
+#define QUADSPI_RSER			0x164
+#define QUADSPI_RSER_TFIE		BIT(0)
+
+#define QUADSPI_LUT_BASE		0x310
+#define QUADSPI_LUT_OFFSET		(SEQID_LUT * 4 * 4)
+#define QUADSPI_LUT_REG(idx) \
+	(QUADSPI_LUT_BASE + QUADSPI_LUT_OFFSET + (idx) * 4)
+
+/* Instruction set for the LUT register */
+#define LUT_STOP		0
+#define LUT_CMD			1
+#define LUT_ADDR		2
+#define LUT_DUMMY		3
+#define LUT_MODE		4
+#define LUT_MODE2		5
+#define LUT_MODE4		6
+#define LUT_FSL_READ		7
+#define LUT_FSL_WRITE		8
+#define LUT_JMP_ON_CS		9
+#define LUT_ADDR_DDR		10
+#define LUT_MODE_DDR		11
+#define LUT_MODE2_DDR		12
+#define LUT_MODE4_DDR		13
+#define LUT_FSL_READ_DDR	14
+#define LUT_FSL_WRITE_DDR	15
+#define LUT_DATA_LEARN		16
+
+/*
+ * The PAD definitions for LUT register.
+ *
+ * The pad stands for the number of IO lines [0:3].
+ * For example, the quad read needs four IO lines,
+ * so you should use LUT_PAD(4).
+ */
+#define LUT_PAD(x) (fls(x) - 1)
+
+/*
+ * Macro for constructing the LUT entries with the following
+ * register layout:
+ *
+ *  ---------------------------------------------------
+ *  | INSTR1 | PAD1 | OPRND1 | INSTR0 | PAD0 | OPRND0 |
+ *  ---------------------------------------------------
+ */
+#define LUT_DEF(idx, ins, pad, opr)					\
+	((((ins) << 10) | ((pad) << 8) | (opr)) << (((idx) % 2) * 16))
+
+/* Controller needs driver to swap endianness */
+#define QUADSPI_QUIRK_SWAP_ENDIAN	BIT(0)
+
+/* Controller needs 4x internal clock */
+#define QUADSPI_QUIRK_4X_INT_CLK	BIT(1)
+
+/*
+ * TKT253890, the controller needs the driver to fill the txfifo with
+ * 16 bytes at least to trigger a data transfer, even though the extra
+ * data won't be transferred.
+ */
+#define QUADSPI_QUIRK_TKT253890		BIT(2)
+
+/* TKT245618, the controller cannot wake up from wait mode */
+#define QUADSPI_QUIRK_TKT245618		BIT(3)
+
+enum fsl_qspi_devtype {
+	FSL_QUADSPI_VYBRID,
+	FSL_QUADSPI_IMX6SX,
+	FSL_QUADSPI_IMX7D,
+	FSL_QUADSPI_IMX6UL,
+	FSL_QUADSPI_LS1021A,
+	FSL_QUADSPI_LS2080A,
+};
+
+struct fsl_qspi_devtype_data {
+	enum fsl_qspi_devtype devtype;
+	unsigned int rxfifo;
+	unsigned int txfifo;
+	unsigned int ahb_buf_size;
+	unsigned int quirks;
+};
+
+static const struct fsl_qspi_devtype_data vybrid_data = {
+	.devtype = FSL_QUADSPI_VYBRID,
+	.rxfifo = SZ_128,
+	.txfifo = SZ_64,
+	.ahb_buf_size = SZ_1K,
+	.quirks = QUADSPI_QUIRK_SWAP_ENDIAN,
+};
+
+static const struct fsl_qspi_devtype_data imx6sx_data = {
+	.devtype = FSL_QUADSPI_IMX6SX,
+	.rxfifo = SZ_128,
+	.txfifo = SZ_512,
+	.ahb_buf_size = SZ_1K,
+	.quirks = QUADSPI_QUIRK_4X_INT_CLK | QUADSPI_QUIRK_TKT245618,
+};
+
+static const struct fsl_qspi_devtype_data imx7d_data = {
+	.devtype = FSL_QUADSPI_IMX7D,
+	.rxfifo = SZ_512,
+	.txfifo = SZ_512,
+	.ahb_buf_size = SZ_1K,
+	.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK,
+};
+
+static const struct fsl_qspi_devtype_data imx6ul_data = {
+	.devtype = FSL_QUADSPI_IMX6UL,
+	.rxfifo = SZ_128,
+	.txfifo = SZ_512,
+	.ahb_buf_size = SZ_1K,
+	.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK,
+};
+
+static const struct fsl_qspi_devtype_data ls1021a_data = {
+	.devtype = FSL_QUADSPI_LS1021A,
+	.rxfifo = SZ_128,
+	.txfifo = SZ_64,
+	.ahb_buf_size = SZ_1K,
+	.quirks = 0,
+};
+
+static const struct fsl_qspi_devtype_data ls2080a_data = {
+	.devtype = FSL_QUADSPI_LS2080A,
+	.rxfifo = SZ_128,
+	.txfifo = SZ_64,
+	.ahb_buf_size = SZ_1K,
+	.quirks = QUADSPI_QUIRK_TKT253890,
+};
+
+struct fsl_qspi {
+	void __iomem *iobase;
+	void __iomem *ahb_addr;
+	u32 memmap_phy;
+	struct clk *clk, *clk_en;
+	struct device *dev;
+	struct completion c;
+	const struct fsl_qspi_devtype_data *devtype_data;
+	bool big_endian;
+	struct mutex lock;
+	struct pm_qos_request pm_qos_req;
+	int selected;
+	u8 seq;
+	void (*write)(u32 val, void __iomem *addr);
+	u32 (*read)(void __iomem *addr);
+};
+
+static inline int needs_swap_endian(struct fsl_qspi *q)
+{
+	return q->devtype_data->quirks & QUADSPI_QUIRK_SWAP_ENDIAN;
+}
+
+static inline int needs_4x_clock(struct fsl_qspi *q)
+{
+	return q->devtype_data->quirks & QUADSPI_QUIRK_4X_INT_CLK;
+}
+
+static inline int needs_fill_txfifo(struct fsl_qspi *q)
+{
+	return q->devtype_data->quirks & QUADSPI_QUIRK_TKT253890;
+}
+
+static inline int needs_wakeup_wait_mode(struct fsl_qspi *q)
+{
+	return q->devtype_data->quirks & QUADSPI_QUIRK_TKT245618;
+}
+
+/*
+ * An IC bug makes it necessary to rearrange the 32-bit data.
+ * Later chips, such as IMX6SLX, have fixed this bug.
+ */
+static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a)
+{
+	return needs_swap_endian(q) ? __swab32(a) : a;
+}
+
+static void qspi_writel_be(u32 val, void __iomem *addr)
+{
+	iowrite32be(val, addr);
+}
+
+static void qspi_writel(u32 val, void __iomem *addr)
+{
+	iowrite32(val, addr);
+}
+
+static u32 qspi_readl_be(void __iomem *addr)
+{
+	return ioread32be(addr);
+}
+
+static u32 qspi_readl(void __iomem *addr)
+{
+	return ioread32(addr);
+}
+
+static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
+{
+	struct fsl_qspi *q = dev_id;
+	u32 reg;
+
+	/* clear interrupt */
+	reg = q->read(q->iobase + QUADSPI_FR);
+	q->write(reg, q->iobase + QUADSPI_FR);
+
+	if (reg & QUADSPI_FR_TFF_MASK)
+		complete(&q->c);
+
+	dev_dbg(q->dev, "QUADSPI_FR : 0x%.8x:0x%.8x\n", 0, reg);
+	return IRQ_HANDLED;
+}
+
+static int fsl_qspi_check_buswidth(struct fsl_qspi *q, u8 width)
+{
+	switch (width) {
+	case 1:
+	case 2:
+	case 4:
+		return 0;
+	}
+
+	return -ENOTSUPP;
+}
+
+static bool fsl_qspi_supports_op(struct spi_mem *mem,
+				 const struct spi_mem_op *op)
+{
+	struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->master);
+	int ret;
+
+	ret = fsl_qspi_check_buswidth(q, op->cmd.buswidth);
+
+	if (op->addr.nbytes)
+		ret |= fsl_qspi_check_buswidth(q, op->addr.buswidth);
+
+	if (op->dummy.nbytes)
+		ret |= fsl_qspi_check_buswidth(q, op->dummy.buswidth);
+
+	if (op->data.nbytes)
+		ret |= fsl_qspi_check_buswidth(q, op->data.buswidth);
+
+	if (ret)
+		return false;
+
+	/*
+	 * The number of instructions needed for the op, needs
+	 * to fit into a single LUT entry.
+	 */
+	if (op->addr.nbytes +
+	   (op->dummy.nbytes ? 1:0) +
+	   (op->data.nbytes ? 1:0) > 6)
+		return false;
+
+	/* Max 64 dummy clock cycles supported */
+	if (op->dummy.nbytes * 8 / op->dummy.buswidth > 64)
+		return false;
+
+	/* Max data length, check controller limits and alignment */
+	if (op->data.dir == SPI_MEM_DATA_IN &&
+	    (op->data.nbytes > q->devtype_data->ahb_buf_size ||
+	     (op->data.nbytes > q->devtype_data->rxfifo - 4 &&
+	      !IS_ALIGNED(op->data.nbytes, 8))))
+		return false;
+
+	if (op->data.dir == SPI_MEM_DATA_OUT &&
+	    op->data.nbytes > q->devtype_data->txfifo)
+		return false;
+
+	return true;
+}
+
+static void fsl_qspi_prepare_lut(struct fsl_qspi *q,
+				 const struct spi_mem_op *op)
+{
+	void __iomem *base = q->iobase;
+	u32 lutval[4] = {};
+	int lutidx = 1, i;
+
+	lutval[0] |= LUT_DEF(0, LUT_CMD, LUT_PAD(op->cmd.buswidth),
+			     op->cmd.opcode);
+
+	/*
+	 * For some unknown reason, using LUT_ADDR doesn't work in some
+	 * cases (at least with only one byte long addresses), so
+	 * let's use LUT_MODE to write the address bytes one by one
+	 */
+	for (i = 0; i < op->addr.nbytes; i++) {
+		u8 addrbyte = op->addr.val >> (8 * (op->addr.nbytes - i - 1));
+
+		lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_MODE,
+					      LUT_PAD(op->addr.buswidth),
+					      addrbyte);
+		lutidx++;
+	}
+
+	if (op->dummy.nbytes) {
+		lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_DUMMY,
+					      LUT_PAD(op->dummy.buswidth),
+					      op->dummy.nbytes * 8 /
+					      op->dummy.buswidth);
+		lutidx++;
+	}
+
+	if (op->data.nbytes) {
+		lutval[lutidx / 2] |= LUT_DEF(lutidx,
+					      op->data.dir == SPI_MEM_DATA_IN ?
+					      LUT_FSL_READ : LUT_FSL_WRITE,
+					      LUT_PAD(op->data.buswidth),
+					      0);
+		lutidx++;
+	}
+
+	lutval[lutidx / 2] |= LUT_DEF(lutidx, LUT_STOP, 0, 0);
+
+	/* unlock LUT */
+	q->write(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
+	q->write(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
+
+	/* fill LUT */
+	for (i = 0; i < ARRAY_SIZE(lutval); i++)
+		q->write(lutval[i], base + QUADSPI_LUT_REG(i));
+
+	/* lock LUT */
+	q->write(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
+	q->write(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
+}
+
+static int fsl_qspi_clk_prep_enable(struct fsl_qspi *q)
+{
+	int ret;
+
+	ret = clk_prepare_enable(q->clk_en);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(q->clk);
+	if (ret) {
+		clk_disable_unprepare(q->clk_en);
+		return ret;
+	}
+
+	if (needs_wakeup_wait_mode(q))
+		pm_qos_add_request(&q->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, 0);
+
+	return 0;
+}
+
+static void fsl_qspi_clk_disable_unprep(struct fsl_qspi *q)
+{
+	if (needs_wakeup_wait_mode(q))
+		pm_qos_remove_request(&q->pm_qos_req);
+
+	clk_disable_unprepare(q->clk);
+	clk_disable_unprepare(q->clk_en);
+}
+
+static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi)
+{
+	unsigned long rate = spi->max_speed_hz;
+	int ret, i;
+	u32 map_addr;
+
+	if (q->selected == spi->chip_select)
+		return;
+
+	/*
+	 * In HW there can be a maximum of four chips on two buses with
+	 * two chip selects on each bus. We use four chip selects in SW
+	 * to differentiate between the four chips.
+	 * We use the SFA1AD, SFA2AD, SFB1AD, SFB2AD registers to select
+	 * the chip we want to access.
+	 */
+	for (i = 0; i < 4; i++) {
+		if (i < spi->chip_select)
+			map_addr = q->memmap_phy;
+		else
+			map_addr = q->memmap_phy +
+				   2 * q->devtype_data->ahb_buf_size;
+
+		q->write(map_addr, q->iobase + QUADSPI_SFA1AD + (i * 4));
+	}
+
+	if (needs_4x_clock(q))
+		rate *= 4;
+
+	fsl_qspi_clk_disable_unprep(q);
+
+	ret = clk_set_rate(q->clk, rate);
+	if (ret)
+		return;
+
+	ret = fsl_qspi_clk_prep_enable(q);
+	if (ret)
+		return;
+
+	q->selected = spi->chip_select;
+}
+
+static void fsl_qspi_read_ahb(struct fsl_qspi *q, const struct spi_mem_op *op)
+{
+	/*
+	 * We want to avoid needing to invalidate the cache by issueing
+	 * a reset to the AHB and Serial Flash domain, as this needs
+	 * time. So we change the address on each read to trigger an
+	 * actual read operation on the flash. The actual address for
+	 * the flash memory is set by programming the LUT.
+	 */
+	memcpy_fromio(op->data.buf.in,
+		      q->ahb_addr +
+		      (((q->seq & (1 << q->selected)) == 0 ? 0:1) *
+		       q->devtype_data->ahb_buf_size),
+		      op->data.nbytes);
+
+	q->seq ^= 1 << q->selected;
+}
+
+static void fsl_qspi_fill_txfifo(struct fsl_qspi *q,
+				 const struct spi_mem_op *op)
+{
+	void __iomem *base = q->iobase;
+	int i;
+	u32 val;
+
+	for (i = 0; i < ALIGN_DOWN(op->data.nbytes, 4); i += 4) {
+		memcpy(&val, op->data.buf.out + i, 4);
+		val = fsl_qspi_endian_xchg(q, val);
+		q->write(val, base + QUADSPI_TBDR);
+	}
+
+	if (i < op->data.nbytes) {
+		memcpy(&val, op->data.buf.out + i, op->data.nbytes - i);
+		val = fsl_qspi_endian_xchg(q, val);
+		q->write(val, base + QUADSPI_TBDR);
+	}
+
+	if (needs_fill_txfifo(q)) {
+		for (i = op->data.nbytes; i < 16; i += 4)
+			q->write(0, base + QUADSPI_TBDR);
+	}
+}
+
+static void fsl_qspi_read_rxfifo(struct fsl_qspi *q,
+			  const struct spi_mem_op *op)
+{
+	void __iomem *base = q->iobase;
+	int i;
+	u8 *buf = op->data.buf.in;
+	u32 val;
+
+	for (i = 0; i < ALIGN_DOWN(op->data.nbytes, 4); i += 4) {
+		val = q->read(base + QUADSPI_RBDR(i / 4));
+		val = fsl_qspi_endian_xchg(q, val);
+		memcpy(buf + i, &val, 4);
+	}
+
+	if (i < op->data.nbytes) {
+		val = q->read(base + QUADSPI_RBDR(i / 4));
+		val = fsl_qspi_endian_xchg(q, val);
+		memcpy(buf + i, &val, op->data.nbytes - i);
+	}
+}
+
+static int fsl_qspi_do_op(struct fsl_qspi *q, const struct spi_mem_op *op)
+{
+	void __iomem *base = q->iobase;
+	int err = 0;
+
+	init_completion(&q->c);
+
+	/*
+	 * Always start the sequence at the same index since we update
+	 * the LUT at each exec_op() call. And also specify the DATA
+	 * length, since it's has not been specified in the LUT.
+	 */
+	q->write(op->data.nbytes |
+		    (SEQID_LUT << QUADSPI_IPCR_SEQID_SHIFT),
+		    base + QUADSPI_IPCR);
+
+	/* Wait for the interrupt. */
+	if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000)))
+		err = -ETIMEDOUT;
+
+	if (!err && op->data.nbytes && op->data.dir == SPI_MEM_DATA_IN)
+		fsl_qspi_read_rxfifo(q, op);
+
+	return err;
+}
+
+static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+	struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->master);
+	void __iomem *base = q->iobase;
+	int err = 0;
+	unsigned int timeout = 1000;
+
+	mutex_lock(&q->lock);
+
+	/* wait for the controller being ready */
+	do {
+		u32 status;
+
+		status = q->read(base + QUADSPI_SR);
+		if (status &
+		    (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) {
+			udelay(1);
+			dev_dbg(q->dev, "The controller is busy, 0x%x\n",
+				status);
+			continue;
+		}
+		break;
+	} while (--timeout);
+
+	fsl_qspi_select_mem(q, mem->spi);
+
+	q->write(q->memmap_phy, base + QUADSPI_SFAR);
+
+	q->write(q->read(base + QUADSPI_MCR) |
+		 QUADSPI_MCR_CLR_RXF_MASK | QUADSPI_MCR_CLR_TXF_MASK,
+		 base + QUADSPI_MCR);
+
+	q->write(QUADSPI_SPTRCLR_BFPTRC | QUADSPI_SPTRCLR_IPPTRC,
+		    base + QUADSPI_SPTRCLR);
+
+	fsl_qspi_prepare_lut(q, op);
+
+	/*
+	 * If we have large chunks of data, we read them through the AHB bus
+	 * by accessing the mapped memory. In all other cases we use
+	 * IP commands to access the flash.
+	 */
+	if (op->data.nbytes > (q->devtype_data->rxfifo - 4) &&
+	    op->data.dir == SPI_MEM_DATA_IN) {
+		fsl_qspi_read_ahb(q, op);
+	} else {
+		q->write(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
+			 base + QUADSPI_RBCT);
+
+		if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT)
+			fsl_qspi_fill_txfifo(q, op);
+
+		err = fsl_qspi_do_op(q, op);
+	}
+
+	mutex_unlock(&q->lock);
+
+	return err;
+}
+
+static int fsl_qspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+{
+	struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->master);
+
+	if (op->data.dir == SPI_MEM_DATA_OUT) {
+		if (op->data.nbytes > q->devtype_data->txfifo)
+			op->data.nbytes = q->devtype_data->txfifo;
+	} else {
+		if (op->data.nbytes > q->devtype_data->ahb_buf_size)
+			op->data.nbytes = q->devtype_data->ahb_buf_size;
+		else if (op->data.nbytes > (q->devtype_data->rxfifo - 4))
+			op->data.nbytes = ALIGN_DOWN(op->data.nbytes, 8);
+	}
+
+	return 0;
+}
+
+static int fsl_qspi_default_setup(struct fsl_qspi *q)
+{
+	void __iomem *base = q->iobase;
+	u32 reg;
+	int ret;
+
+	/* disable and unprepare clock to avoid glitch pass to controller */
+	fsl_qspi_clk_disable_unprep(q);
+
+	/* the default frequency, we will change it later if necessary. */
+	ret = clk_set_rate(q->clk, 66000000);
+	if (ret)
+		return ret;
+
+	ret = fsl_qspi_clk_prep_enable(q);
+	if (ret)
+		return ret;
+
+	/* Reset the module */
+	q->write(QUADSPI_MCR_SWRSTSD_MASK | QUADSPI_MCR_SWRSTHD_MASK,
+		 base + QUADSPI_MCR);
+	udelay(1);
+
+	/* Disable the module */
+	q->write(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
+		 base + QUADSPI_MCR);
+
+	reg = q->read(base + QUADSPI_SMPR);
+	q->write(reg & ~(QUADSPI_SMPR_FSDLY_MASK
+			| QUADSPI_SMPR_FSPHS_MASK
+			| QUADSPI_SMPR_HSENA_MASK
+			| QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR);
+
+	/* We only use the buffer3 for AHB read */
+	q->write(0, base + QUADSPI_BUF0IND);
+	q->write(0, base + QUADSPI_BUF1IND);
+	q->write(0, base + QUADSPI_BUF2IND);
+
+	q->write(SEQID_LUT << QUADSPI_BFGENCR_SEQID_SHIFT,
+		 q->iobase + QUADSPI_BFGENCR);
+	q->write(QUADSPI_RBCT_WMRK_MASK, base + QUADSPI_RBCT);
+	q->write(QUADSPI_BUF3CR_ALLMST_MASK |
+		 ((q->devtype_data->ahb_buf_size / 8) <<
+		  QUADSPI_BUF3CR_ADATSZ_SHIFT),
+		 base + QUADSPI_BUF3CR);
+
+	q->selected = -1;
+	q->seq = 0;
+
+	/* Enable the module */
+	q->write(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
+		 base + QUADSPI_MCR);
+
+	/* clear all interrupt status */
+	q->write(0xffffffff, q->iobase + QUADSPI_FR);
+
+	/* enable the interrupt */
+	q->write(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
+
+	return 0;
+}
+
+static const char *fsl_qspi_get_name(struct spi_mem *mem)
+{
+	struct fsl_qspi *q = spi_controller_get_devdata(mem->spi->master);
+	struct device *dev = &mem->spi->dev;
+	const char *name;
+
+	/*
+	 * In order to keep mtdparts compatible with the old MTD driver at
+	 * mtd/spi-nor/fsl-quadspi.c, we set a custom name derived from the
+	 * platform_device of the controller.
+	 */
+	if (of_get_available_child_count(q->dev->of_node) == 1)
+		return dev_name(q->dev);
+
+	name = devm_kasprintf(dev, GFP_KERNEL,
+			      "%s-%d", dev_name(q->dev),
+			      mem->spi->chip_select);
+
+	if (!name) {
+		dev_err(dev, "failed to get memory for custom flash name\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return name;
+}
+
+static const struct spi_controller_mem_ops fsl_qspi_mem_ops = {
+	.adjust_op_size = fsl_qspi_adjust_op_size,
+	.supports_op = fsl_qspi_supports_op,
+	.exec_op = fsl_qspi_exec_op,
+	.get_name = fsl_qspi_get_name,
+};
+
+static int fsl_qspi_probe(struct platform_device *pdev)
+{
+	struct spi_controller *ctlr;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct resource *res;
+	struct fsl_qspi *q;
+	int ret;
+
+	ctlr = spi_alloc_master(&pdev->dev, sizeof(*q));
+	if (!ctlr)
+		return -ENOMEM;
+
+	ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD |
+			  SPI_TX_DUAL | SPI_TX_QUAD;
+
+	q = spi_controller_get_devdata(ctlr);
+	q->dev = dev;
+	q->devtype_data = of_device_get_match_data(dev);
+	if (!q->devtype_data) {
+		ret = -ENODEV;
+		goto err_put_ctrl;
+	}
+
+	platform_set_drvdata(pdev, q);
+
+	/* find the resources */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "QuadSPI");
+	q->iobase = devm_ioremap_resource(dev, res);
+	if (IS_ERR(q->iobase)) {
+		ret = PTR_ERR(q->iobase);
+		goto err_put_ctrl;
+	}
+
+	/*
+	 * R/W functions for big- or little-endian registers:
+	 * The QSPI controller's endianness is independent of
+	 * the CPU core's endianness. So far, although the CPU
+	 * core is little-endian the QSPI controller can use
+	 * big-endian or little-endian.
+	 */
+	if (of_property_read_bool(np, "big-endian")) {
+		q->write = qspi_writel_be;
+		q->read = qspi_readl_be;
+	} else {
+		q->write = qspi_writel;
+		q->read = qspi_readl;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					"QuadSPI-memory");
+	q->ahb_addr = devm_ioremap_resource(dev, res);
+	if (IS_ERR(q->ahb_addr)) {
+		ret = PTR_ERR(q->ahb_addr);
+		goto err_put_ctrl;
+	}
+
+	q->memmap_phy = res->start;
+
+	/* find the clocks */
+	q->clk_en = devm_clk_get(dev, "qspi_en");
+	if (IS_ERR(q->clk_en)) {
+		ret = PTR_ERR(q->clk_en);
+		goto err_put_ctrl;
+	}
+
+	q->clk = devm_clk_get(dev, "qspi");
+	if (IS_ERR(q->clk)) {
+		ret = PTR_ERR(q->clk);
+		goto err_put_ctrl;
+	}
+
+	ret = fsl_qspi_clk_prep_enable(q);
+	if (ret) {
+		dev_err(dev, "can not enable the clock\n");
+		goto err_put_ctrl;
+	}
+
+	/* find the irq */
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0) {
+		dev_err(dev, "failed to get the irq: %d\n", ret);
+		goto err_disable_clk;
+	}
+
+	ret = devm_request_irq(dev, ret,
+			fsl_qspi_irq_handler, 0, pdev->name, q);
+	if (ret) {
+		dev_err(dev, "failed to request irq: %d\n", ret);
+		goto err_disable_clk;
+	}
+
+	mutex_init(&q->lock);
+
+	ctlr->bus_num = -1;
+	ctlr->num_chipselect = 4;
+	ctlr->mem_ops = &fsl_qspi_mem_ops;
+
+	fsl_qspi_default_setup(q);
+
+	ctlr->dev.of_node = np;
+
+	ret = spi_register_controller(ctlr);
+	if (ret)
+		goto err_destroy_mutex;
+
+	return 0;
+
+err_destroy_mutex:
+	mutex_destroy(&q->lock);
+
+err_disable_clk:
+	fsl_qspi_clk_disable_unprep(q);
+
+err_put_ctrl:
+	spi_controller_put(ctlr);
+
+	dev_err(dev, "Freescale QuadSPI probe failed\n");
+	return ret;
+}
+
+static int fsl_qspi_remove(struct platform_device *pdev)
+{
+	struct fsl_qspi *q = platform_get_drvdata(pdev);
+
+	/* disable the hardware */
+	q->write(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
+	q->write(0x0, q->iobase + QUADSPI_RSER);
+
+	fsl_qspi_clk_disable_unprep(q);
+
+	mutex_destroy(&q->lock);
+
+	return 0;
+}
+
+static int fsl_qspi_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int fsl_qspi_resume(struct device *dev)
+{
+	struct fsl_qspi *q = dev_get_drvdata(dev);
+
+	fsl_qspi_default_setup(q);
+
+	return 0;
+}
+
+static const struct of_device_id fsl_qspi_dt_ids[] = {
+	{ .compatible = "fsl,vf610-qspi", .data = &vybrid_data, },
+	{ .compatible = "fsl,imx6sx-qspi", .data = &imx6sx_data, },
+	{ .compatible = "fsl,imx7d-qspi", .data = &imx7d_data, },
+	{ .compatible = "fsl,imx6ul-qspi", .data = &imx6ul_data, },
+	{ .compatible = "fsl,ls1021a-qspi", .data = &ls1021a_data, },
+	{ .compatible = "fsl,ls2080a-qspi", .data = &ls2080a_data, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
+
+static const struct dev_pm_ops fsl_qspi_pm_ops = {
+	.suspend	= fsl_qspi_suspend,
+	.resume		= fsl_qspi_resume,
+};
+
+static struct platform_driver fsl_qspi_driver = {
+	.driver = {
+		.name	= "fsl-quadspi",
+		.of_match_table = fsl_qspi_dt_ids,
+		.pm =   &fsl_qspi_pm_ops,
+	},
+	.probe          = fsl_qspi_probe,
+	.remove		= fsl_qspi_remove,
+};
+module_platform_driver(fsl_qspi_driver);
+
+MODULE_DESCRIPTION("Freescale QuadSPI Controller Driver");
+MODULE_AUTHOR("Freescale Semiconductor Inc.");
+MODULE_AUTHOR("Boris Brezillion <boris.brezillon@bootlin.com>");
+MODULE_AUTHOR("Frieder Schrempf <frieder.schrempf@exceet.de>");
+MODULE_AUTHOR("Yogesh Gaur <yogeshnarayan.gaur@nxp.com>");
+MODULE_AUTHOR("Suresh Gupta <suresh.gupta@nxp.com>");
+MODULE_LICENSE("GPL v2");