OMAP2+ OneNAND driver update
Subsystems (8)
v6 cover OMAP2+ OneNAND driver update
this patch serie updates OMAP2+ OneNAND driver to the present times, making it fully DT configurable, using libgpio and dmaengine apis.
Please note that unlike previous driver version, which basically ignored DT specified timings, this one relies on it, so it is important to get it right in your DT (dumping it from previous kernel version).
In case synchronous timings is requested, it is okay to specify timings for the slowest chip ever used for you board as it is evetually optimized after chip probe.
Original driver used DMA only if user specified INT gpio in platform data, now DMA is used unconditionally and PIO mode is used as fallback.
In case anyone wants to give it a try, few DT related changes are needed:
- onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is done in patch 2)
- to use INT pin, int-gpios needs to be specified.
Most notable changes from v3:
- added dmaengine patches by Peter Ujfalusi
- added dt bindings documentation
- added cleanup patches
- DMA enabled by default
Most notable changes from v4:
- collected tags
- used INT pin name properly
- hopefully all comments taken into account
Most notable changes from v5:
- as this serie is expected to be merged via single tree patches 13 and 14 were squashed together not to break bisecting.
- patch 16 was dropped.
This patchset depends on an immutable commit:
The following changes since commit 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:
Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)
are available in the git repository at:
https://github.com/rogerq/linux.git for-v4.16/gpmc-omap-immutable
for you to fetch changes up to c18a7ac3398d0cef29749f9568666db8321aa4c9:
memory: omap-gpmc: Make 'bank-width' property optional (2017-12-01 15:37:49 +0200)
Ladislav Michl (12):
dt-bindings: mtd: gpmc-onenand: Update properties description
ARM: dts: OMAP2+: Add compatible property to onenand node
ARM: dts: omap3-igep: Update onenand node timings
mtd: onenand: omap2: Remove regulator support
mtd: onenand: omap2: Remove skip initial unlocking support
mtd: onenand: omap2: Remove partitioning support from platform data
mtd: onenand: omap2: Account waiting time as waiting on IO
mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
mtd: onenand: omap2: Configure driver from DT
ARM: OMAP2+: Remove gpmc-onenand
Peter Ujfalusi (2):
mtd: onenand: omap2: Simplify the DMA setup for various paths
mtd: onenand: omap2: Convert to use dmaengine for memcpy
.../devicetree/bindings/mtd/gpmc-onenand.txt | 6 +- arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 + arch/arm/boot/dts/omap3-igep.dtsi | 30 +- arch/arm/boot/dts/omap3-n900.dts | 1 + arch/arm/boot/dts/omap3-n950-n9.dtsi | 1 + arch/arm/boot/dts/omap3430-sdp.dts | 1 + arch/arm/mach-omap2/Makefile | 3 - arch/arm/mach-omap2/gpmc-onenand.c | 409 --------------- drivers/memory/omap-gpmc.c | 158 ++++-- drivers/mtd/onenand/Kconfig | 4 +- drivers/mtd/onenand/omap2.c | 576 ++++++++------------- include/linux/omap-gpmc.h | 28 + include/linux/platform_data/mtd-onenand-omap2.h | 34 -- 13 files changed, 386 insertions(+), 866 deletions(-) delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 1/14 dt-bindings: mtd: gpmc-onenand: Update properties description
Compatible property is required for OMAP2+ mtd driver. Also add INT pin gpio description and delete unused dma-channel property.
---
Changes in v6: None
Changes in v5:
- renamed R/B pin to INT pin
Changes in v4:
- new patch
Changes in v3: None
Changes in v2: None
Documentation/devicetree/bindings/mtd/gpmc-onenand.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-onenand.txt +4 -2
@@ -9,13 +9,14 @@ Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt Required properties: + - compatible: "ti,omap2-onenand" - reg: The CS line the peripheral is connected to - - gpmc,device-width Width of the ONENAND device connected to the GPMC + - gpmc,device-width: Width of the ONENAND device connected to the GPMC in bytes. Must be 1 or 2. Optional properties: - - dma-channel: DMA Channel index + - int-gpios: GPIO specifier for the INT pin. For inline partition table parsing (optional):
@@ -35,6 +36,7 @@ Example for an OMAP3430 board: #size-cells = <1>; onenand@0 { + compatible = "ti,omap2-onenand"; reg = <0 0 0>; /* CS0, offset 0 */ gpmc,device-width = <2>;
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 2/14 ARM: dts: OMAP2+: Add compatible property to onenand node
In reply to Ladislav MichlOMAP onenand nodes are missing compatible property, add it.
---
Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 + arch/arm/boot/dts/omap3-n900.dts | 1 + arch/arm/boot/dts/omap3-n950-n9.dtsi | 1 + arch/arm/boot/dts/omap3430-sdp.dts | 1 + 4 files changed, 4 insertions(+)
arch/arm/boot/dts/omap2420-n8x0-common.dtsi +1 -0
@@ -52,6 +52,7 @@ onenand@0,0 { #address-cells = <1>; #size-cells = <1>; + compatible = "ti,omap2-onenand"; reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */ gpmc,sync-read;
arch/arm/boot/dts/omap3-n900.dts +1 -0
@@ -840,6 +840,7 @@ onenand@0,0 { #address-cells = <1>; #size-cells = <1>; + compatible = "ti,omap2-onenand"; reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */ gpmc,sync-read;
arch/arm/boot/dts/omap3-n950-n9.dtsi +1 -0
@@ -367,6 +367,7 @@ onenand@0,0 { #address-cells = <1>; #size-cells = <1>; + compatible = "ti,omap2-onenand"; reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */ gpmc,sync-read;
arch/arm/boot/dts/omap3430-sdp.dts +1 -0
@@ -154,6 +154,7 @@ linux,mtd-name= "samsung,kfm2g16q2m-deb8"; #address-cells = <1>; #size-cells = <1>; + compatible = "ti,omap2-onenand"; reg = <2 0 0x20000>; /* CS2, offset 0, IO size 4 */ gpmc,device-width = <2>;
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 3/14 ARM: dts: omap3-igep: Update onenand node timings
In reply to Ladislav MichlUpdate node timings to be compatible with actual chip used - gpmc_cs_show_timings utilized to dump values.
---
Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/omap3-igep.dtsi | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
arch/arm/boot/dts/omap3-igep.dtsi +15 -15
@@ -147,32 +147,32 @@ gpmc,sync-read; gpmc,sync-write; gpmc,burst-length = <16>; - gpmc,burst-read; gpmc,burst-wrap; + gpmc,burst-read; gpmc,burst-write; gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */ gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */ gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <87>; - gpmc,cs-wr-off-ns = <87>; + gpmc,cs-rd-off-ns = <96>; + gpmc,cs-wr-off-ns = <96>; gpmc,adv-on-ns = <0>; - gpmc,adv-rd-off-ns = <10>; - gpmc,adv-wr-off-ns = <10>; - gpmc,oe-on-ns = <15>; - gpmc,oe-off-ns = <87>; + gpmc,adv-rd-off-ns = <12>; + gpmc,adv-wr-off-ns = <12>; + gpmc,oe-on-ns = <18>; + gpmc,oe-off-ns = <96>; gpmc,we-on-ns = <0>; - gpmc,we-off-ns = <87>; - gpmc,rd-cycle-ns = <112>; - gpmc,wr-cycle-ns = <112>; - gpmc,access-ns = <81>; - gpmc,page-burst-access-ns = <15>; + gpmc,we-off-ns = <96>; + gpmc,rd-cycle-ns = <114>; + gpmc,wr-cycle-ns = <114>; + gpmc,access-ns = <90>; + gpmc,page-burst-access-ns = <12>; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,wait-monitoring-ns = <0>; - gpmc,clk-activation-ns = <5>; + gpmc,clk-activation-ns = <6>; gpmc,wr-data-mux-bus-ns = <30>; - gpmc,wr-access-ns = <81>; - gpmc,sync-clk-ps = <15000>; + gpmc,wr-access-ns = <90>; + gpmc,sync-clk-ps = <12000>; #address-cells = <1>; #size-cells = <1>;
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 4/14 mtd: onenand: omap2: Remove regulator support
In reply to Ladislav MichlAs no platform data user sets regulator_can_sleep, regulator code is no-op and can be deleted.
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- new patch
drivers/mtd/onenand/omap2.c | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-)
drivers/mtd/onenand/omap2.c +1 -41
@@ -34,7 +34,6 @@#include <linux/dma-mapping.h> #include <linux/io.h> #include <linux/slab.h> -#include <linux/regulator/consumer.h> #include <linux/gpio.h> #include <asm/mach/flash.h>
@@ -59,7 +58,6 @@ struct omap2_onenand {int dma_channel;int freq;int (*setup)(void __iomem *base,int *freq_ptr); -struct regulator *regulator;u8 flags; };
@@ -583,30 +581,6 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)memset ((__force void *)c->onenand.base,0 ,ONENAND_BUFRAM_SIZE ); } -static int omap2_onenand_enable (struct mtd_info *mtd) -{ -int ret; - struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); - - ret =regulator_enable (c->regulator); -if (ret !=0 ) -dev_err (&c->pdev->dev,"can't enable regulator\n" ); - -return ret; -} - -static int omap2_onenand_disable (struct mtd_info *mtd) -{ -int ret; - struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); - - ret =regulator_disable (c->regulator); -if (ret !=0 ) -dev_err (&c->pdev->dev,"can't disable regulator\n" ); - -return ret; -} -static int omap2_onenand_probe (struct platform_device *pdev) {struct omap_onenand_platform_data *pdata;
@@ -726,22 +700,11 @@ static int omap2_onenand_probe(struct platform_device *pdev) } } -if (pdata->regulator_can_sleep) { - c->regulator =regulator_get (&pdev->dev,"vonenand" ); -if (IS_ERR (c->regulator)) { -dev_err (&pdev->dev,"Failed to get regulator\n" ); - r =PTR_ERR (c->regulator); - goto err_release_dma; - } - c->onenand.enable = omap2_onenand_enable; - c->onenand.disable = omap2_onenand_disable; - } -if (pdata->skip_initial_unlocking) this->options |=ONENAND_SKIP_INITIAL_UNLOCKING ;if ((r =onenand_scan (&c->mtd,1 )) <0 ) - goto err_release_regulator; + goto err_release_dma; r =mtd_device_register (&c->mtd, pdata ? pdata->parts :NULL , pdata ? pdata->nr_parts :0 );
@@ -754,8 +717,6 @@ static int omap2_onenand_probe(struct platform_device *pdev) err_release_onenand:onenand_release (&c->mtd); -err_release_regulator: -regulator_put (c->regulator); err_release_dma:if (c->dma_channel !=-1 )omap_free_dma (c->dma_channel);
@@ -779,7 +740,6 @@ static int omap2_onenand_remove(struct platform_device *pdev)struct omap2_onenand *c =dev_get_drvdata (&pdev->dev);onenand_release (&c->mtd); -regulator_put (c->regulator);if (c->dma_channel !=-1 )omap_free_dma (c->dma_channel);omap2_onenand_shutdown (pdev);
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 5/14 mtd: onenand: omap2: Remove skip initial unlocking support
In reply to Ladislav MichlNo platform data user sets skip_initial_unlocking, so remove test for this field.
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- new patch
drivers/mtd/onenand/omap2.c | 3 --- 1 file changed, 3 deletions(-)
drivers/mtd/onenand/omap2.c +0 -3
@@ -700,9 +700,6 @@ static int omap2_onenand_probe(struct platform_device *pdev) } } -if (pdata->skip_initial_unlocking) - this->options |=ONENAND_SKIP_INITIAL_UNLOCKING ; -if ((r =onenand_scan (&c->mtd,1 )) <0 ) goto err_release_dma;
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 6/14 mtd: onenand: omap2: Remove partitioning support from platform data
In reply to Ladislav MichlNo platform data user setups partitioning information, so remove.
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- new patch
drivers/mtd/onenand/omap2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/mtd/onenand/omap2.c +1 -2
@@ -703,8 +703,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)if ((r =onenand_scan (&c->mtd,1 )) <0 ) goto err_release_dma; - r =mtd_device_register (&c->mtd, pdata ? pdata->parts :NULL , - pdata ? pdata->nr_parts :0 ); + r =mtd_device_register (&c->mtd,NULL ,0 );if (r) goto err_release_onenand;
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 7/14 mtd: onenand: omap2: Account waiting time as waiting on IO
In reply to Ladislav MichlUse wait_for_completion_io_timeout, which has an impact on how the task is accounted in scheduling stats.
---
Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch
Changes in v3: None
Changes in v2: None
drivers/mtd/onenand/omap2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/mtd/onenand/omap2.c +2 -3
@@ -170,9 +170,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)if (result ==0 ) {int retry_cnt =0 ; retry: - result =wait_for_completion_timeout (&c->irq_done, -msecs_to_jiffies (20 )); -if (result ==0 ) { +if (!wait_for_completion_io_timeout (&c->irq_done, +msecs_to_jiffies (20 ))) {/* Timeout after 20ms */ ctrl =read_reg (c,ONENAND_REG_CTRL_STATUS ); if (ctrl & ONENAND_CTRL_ONGO &&
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 8/14 mtd: onenand: omap2: Simplify the DMA setup for various paths
In reply to Ladislav MichlFrom: Peter Ujfalusi <[email protected]>
We have 4 functions containing almost identical DMA setup code. Create one function which can set up the DMA for both read and write and use this in place for the setup code in the driver.
The new function will use wait_for_completion_io_timeout() and it will figure out the best data_type to be used for the transfer instead of hardwiring 32 or 16 bit data.
---
Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch
Changes in v3: None
Changes in v2: None
drivers/mtd/onenand/omap2.c | 109 ++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 64 deletions(-)
drivers/mtd/onenand/omap2.c +45 -64
@@ -288,6 +288,33 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)return 0 ; } +static inline int omap2_onenand_dma_transfer (struct omap2_onenand *c, +dma_addr_t src,dma_addr_t dst, +size_t count) +{ +int data_type =__ffs ((src | dst | count)); + +if (data_type >OMAP_DMA_DATA_TYPE_S32 ) + data_type =OMAP_DMA_DATA_TYPE_S32 ; + +omap_set_dma_transfer_params (c->dma_channel, data_type, + count /BIT (data_type),1 ,0 ,0 ,0 ); +omap_set_dma_src_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , + src,0 ,0 ); +omap_set_dma_dest_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , + dst,0 ,0 ); + +reinit_completion (&c->dma_done); +omap_start_dma (c->dma_channel); +if (!wait_for_completion_io_timeout (&c->dma_done, +msecs_to_jiffies (20 ))) { +omap_stop_dma (c->dma_channel); +return -ETIMEDOUT ; + } + +return 0 ; +} +#if defined(CONFIG_ARCH_OMAP3 ) || defined(MULTI_OMAP2 ) static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
@@ -298,10 +325,9 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,struct onenand_chip *this = mtd->priv;dma_addr_t dma_src, dma_dst;int bram_offset; -unsigned long timeout;void *buf = (void *)buffer;size_t xtra; -volatile unsigned *done; +int ret; bram_offset =omap2_onenand_bufferram_offset (mtd, area) + area + offset;if (bram_offset &3 || (size_t )buf &3 || count <384 )
@@ -338,25 +364,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area, goto out_copy; } -omap_set_dma_transfer_params (c->dma_channel,OMAP_DMA_DATA_TYPE_S32 , - count >>2 ,1 ,0 ,0 ,0 ); -omap_set_dma_src_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - dma_src,0 ,0 ); -omap_set_dma_dest_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - dma_dst,0 ,0 ); - -reinit_completion (&c->dma_done); -omap_start_dma (c->dma_channel); - - timeout = jiffies +msecs_to_jiffies (20 ); - done = &c->dma_done.done; -while (time_before (jiffies, timeout)) -if (*done) -break ; - + ret =omap2_onenand_dma_transfer (c, dma_src, dma_dst, count);dma_unmap_single (&c->pdev->dev, dma_dst, count,DMA_FROM_DEVICE ); -if (!*done) { +if (ret) {dev_err (&c->pdev->dev,"timeout waiting for DMA\n" ); goto out_copy; }
@@ -376,9 +387,8 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,struct onenand_chip *this = mtd->priv;dma_addr_t dma_src, dma_dst;int bram_offset; -unsigned long timeout;void *buf = (void *)buffer; -volatile unsigned *done; +int ret; bram_offset =omap2_onenand_bufferram_offset (mtd, area) + area + offset;if (bram_offset &3 || (size_t )buf &3 || count <384 )
@@ -409,25 +419,10 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,return -1 ; } -omap_set_dma_transfer_params (c->dma_channel,OMAP_DMA_DATA_TYPE_S32 , - count >>2 ,1 ,0 ,0 ,0 ); -omap_set_dma_src_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - dma_src,0 ,0 ); -omap_set_dma_dest_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - dma_dst,0 ,0 ); - -reinit_completion (&c->dma_done); -omap_start_dma (c->dma_channel); - - timeout = jiffies +msecs_to_jiffies (20 ); - done = &c->dma_done.done; -while (time_before (jiffies, timeout)) -if (*done) -break ; - + ret =omap2_onenand_dma_transfer (c, dma_src, dma_dst, count);dma_unmap_single (&c->pdev->dev, dma_src, count,DMA_TO_DEVICE ); -if (!*done) { +if (ret) {dev_err (&c->pdev->dev,"timeout waiting for DMA\n" ); goto out_copy; }
@@ -466,7 +461,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area, struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);struct onenand_chip *this = mtd->priv;dma_addr_t dma_src, dma_dst; -int bram_offset; +int bram_offset, ret; bram_offset =omap2_onenand_bufferram_offset (mtd, area) + area + offset;/* DMA is not used. Revisit PM requirements before enabling it. */
@@ -488,20 +483,13 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,return -1 ; } -omap_set_dma_transfer_params (c->dma_channel,OMAP_DMA_DATA_TYPE_S32 , - count /4 ,1 ,0 ,0 ,0 ); -omap_set_dma_src_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - dma_src,0 ,0 ); -omap_set_dma_dest_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - dma_dst,0 ,0 ); - -reinit_completion (&c->dma_done); -omap_start_dma (c->dma_channel); -wait_for_completion (&c->dma_done); - + ret =omap2_onenand_dma_transfer (c, dma_src, dma_dst, count);dma_unmap_single (&c->pdev->dev, dma_dst, count,DMA_FROM_DEVICE ); -return 0 ; +if (ret) +dev_err (&c->pdev->dev,"timeout waiting for DMA\n" ); + +return ret; } static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
@@ -511,7 +499,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area, struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);struct onenand_chip *this = mtd->priv;dma_addr_t dma_src, dma_dst; -int bram_offset; +int bram_offset, ret; bram_offset =omap2_onenand_bufferram_offset (mtd, area) + area + offset;/* DMA is not used. Revisit PM requirements before enabling it. */
@@ -533,20 +521,13 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area, return -1; } -omap_set_dma_transfer_params (c->dma_channel,OMAP_DMA_DATA_TYPE_S16 , - count /2 ,1 ,0 ,0 ,0 ); -omap_set_dma_src_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - dma_src,0 ,0 ); -omap_set_dma_dest_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - dma_dst,0 ,0 ); - -reinit_completion (&c->dma_done); -omap_start_dma (c->dma_channel); -wait_for_completion (&c->dma_done); - + ret =omap2_onenand_dma_transfer (c, dma_src, dma_dst, count);dma_unmap_single (&c->pdev->dev, dma_src, count,DMA_TO_DEVICE ); -return 0 ; +if (ret) +dev_err (&c->pdev->dev,"timeout waiting for DMA\n" ); + +return ret; }#else
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 9/14 mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
In reply to Ladislav MichlSince the very first commit (36cd4fb5d277: "[MTD] [OneNAND] Add OMAP2 / OMAP3 OneNAND driver") DMA is disabled for OMAP2. Later fixes thus went only into OMAP3 specific DMA functions which turned out not to be so OMAP3 specific, so merge those two implementations.
---
Changes in v6: None
Changes in v5: None
Changes in v4:
- rebase on top of Peter's patch
Changes in v3:
- new patch
Changes in v2: None
drivers/mtd/onenand/omap2.c | 129 ++------------------------------------------ 1 file changed, 4 insertions(+), 125 deletions(-)
drivers/mtd/onenand/omap2.c +4 -125
@@ -315,9 +315,7 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,return 0 ; } -#if defined(CONFIG_ARCH_OMAP3 ) || defined(MULTI_OMAP2 ) - -static int omap3_onenand_read_bufferram (struct mtd_info *mtd,int area, +static int omap2_onenand_read_bufferram (struct mtd_info *mtd,int area,unsigned char *buffer,int offset,size_t count) {
@@ -379,7 +377,7 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,return 0 ; } -static int omap3_onenand_write_bufferram (struct mtd_info *mtd,int area, +static int omap2_onenand_write_bufferram (struct mtd_info *mtd,int area,const unsigned char *buffer,int offset,size_t count) {
@@ -434,120 +432,6 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,return 0 ; } -#else - -static int omap3_onenand_read_bufferram (struct mtd_info *mtd,int area, -unsigned char *buffer,int offset, -size_t count) -{ -return -ENOSYS ; -} - -static int omap3_onenand_write_bufferram (struct mtd_info *mtd,int area, -const unsigned char *buffer, -int offset,size_t count) -{ -return -ENOSYS ; -} - -#endif - -#if defined(CONFIG_ARCH_OMAP2 ) || defined(MULTI_OMAP2 ) - -static int omap2_onenand_read_bufferram (struct mtd_info *mtd,int area, -unsigned char *buffer,int offset, -size_t count) -{ - struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); -struct onenand_chip *this = mtd->priv; -dma_addr_t dma_src, dma_dst; -int bram_offset, ret; - - bram_offset =omap2_onenand_bufferram_offset (mtd, area) + area + offset; -/* DMA is not used. Revisit PM requirements before enabling it. */ -if (1 || (c->dma_channel <0 ) || - ((void *) buffer >= (void *) high_memory) || (bram_offset &3 ) || - (((unsigned int ) buffer) &3 ) || (count <1024 ) || (count &3 )) { -memcpy (buffer, (__force void *)(this->base + bram_offset), - count); -return 0 ; - } - - dma_src = c->phys_base + bram_offset; - dma_dst =dma_map_single (&c->pdev->dev, buffer, count, -DMA_FROM_DEVICE ); -if (dma_mapping_error (&c->pdev->dev, dma_dst)) { -dev_err (&c->pdev->dev, -"Couldn't DMA map a %d byte buffer\n" , - count); -return -1 ; - } - - ret =omap2_onenand_dma_transfer (c, dma_src, dma_dst, count); -dma_unmap_single (&c->pdev->dev, dma_dst, count,DMA_FROM_DEVICE ); - -if (ret) -dev_err (&c->pdev->dev,"timeout waiting for DMA\n" ); - -return ret; -} - -static int omap2_onenand_write_bufferram (struct mtd_info *mtd,int area, -const unsigned char *buffer, -int offset,size_t count) -{ - struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); -struct onenand_chip *this = mtd->priv; -dma_addr_t dma_src, dma_dst; -int bram_offset, ret; - - bram_offset =omap2_onenand_bufferram_offset (mtd, area) + area + offset; -/* DMA is not used. Revisit PM requirements before enabling it. */ -if (1 || (c->dma_channel <0 ) || - ((void *) buffer >= (void *) high_memory) || (bram_offset &3 ) || - (((unsigned int ) buffer) &3 ) || (count <1024 ) || (count &3 )) { -memcpy ((__force void *)(this->base + bram_offset), buffer, - count); -return 0 ; - } - - dma_src =dma_map_single (&c->pdev->dev, (void *) buffer, count, -DMA_TO_DEVICE ); - dma_dst = c->phys_base + bram_offset; -if (dma_mapping_error (&c->pdev->dev, dma_src)) { -dev_err (&c->pdev->dev, -"Couldn't DMA map a %d byte buffer\n" , - count); -return -1 ; - } - - ret =omap2_onenand_dma_transfer (c, dma_src, dma_dst, count); -dma_unmap_single (&c->pdev->dev, dma_src, count,DMA_TO_DEVICE ); - -if (ret) -dev_err (&c->pdev->dev,"timeout waiting for DMA\n" ); - -return ret; -} - -#else - -static int omap2_onenand_read_bufferram (struct mtd_info *mtd,int area, -unsigned char *buffer,int offset, -size_t count) -{ -return -ENOSYS ; -} - -static int omap2_onenand_write_bufferram (struct mtd_info *mtd,int area, -const unsigned char *buffer, -int offset,size_t count) -{ -return -ENOSYS ; -} - -#endif -static struct platform_driver omap2_onenand_driver;static void omap2_onenand_shutdown (struct platform_device *pdev)
@@ -671,13 +555,8 @@ static int omap2_onenand_probe(struct platform_device *pdev) this = &c->onenand;if (c->dma_channel >=0 ) { this->wait = omap2_onenand_wait; -if (c->flags &ONENAND_IN_OMAP34XX ) { - this->read_bufferram = omap3_onenand_read_bufferram; - this->write_bufferram = omap3_onenand_write_bufferram; - }else { - this->read_bufferram = omap2_onenand_read_bufferram; - this->write_bufferram = omap2_onenand_write_bufferram; - } + this->read_bufferram = omap2_onenand_read_bufferram; + this->write_bufferram = omap2_onenand_write_bufferram; }if ((r =onenand_scan (&c->mtd,1 )) <0 )
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 10/14 mtd: onenand: omap2: Convert to use dmaengine for memcpy
In reply to Ladislav MichlFrom: Peter Ujfalusi <[email protected]>
Do not use the legacy and deprecated omap-dma interface for setting up the memcpy.
---
Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch
Changes in v3: None
Changes in v2: None
drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 42 deletions(-)
drivers/mtd/onenand/omap2.c +38 -42
@@ -32,6 +32,7 @@#include <linux/interrupt.h> #include <linux/delay.h> #include <linux/dma-mapping.h> +#include <linux/dmaengine.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/gpio.h>
@@ -39,8 +40,6 @@#include <asm/mach/flash.h> #include <linux/platform_data/mtd-onenand-omap2.h> -#include <linux/omap-dma.h> -#define DRIVER_NAME "omap2-onenand"#define ONENAND_BUFRAM_SIZE (1024 * 5)
@@ -55,17 +54,15 @@ struct omap2_onenand {struct onenand_chip onenand;struct completion irq_done;struct completion dma_done; -int dma_channel; +struct dma_chan *dma_chan;int freq;int (*setup)(void __iomem *base,int *freq_ptr);u8 flags; }; -static void omap2_onenand_dma_cb (int lch,u16 ch_status,void *data) +static void omap2_onenand_dma_complete_func (void *completion) { -struct omap2_onenand *c = data; - -complete (&c->dma_done); +complete (completion); }static irqreturn_t omap2_onenand_interrupt (int irq,void *dev_id)
@@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c, dma_addr_t src, dma_addr_t dst, size_t count) { - int data_type = __ffs((src | dst | count)); + struct dma_async_tx_descriptor *tx; +dma_cookie_t cookie; -if (data_type >OMAP_DMA_DATA_TYPE_S32 ) - data_type =OMAP_DMA_DATA_TYPE_S32 ; - -omap_set_dma_transfer_params (c->dma_channel, data_type, - count /BIT (data_type),1 ,0 ,0 ,0 ); -omap_set_dma_src_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - src,0 ,0 ); -omap_set_dma_dest_params (c->dma_channel,0 ,OMAP_DMA_AMODE_POST_INC , - dst,0 ,0 ); + tx =dmaengine_prep_dma_memcpy (c->dma_chan, dst, src, count,0 ); +if (!tx) { +dev_err (&c->pdev->dev,"Failed to prepare DMA memcpy\n" ); +return -EIO ; + }reinit_completion (&c->dma_done); -omap_start_dma (c->dma_channel); + + tx->callback = omap2_onenand_dma_complete_func; + tx->callback_param = &c->dma_done; + + cookie = tx->tx_submit (tx); +if (dma_submit_error (cookie)) { +dev_err (&c->pdev->dev,"Failed to do DMA tx_submit\n" ); +return -EIO ; + } + +dma_async_issue_pending (c->dma_chan); +if (!wait_for_completion_io_timeout (&c->dma_done,msecs_to_jiffies (20 ))) { -omap_stop_dma (c->dma_channel); +dmaengine_terminate_sync (c->dma_chan);return -ETIMEDOUT ; }
@@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev) c->flags = pdata->flags; c->gpmc_cs = pdata->cs; c->gpio_irq = pdata->gpio_irq; - c->dma_channel = pdata->dma_channel; -if (c->dma_channel <0 ) { +if (pdata->dma_channel <0 ) {/* if -1, don't use DMA */ c->gpio_irq =0 ; }
@@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev) goto err_release_gpio; } -if (c->dma_channel >=0 ) { - r =omap_request_dma (0 , pdev->dev.driver->name, - omap2_onenand_dma_cb, (void *) c, - &c->dma_channel); -if (r ==0 ) { -omap_set_dma_write_mode (c->dma_channel, -OMAP_DMA_WRITE_NON_POSTED ); -omap_set_dma_src_data_pack (c->dma_channel,1 ); -omap_set_dma_src_burst_mode (c->dma_channel, -OMAP_DMA_DATA_BURST_8 ); -omap_set_dma_dest_data_pack (c->dma_channel,1 ); -omap_set_dma_dest_burst_mode (c->dma_channel, -OMAP_DMA_DATA_BURST_8 ); - }else { +if (pdata->dma_channel >=0 ) { +dma_cap_mask_t mask; + +dma_cap_zero (mask); +dma_cap_set (DMA_MEMCPY , mask); + + c->dma_chan =dma_request_channel (mask,NULL ,NULL ); +if (!c->dma_chan)dev_info (&pdev->dev,"failed to allocate DMA for OneNAND, " "using PIO instead\n" ); - c->dma_channel =-1 ; - } } dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
@@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)mtd_set_of_node (&c->mtd, pdata->of_node); this = &c->onenand; -if (c->dma_channel >=0 ) { +if (c->dma_chan) { this->wait = omap2_onenand_wait; this->read_bufferram = omap2_onenand_read_bufferram; this->write_bufferram = omap2_onenand_write_bufferram;
@@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev) err_release_onenand:onenand_release (&c->mtd); err_release_dma: -if (c->dma_channel !=-1 ) -omap_free_dma (c->dma_channel); +if (c->dma_chan) +dma_release_channel (c->dma_chan);if (c->gpio_irq)free_irq (gpio_to_irq (c->gpio_irq), c); err_release_gpio:
@@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)struct omap2_onenand *c =dev_get_drvdata (&pdev->dev);onenand_release (&c->mtd); -if (c->dma_channel !=-1 ) -omap_free_dma (c->dma_channel); +if (c->dma_chan) +dma_release_channel (c->dma_chan);omap2_onenand_shutdown (pdev);if (c->gpio_irq) {free_irq (gpio_to_irq (c->gpio_irq), c);
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 11/14 mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
In reply to Ladislav MichlSecond commit in driver history (782b7a367d81: "[MTD] [OneNAND] OMAP3:
add delay for GPIO") added quirk for waiting until GPIO line settle. As DMA was disabled for OMAP2 boards, chances are this problem was not OMAP3 specific and as it is just one register read, previous test for SoC type is approximately as expensive as read itself. Make delay unconditional, which allows removing SoC specific code alltogether.
---
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- new patch
Changes in v2: None
drivers/mtd/onenand/omap2.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/mtd/onenand/omap2.c +2 -5
@@ -57,7 +57,6 @@ struct omap2_onenand {struct dma_chan *dma_chan;int freq;int (*setup)(void __iomem *base,int *freq_ptr); -u8 flags; };static void omap2_onenand_dma_complete_func (void *completion)
@@ -148,9 +147,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)if (!(syscfg &ONENAND_SYS_CFG1_IOBE )) { syscfg |=ONENAND_SYS_CFG1_IOBE ;write_reg (c, syscfg,ONENAND_REG_SYS_CFG1 ); -if (c->flags &ONENAND_IN_OMAP34XX ) -/* Add a delay to let GPIO settle */ - syscfg =read_reg (c,ONENAND_REG_SYS_CFG1 ); +/* Add a delay to let GPIO settle */ + syscfg =read_reg (c,ONENAND_REG_SYS_CFG1 ); }reinit_completion (&c->irq_done);
@@ -470,7 +468,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)init_completion (&c->irq_done);init_completion (&c->dma_done); - c->flags = pdata->flags; c->gpmc_cs = pdata->cs; c->gpio_irq = pdata->gpio_irq;if (pdata->dma_channel <0 ) {
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 12/14 mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
In reply to Ladislav MichlINT pin (gpio_irq) is not really needed for DMA but only for notification when a command that needs wait has completed. DMA memcpy can be still used even without gpio_irq available, so enable it unconditionally.
---
Changes in v6: None
Changes in v5:
- rename patch and fix commit message
Changes in v4:
- new patch
Changes in v3: None
Changes in v2: None
drivers/mtd/onenand/omap2.c | 52 ++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 31 deletions(-)
drivers/mtd/onenand/omap2.c +21 -31
@@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state) }reinit_completion (&c->irq_done); -if (c->gpio_irq) { - result =gpio_get_value (c->gpio_irq); -if (result ==-1 ) { - ctrl =read_reg (c,ONENAND_REG_CTRL_STATUS ); - intr =read_reg (c,ONENAND_REG_INTERRUPT ); -wait_err ("gpio error" , state, ctrl, intr); -return -EIO ; - } - }else - result =0 ; - if (result == 0) { + result =gpio_get_value (c->gpio_irq); +if (result <0 ) { + ctrl =read_reg (c,ONENAND_REG_CTRL_STATUS ); + intr =read_reg (c,ONENAND_REG_INTERRUPT ); +wait_err ("gpio error" , state, ctrl, intr); +return -EIO ; + } else if (result == 0) { int retry_cnt = 0; retry: if (!wait_for_completion_io_timeout(&c->irq_done,
@@ -450,6 +446,7 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)static int omap2_onenand_probe (struct platform_device *pdev) { +dma_cap_mask_t mask;struct omap_onenand_platform_data *pdata;struct omap2_onenand *c;struct onenand_chip *this;
@@ -513,31 +510,25 @@ static int omap2_onenand_probe(struct platform_device *pdev)dev_err (&pdev->dev,"Failed to request GPIO%d for " "OneNAND\n" , c->gpio_irq); goto err_iounmap; - } -gpio_direction_input (c->gpio_irq); + } +gpio_direction_input (c->gpio_irq); -if ((r =request_irq (gpio_to_irq (c->gpio_irq), - omap2_onenand_interrupt,IRQF_TRIGGER_RISING , - pdev->dev.driver->name, c)) <0 ) - goto err_release_gpio; - } +if ((r =request_irq (gpio_to_irq (c->gpio_irq), + omap2_onenand_interrupt,IRQF_TRIGGER_RISING , + pdev->dev.driver->name, c)) <0 ) + goto err_release_gpio; -if (pdata->dma_channel >=0 ) { -dma_cap_mask_t mask; + this->wait = omap2_onenand_wait; + } -dma_cap_zero (mask); -dma_cap_set (DMA_MEMCPY , mask); +dma_cap_zero (mask); +dma_cap_set (DMA_MEMCPY , mask); - c->dma_chan =dma_request_channel (mask,NULL ,NULL ); -if (!c->dma_chan) -dev_info (&pdev->dev, -"failed to allocate DMA for OneNAND, " -"using PIO instead\n" ); - } + c->dma_chan =dma_request_channel (mask,NULL ,NULL );dev_info (&pdev->dev,"initializing on CS%d, phys base 0x%08lx, virtual " -"base %p, freq %d MHz\n" , c->gpmc_cs, c->phys_base, - c->onenand.base, c->freq); +"base %p, freq %d MHz, %s mode\n" , c->gpmc_cs, c->phys_base, + c->onenand.base, c->freq, c->dma_chan ?"DMA" :"PIO" ); c->pdev = pdev; c->mtd.priv = &c->onenand;
@@ -547,7 +538,6 @@ static int omap2_onenand_probe(struct platform_device *pdev) this = &c->onenand;if (c->dma_chan) { - this->wait = omap2_onenand_wait; this->read_bufferram = omap2_onenand_read_bufferram; this->write_bufferram = omap2_onenand_write_bufferram; }
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
Re: [PATCH v6 12/14] mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
Quoted 8 lines · Ladislav Michl
INT pin (
gpio_irq) is not really needed for DMA but only for notification when a command that needs wait has completed. DMA memcpy can be still used even withoutgpio_irqavailable, so enable it unconditionally.Signed-off-by Ladislav Michl <[email protected]>Reviewed-by Peter Ujfalusi <[email protected]>Tested-by Tony Lindgren <[email protected]>Tested-by Aaro Koskinen <[email protected]>
Signature · 8 lines
cheers, -roger Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
Roger Quadros
Acked-byRe: [PATCH v6 12/14] mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
Quoted 5 lines · Roger Quadros
Quoted 4 lines · Ladislav Michl
INT pin (
gpio_irq) is not really needed for DMA but only for notification when a command that needs wait has completed. DMA memcpy can be still used even withoutgpio_irqavailable, so enable it unconditionally.
Quoted 7 lines
Quoted 4 lines
Signed-off-by Ladislav Michl <[email protected]>Reviewed-by Peter Ujfalusi <[email protected]>Tested-by Tony Lindgren <[email protected]>Tested-by Aaro Koskinen <[email protected]>Acked-by Tony Lindgren <[email protected]>
oops. sorry.
Signature · 8 lines
cheers, -roger Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 13/14 mtd: onenand: omap2: Configure driver from DT
In reply to Ladislav MichlMove away from platform data configuration and use pure DT approach.
Use generic probe function to deal with OneNAND node and remove now useless gpmc_probe_onenand_child function. Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
---
Changes in v6:
- squashed with previous patch
Changes in v5:
- rename ready_gpiod to int_gpiod
- use int-gpios as property name
- use devm_ioremap_resource
- "onenand" is now requested irq name
- add Kconfig dependencies
- make gpmc_omap_onenand_set_timings decsription more descriptive
Changes in v4: None
Changes in v3:
- remove 'ti,omap3-onenand' compatible as it is not needed anymore
Changes in v2:
- move cleanups into separate patches
- simplify dma setup
- fix checkpatch error
- print info about otimized timings in sync mode only
- add gpmc_omap_onenand_set_timings description
drivers/memory/omap-gpmc.c | 158 ++++++++++++++++++++-------- drivers/mtd/onenand/Kconfig | 4 +- drivers/mtd/onenand/omap2.c | 250 +++++++++++++++++++++++++++----------------- include/linux/omap-gpmc.h | 28 +++++ 4 files changed, 301 insertions(+), 139 deletions(-)
drivers/memory/omap-gpmc.c +117 -41
@@ -32,7 +32,6 @@#include <linux/pm_runtime.h> #include <linux/platform_data/mtd-nand-omap2.h> -#include <linux/platform_data/mtd-onenand-omap2.h> #include <asm/mach-types.h>
@@ -1138,6 +1137,112 @@ struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs) }EXPORT_SYMBOL_GPL (gpmc_omap_get_nand_ops); +static void gpmc_omap_onenand_calc_sync_timings (struct gpmc_timings *t, +struct gpmc_settings *s, +int freq,int latency) +{ +struct gpmc_device_timings dev_t; +const int t_cer =15 ; +const int t_avdp =12 ; +const int t_cez =20 ;/* max of t_cez, t_oez */ +const int t_wpl =40 ; +const int t_wph =30 ; +int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; + +switch (freq) { +case 104 : + min_gpmc_clk_period =9600 ;/* 104 MHz */ + t_ces =3 ; + t_avds =4 ; + t_avdh =2 ; + t_ach =3 ; + t_aavdh =6 ; + t_rdyo =6 ; +break ; +case 83 : + min_gpmc_clk_period =12000 ;/* 83 MHz */ + t_ces =5 ; + t_avds =4 ; + t_avdh =2 ; + t_ach =6 ; + t_aavdh =6 ; + t_rdyo =9 ; +break ; +case 66 : + min_gpmc_clk_period =15000 ;/* 66 MHz */ + t_ces =6 ; + t_avds =5 ; + t_avdh =2 ; + t_ach =6 ; + t_aavdh =6 ; + t_rdyo =11 ; +break ; +default : + min_gpmc_clk_period =18500 ;/* 54 MHz */ + t_ces =7 ; + t_avds =7 ; + t_avdh =7 ; + t_ach =9 ; + t_aavdh =7 ; + t_rdyo =15 ; +break ; + } + +/* Set synchronous read timings */ +memset (&dev_t,0 ,sizeof (dev_t)); + +if (!s->sync_write) { + dev_t.t_avdp_w =max (t_avdp, t_cer) *1000 ; + dev_t.t_wpl = t_wpl *1000 ; + dev_t.t_wph = t_wph *1000 ; + dev_t.t_aavdh = t_aavdh *1000 ; + } + dev_t.ce_xdelay = true; + dev_t.avd_xdelay = true; + dev_t.oe_xdelay = true; + dev_t.we_xdelay = true; + dev_t.clk = min_gpmc_clk_period; + dev_t.t_bacc = dev_t.clk; + dev_t.t_ces = t_ces *1000 ; + dev_t.t_avds = t_avds *1000 ; + dev_t.t_avdh = t_avdh *1000 ; + dev_t.t_ach = t_ach *1000 ; + dev_t.cyc_iaa = (latency +1 ); + dev_t.t_cez_r = t_cez *1000 ; + dev_t.t_cez_w = dev_t.t_cez_r; + dev_t.cyc_aavdh_oe =1 ; + dev_t.t_rdyo = t_rdyo *1000 + min_gpmc_clk_period; + +gpmc_calc_timings (t, s, &dev_t); +} + +int gpmc_omap_onenand_set_timings (struct device *dev,int cs,int freq, +int latency, +struct gpmc_onenand_info *info) +{ +int ret; +struct gpmc_timings gpmc_t; +struct gpmc_settings gpmc_s; + +gpmc_read_settings_dt (dev->of_node, &gpmc_s); + + info->sync_read = gpmc_s.sync_read; + info->sync_write = gpmc_s.sync_write; + info->burst_len = gpmc_s.burst_len; + +if (!gpmc_s.sync_read && !gpmc_s.sync_write) +return 0 ; + +gpmc_omap_onenand_calc_sync_timings (&gpmc_t, &gpmc_s, freq, latency); + + ret =gpmc_cs_program_settings (cs, &gpmc_s); +if (ret <0 ) +return ret; + +return gpmc_cs_set_timings (cs, &gpmc_t, &gpmc_s); +} +EXPORT_SYMBOL_GPL (gpmc_omap_onenand_set_timings); +int gpmc_get_client_irq (unsigned irq_config) {if (!gpmc_irq_domain) {
@@ -1916,41 +2021,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,of_property_read_bool (np,"gpmc,time-para-granularity" ); } -#if IS_ENABLED (CONFIG_MTD_ONENAND ) -static int gpmc_probe_onenand_child (struct platform_device *pdev, -struct device_node *child) -{ -u32 val; -struct omap_onenand_platform_data *gpmc_onenand_data; - -if (of_property_read_u32 (child,"reg" , &val) <0 ) { -dev_err (&pdev->dev,"%pOF has no 'reg' property\n" , - child); -return -ENODEV ; - } - - gpmc_onenand_data =devm_kzalloc (&pdev->dev,sizeof (*gpmc_onenand_data), -GFP_KERNEL ); -if (!gpmc_onenand_data) -return -ENOMEM ; - - gpmc_onenand_data->cs = val; - gpmc_onenand_data->of_node = child; - gpmc_onenand_data->dma_channel =-1 ; - -if (!of_property_read_u32 (child,"dma-channel" , &val)) - gpmc_onenand_data->dma_channel = val; - -return gpmc_onenand_init (gpmc_onenand_data); -} -#else -static int gpmc_probe_onenand_child (struct platform_device *pdev, -struct device_node *child) -{ -return 0 ; -} -#endif -/** * gpmc_probe_generic_child - configures the gpmc for a child device * @pdev: pointer to gpmc platform device
@@ -2053,6 +2123,16 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, } } +if (of_node_cmp (child->name,"onenand" ) ==0 ) { +/* Warn about older DT blobs with no compatible property */ +if (!of_property_read_bool (child,"compatible" )) { +dev_warn (&pdev->dev, +"Incompatible OneNAND node: missing compatible" ); + ret = -EINVAL ; + goto err; + } + } +if (of_device_is_compatible (child,"ti,omap2-nand" )) {/* NAND specific setup */ val =8 ;
@@ -2189,11 +2269,7 @@ static void gpmc_probe_dt_children(struct platform_device *pdev)if (!child->name)continue ; -if (of_node_cmp (child->name,"onenand" ) ==0 ) - ret =gpmc_probe_onenand_child (pdev, child); -else - ret =gpmc_probe_generic_child (pdev, child); - + ret =gpmc_probe_generic_child (pdev, child);if (ret) {dev_err (&pdev->dev,"failed to probe DT child '%s': %d\n" , child->name, ret);
drivers/mtd/onenand/Kconfig +3 -1
@@ -25,9 +25,11 @@ config MTD_ONENAND_GENERIC config MTD_ONENAND_OMAP2 tristate "OneNAND on OMAP2/OMAP3 support" depends on ARCH_OMAP2 || ARCH_OMAP3 + depends on OF || COMPILE_TEST help - Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU + Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC via the GPMC memory controller. + Enable dmaengine and gpiolib for better performance. config MTD_ONENAND_SAMSUNG tristate "OneNAND on Samsung SOC controller support"
drivers/mtd/onenand/omap2.c +153 -97
355 lines not on this page · raw message
include/linux/omap-gpmc.h +28 -0
@@ -25,15 +25,43 @@ struct gpmc_nand_ops {struct gpmc_nand_regs ; +struct gpmc_onenand_info { +bool sync_read; +bool sync_write; +int burst_len; +}; +#if IS_ENABLED (CONFIG_OMAP_GPMC )struct gpmc_nand_ops *gpmc_omap_get_nand_ops (struct gpmc_nand_regs *regs,int cs); +/** +* gpmc_omap_onenand_set_timings - set optimized sync timings. +* @cs: Chip Select Region +* @freq: Chip frequency +* @latency: Burst latency cycle count +* @info: Structure describing parameters used +* +* Sets optimized timings for the @cs region based on @freq and @latency. +* Updates the @info structure based on the GPMC settings. +*/ +int gpmc_omap_onenand_set_timings (struct device *dev,int cs,int freq, +int latency, +struct gpmc_onenand_info *info); +#else static inline struct gpmc_nand_ops *gpmc_omap_get_nand_ops (struct gpmc_nand_regs *regs,int cs) {return NULL ; } + +static inline +int gpmc_omap_onenand_set_timings (struct device *dev,int cs,int freq, +int latency, +struct gpmc_onenand_info *info) +{ +return -EINVAL ; +}#endif /* CONFIG_OMAP_GPMC */ extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
Re: [PATCH v6 13/14] mtd: onenand: omap2: Configure driver from DT
Quoted 10 lines · Ladislav Michl
Move away from platform data configuration and use pure DT approach.
Use generic probe function to deal with OneNAND node and remove now useless
gpmc_probe_onenand_childfunction. Import sync mode timing calculation function frommach-omap2/gpmc-onenand.cSigned-off-by Ladislav Michl <[email protected]>Reviewed-by Peter Ujfalusi <[email protected]>Tested-by Tony Lindgren <[email protected]>Tested-by Aaro Koskinen <[email protected]>
Signature · 8 lines
cheers, -roger Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
Aaro Koskinen
maintainerRe: [PATCH v6 13/14] mtd: onenand: omap2: Configure driver from DT
In reply to Ladislav MichlHi,
Quoted 1 line · Ladislav Michl
Move away from platform data configuration and use pure DT approach.
Unfortunately this patch (now commit a758f50f10cf) has broken onenand probe on N9/N950:
[ 3.129364] OneNAND Manufacturer: Unknown (0xa0)
The init order was changed so that onenand_scan() is called before the timings are configured:
Quoted 26 lines
drivers/mtd/onenand/omap2.c +23
-0if ((r =onenand_scan (&c->mtd,1 )) <0 ) goto err_release_dma; + freq =omap2_onenand_get_freq (c->onenand.version_id); +if (freq >0 ) { +switch (freq) { +case 104 : + latency =7 ; +break ; +case 83 : + latency =6 ; +break ; +case 66 : + latency =5 ; +break ; +case 56 : + latency =4 ; +break ; +default :/* 40 MHz or lower */ + latency =3 ; +break ; + } + + r =gpmc_omap_onenand_set_timings (dev, c->gpmc_cs, + freq, latency, &info); +if (r)
drivers/mtd/onenand/omap2.c static void omap2_onenand_shutdown(struct platform_device *pdev) · line 613
Quoted 10 lines
drivers/mtd/onenand/omap2.c +10
-0+ goto err_release_onenand; + + r =omap2_onenand_set_cfg (c, info.sync_read, info.sync_write, + latency, info.burst_len); +if (r) + goto err_release_onenand; + +if (info.sync_read || info.sync_write) +dev_info (dev,"optimized timings for %d MHz\n" , freq); + }
But looks like on N9/N950 we need to do the configuration for the onenand_scan() to succeed. I guess the order has to be this because we have no other way to know "version_id".
I tested by changing this other way round (and hardcoding the freq manually) and it seems to work.
A.
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Re: [PATCH v6 13/14] mtd: onenand: omap2: Configure driver from DT
Hi Aaro,
Quoted 5 lines · Aaro Koskinen
Hi,
Quoted 1 line · Ladislav Michl
Move away from platform data configuration and use pure DT approach.
Quoted 7 lines
Unfortunately this patch (now commit
a758f50f10cf) has broken onenand probe on N9/N950:[ 3.129364] OneNAND Manufacturer: Unknown (0xa0)The init order was changed so that
onenand_scan()is called before the timings are configured:
That is intentional, as stated in cover letter:
"
Please note that unlike previous driver version, which basically ignored DT specified timings, this one relies on it, so it is important to get it right in your DT (dumping it from previous kernel version).
In case synchronous timings is requested, it is okay to specify timings for the slowest chip ever used for you board as it is evetually optimized after chip probe.
"
Quoted 41 lines
Quoted 26 lines
drivers/mtd/onenand/omap2.c +23
-0if ((r =onenand_scan (&c->mtd,1 )) <0 ) goto err_release_dma; + freq =omap2_onenand_get_freq (c->onenand.version_id); +if (freq >0 ) { +switch (freq) { +case 104 : + latency =7 ; +break ; +case 83 : + latency =6 ; +break ; +case 66 : + latency =5 ; +break ; +case 56 : + latency =4 ; +break ; +default :/* 40 MHz or lower */ + latency =3 ; +break ; + } + + r =gpmc_omap_onenand_set_timings (dev, c->gpmc_cs, + freq, latency, &info); +if (r)drivers/mtd/onenand/omap2.c static void omap2_onenand_shutdown(struct platform_device *pdev) · line 613
Quoted 10 lines
drivers/mtd/onenand/omap2.c +10
-0+ goto err_release_onenand; + + r =omap2_onenand_set_cfg (c, info.sync_read, info.sync_write, + latency, info.burst_len); +if (r) + goto err_release_onenand; + +if (info.sync_read || info.sync_write) +dev_info (dev,"optimized timings for %d MHz\n" , freq); + }But looks like on N9/N950 we need to do the configuration for the
onenand_scan()to succeed. I guess the order has to be this because we have no other way to know "version_id".
Quoted 2 lines
I tested by changing this other way round (and hardcoding the freq manually) and it seems to work.
Well, DT timings for onenand node seems to be copied over without actually verifying correctness. I do not know which chip comes with N950, so please verify timings in you DT according chip used. Idea is to use timings for slowest chip used and driver will ask for faster one if possible.
Best regards,
ladis
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Aaro Koskinen
maintainerRe: [PATCH v6 13/14] mtd: onenand: omap2: Configure driver from DT
Hi,
Quoted 4 lines · Ladislav Michl
Well, DT timings for onenand node seems to be copied over without actually verifying correctness. I do not know which chip comes with N950, so please verify timings in you DT according chip used. Idea is to use timings for slowest chip used and driver will ask for faster one if possible.
Hmm, right. I thought we had some dumped values in the DT, but apparently wrong ones. What is the method for dumping the "right" values? If I just enable GPMC debug with old kernel, it's dumping the DT entries twice, but neither set works with the new kernel.
Then I tried the "before" values from the new kernel, and they seem to work (patch below)...
A.
arch/arm/boot/dts/omap3-n950-n9.dtsi +13 -13
@@ -379,25 +379,25 @@ gpmc,device-width = <2>; gpmc,mux-add-data = <2>; gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <87>; - gpmc,cs-wr-off-ns = <87>; + gpmc,cs-rd-off-ns = <122>; + gpmc,cs-wr-off-ns = <122>; gpmc,adv-on-ns = <0>; - gpmc,adv-rd-off-ns = <10>; - gpmc,adv-wr-off-ns = <10>; - gpmc,oe-on-ns = <15>; - gpmc,oe-off-ns = <87>; + gpmc,adv-rd-off-ns = <15>; + gpmc,adv-wr-off-ns = <15>; + gpmc,oe-on-ns = <20>; + gpmc,oe-off-ns = <122>; gpmc,we-on-ns = <0>; - gpmc,we-off-ns = <87>; - gpmc,rd-cycle-ns = <112>; - gpmc,wr-cycle-ns = <112>; - gpmc,access-ns = <81>; + gpmc,we-off-ns = <122>; + gpmc,rd-cycle-ns = <148>; + gpmc,wr-cycle-ns = <148>; + gpmc,access-ns = <117>; gpmc,page-burst-access-ns = <15>; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,wait-monitoring-ns = <0>; - gpmc,clk-activation-ns = <5>; - gpmc,wr-data-mux-bus-ns = <30>; - gpmc,wr-access-ns = <81>; + gpmc,clk-activation-ns = <10>; + gpmc,wr-data-mux-bus-ns = <40>; + gpmc,wr-access-ns = <117>; gpmc,sync-clk-ps = <15000>; /*
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Tony Lindgren
maintainerRe: [PATCH v6 13/14] mtd: onenand: omap2: Configure driver from DT
Quoted 8 lines · Aaro Koskinen
Hi,
Quoted 4 lines · Ladislav Michl
Well, DT timings for onenand node seems to be copied over without actually verifying correctness. I do not know which chip comes with N950, so please verify timings in you DT according chip used. Idea is to use timings for slowest chip used and driver will ask for faster one if possible.
Quoted 7 lines
Hmm, right. I thought we had some dumped values in the DT, but apparently wrong ones. What is the method for dumping the "right" values? If I just enable GPMC debug with old kernel, it's dumping the DT entries twice, but neither set works with the new kernel.
Then I tried the "before" values from the new kernel, and they seem to work (patch below)...
You can enable CONFIG_OMAP_GPMC_DEBUG=y and the gpmc driver should print out the bootloader timings for you on boot to make sure they're what you posted. Then if the values are different between devices, then it makes sense to add them to the device specific dts files.
Regards,
Tony
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
PATCH v6 14/14 ARM: OMAP2+: Remove gpmc-onenand
In reply to Ladislav MichlAs OneNAND driver is now using devicetree gpmc-onenand and its platform data is unused and can be removed.
---
Changes in v6: None
Changes in v5: None
Changes in v4:
- new patch
Changes in v3: None
Changes in v2: None
arch/arm/mach-omap2/Makefile | 3 - arch/arm/mach-omap2/gpmc-onenand.c | 409 ------------------------ include/linux/platform_data/mtd-onenand-omap2.h | 34 -- 3 files changed, 446 deletions(-) delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
arch/arm/mach-omap2/Makefile +0 -3
@@ -232,6 +232,3 @@ obj-y += $(omap-hsmmc-m) $(omap-hsmmc-y) obj-y += omap_phy_internal.o obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o - -onenand-$(CONFIG_MTD_ONENAND_OMAP2) := gpmc-onenand.o -obj-y += $(onenand-m) $(onenand-y)
arch/arm/mach-omap2/gpmc-onenand.c deleted +0 -409
409 lines not on this page · raw message
include/linux/platform_data/mtd-onenand-omap2.h deleted +0 -34
@@ -1,34 +0,0 @@ -/* -* Copyright (C) 2006 Nokia Corporation -* Author: Juha Yrjola -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -*/ - -#ifndef __MTD_ONENAND_OMAP2_H -#define __MTD_ONENAND_OMAP2_H - -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> - -#define ONENAND_SYNC_READ (1 << 0) -#define ONENAND_SYNC_READWRITE (1 << 1) -#define ONENAND_IN_OMAP34XX (1 << 2) - -struct omap_onenand_platform_data { -int cs; -int gpio_irq; -struct mtd_partition *parts; -int nr_parts; -int (*onenand_setup)(void __iomem *,int *freq_ptr); -int dma_channel; -u8 flags; -u8 regulator_can_sleep; -u8 skip_initial_unlocking; - -/* for passing the partitions */ -struct device_node *of_node; -}; -#endif
Signature · 6 lines
2.15.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
Quoted 11 lines · On Fri, 12 Jan 2018 14:11:05 +0100 Ladislav Michl <[email protected]> wrote:
this patch serie updates OMAP2+ OneNAND driver to the present times, making it fully DT configurable, using libgpio and dmaengine apis.
Please note that unlike previous driver version, which basically ignored DT specified timings, this one relies on it, so it is important to get it right in your DT (dumping it from previous kernel version).
In case synchronous timings is requested, it is okay to specify timings for the slowest chip ever used for you board as it is evetually optimized after chip probe.
Quoted 7 lines
Original driver used DMA only if user specified INT gpio in platform data, now DMA is used unconditionally and PIO mode is used as fallback.
In case anyone wants to give it a try, few DT related changes are needed:
- onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is done in patch 2)
- to use INT pin, int-gpios needs to be specified.
Roger, Tony, are you happy with this version? If this is the case, I'll queue all patches to my nand/next branch (after merging Roger's immutable branch in).
Quoted 50 lines
Most notable changes from v3:
- added dmaengine patches by Peter Ujfalusi
- added dt bindings documentation
- added cleanup patches
- DMA enabled by defaultMost notable changes from v4:
- collected tags
- used INT pin name properly
- hopefully all comments taken into accountMost notable changes from v5:
- as this serie is expected to be merged via single tree patches 13 and 14 were squashed together not to break bisecting.
- patch 16 was dropped.This patchset depends on an immutable commit:
The following changes since commit
4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)
are available in the git repository at:
https://github.com/rogerq/linux.git for-v4.16/gpmc-omap-immutable
for you to fetch changes up to
c18a7ac3398d0cef29749f9568666db8321aa4c9:memory: omap-gpmc: Make 'bank-width' property optional (2017-12-01 15:37:49 +0200)
Ladislav Michl (12):
dt-bindings: mtd: gpmc-onenand: Update properties description
ARM: dts: OMAP2+: Add compatible property to onenand node
ARM: dts: omap3-igep: Update onenand node timings
mtd: onenand: omap2: Remove regulator support
mtd: onenand: omap2: Remove skip initial unlocking support
mtd: onenand: omap2: Remove partitioning support from platform data
mtd: onenand: omap2: Account waiting time as waiting on IO
mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
mtd: onenand: omap2: Configure driver from DT
ARM: OMAP2+: Remove gpmc-onenandPeter Ujfalusi (2):
mtd: onenand: omap2: Simplify the DMA setup for various paths
mtd: onenand: omap2: Convert to use dmaengine for memcpy
Quoted 17 lines
.../devicetree/bindings/mtd/gpmc-onenand.txt | 6 +- arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 + arch/arm/boot/dts/omap3-igep.dtsi | 30 +- arch/arm/boot/dts/omap3-n900.dts | 1 + arch/arm/boot/dts/omap3-n950-n9.dtsi | 1 + arch/arm/boot/dts/omap3430-sdp.dts | 1 + arch/arm/mach-omap2/Makefile | 3 - arch/arm/mach-omap2/gpmc-onenand.c | 409 --------------- drivers/memory/omap-gpmc.c | 158 ++++-- drivers/mtd/onenand/Kconfig | 4 +- drivers/mtd/onenand/omap2.c | 576 ++++++++------------- include/linux/omap-gpmc.h | 28 + include/linux/platform_data/mtd-onenand-omap2.h | 34 -- 13 files changed, 386 insertions(+), 866 deletions(-) delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Tony Lindgren
maintainerQuoted 17 lines · Boris Brezillon
Quoted 14 lines · On Fri, 12 Jan 2018 14:11:05 +0100 Ladislav Michl <[email protected]> wrote:
this patch serie updates OMAP2+ OneNAND driver to the present times, making it fully DT configurable, using libgpio and dmaengine apis.
Please note that unlike previous driver version, which basically ignored DT specified timings, this one relies on it, so it is important to get it right in your DT (dumping it from previous kernel version).
In case synchronous timings is requested, it is okay to specify timings for the slowest chip ever used for you board as it is evetually optimized after chip probe.
Original driver used DMA only if user specified INT gpio in platform data, now DMA is used unconditionally and PIO mode is used as fallback.
Quoted 8 lines
Quoted 4 lines
In case anyone wants to give it a try, few DT related changes are needed:
- onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is done in patch 2)
- to use INT pin, int-gpios needs to be specified.Roger, Tony, are you happy with this version? If this is the case, I'll queue all patches to my nand/next branch (after merging Roger's immutable branch in).
Yes thanks Aaro for testing, sounds good to me.
Regards,
Tony
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
Quoted 17 lines · Boris Brezillon
Quoted 14 lines · On Fri, 12 Jan 2018 14:11:05 +0100 Ladislav Michl <[email protected]> wrote:
this patch serie updates OMAP2+ OneNAND driver to the present times, making it fully DT configurable, using libgpio and dmaengine apis.
Please note that unlike previous driver version, which basically ignored DT specified timings, this one relies on it, so it is important to get it right in your DT (dumping it from previous kernel version).
In case synchronous timings is requested, it is okay to specify timings for the slowest chip ever used for you board as it is evetually optimized after chip probe.
Original driver used DMA only if user specified INT gpio in platform data, now DMA is used unconditionally and PIO mode is used as fallback.
Quoted 8 lines
Quoted 4 lines
In case anyone wants to give it a try, few DT related changes are needed:
- onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is done in patch 2)
- to use INT pin, int-gpios needs to be specified.Roger, Tony, are you happy with this version? If this is the case, I'll queue all patches to my nand/next branch (after merging Roger's immutable branch in).
Yes Boris. Series looks good to me. Thanks Ladislav. Great work :)
Quoted 69 lines
Quoted 68 lines
Most notable changes from v3:
- added dmaengine patches by Peter Ujfalusi
- added dt bindings documentation
- added cleanup patches
- DMA enabled by defaultMost notable changes from v4:
- collected tags
- used INT pin name properly
- hopefully all comments taken into accountMost notable changes from v5:
- as this serie is expected to be merged via single tree patches 13 and 14 were squashed together not to break bisecting.
- patch 16 was dropped.This patchset depends on an immutable commit:
The following changes since commit
4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)
are available in the git repository at:
https://github.com/rogerq/linux.git for-v4.16/gpmc-omap-immutable
for you to fetch changes up to
c18a7ac3398d0cef29749f9568666db8321aa4c9:memory: omap-gpmc: Make 'bank-width' property optional (2017-12-01 15:37:49 +0200)
Ladislav Michl (12):
dt-bindings: mtd: gpmc-onenand: Update properties description
ARM: dts: OMAP2+: Add compatible property to onenand node
ARM: dts: omap3-igep: Update onenand node timings
mtd: onenand: omap2: Remove regulator support
mtd: onenand: omap2: Remove skip initial unlocking support
mtd: onenand: omap2: Remove partitioning support from platform data
mtd: onenand: omap2: Account waiting time as waiting on IO
mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
mtd: onenand: omap2: Configure driver from DT
ARM: OMAP2+: Remove gpmc-onenandPeter Ujfalusi (2):
mtd: onenand: omap2: Simplify the DMA setup for various paths
mtd: onenand: omap2: Convert to use dmaengine for memcpy.../devicetree/bindings/mtd/gpmc-onenand.txt | 6 +- arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 + arch/arm/boot/dts/omap3-igep.dtsi | 30 +- arch/arm/boot/dts/omap3-n900.dts | 1 + arch/arm/boot/dts/omap3-n950-n9.dtsi | 1 + arch/arm/boot/dts/omap3430-sdp.dts | 1 + arch/arm/mach-omap2/Makefile | 3 - arch/arm/mach-omap2/gpmc-onenand.c | 409 --------------- drivers/memory/omap-gpmc.c | 158 ++++-- drivers/mtd/onenand/Kconfig | 4 +- drivers/mtd/onenand/omap2.c | 576 ++++++++------------- include/linux/omap-gpmc.h | 28 + include/linux/platform_data/mtd-onenand-omap2.h | 34 -- 13 files changed, 386 insertions(+), 866 deletions(-) delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
Signature · 8 lines
cheers, -roger Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
Quoted 64 lines · On Fri, 12 Jan 2018 14:11:05 +0100 Ladislav Michl <[email protected]> wrote:
this patch serie updates OMAP2+ OneNAND driver to the present times, making it fully DT configurable, using libgpio and dmaengine apis.
Please note that unlike previous driver version, which basically ignored DT specified timings, this one relies on it, so it is important to get it right in your DT (dumping it from previous kernel version).
In case synchronous timings is requested, it is okay to specify timings for the slowest chip ever used for you board as it is evetually optimized after chip probe.
Original driver used DMA only if user specified INT gpio in platform data, now DMA is used unconditionally and PIO mode is used as fallback.
In case anyone wants to give it a try, few DT related changes are needed:
- onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is done in patch 2)
- to use INT pin, int-gpios needs to be specified.Most notable changes from v3:
- added dmaengine patches by Peter Ujfalusi
- added dt bindings documentation
- added cleanup patches
- DMA enabled by defaultMost notable changes from v4:
- collected tags
- used INT pin name properly
- hopefully all comments taken into accountMost notable changes from v5:
- as this serie is expected to be merged via single tree patches 13 and 14 were squashed together not to break bisecting.
- patch 16 was dropped.This patchset depends on an immutable commit:
The following changes since commit
4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323:Linux 4.15-rc1 (2017-11-26 16:01:47 -0800)
are available in the git repository at:
https://github.com/rogerq/linux.git for-v4.16/gpmc-omap-immutable
for you to fetch changes up to
c18a7ac3398d0cef29749f9568666db8321aa4c9:memory: omap-gpmc: Make 'bank-width' property optional (2017-12-01 15:37:49 +0200)
Ladislav Michl (12):
dt-bindings: mtd: gpmc-onenand: Update properties description
ARM: dts: OMAP2+: Add compatible property to onenand node
ARM: dts: omap3-igep: Update onenand node timings
mtd: onenand: omap2: Remove regulator support
mtd: onenand: omap2: Remove skip initial unlocking support
mtd: onenand: omap2: Remove partitioning support from platform data
mtd: onenand: omap2: Account waiting time as waiting on IO
mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
mtd: onenand: omap2: Decouple DMA enabling from INT pin availability
mtd: onenand: omap2: Configure driver from DT
ARM: OMAP2+: Remove gpmc-onenand
Quoted 3 lines
Peter Ujfalusi (2):
mtd: onenand: omap2: Simplify the DMA setup for various paths
mtd: onenand: omap2: Convert to use dmaengine for memcpy
Applied the whole series.
Thanks,
Boris
Quoted 18 lines
.../devicetree/bindings/mtd/gpmc-onenand.txt | 6 +- arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 + arch/arm/boot/dts/omap3-igep.dtsi | 30 +- arch/arm/boot/dts/omap3-n900.dts | 1 + arch/arm/boot/dts/omap3-n950-n9.dtsi | 1 + arch/arm/boot/dts/omap3430-sdp.dts | 1 + arch/arm/mach-omap2/Makefile | 3 - arch/arm/mach-omap2/gpmc-onenand.c | 409 --------------- drivers/memory/omap-gpmc.c | 158 ++++-- drivers/mtd/onenand/Kconfig | 4 +- drivers/mtd/onenand/omap2.c | 576 ++++++++------------- include/linux/omap-gpmc.h | 28 + include/linux/platform_data/mtd-onenand-omap2.h | 34 -- 13 files changed, 386 insertions(+), 866 deletions(-) delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/