diff mbox series

[1/2] mtd: mtk-quadspi: add support for memory-mapped flash reading

Message ID 20191106140748.13100-2-gch981213@gmail.com (mailing list archive)
State New, archived
Headers show
Series mtd: mtk-quadspi: add support for memory-mapped flash reading | expand

Commit Message

Chuanhong Guo Nov. 6, 2019, 2:07 p.m. UTC
PIO reading mode on this controller is ridiculously inefficient
(one cmd+addr+dummy sequence reads only one byte)
This patch adds support for reading from memory-mapped flash area
which increases reading speed from 1MB/s to 5.6MB/s

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
---
 drivers/mtd/spi-nor/mtk-quadspi.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

Comments

Vignesh Raghavendra Nov. 7, 2019, 6:06 a.m. UTC | #1
Hi,

On 06/11/19 7:37 PM, Chuanhong Guo wrote:
> PIO reading mode on this controller is ridiculously inefficient
> (one cmd+addr+dummy sequence reads only one byte)
> This patch adds support for reading from memory-mapped flash area
> which increases reading speed from 1MB/s to 5.6MB/s
> 
> Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
> ---
>  drivers/mtd/spi-nor/mtk-quadspi.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c
> index 34db01ab6cab..ba8b3be39896 100644
> --- a/drivers/mtd/spi-nor/mtk-quadspi.c
> +++ b/drivers/mtd/spi-nor/mtk-quadspi.c
> @@ -106,6 +106,7 @@ struct mtk_nor {
>  	struct spi_nor nor;
>  	struct device *dev;
>  	void __iomem *base;	/* nor flash base address */
> +	void __iomem *flash_base;
>  	struct clk *spi_clk;
>  	struct clk *nor_clk;
>  };
> @@ -272,6 +273,11 @@ static ssize_t mtk_nor_read(struct spi_nor *nor, loff_t from, size_t length,
>  	mtk_nor_set_read_mode(mtk_nor);
>  	mtk_nor_set_addr(mtk_nor, addr);
>  
> +	if (mtk_nor->flash_base) {
> +		memcpy_fromio(buffer, mtk_nor->flash_base + from, length);
> +		return length;
> +	}
> +

Don't you need to check if access is still within valid memory mapped
window?

>  	for (i = 0; i < length; i++) {
>  		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_READ_CMD);
>  		if (ret < 0)
> @@ -475,6 +481,11 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
>  	if (IS_ERR(mtk_nor->base))
>  		return PTR_ERR(mtk_nor->base);
>  
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	mtk_nor->flash_base = devm_ioremap_resource(&pdev->dev, res);

There is a single API now: devm_platform_ioremap_resource().

> +	if (IS_ERR(mtk_nor->flash_base))
> +		mtk_nor->flash_base = NULL;
> +
>  	mtk_nor->spi_clk = devm_clk_get(&pdev->dev, "spi");
>  	if (IS_ERR(mtk_nor->spi_clk))
>  		return PTR_ERR(mtk_nor->spi_clk);
>
Chuanhong Guo Nov. 7, 2019, 9:31 a.m. UTC | #2
Hi!

On Thu, Nov 7, 2019 at 2:05 PM Vignesh Raghavendra <vigneshr@ti.com> wrote:
> > @@ -272,6 +273,11 @@ static ssize_t mtk_nor_read(struct spi_nor *nor, loff_t from, size_t length,
> >       mtk_nor_set_read_mode(mtk_nor);
> >       mtk_nor_set_addr(mtk_nor, addr);
> >
> > +     if (mtk_nor->flash_base) {
> > +             memcpy_fromio(buffer, mtk_nor->flash_base + from, length);
> > +             return length;
> > +     }
> > +
>
> Don't you need to check if access is still within valid memory mapped
> window?

The mapped area is 256MB and I don't quite believe there will be such
a big NOR flash.
I'll add a check here in the next version.

>
> >       for (i = 0; i < length; i++) {
> >               ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_READ_CMD);
> >               if (ret < 0)
> > @@ -475,6 +481,11 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
> >       if (IS_ERR(mtk_nor->base))
> >               return PTR_ERR(mtk_nor->base);
> >
> > +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +     mtk_nor->flash_base = devm_ioremap_resource(&pdev->dev, res);
>
> There is a single API now: devm_platform_ioremap_resource().

Cool. I'll change it.
Should I add another patch to change the same mapping operation right
above this piece of code?

Regards,
Chuanhong Guo
Vignesh Raghavendra Nov. 7, 2019, 12:25 p.m. UTC | #3
On 07/11/19 3:01 PM, Chuanhong Guo wrote:
> Hi!
> 
> On Thu, Nov 7, 2019 at 2:05 PM Vignesh Raghavendra <vigneshr@ti.com> wrote:
>>> @@ -272,6 +273,11 @@ static ssize_t mtk_nor_read(struct spi_nor *nor, loff_t from, size_t length,
>>>       mtk_nor_set_read_mode(mtk_nor);
>>>       mtk_nor_set_addr(mtk_nor, addr);
>>>
>>> +     if (mtk_nor->flash_base) {
>>> +             memcpy_fromio(buffer, mtk_nor->flash_base + from, length);
>>> +             return length;
>>> +     }
>>> +
>>
>> Don't you need to check if access is still within valid memory mapped
>> window?
> 
> The mapped area is 256MB and I don't quite believe there will be such
> a big NOR flash.
> I'll add a check here in the next version.
>


There are 256MB (2GiB) NORs out there in market already. So, pretty
soon, 256MB window won't be big enough :)

>>
>>>       for (i = 0; i < length; i++) {
>>>               ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_READ_CMD);
>>>               if (ret < 0)
>>> @@ -475,6 +481,11 @@ static int mtk_nor_drv_probe(struct platform_device *pdev)
>>>       if (IS_ERR(mtk_nor->base))
>>>               return PTR_ERR(mtk_nor->base);
>>>
>>> +     res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>>> +     mtk_nor->flash_base = devm_ioremap_resource(&pdev->dev, res);
>>
>> There is a single API now: devm_platform_ioremap_resource().
> 
> Cool. I'll change it.
> Should I add another patch to change the same mapping operation right
> above this piece of code?
> 

That would be nice to do too, please send a separate patch.
Yingjoe Chen Nov. 7, 2019, 1:23 p.m. UTC | #4
On Wed, 2019-11-06 at 22:07 +0800, Chuanhong Guo wrote:
> PIO reading mode on this controller is ridiculously inefficient
> (one cmd+addr+dummy sequence reads only one byte)
> This patch adds support for reading from memory-mapped flash area
> which increases reading speed from 1MB/s to 5.6MB/s

This may not be true for all MTK SoC. Which one are you testing?

Joe.C
Chuanhong Guo Nov. 7, 2019, 3:34 p.m. UTC | #5
Hi!

On Thu, Nov 7, 2019 at 9:23 PM Yingjoe Chen <yingjoe.chen@mediatek.com> wrote:
>
> On Wed, 2019-11-06 at 22:07 +0800, Chuanhong Guo wrote:
> > PIO reading mode on this controller is ridiculously inefficient
> > (one cmd+addr+dummy sequence reads only one byte)
> > This patch adds support for reading from memory-mapped flash area
> > which increases reading speed from 1MB/s to 5.6MB/s
>
> This may not be true for all MTK SoC. Which one are you testing?
>

I tested it on MT7629.
There should be a 5x reading speed increment under DMA or direct read
mode than PIO mode because PIO mode needs 30 or 36 clocks for every
single byte of data while DMA or direct read only needs 24 or 30
clocks for initial command/address/dummy and every byte of data after
that only need 8 clocks.

Regards,
Chuanhong Guo
Chuanhong Guo Nov. 8, 2019, 3:52 a.m. UTC | #6
Hi all!

On Wed, Nov 6, 2019 at 10:08 PM Chuanhong Guo <gch981213@gmail.com> wrote:
>
> PIO reading mode on this controller is ridiculously inefficient
> (one cmd+addr+dummy sequence reads only one byte)
> This patch adds support for reading from memory-mapped flash area
> which increases reading speed from 1MB/s to 5.6MB/s
>
> Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
> ---
>  drivers/mtd/spi-nor/mtk-quadspi.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>

I'll abandon this patchset and implement DMA reading instead.

Regards,
Chuanhong Guo
diff mbox series

Patch

diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c
index 34db01ab6cab..ba8b3be39896 100644
--- a/drivers/mtd/spi-nor/mtk-quadspi.c
+++ b/drivers/mtd/spi-nor/mtk-quadspi.c
@@ -106,6 +106,7 @@  struct mtk_nor {
 	struct spi_nor nor;
 	struct device *dev;
 	void __iomem *base;	/* nor flash base address */
+	void __iomem *flash_base;
 	struct clk *spi_clk;
 	struct clk *nor_clk;
 };
@@ -272,6 +273,11 @@  static ssize_t mtk_nor_read(struct spi_nor *nor, loff_t from, size_t length,
 	mtk_nor_set_read_mode(mtk_nor);
 	mtk_nor_set_addr(mtk_nor, addr);
 
+	if (mtk_nor->flash_base) {
+		memcpy_fromio(buffer, mtk_nor->flash_base + from, length);
+		return length;
+	}
+
 	for (i = 0; i < length; i++) {
 		ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PIO_READ_CMD);
 		if (ret < 0)
@@ -475,6 +481,11 @@  static int mtk_nor_drv_probe(struct platform_device *pdev)
 	if (IS_ERR(mtk_nor->base))
 		return PTR_ERR(mtk_nor->base);
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mtk_nor->flash_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mtk_nor->flash_base))
+		mtk_nor->flash_base = NULL;
+
 	mtk_nor->spi_clk = devm_clk_get(&pdev->dev, "spi");
 	if (IS_ERR(mtk_nor->spi_clk))
 		return PTR_ERR(mtk_nor->spi_clk);