[GIT PULL] ARM: OMAP2+: GPMC fixes for v3.10
The following changes since commit aecb65a34a780cd07fbaa652cc5d640f13f3ed5f: Merge branch 'omap-gpmc-for-v3.10-take2' of git://github.com/jonhunter/linux into omap-for-v3.10/gpmc (2013-04-04 11:22:33 -0700) are available in the git repository at: git://github.com/jonhunter/linux.git omap-gpmc-fixes-for-v3.10 for you to fetch changes up to b327b3627bb428eb7d98f25224532425a673d89e: ARM: OMAP2+: only WARN if a GPMC child probe function fail (2013-04-30 08:43:05 -0500) GPMC fixes for v3.10. Main fix is to only search the GPMC node for GPMC child devices and not the entire device-tree (which was breaking ethernet support on some boards where the GPMC does not interface with the ethernet chip). This branch is based upon Tony's omap-for-v3.10/gpmc branch. Javier Martinez Canillas (3): Documentation: dt: update TI GPMC ethernet binding properties ARM: OMAP2+: only search for GPMC DT child nodes on probe ARM: OMAP2+: only WARN if a GPMC child probe function fail Jon Hunter (1): Documentation: dt: update properties in TI GPMC NAND example .../devicetree/bindings/mtd/gpmc-nand.txt | 28 +- Documentation/devicetree/bindings/net/gpmc-eth.txt | 56 ++-- arch/arm/mach-omap2/gpmc.c | 38 + 3 files changed, 54 insertions(+), 68 deletions(-) ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH] ARM: dts: OMAP2+: Simplify NAND support
Commit 8c8a777 (ARM: OMAP2+: Add function to read GPMC settings from device-tree) added a device-tree property gpmc,device-nand to indicate is the GPMC child device is NAND. This commit should have updated the GPMC NAND documentation (Documentation/devicetree/bindings/mtd/gpmc-nand.txt) to list the property gpmc,device-nand as a required property and also updated the example. However, this property is redundant and not needed because the GPMC child device node for NAND is called nand. Therefore, remove this property. Signed-off-by: Jon Hunter jon-hun...@ti.com --- Documentation/devicetree/bindings/bus/ti-gpmc.txt |1 - arch/arm/boot/dts/omap3430-sdp.dts|1 - arch/arm/mach-omap2/gpmc-nand.c |4 ++-- arch/arm/mach-omap2/gpmc.c|1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 4b87ea1..704be93 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -95,7 +95,6 @@ GPMC chip-select settings properties for child nodes. All are optional. - gpmc,burst-wrap Enables wrap bursting - gpmc,burst-read Enables read page/burst mode - gpmc,burst-write Enables write page/burst mode -- gpmc,device-nand Device is NAND - gpmc,device-widthTotal width of device(s) connected to a GPMC chip-select in bytes. The GPMC supports 8-bit and 16-bit devices and so this property must be diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts index 144ae43..6076d01 100644 --- a/arch/arm/boot/dts/omap3430-sdp.dts +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -105,7 +105,6 @@ nand-bus-width = 8; ti,nand-ecc-opt = sw; - gpmc,device-nand; gpmc,cs-on-ns = 0; gpmc,cs-rd-off-ns = 36; gpmc,cs-wr-off-ns = 36; diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index c8044b0..662c7fd 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -102,8 +102,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, if (gpmc_nand_data-of_node) { gpmc_read_settings_dt(gpmc_nand_data-of_node, s); } else { - s.device_nand = true; - /* Enable RD PIN Monitoring Reg */ if (gpmc_nand_data-dev_ready) { s.wait_on_read = true; @@ -111,6 +109,8 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, } } + s.device_nand = true; + if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16) s.device_width = GPMC_DEVWIDTH_16BIT; else diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 6c4da12..6f1beb4 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1245,7 +1245,6 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) p-sync_read = of_property_read_bool(np, gpmc,sync-read); p-sync_write = of_property_read_bool(np, gpmc,sync-write); - p-device_nand = of_property_read_bool(np, gpmc,device-nand); of_property_read_u32(np, gpmc,device-width, p-device_width); of_property_read_u32(np, gpmc,mux-add-data, p-mux_add_data); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/26/2013 02:27 AM, Linus Walleij wrote: On Wed, Apr 17, 2013 at 5:41 PM, Stephen Warren swar...@wwwdotorg.org wrote: On 04/16/2013 05:14 PM, Jon Hunter wrote: c) I have the feeling that hooking the of_xlate function for this is a bit of an abuse of the function. I was wondering about that. So I was grep'ing through the various xlate implementations and found this [1]. Also you may recall that in the of_dma_simple_xlate() we call the dma_request_channel() to allocate the channel, which is very similar. However, I don't wish to get a reputation as abusing APIs so would be good to know if this really is abuse or not ;-) Cheers Jon [1] http://permalink.gmane.org/gmane.linux.ports.arm.kernel/195124 Interesting. This is really something that the core DT and GPIO and IRQ maintainers should weigh in on. Hence, changing them from Cc: to To: in this message and/or adding them. So I guess it is OK for a driver or DT node to use a GPIO as IRQ *only*, and then have the GPIO requested implicitly through the xlate function in the irqdomain. It's the use cases where one and the same driver tries to use the same GPIO line *also* by requesting it using gpio_request() that madness starts. In such cases the driver deserves to have an error thrown back at it, as it definately knows the GPIO pin and can be refactored to use gpio_to_irq() to translate it into an IRQ rather than having it implicitly done in the xlate function. You will just have to give the xlate function information about which GPIOs are used as IRQs only, and only request the GPIO on these. That should not be necessary. The xlate is only called in the case where the gpio controller is declared as the interrupt controller in the device tree source ... eth@0 { compatible = ks8851; ... interrupt-parent = gpio2; interrupts = 2 8; /* gpio line 34, low triggered */ ... }; So in the case where you have a driver call gpio_request() and then request_irq(), in the device tree source, the gpio controller will not be declared as an interrupt controller. It will just list the gpios ... sdhci@c8000200 { ... cd-gpios = gpio 69 0; /* gpio PI5 */ wp-gpios = gpio 57 0; /* gpio PH1 */ ... }; And I recently suggested a mechanism to do that, and that is what I called GPIO input-hogs, which means that you mark (e.g. from the device tree) at probe() of the gpiochip which GPIOs will only be used as inputs, so as to generate IRQs. This is perfectly OS-neutral information about the how the hardware is set up in the system. If you only allow these hogges inputs to be translated and requested in the xlate function, everything goes smooth. It all comes back to this: keep all applicable knowledge in the system, so it can make proper decisions, don't try to create mechanisms that will half-guess things. Agreed. However the xlate looks like a good place to request the gpio without needing to add these input-hogs or any other platform code. So if this is not considered abuse of the xlate, then it seems like an ideal solution. I have been also implementing a generic xlate so that we don't need to have a xlate for each platform as well. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/26/2013 02:31 AM, Linus Walleij wrote: On Wed, Apr 17, 2013 at 2:41 AM, Javier Martinez Canillas martinez.jav...@gmail.com wrote: So: +static int omap_gpio_irq_domain_xlate(struct irq_domain *d, + struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, + unsigned int *out_type) +{ + int ret; + struct gpio_bank *bank = d-host_data; + int gpio = bank-chip.base + intspec[0]; + + if (WARN_ON(intsize 2)) + return -EINVAL; + + ret = gpio_request_one(gpio, GPIOF_IN, ctrlr-full_name); + if (ret) + return ret; So how to figure out if a device is already requesting this GPIO on some orthogonal axis? I really don't think that is necessary. Hopefully, my other email [1] elaborates on why. Let me know if this makes sense. Cheers Jon [1] http://marc.info/?l=linux-arm-kernelm=136701158117966w=1 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: Regarding dtc+cpp support
On 04/18/2013 04:12 AM, Padma Venkat wrote: Hi Stephen, I am trying to add a header file for samsung audio subsystem clk definitions, which can be used in kernel and dt files. I applied following patches posted by you in my working tree. [1/7] kbuild: create an include chroot for DT bindings [2/7] kbuild: fixdep: support concatenated dep files [3/7] kbuild: cmd_dtc_cpp: extract deps from both gcc -E and dtc [4/7] kbuild: always run gcc -E on *.dts, remove cmd_dtc_cpp [5/7] ARM: dt: add header to define GPIO flags [6/7] ARM: dt: add header to define IRQ flags [7/7] ARM: dt: create a DT header for the GIC I created a header file in arch/arm/boot/dts/include/clk/samsung-audss-clk.h and I included this header in driver and dtsi files Please see the code snippet in dtsi below. #include dt-bindings/clk/samsung-audss-clk.h /include/ skeleton.dtsi /include/ exynos5250-pinctrl.dtsi Try making all of the above #include ... #include dt-bindings/clk/samsung-audss-clk.h #include skeleton.dtsi #include exynos5250-pinctrl.dtsi In driver it is compiling successfully but in dtsi files I am getting the follwing compilation error. Error: arch/arm/boot/dts/exynos5250.dtsi:21.1-9 syntax error FATAL ERROR: Unable to parse input tree make[1]: *** [arch/arm/boot/dts/exynos5250-arndale.dtb] Error 1 make[1]: *** Waiting for unfinished jobs DTC arch/arm/boot/dts/exynos5250-snow.dtb Error: arch/arm/boot/dts/exynos5250.dtsi:21.1-9 syntax error FATAL ERROR: Unable to parse input tree make[1]: *** [arch/arm/boot/dts/exynos5250-smdk5250.dtb] Error 1 Error: arch/arm/boot/dts/exynos5250.dtsi:21.1-9 syntax error FATAL ERROR: Unable to parse input tree make[1]: *** [arch/arm/boot/dts/exynos5250-snow.dtb] Error 1 make: *** [dtbs] Error 2 make: *** Waiting for unfinished jobs where #include dt-bindings/clk/samsung-audss-clk.h is the 21st line in the dtsi file. Please let me know if any extra patches are required to solve this compilation error? I was seeing some compile errors when I had a mixture of /include/ and #include. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: Regarding dtc+cpp support
On 04/18/2013 11:21 AM, Padma Venkat wrote: Hi, On Thu, Apr 18, 2013 at 8:19 PM, Jon Hunter jon-hun...@ti.com wrote: On 04/18/2013 04:12 AM, Padma Venkat wrote: Hi Stephen, I am trying to add a header file for samsung audio subsystem clk definitions, which can be used in kernel and dt files. I applied following patches posted by you in my working tree. [1/7] kbuild: create an include chroot for DT bindings [2/7] kbuild: fixdep: support concatenated dep files [3/7] kbuild: cmd_dtc_cpp: extract deps from both gcc -E and dtc [4/7] kbuild: always run gcc -E on *.dts, remove cmd_dtc_cpp [5/7] ARM: dt: add header to define GPIO flags [6/7] ARM: dt: add header to define IRQ flags [7/7] ARM: dt: create a DT header for the GIC I created a header file in arch/arm/boot/dts/include/clk/samsung-audss-clk.h and I included this header in driver and dtsi files Please see the code snippet in dtsi below. #include dt-bindings/clk/samsung-audss-clk.h /include/ skeleton.dtsi /include/ exynos5250-pinctrl.dtsi Try making all of the above #include ... I haven't changed all dts files but I tried below with no success. I should mentioned that you should also make any /include/ in the *.dtsi above #include too. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/17/2013 02:55 AM, Javier Martinez Canillas wrote: ... There are so many patches flying around in this thread that I missed it :-) Sorry about that... No problem. I was trying to see if we could find a common solution that everyone could use as it seems that ideally we should all be requesting the gpio. Cheers Jon [1] http://marc.info/?l=linux-arm-kernelm=136606204823845w=1 btw, I shared the latest patch with only build testing it, but today I gave a try and I found a problem with this approach. The .xlate function is being called twice for each GPIO-IRQ so the first time gpio_request_one() succeeds but the second time it fails returning -EBUSY. I tried it and I did not see that. I don't see the below warning either. This raises a warning on drivers/of/platform.c (WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq)): 0.285308] [ cut here ] [0.285369] WARNING: at drivers/of/platform.c:171 of_device_alloc+0x154/0x168() [0.285430] Modules linked in: [0.285491] [c001a944] (unwind_backtrace+0x0/0xf0) from [c0041edc] (warn_slowpath_common+0x4c/0x68) [0.285552] [c0041edc] (warn_slowpath_common+0x4c/0x68) from [c0041f14] (warn_slowpath_null+0x1c/0x24) [0.285614] [c0041f14] (warn_slowpath_null+0x1c/0x24) from [c041ac3c] (of_device_alloc+0x154/0x168) [0.285675] [c041ac3c] (of_device_alloc+0x154/0x168) from [c041ac84] (of_platform_device_create_pdata+0x34/0x80) [0.285736] [c041ac84] (of_platform_device_create_pdata+0x34/0x80) from [c0027364] (gpmc_probe_generic_child+0x180/0x240) [0.285827] [c0027364] (gpmc_probe_generic_child+0x180/0x240) from [c00278d8] (gpmc_probe+0x4b4/0x614) [0.285888] [c00278d8] (gpmc_probe+0x4b4/0x614) from [c0325514] (platform_drv_probe+0x18/0x1c) [0.285949] [c0325514] (platform_drv_probe+0x18/0x1c) from [c0324354] (driver_probe_device+0x108/0x21c) Any chance you have still have some additional code in your dts to request the gpio? I recall you made some hacks to make this work before. I probably won't have time to dig further on this until later this week but I wanted to share with you in case you know why is being calling twice and if you thought about a solution. Care to post your dts file? It works if I don't check the return gpio_request_one() (or better if we don't return on omap_gpio_irq_domain_xlate) but of course is not the right solution. Yes we need to check the return value. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v3 3/3] ARM: OMAP2+: Add GPMC DT support for Ethernet child nodes
On 04/17/2013 07:05 AM, Javier Martinez Canillas wrote: ... Yes, in fact I just realized that for_each_node_by_name() expand to: #define for_each_node_by_name(dn, name) \ for (dn = of_find_node_by_name(NULL, name); dn; \ dn = of_find_node_by_name(dn, name)) which means that it will search for a node with name on the complete DeviceTree and this is wrong. It should only search on GPMC childs. Good catch. I guess we could have flash ethernet devices connected to other interfaces such as SPI. Could you please test the following patch? If it works for you I'll add a proper description and submit it as a PATCH. Thanks a lot and best regards, Javier From d8dab9ae9a0284f17553875c2fddd806d9f6ab2e Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas javier.marti...@collabora.co.uk Date: Wed, 17 Apr 2013 13:50:30 +0200 Subject: [PATCH] ARM: OMAP2+: only search for GPMC DT child nodes on probe Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk --- arch/arm/mach-omap2/gpmc.c | 51 --- 1 files changed, 24 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ed946df..58e2415 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1520,35 +1520,32 @@ static int gpmc_probe_dt(struct platform_device *pdev) return ret; } - for_each_node_by_name(child, nand) { - ret = gpmc_probe_nand_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } - - for_each_node_by_name(child, onenand) { - ret = gpmc_probe_onenand_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } + for_each_child_of_node(pdev-dev.of_node, child) { + if (child-name) { Minor nit ... how about ... + if (!child-name) continue; + if (of_node_cmp(child-name, nand) == 0) { + ret = gpmc_probe_nand_child(pdev, child); + if (ret 0) { + of_node_put(child); + return ret; + } + } - for_each_node_by_name(child, nor) { - ret = gpmc_probe_generic_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } + if (of_node_cmp(child-name, onenand) == 0) { + ret = gpmc_probe_onenand_child(pdev, child); + if (ret 0) { + of_node_put(child); + return ret; + } + } - for_each_node_by_name(child, ethernet) { - ret = gpmc_probe_generic_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; + if (of_node_cmp(child-name, ethernet) == 0 || + of_node_cmp(child-name, nor) == 0) { + ret = gpmc_probe_generic_child(pdev, child); + if (ret 0) { + of_node_put(child); + return ret; + } + } } } I am also wondering if the probe should fail if one of its children fails. The panic that Lars reported occurred because the nand successfully probed and so the nand device was registered, but because the ethernet device probe failed, the gpmc probe fails, and then when the nand device is probed by the mtd driver the kernel panics. I wonder if it would be better to WARN on child devices that fail to probe but not return error from the gpmc probe. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/17/2013 08:42 AM, Javier Martinez Canillas wrote: On Wed, Apr 17, 2013 at 3:25 PM, Jon Hunter jon-hun...@ti.com wrote: On 04/17/2013 02:55 AM, Javier Martinez Canillas wrote: ... There are so many patches flying around in this thread that I missed it :-) Sorry about that... No problem. I was trying to see if we could find a common solution that everyone could use as it seems that ideally we should all be requesting the gpio. Cheers Jon [1] http://marc.info/?l=linux-arm-kernelm=136606204823845w=1 btw, I shared the latest patch with only build testing it, but today I gave a try and I found a problem with this approach. The .xlate function is being called twice for each GPIO-IRQ so the first time gpio_request_one() succeeds but the second time it fails returning -EBUSY. I tried it and I did not see that. I don't see the below warning either. weird, I wonder what's different here. I am testing on an omap4-sdp which uses a spi based ethernet device. However, I could try with the omap3430-sdp which uses gpmc. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v3 3/3] ARM: OMAP2+: Add GPMC DT support for Ethernet child nodes
On 04/17/2013 09:07 AM, Javier Martinez Canillas wrote: On 04/17/2013 03:48 PM, Jon Hunter wrote: On 04/17/2013 07:05 AM, Javier Martinez Canillas wrote: ... Yes, in fact I just realized that for_each_node_by_name() expand to: #define for_each_node_by_name(dn, name) \ for (dn = of_find_node_by_name(NULL, name); dn; \ dn = of_find_node_by_name(dn, name)) which means that it will search for a node with name on the complete DeviceTree and this is wrong. It should only search on GPMC childs. Good catch. I guess we could have flash ethernet devices connected to other interfaces such as SPI. Yes, in fact this is the case for omap4-sdp.dts which has an ethernet controller connected through SPI: mcspi1 { eth@0 { compatible = ks8851; spi-max-frequency = 2400; reg = 0; interrupt-parent = gpio2; interrupts = 2; /* gpio line 34 */ vdd-supply = vdd_eth; }; }; it just didn't fail because the device node name is eth and not ethernet. Yes we got lucky here or unlucky as this would have tripped us up earlier ;-) which makes me wonder if is OK to rely on a device node name or we should use compatible properties instead such as ti,gpmc-{eth,nand,nor,onenand} and do something like: for_each_compatible_node(pdev-dev.of_node, NULL, ti,gpmc-eth) and so on. Yes I was wondering about that too. However, it does seem simpler to just search through the child devices and that would be an easier fix. Could you please test the following patch? If it works for you I'll add a proper description and submit it as a PATCH. Thanks a lot and best regards, Javier From d8dab9ae9a0284f17553875c2fddd806d9f6ab2e Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas javier.marti...@collabora.co.uk Date: Wed, 17 Apr 2013 13:50:30 +0200 Subject: [PATCH] ARM: OMAP2+: only search for GPMC DT child nodes on probe Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk --- arch/arm/mach-omap2/gpmc.c | 51 --- 1 files changed, 24 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ed946df..58e2415 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1520,35 +1520,32 @@ static int gpmc_probe_dt(struct platform_device *pdev) return ret; } - for_each_node_by_name(child, nand) { - ret = gpmc_probe_nand_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } - - for_each_node_by_name(child, onenand) { - ret = gpmc_probe_onenand_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } + for_each_child_of_node(pdev-dev.of_node, child) { + if (child-name) { Minor nit ... how about ... +if (!child-name) continue; Yes, much better. I just cooked a quick patch so Lars could test it ;-) + if (of_node_cmp(child-name, nand) == 0) { + ret = gpmc_probe_nand_child(pdev, child); + if (ret 0) { + of_node_put(child); + return ret; + } + } - for_each_node_by_name(child, nor) { - ret = gpmc_probe_generic_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } + if (of_node_cmp(child-name, onenand) == 0) { + ret = gpmc_probe_onenand_child(pdev, child); + if (ret 0) { + of_node_put(child); + return ret; + } + } - for_each_node_by_name(child, ethernet) { - ret = gpmc_probe_generic_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; + if (of_node_cmp(child-name, ethernet) == 0 || + of_node_cmp(child-name, nor) == 0) { + ret = gpmc_probe_generic_child(pdev, child); + if (ret 0) { + of_node_put(child); + return ret; + } + } } } I am also wondering if the probe should fail if one of its children fails. The panic that Lars reported occurred because the nand successfully probed and so the nand device was registered, but because the ethernet device probe failed
Re: [PATCH] ARM: OMAP2+: only search for GPMC DT child nodes on probe
On 04/17/2013 11:37 AM, Javier Martinez Canillas wrote: The GPMC DT probe function use for_each_node_by_name() to search child device nodes of the GPMC controller. But this function does not use the GPMC device node as the root of the search and instead search across the complete Device Tree. This means that any device node on the DT that is using any of the GPMC child nodes names searched for will be returned even if they are not connected to the GPMC, making the gpmc_probe_xxx_child() function to fail. Fix this by using the GPMC device node as the search root so the search will be restricted to its children. Also, if any of the GPMC child nodes fails, this shouldn't make the whole gpmc_probe_dt() function to fail. It is better to just WARN and allow other devices probe function to succeed. Reported-by: Lars Poeschel poesc...@lemonage.de Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk --- arch/arm/mach-omap2/gpmc.c | 41 + 1 files changed, 17 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ed946df..f10d735 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1520,35 +1520,28 @@ static int gpmc_probe_dt(struct platform_device *pdev) return ret; } - for_each_node_by_name(child, nand) { - ret = gpmc_probe_nand_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } + for_each_child_of_node(pdev-dev.of_node, child) { + + if (!child-name) + continue; - for_each_node_by_name(child, onenand) { - ret = gpmc_probe_onenand_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; + if (of_node_cmp(child-name, nand) == 0) { + ret = gpmc_probe_nand_child(pdev, child); + if (WARN_ON(ret 0)) I am wondering if we should use WARN here and say probing gpmc child %s failed\n and print the fullname. Otherwise it may be unclear which device failed. + of_node_put(child); } - } - for_each_node_by_name(child, nor) { - ret = gpmc_probe_generic_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; + if (of_node_cmp(child-name, onenand) == 0) { This could also be an else if to save comparing each child unnecessarily if it previously matched. That way you could just have a single WARN statement at the end of the loop and condense this code. + ret = gpmc_probe_onenand_child(pdev, child); + if (WARN_ON(ret 0)) + of_node_put(child); } - } - for_each_node_by_name(child, ethernet) { - ret = gpmc_probe_generic_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; + if (of_node_cmp(child-name, ethernet) == 0 || + of_node_cmp(child-name, nor) == 0) { + ret = gpmc_probe_generic_child(pdev, child); + if (WARN_ON(ret 0)) + of_node_put(child); } } Otherwise looks good. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v2 1/2] ARM: OMAP2+: only search for GPMC DT child nodes on probe
On 04/17/2013 03:34 PM, Javier Martinez Canillas wrote: The GPMC DT probe function use for_each_node_by_name() to search child device nodes of the GPMC controller. But this function does not use the GPMC device node as the root of the search and instead search across the complete Device Tree. This means that any device node on the DT that is using any of the GPMC child nodes names searched for will be returned even if they are not connected to the GPMC, making the gpmc_probe_xxx_child() function to fail. Fix this by using the GPMC device node as the search root so the search will be restricted to its children. Reported-by: Lars Poeschel poesc...@lemonage.de Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk --- Changes since v1 (suggested by Jon Hunter): - Split the search for GPMC child nodes and only warn if a child probe fails on two different patches - Don't probe all childs unnecesary if a previous matched arch/arm/mach-omap2/gpmc.c | 33 ++--- 1 files changed, 10 insertions(+), 23 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ed946df..6166847 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1520,32 +1520,19 @@ static int gpmc_probe_dt(struct platform_device *pdev) return ret; } - for_each_node_by_name(child, nand) { - ret = gpmc_probe_nand_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } + for_each_child_of_node(pdev-dev.of_node, child) { - for_each_node_by_name(child, onenand) { - ret = gpmc_probe_onenand_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } + if (!child-name) + continue; - for_each_node_by_name(child, nor) { - ret = gpmc_probe_generic_child(pdev, child); - if (ret 0) { - of_node_put(child); - return ret; - } - } + if (of_node_cmp(child-name, nand) == 0) + ret = gpmc_probe_nand_child(pdev, child); + else if (of_node_cmp(child-name, onenand) == 0) + ret = gpmc_probe_onenand_child(pdev, child); + else if (of_node_cmp(child-name, ethernet) == 0 || + of_node_cmp(child-name, nor) == 0) + ret = gpmc_probe_generic_child(pdev, child); - for_each_node_by_name(child, ethernet) { - ret = gpmc_probe_generic_child(pdev, child); if (ret 0) { I think that we need to make sure that ret is initialised to 0 at the beginning of the function. We should not have a case where the child name does not match but who knows. Actually that raises another point, should we have an else clause at the end that WARNs on unknown/unsupported child device? of_node_put(child); return ret; Otherwise looks great. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 1/2] ARM: dts: OMAP5: add PWM capability to timer nodes missing it
On 04/17/2013 06:23 PM, Suman Anna wrote: OMAP5 has 6 timers (GPTimers 5, 6, 8 to 11) that are capable of PWM. The PWM capability property is missing from the node definitions of couple of timers, and this has been fixed. Signed-off-by: Suman Anna s-a...@ti.com --- arch/arm/boot/dts/omap5.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 790bb2a..0d155f5 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -422,6 +422,7 @@ interrupts = 0 41 0x4; ti,hwmods = timer5; ti,timer-dsp; + ti,timer-pwm; }; timer6: timer@4013a000 { @@ -458,6 +459,7 @@ reg = 0x4803e000 0x80; interrupts = 0 45 0x4; ti,hwmods = timer9; + ti,timer-pwm; }; timer10: timer@48086000 { @@ -465,6 +467,7 @@ reg = 0x48086000 0x80; interrupts = 0 46 0x4; ti,hwmods = timer10; + ti,timer-pwm; }; timer11: timer@48088000 { Make sure you copy the linux-arm and device-tree mailing lists. Acked-by: Jon Hunter jon-hun...@ti.com Thanks! Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/16/2013 01:40 PM, Stephen Warren wrote: On 04/15/2013 05:04 PM, Jon Hunter wrote: On 04/15/2013 05:16 PM, Stephen Warren wrote: On 04/15/2013 03:40 PM, Jon Hunter wrote: ... mmc { label = pandaboard::status2; gpios = gpio1 8 0; ... }; But that's a gpio-leds instance, not an MMC controller... I really really hope there's no DT node using gpios to mean interrupts... And it wouldn't make any sense for an on-SoC device anyway. Oops yes, I overlooked that. However, the omap mmc driver (drivers/mmc/host/omap_hsmmc.c) does call gpio_request() and request_threaded_irq() for the mmc card-detect interrupt. I believe tegra is doing the same ... sdhci@7800 { ... cd-gpios = gpio 69 0; /* gpio PI5 */ ... }; Ah true. I guess at least all MMC drivers are likely hooking cd-gpios as an interrupt, /and/ requesting it as a GPIO so that they can read the current state when the GPIO goes off. That tends to imply that no core code can possibly call gpio_request() in response to request_irq(), since doing so likely will conflict with quite a few drivers... Yes that was my concern. Both these devices are using a gpio as an interrupt source, but the mmc driver is requesting the gpio directly. In the first case the xlate function for the gpio irq domain will be called where as it is not used in the 2nd case. Therefore, we could add a custom xlate function. For example ... diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c +int omap_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, ... + gpio_request_one(irq_to_gpio(bank, intspec[0]), GPIOF_IN, ctrlr-name); I guess that could work, but: a) It still means doing the gpio_request() in each driver instead of centrally. Right this is device specific, but it avoids exposing irq_to_gpio for a device. However, we could make this generic if we did expose irq_to_gpio for each device. b) This approach doesn't solve the issue where some client driver has already requested the GPIO. This code would simply prevent that call from succeeding, which would probably make the driver probe() error out, which isn't any different to the equivalent proposed centralized gpio_request() inside some request_irq() failing, and causing the device's probe() to error out. If some driver is calling gpio_request() directly, then they will most likely just call gpio_to_irq() when requesting the interrupt and so the xlate function would not be called in this case (mmc drivers are a good example). So I don't see that as being a problem. In fact that's the benefit of this approach as AFAICT it solves this problem. Oh. That assumption seems very fragile. What about drivers that actually do have platform data (or DT bindings) that provide both the IRQ and GPIO IDs, and hence don't use gpio_to_irq()? That's entirely possible. Right. In the DT case though, if someone does provide the IRQ and GPIO IDs then at least they would use a different xlate function. Another option to consider would be defining the #interrupt-cells = 3 where we would have ... cell-#1 -- IRQ domain ID cell-#2 -- Trigger type cell-#3 -- GPIO ID Then we could have a generic xlate for 3 cells that would also request the GPIO. Again not sure if people are against a gpio being requested in the xlate but just an idea. Or given that irq_of_parse_and_map() calls the xlate, we could have this function call gpio_request() if the interrupt controller is a gpio and there are 3 cells. Given all this, I guess simply having each GPIO+IRQ driver's set_type function simply do whatever is required in HW to set up that GPIO actually does seem like the best idea. Admittedly that isn't centralized, but I'm not sure now that any centralized implementation is possible, without significant rework of a bunch of drivers. This is what the Tegra GPIO driver already does, and I think one of the earlier patches in this thread did exactly that for OMAP IRQs too right? Yes, however, Linus wanted us to make sure the gpio is requested which is why we have not taken that patch. However, if we cannot find a better alternative may be we have to do that for now. BTW, just so you know, I'm on vacation for 2 weeks starting Wed afternoon, so replies will be non-existent or spotty during that time. Thanks! Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/16/2013 02:27 PM, Jon Hunter wrote: ... Right. In the DT case though, if someone does provide the IRQ and GPIO IDs then at least they would use a different xlate function. Another option to consider would be defining the #interrupt-cells = 3 where we would have ... cell-#1 -- IRQ domain ID cell-#2 -- Trigger type cell-#3 -- GPIO ID Then we could have a generic xlate for 3 cells that would also request the GPIO. Again not sure if people are against a gpio being requested in the xlate but just an idea. Or given that irq_of_parse_and_map() calls the xlate, we could have this function call gpio_request() if the interrupt controller is a gpio and there are 3 cells. So basically some like the following (note I have only included the omap portion in here for an example). The other benefit being no need to re-introduce irq_to_gpio. Jon From f01ce047075a922969fcbe904b339fe8d03a997b Mon Sep 17 00:00:00 2001 From: Jon Hunter jon-hun...@ti.com Date: Tue, 16 Apr 2013 09:54:28 -0500 Subject: [PATCH] gpio: add custom xlate for gpio irqs --- drivers/gpio/gpio-omap.c |3 ++- drivers/gpio/gpiolib-of.c | 24 include/linux/of_gpio.h |1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index d337318..b3d7d43 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -24,6 +24,7 @@ #include linux/pm.h #include linux/of.h #include linux/of_device.h +#include linux/of_gpio.h #include linux/irqdomain.h #include linux/gpio.h #include linux/platform_data/gpio-omap.h @@ -1135,7 +1136,7 @@ static int omap_gpio_probe(struct platform_device *pdev) bank-domain = irq_domain_add_linear(node, bank-width, -irq_domain_simple_ops, NULL); +of_gpio_irq_domain_ops, NULL); if (!bank-domain) return -ENODEV; diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 5150df6..fc01ec1 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -15,6 +15,8 @@ #include linux/errno.h #include linux/module.h #include linux/io.h +#include linux/irq.h +#include linux/irqdomain.h #include linux/gpio.h #include linux/of.h #include linux/of_address.h @@ -253,3 +255,25 @@ void of_gpiochip_remove(struct gpio_chip *chip) if (chip-of_node) of_node_put(chip-of_node); } + +int of_gpio_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, +const u32 *intspec, unsigned int intsize, +unsigned long *out_hwirq, unsigned int *out_type) +{ + int ret; + + if (WARN_ON(intsize 3)) + return -EINVAL; + + ret = gpio_request_one(intspec[2], GPIOF_IN, NULL); + if (ret) + return ret; + + *out_hwirq = intspec[0]; + *out_type = (intsize 1) ? intspec[1] : IRQ_TYPE_NONE; + return 0; +} + +const struct irq_domain_ops of_gpio_irq_domain_ops = { + .xlate = of_gpio_irq_domain_xlate, +}; diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index a83dc6f..ad2b962 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -58,6 +58,7 @@ extern void of_gpiochip_remove(struct gpio_chip *gc); extern int of_gpio_simple_xlate(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags); +extern const struct irq_domain_ops of_gpio_irq_domain_ops; #else /* CONFIG_OF_GPIO */ -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/16/2013 05:11 PM, Stephen Warren wrote: On 04/16/2013 01:27 PM, Jon Hunter wrote: On 04/16/2013 01:40 PM, Stephen Warren wrote: On 04/15/2013 05:04 PM, Jon Hunter wrote: ... If some driver is calling gpio_request() directly, then they will most likely just call gpio_to_irq() when requesting the interrupt and so the xlate function would not be called in this case (mmc drivers are a good example). So I don't see that as being a problem. In fact that's the benefit of this approach as AFAICT it solves this problem. Oh. That assumption seems very fragile. What about drivers that actually do have platform data (or DT bindings) that provide both the IRQ and GPIO IDs, and hence don't use gpio_to_irq()? That's entirely possible. Right. In the DT case though, if someone does provide the IRQ and GPIO IDs then at least they would use a different xlate function. Another option to consider would be defining the #interrupt-cells = 3 where we would have ... cell-#1 -- IRQ domain ID cell-#2 -- Trigger type cell-#3 -- GPIO ID Then we could have a generic xlate for 3 cells that would also request the GPIO. Again not sure if people are against a gpio being requested in the xlate but just an idea. Or given that irq_of_parse_and_map() calls the xlate, we could have this function call gpio_request() if the interrupt controller is a gpio and there are 3 cells. I rather dislike this approach since: a) It requires changes to the DT bindings, which are already defined. Admittedly it's backwards-compatible, but still. b) There isn't really any need for the DT to represent this; the GPIO+IRQ driver itself already knows which IRQ ID is which GPIO ID and vice-versa (if the HW has such a concept), so there's no need for the DT to contain this information. This seems like pushing Linux's internal requirements into the design of the DT binding. Yes, so the only alternative is to use irq_to_gpio to avoid this. c) I have the feeling that hooking the of_xlate function for this is a bit of an abuse of the function. I was wondering about that. So I was grep'ing through the various xlate implementations and found this [1]. Also you may recall that in the of_dma_simple_xlate() we call the dma_request_channel() to allocate the channel, which is very similar. However, I don't wish to get a reputation as abusing APIs so would be good to know if this really is abuse or not ;-) Cheers Jon [1] http://permalink.gmane.org/gmane.linux.ports.arm.kernel/195124 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/16/2013 07:41 PM, Javier Martinez Canillas wrote: On Wed, Apr 17, 2013 at 1:14 AM, Jon Hunter jon-hun...@ti.com wrote: On 04/16/2013 05:11 PM, Stephen Warren wrote: On 04/16/2013 01:27 PM, Jon Hunter wrote: On 04/16/2013 01:40 PM, Stephen Warren wrote: On 04/15/2013 05:04 PM, Jon Hunter wrote: ... If some driver is calling gpio_request() directly, then they will most likely just call gpio_to_irq() when requesting the interrupt and so the xlate function would not be called in this case (mmc drivers are a good example). So I don't see that as being a problem. In fact that's the benefit of this approach as AFAICT it solves this problem. Oh. That assumption seems very fragile. What about drivers that actually do have platform data (or DT bindings) that provide both the IRQ and GPIO IDs, and hence don't use gpio_to_irq()? That's entirely possible. Right. In the DT case though, if someone does provide the IRQ and GPIO IDs then at least they would use a different xlate function. Another option to consider would be defining the #interrupt-cells = 3 where we would have ... cell-#1 -- IRQ domain ID cell-#2 -- Trigger type cell-#3 -- GPIO ID Then we could have a generic xlate for 3 cells that would also request the GPIO. Again not sure if people are against a gpio being requested in the xlate but just an idea. Or given that irq_of_parse_and_map() calls the xlate, we could have this function call gpio_request() if the interrupt controller is a gpio and there are 3 cells. I rather dislike this approach since: a) It requires changes to the DT bindings, which are already defined. Admittedly it's backwards-compatible, but still. b) There isn't really any need for the DT to represent this; the GPIO+IRQ driver itself already knows which IRQ ID is which GPIO ID and vice-versa (if the HW has such a concept), so there's no need for the DT to contain this information. This seems like pushing Linux's internal requirements into the design of the DT binding. Yes, so the only alternative is to use irq_to_gpio to avoid this. c) I have the feeling that hooking the of_xlate function for this is a bit of an abuse of the function. I was wondering about that. So I was grep'ing through the various xlate implementations and found this [1]. Also you may recall that in the of_dma_simple_xlate() we call the dma_request_channel() to allocate the channel, which is very similar. However, I don't wish to get a reputation as abusing APIs so would be good to know if this really is abuse or not ;-) Cheers Jon [1] http://permalink.gmane.org/gmane.linux.ports.arm.kernel/195124 I was looking at [1] shared by Jon and come up with the following patch that does something similar for OMAP GPIO. This has the advantage that is local to gpio-omap instead changing gpiolib-of and also doesn't require DT changes But I don't want to get a reputation for abusing APIs neither :-) Best regards, Javier From 23368eb72b125227fcf4b22be19ea70b4ab94556 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas javier.marti...@collabora.co.uk Date: Wed, 17 Apr 2013 02:03:08 +0200 Subject: [PATCH 1/1] gpio/omap: add custom xlate function handler Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk --- drivers/gpio/gpio-omap.c | 29 - 1 files changed, 28 insertions(+), 1 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 8524ce5..77216f9 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1097,6 +1097,33 @@ static void omap_gpio_chip_init(struct gpio_bank *bank) static const struct of_device_id omap_gpio_match[]; static void omap_gpio_init_context(struct gpio_bank *p); +static int omap_gpio_irq_domain_xlate(struct irq_domain *d, + struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, + unsigned int *out_type) +{ + int ret; + struct gpio_bank *bank = d-host_data; + int gpio = bank-chip.base + intspec[0]; + + if (WARN_ON(intsize 2)) + return -EINVAL; + + ret = gpio_request_one(gpio, GPIOF_IN, ctrlr-full_name); + if (ret) + return ret; + + *out_hwirq = intspec[0]; + *out_type = (intsize 1) ? intspec[1] : IRQ_TYPE_NONE; + + return 0; +} + +static struct irq_domain_ops omap_gpio_irq_ops = { + .xlate = omap_gpio_irq_domain_xlate, +}; + static int omap_gpio_probe(struct platform_device *pdev) { struct device *dev = pdev-dev; @@ -1144,7 +1171,7 @@ static int omap_gpio_probe(struct platform_device *pdev) bank-domain = irq_domain_add_linear(node, bank-width, - irq_domain_simple_ops, NULL
Re: [PATCH V4 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree
On 04/15/2013 08:27 AM, Grant Likely wrote: On Tue, 19 Mar 2013 11:35:48 -0500, Jon Hunter jon-hun...@ti.com wrote: Adds a function to read the various GPMC chip-select settings from device-tree and store them in the gpmc_settings structure. Update the GPMC device-tree binding documentation to describe these options. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- Documentation/devicetree/bindings/bus/ti-gpmc.txt | 23 arch/arm/mach-omap2/gpmc.c| 40 + arch/arm/mach-omap2/gpmc.h|2 ++ 3 files changed, 65 insertions(+) diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 5ddb2e9..6fde1cf 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -65,6 +65,29 @@ The following are only applicable to OMAP3+ and AM335x: - gpmc,wr-access - gpmc,wr-data-mux-bus +GPMC chip-select settings properties for child nodes. All are optional. + +- gpmc,burst-length Page/burst length. Must be 4, 8 or 16. +- gpmc,burst-wrap Enables wrap bursting +- gpmc,burst-read Enables read page/burst mode +- gpmc,burst-write Enables write page/burst mode +- gpmc,device-nand Device is NAND +- gpmc,device-width Total width of device(s) connected to a GPMC +chip-select in bytes. The GPMC supports 8-bit +and 16-bit devices and so this property must be +1 or 2. I would suggest specifying the actual number of bits. ie. 8 or 16. There is some precidence for that already in DT bindings. I used bytes and not bits here as it was more convenient for programming a register bit field. However, it would be equally easy to shift the value and program the register if we use bits. So this can be changed. By the way, I have seen some of the flash bindings (eg. mtd-physmap.txt) use bytes and not bits, however, I do see others use bits (nand.txt). However, if the preference is for bits then we can conform to that. Tony has this queued for v3.10 now. However, we can fix this up if you feel strongly about this. +- gpmc,mux-add-data Address and data multiplexing configuration. +Valid values are 1 for address-address-data +multiplexing mode and 2 for address-data +multiplexing mode. +- gpmc,sync-readEnables synchronous read. Defaults to asynchronous +is this is not set. 'if'? +- gpmc,sync-write Enables synchronous writes. Defaults to asynchronous +is this is not set. +- gpmc,wait-pin Wait-pin used by client. Must be less than +gpmc,num-waitpins. +- gpmc,wait-on-read Enables wait monitoring on reads. +- gpmc,wait-on-writeEnables wait monitoring on writes. Otherwise looks okay to me. Thanks Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/15/2013 11:53 AM, Stephen Warren wrote: On 04/13/2013 07:35 PM, Javier Martinez Canillas wrote: ... Is the following inlined patch [1] what you were thinking that would be the right approach? ... diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c ... +static int omap_gpio_irq_request(struct irq_data *d) +{ +struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + +return omap_gpio_request(bank-chip, d-hwirq); If you want the GPIO usage to be known to the GPIO subsystem, then wouldn't you call gpio_request() here rather than omap_gpio_request()? The above code will certainly do enough so that the OMAP GPIO HW is fully enabled as you need, but I thought the idea was to also prevent some other code successfully running gpio_request() on that same GPIO? Also, although omap gpios default to being inputs, we should not assume that. So may be you should call gpio_request_one() here passing as flags GPIOF_IN to configure as an input. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/15/2013 11:58 AM, Stephen Warren wrote: On 04/14/2013 02:53 PM, Linus Walleij wrote: On Sun, Apr 14, 2013 at 3:35 AM, Javier Martinez Canillas martinez.jav...@gmail.com wrote: Is the following inlined patch [1] what you were thinking that would be the right approach? This looks sort of OK, but I'm still struggling with the question of what we could do to help other implementations facing the same issue. This is a pretty hard design pattern to properly replicate in every such driver is it not? Well, instead of adding .request_irq() to the irqchip, and then making each driver call gpio_request() from the implementation, perhaps you could add a .irq_to_gpio() to the irqchip, have the IRQ core call that, and if it gets back a non-error response, the IRQ core could call gpio_request(). That means that the change to each GPIO+IRQ driver is simply to implement a standalone data transformation function .irq_to_gpio(). I am still concerned about the case where a driver may have already called gpio_request() and then calls request_irq(). I think that the solution needs to handle cases where the driver may or may not call gpio_request() to allocate the gpio. Although it could be argued that this is problem is not DT specific, it does become a bigger problem to handle in the case of DT. Therefore, I am wondering if we should just focus on the DT case for now. Now, this does re-introduce irq_to_gpio() in some way, but with the following advantages: 1) The implementation is per-controller, not a single global function, so isn't introducing any kind of centralized mapping scheme again. 2) This irq-chip-specific .irq_to_gpio() would only be implemented for IRQ+GPIO chips that actually have a 1:1 mapping between GPIOs and IRQs. Its potential existence doesn't imply that all IRQ chips need implement this; it would be very specifically be for this one particular case. So, I think it's reasonable to introduce this. How about using the gpio irq domain xlate function? Typically, in DT land a device using a gpio as an interrupt source will have something like the following ... eth@0 { compatible = ks8851; ... interrupt-parent = gpio2; interrupts = 2 8; /* gpio line 34, low triggered */ }; ... or ... mmc { label = pandaboard::status2; gpios = gpio1 8 0; ... }; Both these devices are using a gpio as an interrupt source, but the mmc driver is requesting the gpio directly. In the first case the xlate function for the gpio irq domain will be called where as it is not used in the 2nd case. Therefore, we could add a custom xlate function. For example ... diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 53bb8d5..caaeab2 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1085,6 +1085,33 @@ static void omap_gpio_chip_init(struct gpio_bank *bank) irq_set_handler_data(bank-irq, bank); } + +int omap_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type) +{ + struct gpio_bank *bank; + int irq; + + if (WARN_ON(intsize 1)) + return -EINVAL; + + irq = irq_find_mapping(d, intspec[0]); + bank = irq_get_chip_data(irq); + if (!bank) + return -ENODEV; + + gpio_request_one(irq_to_gpio(bank, intspec[0]), GPIOF_IN, ctrlr-name); + + *out_hwirq = intspec[0]; + *out_type = (intsize 1) ? intspec[1] : IRQ_TYPE_NONE; + return 0; +} + +static const struct irq_domain_ops omap_irq_domain_ops = { + .xlate = omap_irq_domain_xlate, +}; + static const struct of_device_id omap_gpio_match[]; static void omap_gpio_setup_context(struct gpio_bank *p); @@ -1135,7 +1162,7 @@ static int omap_gpio_probe(struct platform_device *pdev) bank-domain = irq_domain_add_linear(node, bank-width, -irq_domain_simple_ops, NULL); +omap_irq_domain_ops, NULL); if (!bank-domain) return -ENODEV; Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/15/2013 04:40 PM, Jon Hunter wrote: On 04/15/2013 11:58 AM, Stephen Warren wrote: On 04/14/2013 02:53 PM, Linus Walleij wrote: On Sun, Apr 14, 2013 at 3:35 AM, Javier Martinez Canillas martinez.jav...@gmail.com wrote: Is the following inlined patch [1] what you were thinking that would be the right approach? This looks sort of OK, but I'm still struggling with the question of what we could do to help other implementations facing the same issue. This is a pretty hard design pattern to properly replicate in every such driver is it not? Well, instead of adding .request_irq() to the irqchip, and then making each driver call gpio_request() from the implementation, perhaps you could add a .irq_to_gpio() to the irqchip, have the IRQ core call that, and if it gets back a non-error response, the IRQ core could call gpio_request(). That means that the change to each GPIO+IRQ driver is simply to implement a standalone data transformation function .irq_to_gpio(). I am still concerned about the case where a driver may have already called gpio_request() and then calls request_irq(). I think that the solution needs to handle cases where the driver may or may not call gpio_request() to allocate the gpio. Although it could be argued that this is problem is not DT specific, it does become a bigger problem to handle in the case of DT. Therefore, I am wondering if we should just focus on the DT case for now. Now, this does re-introduce irq_to_gpio() in some way, but with the following advantages: 1) The implementation is per-controller, not a single global function, so isn't introducing any kind of centralized mapping scheme again. 2) This irq-chip-specific .irq_to_gpio() would only be implemented for IRQ+GPIO chips that actually have a 1:1 mapping between GPIOs and IRQs. Its potential existence doesn't imply that all IRQ chips need implement this; it would be very specifically be for this one particular case. So, I think it's reasonable to introduce this. How about using the gpio irq domain xlate function? Typically, in DT land a device using a gpio as an interrupt source will have something like the following ... eth@0 { compatible = ks8851; ... interrupt-parent = gpio2; interrupts = 2 8; /* gpio line 34, low triggered */ }; ... or ... mmc { label = pandaboard::status2; gpios = gpio1 8 0; ... }; Both these devices are using a gpio as an interrupt source, but the mmc driver is requesting the gpio directly. In the first case the xlate function for the gpio irq domain will be called where as it is not used in the 2nd case. Therefore, we could add a custom xlate function. For example ... diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 53bb8d5..caaeab2 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1085,6 +1085,33 @@ static void omap_gpio_chip_init(struct gpio_bank *bank) irq_set_handler_data(bank-irq, bank); } + +int omap_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, unsigned int *out_type) +{ + struct gpio_bank *bank; + int irq; + + if (WARN_ON(intsize 1)) + return -EINVAL; + + irq = irq_find_mapping(d, intspec[0]); + bank = irq_get_chip_data(irq); + if (!bank) + return -ENODEV; + + gpio_request_one(irq_to_gpio(bank, intspec[0]), GPIOF_IN, ctrlr-name); By the way, I know that I should check the return code here, but this was just an example. Also I don't think using ctrlr-name here works either as this is just gpio. Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 04/15/2013 05:16 PM, Stephen Warren wrote: On 04/15/2013 03:40 PM, Jon Hunter wrote: On 04/15/2013 11:58 AM, Stephen Warren wrote: On 04/14/2013 02:53 PM, Linus Walleij wrote: On Sun, Apr 14, 2013 at 3:35 AM, Javier Martinez Canillas martinez.jav...@gmail.com wrote: Is the following inlined patch [1] what you were thinking that would be the right approach? This looks sort of OK, but I'm still struggling with the question of what we could do to help other implementations facing the same issue. This is a pretty hard design pattern to properly replicate in every such driver is it not? Well, instead of adding .request_irq() to the irqchip, and then making each driver call gpio_request() from the implementation, perhaps you could add a .irq_to_gpio() to the irqchip, have the IRQ core call that, and if it gets back a non-error response, the IRQ core could call gpio_request(). That means that the change to each GPIO+IRQ driver is simply to implement a standalone data transformation function .irq_to_gpio(). I am still concerned about the case where a driver may have already called gpio_request() and then calls request_irq(). I think that the solution needs to handle cases where the driver may or may not call gpio_request() to allocate the gpio. Are there actually drivers that do this? Perhaps they could just be fixed not to. Yes ideally, but my fear is that there are several. I know both omap display and mmc drivers do this. There are many drivers calling gpio_direction_input() but I have not looked to see which of those are just reading state versus configuring an interrupt. Although it could be argued that this is problem is not DT specific, it does become a bigger problem to handle in the case of DT. Therefore, I am wondering if we should just focus on the DT case for now. That doesn't sound like a good idea; this issue is entirely orthogonal to DT. True, but it is proving to be difficult to find a solution that everyone can agree on. Now, this does re-introduce irq_to_gpio() in some way, but with the following advantages: 1) The implementation is per-controller, not a single global function, so isn't introducing any kind of centralized mapping scheme again. 2) This irq-chip-specific .irq_to_gpio() would only be implemented for IRQ+GPIO chips that actually have a 1:1 mapping between GPIOs and IRQs. Its potential existence doesn't imply that all IRQ chips need implement this; it would be very specifically be for this one particular case. So, I think it's reasonable to introduce this. How about using the gpio irq domain xlate function? That translates DT IRQ-specifiers to Linux IRQ numbers. There's no reason to believe that, as an absolute rule, it would work for anything GPIO-related. The fact that in practice most GPIO+IRQ controllers happen to use the same numbering for GPIOs and IRQs is just co-incidence. Yes but provides a hook where we could call gpio_request(). However, I am not sure if this would be considered abuse :-p Typically, in DT land a device using a gpio as an interrupt source will have something like the following ... eth@0 { compatible = ks8851; ... interrupt-parent = gpio2; interrupts = 2 8; /* gpio line 34, low triggered */ }; OK, that really is an interrupt... ... or ... mmc { label = pandaboard::status2; gpios = gpio1 8 0; ... }; But that's a gpio-leds instance, not an MMC controller... I really really hope there's no DT node using gpios to mean interrupts... And it wouldn't make any sense for an on-SoC device anyway. Oops yes, I overlooked that. However, the omap mmc driver (drivers/mmc/host/omap_hsmmc.c) does call gpio_request() and request_threaded_irq() for the mmc card-detect interrupt. I believe tegra is doing the same ... sdhci@7800 { ... cd-gpios = gpio 69 0; /* gpio PI5 */ ... }; Both these devices are using a gpio as an interrupt source, but the mmc driver is requesting the gpio directly. In the first case the xlate function for the gpio irq domain will be called where as it is not used in the 2nd case. Therefore, we could add a custom xlate function. For example ... diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c +int omap_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, ... + gpio_request_one(irq_to_gpio(bank, intspec[0]), GPIOF_IN, ctrlr-name); I guess that could work, but: a) It still means doing the gpio_request() in each driver instead of centrally. Right this is device specific, but it avoids exposing irq_to_gpio for a device. However, we could make this generic if we did expose irq_to_gpio for each device. b) This approach doesn't solve the issue where some client driver has already requested the GPIO. This code would simply prevent that call from succeeding, which would probably make the driver probe() error out, which isn't any different
Re: [PATCH 4/5] gpio/omap: force restore if context loss is not detectable
On 04/10/2013 02:39 PM, Linus Walleij wrote: On Thu, Apr 4, 2013 at 10:16 PM, Jon Hunter jon-hun...@ti.com wrote: When booting with device-tree the function pointer for detecting context loss is not populated. Ideally, the pm_runtime framework should be enhanced to allow a means for reporting context/state loss and we could avoid populating such function pointers altogether. In the interim until a generic non-device specific solution is in place, force a restore of the gpio bank when enabling the gpio controller. Adds a new device-tree property for the OMAP GPIO controller to indicate if the GPIO controller is located in a power-domain that never loses power and hence will always maintain its logic state. Signed-off-by: Jon Hunter jon-hun...@ti.com In this case it'd be really helpful to get an ACK from somebody else. I have no clue whether this thing is doing what it should, and if you were the maintainer I'd apply it but now I'd like to hear from Kevin or Santosh first... Santosh gave the his ACK for 1-4 (see 0/5) and Kevin added his reviewed-by for 1-4 (again see 0/5). Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 1/5] gpio/omap: free irq domain in probe() failure paths
On 04/10/2013 02:33 PM, Linus Walleij wrote: On Thu, Apr 4, 2013 at 10:16 PM, Jon Hunter jon-hun...@ti.com wrote: Currently the IRQ domain is not freed once allocated, in the case where omap_gpio_probe() fails. Therefore, ensure we free the domain if the probe does fail. Furthermore, the local variable ret is not needed and so remove this. Signed-off-by: Jon Hunter jon-hun...@ti.com Hm Kevin is still listed as maintainer on this driver but on a mail address that bounces, can you send a patch replacing him in MAINTAINERS with yourself if you're willing to pick it up? Anyway, patch applied. Thanks. There is a patch to fix this queued for v3.10 [1]. Cheers Jon [1] http://git.kernel.org/cgit/linux/kernel/git/arm/arm-soc.git/commit/MAINTAINERS?h=for-nextid=c69d72aec52eb5234f433259ac5dcc3b68f1480d ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 4/5] gpio/omap: force restore if context loss is not detectable
On 04/10/2013 02:44 PM, Linus Walleij wrote: On Wed, Apr 10, 2013 at 9:41 PM, Jon Hunter jon-hun...@ti.com wrote: On 04/10/2013 02:39 PM, Linus Walleij wrote: On Thu, Apr 4, 2013 at 10:16 PM, Jon Hunter jon-hun...@ti.com wrote: When booting with device-tree the function pointer for detecting context loss is not populated. Ideally, the pm_runtime framework should be enhanced to allow a means for reporting context/state loss and we could avoid populating such function pointers altogether. In the interim until a generic non-device specific solution is in place, force a restore of the gpio bank when enabling the gpio controller. Adds a new device-tree property for the OMAP GPIO controller to indicate if the GPIO controller is located in a power-domain that never loses power and hence will always maintain its logic state. Signed-off-by: Jon Hunter jon-hun...@ti.com In this case it'd be really helpful to get an ACK from somebody else. I have no clue whether this thing is doing what it should, and if you were the maintainer I'd apply it but now I'd like to hear from Kevin or Santosh first... Santosh gave the his ACK for 1-4 (see 0/5) and Kevin added his reviewed-by for 1-4 (again see 0/5). OK all in patch 0 how confusing #-) All patches applied with Kevin's and Santosh's tags! Thanks. Sorry for the confusion! By the way, I am hoping you only took 1-4, per the cover-letter I was planning to have Benoit take 5 through his DT branch as there could be conflicts if you merge this with Benoit's branch. Again sorry if this is even more confusing ;-) Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH] Documentation: dt: update properties in TI GPMC NAND example
The GPMC timing properties for device-tree have been updated by adding a -ns or -ps suffix to indicate the units of time the property represents. Therefore, update the timing property names for TI GPMC NAND example. Signed-off-by: Jon Hunter jon-hun...@ti.com --- .../devicetree/bindings/mtd/gpmc-nand.txt | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt index e7f8d7e..6a983c1 100644 --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt @@ -56,20 +56,20 @@ Example for an AM33xx board: nand-bus-width = 16; ti,nand-ecc-opt = bch8; - gpmc,sync-clk = 0; - gpmc,cs-on = 0; - gpmc,cs-rd-off = 44; - gpmc,cs-wr-off = 44; - gpmc,adv-on = 6; - gpmc,adv-rd-off = 34; - gpmc,adv-wr-off = 44; - gpmc,we-off = 40; - gpmc,oe-off = 54; - gpmc,access = 64; - gpmc,rd-cycle = 82; - gpmc,wr-cycle = 82; - gpmc,wr-access = 40; - gpmc,wr-data-mux-bus = 0; + gpmc,sync-clk-ps = 0; + gpmc,cs-on-ns = 0; + gpmc,cs-rd-off-ns = 44; + gpmc,cs-wr-off-ns = 44; + gpmc,adv-on-ns = 6; + gpmc,adv-rd-off-ns = 34; + gpmc,adv-wr-off-ns = 44; + gpmc,we-off-ns = 40; + gpmc,oe-off-ns = 54; + gpmc,access-ns = 64; + gpmc,rd-cycle-ns = 82; + gpmc,wr-cycle-ns = 82; + gpmc,wr-access-ns = 40; + gpmc,wr-data-mux-bus-ns = 0; #address-cells = 1; #size-cells = 1; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 3/3] ARM: dts: Add OMAP3430 SDP NOR flash memory binding
Add device-tree node for the 128MB NOR on the OMAP3423-SDP board. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/boot/dts/omap3430-sdp.dts | 51 +++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts index 44d2191..144ae43 100644 --- a/arch/arm/boot/dts/omap3430-sdp.dts +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -45,9 +45,58 @@ }; gpmc { - ranges = 1 0 0x2800 0x0800, + ranges = 0 0 0x1000 0x0800, +1 0 0x2800 0x0800, 2 0 0x2000 0x1000; + nor@0,0 { + compatible = cfi-flash; + linux,mtd-name= intel,pf48f6000m0y1be; + #address-cells = 1; + #size-cells = 1; + reg = 0 0 0x0800; + bank-width = 2; + + gpmc,mux-add-data = 2; + gpmc,cs-on-ns = 0; + gpmc,cs-rd-off-ns = 186; + gpmc,cs-wr-off-ns = 186; + gpmc,adv-on-ns = 12; + gpmc,adv-rd-off-ns = 48; + gpmc,adv-wr-off-ns = 48; + gpmc,oe-on-ns = 54; + gpmc,oe-off-ns = 168; + gpmc,we-on-ns = 54; + gpmc,we-off-ns = 168; + gpmc,rd-cycle-ns = 186; + gpmc,wr-cycle-ns = 186; + gpmc,access-ns = 114; + gpmc,page-burst-access-ns = 6; + gpmc,bus-turnaround-ns = 12; + gpmc,cycle2cycle-delay-ns = 18; + gpmc,wr-data-mux-bus-ns = 90; + gpmc,wr-access-ns = 186; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + + partition@0 { + label = bootloader-nor; + reg = 0 0x4; + }; + partition@0x4 { + label = params-nor; + reg = 0x4 0x4; + }; + partition@0x8 { + label = kernel-nor; + reg = 0x8 0x20; + }; + partition@0x28 { + label = filesystem-nor; + reg = 0x24 0x7d8; + }; + }; + nand@1,0 { linux,mtd-name= micron,mt29f1g08abb; #address-cells = 1; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 2/3] ARM: dts: Add NOR flash bindings for OMAP2420 H4
Add device-tree node for the 64MB NOR on the OMAP2420-H4 board. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/boot/dts/omap2420-h4.dts | 46 + 1 file changed, 46 insertions(+) diff --git a/arch/arm/boot/dts/omap2420-h4.dts b/arch/arm/boot/dts/omap2420-h4.dts index 9b0d077..68282ee 100644 --- a/arch/arm/boot/dts/omap2420-h4.dts +++ b/arch/arm/boot/dts/omap2420-h4.dts @@ -18,3 +18,49 @@ reg = 0x8000 0x400; /* 64 MB */ }; }; + +gpmc { + ranges = 0 0 0x0800 0x0400; + + nor@0,0 { + compatible = cfi-flash; + linux,mtd-name= intel,ge28f256l18b85; + #address-cells = 1; + #size-cells = 1; + reg = 0 0 0x0400; + bank-width = 2; + + gpmc,mux-add-data = 2; + gpmc,cs-on-ns = 10; + gpmc,cs-rd-off-ns = 160; + gpmc,cs-wr-off-ns = 160; + gpmc,adv-on-ns = 20; + gpmc,adv-rd-off-ns = 50; + gpmc,adv-wr-off-ns = 50; + gpmc,oe-on-ns = 60; + gpmc,oe-off-ns = 120; + gpmc,we-on-ns = 60; + gpmc,we-off-ns = 120; + gpmc,rd-cycle-ns = 170; + gpmc,wr-cycle-ns = 170; + gpmc,access-ns = 150; + gpmc,page-burst-access-ns = 10; + + partition@0 { + label = bootloader; + reg = 0 0x2; + }; + partition@0x2 { + label = params; + reg = 0x2 0x2; + }; + partition@0x4 { + label = kernel; + reg = 0x4 0x20; + }; + partition@0x24 { + label = file-system; + reg = 0x24 0x3dc; + }; + }; +}; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 1/3] ARM: dts: Update OMAP3430 SDP NAND and ONENAND properties
The GPMC timing properties for device-tree have been updated by adding a -ns or -ps suffix to indicate the units of time the property represents (as suggested by Rob Herring). Therefore, update the timing property names for the OMAP3430 SDP NAND and ONENAND devices. Signed-off-by: Jon Hunter jon-hun...@ti.com --- Hi Benoit, this is a changed that is going to be introduced for v3.10. Feel free to squash this with the patch ARM: dts: OMAP3: Add support for OMAP3430 SDP board that you have queued for v3.10 if you prefer. arch/arm/boot/dts/omap3430-sdp.dts | 56 ++-- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts index 05cd8ba..44d2191 100644 --- a/arch/arm/boot/dts/omap3430-sdp.dts +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -57,20 +57,20 @@ ti,nand-ecc-opt = sw; gpmc,device-nand; - gpmc,cs-on = 0; - gpmc,cs-rd-off = 36; - gpmc,cs-wr-off = 36; - gpmc,adv-on = 6; - gpmc,adv-rd-off = 24; - gpmc,adv-wr-off = 36; - gpmc,oe-on = 6; - gpmc,oe-off = 48; - gpmc,we-on = 6; - gpmc,we-off = 30; - gpmc,rd-cycle = 72; - gpmc,wr-cycle = 72; - gpmc,access = 54; - gpmc,wr-access = 30; + gpmc,cs-on-ns = 0; + gpmc,cs-rd-off-ns = 36; + gpmc,cs-wr-off-ns = 36; + gpmc,adv-on-ns = 6; + gpmc,adv-rd-off-ns = 24; + gpmc,adv-wr-off-ns = 36; + gpmc,oe-on-ns = 6; + gpmc,oe-off-ns = 48; + gpmc,we-on-ns = 6; + gpmc,we-off-ns = 30; + gpmc,rd-cycle-ns = 72; + gpmc,wr-cycle-ns = 72; + gpmc,access-ns = 54; + gpmc,wr-access-ns = 30; partition@0 { label = xloader-nand; @@ -102,20 +102,20 @@ gpmc,device-width = 2; gpmc,mux-add-data = 2; - gpmc,cs-on = 0; - gpmc,cs-rd-off = 84; - gpmc,cs-wr-off = 72; - gpmc,adv-on = 0; - gpmc,adv-rd-off = 18; - gpmc,adv-wr-off = 18; - gpmc,oe-on = 30; - gpmc,oe-off = 84; - gpmc,we-on = 0; - gpmc,we-off = 42; - gpmc,rd-cycle = 108; - gpmc,wr-cycle = 96; - gpmc,access = 78; - gpmc,wr-data-mux-bus = 30; + gpmc,cs-on-ns = 0; + gpmc,cs-rd-off-ns = 84; + gpmc,cs-wr-off-ns = 72; + gpmc,adv-on-ns = 0; + gpmc,adv-rd-off-ns = 18; + gpmc,adv-wr-off-ns = 18; + gpmc,oe-on-ns = 30; + gpmc,oe-off-ns = 84; + gpmc,we-on-ns = 0; + gpmc,we-off-ns = 42; + gpmc,rd-cycle-ns = 108; + gpmc,wr-cycle-ns = 96; + gpmc,access-ns = 78; + gpmc,wr-data-mux-bus-ns = 30; partition@0 { label = xloader-onenand; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/3] ARM: dts: Add OMAP3430 SDP NOR flash memory binding
On 04/07/2013 08:17 PM, Jon Hunter wrote: Add device-tree node for the 128MB NOR on the OMAP3423-SDP board. Bugger ... it seems I have invented and new board. OMAP3423 SDP does not exist. Fixed below. Jon From 4f486b5dddc5d960d786504b4e3e97a28b63c1c0 Mon Sep 17 00:00:00 2001 From: Jon Hunter jon-hun...@ti.com Date: Thu, 21 Feb 2013 18:52:05 -0600 Subject: [PATCH 3/3] ARM: dts: Add OMAP3430 SDP NOR flash memory binding Add device-tree node for the 128MB NOR on the OMAP3430-SDP board. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/boot/dts/omap3430-sdp.dts | 51 +++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts index 44d2191..144ae43 100644 --- a/arch/arm/boot/dts/omap3430-sdp.dts +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -45,9 +45,58 @@ }; gpmc { - ranges = 1 0 0x2800 0x0800, + ranges = 0 0 0x1000 0x0800, +1 0 0x2800 0x0800, 2 0 0x2000 0x1000; + nor@0,0 { + compatible = cfi-flash; + linux,mtd-name= intel,pf48f6000m0y1be; + #address-cells = 1; + #size-cells = 1; + reg = 0 0 0x0800; + bank-width = 2; + + gpmc,mux-add-data = 2; + gpmc,cs-on-ns = 0; + gpmc,cs-rd-off-ns = 186; + gpmc,cs-wr-off-ns = 186; + gpmc,adv-on-ns = 12; + gpmc,adv-rd-off-ns = 48; + gpmc,adv-wr-off-ns = 48; + gpmc,oe-on-ns = 54; + gpmc,oe-off-ns = 168; + gpmc,we-on-ns = 54; + gpmc,we-off-ns = 168; + gpmc,rd-cycle-ns = 186; + gpmc,wr-cycle-ns = 186; + gpmc,access-ns = 114; + gpmc,page-burst-access-ns = 6; + gpmc,bus-turnaround-ns = 12; + gpmc,cycle2cycle-delay-ns = 18; + gpmc,wr-data-mux-bus-ns = 90; + gpmc,wr-access-ns = 186; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + + partition@0 { + label = bootloader-nor; + reg = 0 0x4; + }; + partition@0x4 { + label = params-nor; + reg = 0x4 0x4; + }; + partition@0x8 { + label = kernel-nor; + reg = 0x8 0x20; + }; + partition@0x28 { + label = filesystem-nor; + reg = 0x24 0x7d8; + }; + }; + nand@1,0 { linux,mtd-name= micron,mt29f1g08abb; #address-cells = 1; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 0/5] gpio/omap: 2nd batch of updates for v3.10
On 04/05/2013 01:35 AM, Santosh Shilimkar wrote: On Friday 05 April 2013 01:46 AM, Jon Hunter wrote: Main change is ensuring that the state of a gpio bank is restored when booting with device-tree. The rest of the patches are clean-ups and one optimisation. The patch modifying the *.dtsi files should go via Benoit Cousson's for_3.10/dts branch [1] as it is dependent on changes in his branch but I have included here for completeness. Testing includes: - Boot testing on OMAP5912 OSK, OMAP2420 H4, OMAP3430 SDP, OMAP4430 SDP and AM335x EVM. - Verified that GPIO interrupts are working on OMAP5912 OSK, OMAP2420 H4, OMAP3430 SDP and OMAP4430 SDP by making sure networking was working correctly as these boards use a GPIO with the ethernet chips. Also checked /proc/interrupts to ensure GPIO interrupt counts are incrementing as expected. [1] http://git.kernel.org/cgit/linux/kernel/git/bcousson/linux-omap-dt.git Jon Hunter (4): gpio/omap: free irq domain in probe() failure paths gpio/omap: optimise interrupt service routine gpio/omap: force restore if context loss is not detectable ARM: dts: OMAP2+: Identify GPIO banks that are always powered Tarun Kanti DebBarma (1): gpio/omap: remove extra context restores in *_runtime_resume() Thanks Jon for pulling the fixes. I suggest you to split the series so that 'gpio/omap:*' can be pulled by Grant and 'ARM: dts:*' by Benoit. Agreed. I had kept them altogether here for completeness as it would have been odd to add a new property but not use it. If everyone is ok with the changes, then I can either resend or Grant/Linus just pick up 1-4. All the 'gpio/omap:*' patches in the series looks fine to me. FWIW, Acked-by: Santosh Shilimkar santosh.shilim...@ti.com Thanks Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 0/5] gpio/omap: 2nd batch of updates for v3.10
Main change is ensuring that the state of a gpio bank is restored when booting with device-tree. The rest of the patches are clean-ups and one optimisation. The patch modifying the *.dtsi files should go via Benoit Cousson's for_3.10/dts branch [1] as it is dependent on changes in his branch but I have included here for completeness. Testing includes: - Boot testing on OMAP5912 OSK, OMAP2420 H4, OMAP3430 SDP, OMAP4430 SDP and AM335x EVM. - Verified that GPIO interrupts are working on OMAP5912 OSK, OMAP2420 H4, OMAP3430 SDP and OMAP4430 SDP by making sure networking was working correctly as these boards use a GPIO with the ethernet chips. Also checked /proc/interrupts to ensure GPIO interrupt counts are incrementing as expected. [1] http://git.kernel.org/cgit/linux/kernel/git/bcousson/linux-omap-dt.git Jon Hunter (4): gpio/omap: free irq domain in probe() failure paths gpio/omap: optimise interrupt service routine gpio/omap: force restore if context loss is not detectable ARM: dts: OMAP2+: Identify GPIO banks that are always powered Tarun Kanti DebBarma (1): gpio/omap: remove extra context restores in *_runtime_resume() .../devicetree/bindings/gpio/gpio-omap.txt |7 ++- arch/arm/boot/dts/omap2420.dtsi|4 ++ arch/arm/boot/dts/omap2430.dtsi|4 ++ arch/arm/boot/dts/omap3.dtsi |1 + arch/arm/boot/dts/omap4.dtsi |1 + arch/arm/boot/dts/omap5.dtsi |1 + drivers/gpio/gpio-omap.c | 49 +++- 7 files changed, 44 insertions(+), 23 deletions(-) -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 1/5] gpio/omap: free irq domain in probe() failure paths
Currently the IRQ domain is not freed once allocated, in the case where omap_gpio_probe() fails. Therefore, ensure we free the domain if the probe does fail. Furthermore, the local variable ret is not needed and so remove this. Signed-off-by: Jon Hunter jon-hun...@ti.com --- drivers/gpio/gpio-omap.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0d30c7a..1e666c8 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1094,7 +1094,6 @@ static int omap_gpio_probe(struct platform_device *pdev) const struct omap_gpio_platform_data *pdata; struct resource *res; struct gpio_bank *bank; - int ret = 0; match = of_match_device(of_match_ptr(omap_gpio_match), dev); @@ -1143,18 +1142,21 @@ static int omap_gpio_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!res)) { dev_err(dev, Invalid mem resource\n); + irq_domain_remove(bank-domain); return -ENODEV; } if (!devm_request_mem_region(dev, res-start, resource_size(res), pdev-name)) { dev_err(dev, Region already claimed\n); + irq_domain_remove(bank-domain); return -EBUSY; } bank-base = devm_ioremap(dev, res-start, resource_size(res)); if (!bank-base) { dev_err(dev, Could not ioremap\n); + irq_domain_remove(bank-domain); return -ENOMEM; } @@ -1178,7 +1180,7 @@ static int omap_gpio_probe(struct platform_device *pdev) list_add_tail(bank-node, omap_gpio_list); - return ret; + return 0; } #ifdef CONFIG_ARCH_OMAP2PLUS -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 2/5] gpio/omap: remove extra context restores in *_runtime_resume()
From: Tarun Kanti DebBarma tarun.ka...@ti.com 68942edb09f69b6e09522d1d346665eb3aadde49 (gpio/omap: fix wakeups on level-triggered GPIOs) already restores the fallingdetect and risingdetect contexts in *_runtime_resume(). These registers were modified in *_runtime_suspend() to include even those configured as level-triggered since only edge-triggered gpios can generate wakeup events. Therefore, the old context restores of the same registers present later in the code is not needed any more. Remove them. Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com Signed-off-by: Jon Hunter jon-hun...@ti.com --- drivers/gpio/gpio-omap.c |4 1 file changed, 4 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 1e666c8..5af7acd 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1292,10 +1292,6 @@ static int omap_gpio_runtime_resume(struct device *dev) return 0; } - __raw_writel(bank-context.fallingdetect, - bank-base + bank-regs-fallingdetect); - __raw_writel(bank-context.risingdetect, - bank-base + bank-regs-risingdetect); l = __raw_readl(bank-base + bank-regs-datain); /* -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 4/5] gpio/omap: force restore if context loss is not detectable
When booting with device-tree the function pointer for detecting context loss is not populated. Ideally, the pm_runtime framework should be enhanced to allow a means for reporting context/state loss and we could avoid populating such function pointers altogether. In the interim until a generic non-device specific solution is in place, force a restore of the gpio bank when enabling the gpio controller. Adds a new device-tree property for the OMAP GPIO controller to indicate if the GPIO controller is located in a power-domain that never loses power and hence will always maintain its logic state. Signed-off-by: Jon Hunter jon-hun...@ti.com --- .../devicetree/bindings/gpio/gpio-omap.txt |7 -- drivers/gpio/gpio-omap.c | 25 +--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio-omap.txt b/Documentation/devicetree/bindings/gpio/gpio-omap.txt index a56e3a5..8d95052 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-omap.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-omap.txt @@ -20,8 +20,11 @@ Required properties: 8 = active low level-sensitive. OMAP specific properties: -- ti,hwmods: Name of the hwmod associated to the GPIO: - gpioX, X being the 1-based instance number from the HW spec +- ti,hwmods: Name of the hwmod associated to the GPIO: + gpioX, X being the 1-based instance number + from the HW spec. +- ti,gpio-always-on: Indicates if a GPIO bank is always powered and + so will never lose its logic state. Example: diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 685e850..0557529 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1120,11 +1120,17 @@ static int omap_gpio_probe(struct platform_device *pdev) bank-width = pdata-bank_width; bank-is_mpuio = pdata-is_mpuio; bank-non_wakeup_gpios = pdata-non_wakeup_gpios; - bank-loses_context = pdata-loses_context; bank-regs = pdata-regs; #ifdef CONFIG_OF_GPIO bank-chip.of_node = of_node_get(node); #endif + if (node) { + if (!of_property_read_bool(node, ti,gpio-always-on)) + bank-loses_context = true; + } else { + bank-loses_context = pdata-loses_context; + } + bank-domain = irq_domain_add_linear(node, bank-width, irq_domain_simple_ops, NULL); @@ -1258,9 +1264,9 @@ static int omap_gpio_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct gpio_bank *bank = platform_get_drvdata(pdev); - int context_lost_cnt_after; u32 l = 0, gen, gen0, gen1; unsigned long flags; + int c; spin_lock_irqsave(bank-lock, flags); _gpio_dbck_enable(bank); @@ -1276,14 +1282,17 @@ static int omap_gpio_runtime_resume(struct device *dev) __raw_writel(bank-context.risingdetect, bank-base + bank-regs-risingdetect); - if (bank-get_context_loss_count) { - context_lost_cnt_after = - bank-get_context_loss_count(bank-dev); - if (context_lost_cnt_after != bank-context_loss_count) { + if (bank-loses_context) { + if (!bank-get_context_loss_count) { omap_gpio_restore_context(bank); } else { - spin_unlock_irqrestore(bank-lock, flags); - return 0; + c = bank-get_context_loss_count(bank-dev); + if (c != bank-context_loss_count) { + omap_gpio_restore_context(bank); + } else { + spin_unlock_irqrestore(bank-lock, flags); + return 0; + } } } -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 3/5] gpio/omap: optimise interrupt service routine
The OMAP GPIO interrupt service routine is checking each bit in the GPIO interrupt status register to see which bits are set. It is not efficient to check every bit especially if only a few bits are set. Therefore, instead of checking every bit use the __ffs() function, which returns the location of the first set bit, to find all the set bits. This optimisation was suggested-by and developed in collaboration with Felipe Balbi. Cc: Felipe Balbi ba...@ti.com Signed-off-by: Jon Hunter jon-hun...@ti.com --- drivers/gpio/gpio-omap.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 5af7acd..685e850 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -689,7 +689,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { void __iomem *isr_reg = NULL; u32 isr; - unsigned int i; + unsigned int bit; struct gpio_bank *bank; int unmasked = 0; struct irq_chip *chip = irq_desc_get_chip(desc); @@ -730,9 +730,9 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) if (!isr) break; - for (i = 0; isr != 0; isr = 1, i++) { - if (!(isr 1)) - continue; + while (isr) { + bit = __ffs(isr); + isr = ~(1 bit); /* * Some chips can't respond to both rising and falling @@ -741,10 +741,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) * to respond to the IRQ for the opposite direction. * This will be indicated in the bank toggle_mask. */ - if (bank-toggle_mask (1 i)) - _toggle_gpio_edge_triggering(bank, i); + if (bank-toggle_mask (1 bit)) + _toggle_gpio_edge_triggering(bank, bit); - generic_handle_irq(irq_find_mapping(bank-domain, i)); + generic_handle_irq(irq_find_mapping(bank-domain, bit)); } } /* if bank has any level sensitive GPIO pin interrupt -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 5/5] ARM: dts: OMAP2+: Identify GPIO banks that are always powered
Add the ti,gpio-always-on property to the appropriate GPIO banks to indicate which banks are always powered and will never lose logic state. Cc: Benoit Cousson b-cous...@ti.com Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/boot/dts/omap2420.dtsi |4 arch/arm/boot/dts/omap2430.dtsi |4 arch/arm/boot/dts/omap3.dtsi|1 + arch/arm/boot/dts/omap4.dtsi|1 + arch/arm/boot/dts/omap5.dtsi|1 + 5 files changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi index 455b239..76446ff 100644 --- a/arch/arm/boot/dts/omap2420.dtsi +++ b/arch/arm/boot/dts/omap2420.dtsi @@ -34,6 +34,7 @@ reg = 0x48018000 0x200; interrupts = 29; ti,hwmods = gpio1; + ti,gpio-always-on; #gpio-cells = 2; gpio-controller; #interrupt-cells = 2; @@ -45,6 +46,7 @@ reg = 0x4801a000 0x200; interrupts = 30; ti,hwmods = gpio2; + ti,gpio-always-on; #gpio-cells = 2; gpio-controller; #interrupt-cells = 2; @@ -56,6 +58,7 @@ reg = 0x4801c000 0x200; interrupts = 31; ti,hwmods = gpio3; + ti,gpio-always-on; #gpio-cells = 2; gpio-controller; #interrupt-cells = 2; @@ -67,6 +70,7 @@ reg = 0x4801e000 0x200; interrupts = 32; ti,hwmods = gpio4; + ti,gpio-always-on; #gpio-cells = 2; gpio-controller; #interrupt-cells = 2; diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi index 477b120..ca2c4a3 100644 --- a/arch/arm/boot/dts/omap2430.dtsi +++ b/arch/arm/boot/dts/omap2430.dtsi @@ -34,6 +34,7 @@ reg = 0x4900c000 0x200; interrupts = 29; ti,hwmods = gpio1; + ti,gpio-always-on; #gpio-cells = 2; gpio-controller; #interrupt-cells = 2; @@ -45,6 +46,7 @@ reg = 0x4900e000 0x200; interrupts = 30; ti,hwmods = gpio2; + ti,gpio-always-on; #gpio-cells = 2; gpio-controller; #interrupt-cells = 2; @@ -56,6 +58,7 @@ reg = 0x4901 0x200; interrupts = 31; ti,hwmods = gpio3; + ti,gpio-always-on; #gpio-cells = 2; gpio-controller; #interrupt-cells = 2; @@ -67,6 +70,7 @@ reg = 0x49012000 0x200; interrupts = 32; ti,hwmods = gpio4; + ti,gpio-always-on; #gpio-cells = 2; gpio-controller; #interrupt-cells = 2; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index 3344f05..626406f 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -116,6 +116,7 @@ reg = 0x4831 0x200; interrupts = 29; ti,hwmods = gpio1; + ti,gpio-always-on; gpio-controller; #gpio-cells = 2; interrupt-controller; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 3329140..627f6ca 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -140,6 +140,7 @@ reg = 0x4a31 0x200; interrupts = 0 29 0x4; ti,hwmods = gpio1; + ti,gpio-always-on; gpio-controller; #gpio-cells = 2; interrupt-controller; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index f4c71d9..82a4b03 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -133,6 +133,7 @@ reg = 0x4ae1 0x200; interrupts = 0 29 0x4; ti,hwmods = gpio1; + ti,gpio-always-on; gpio-controller; #gpio-cells = 2; interrupt-controller; -- 1.7.10.4 ___ devicetree-discuss
Re: [RFC][BUG] arm/dts: OMAP3: set #interrupt-cells to two
On 04/02/2013 10:55 AM, Christoph Fritz wrote: On Mon, 2013-04-01 at 22:05 +0200, Javier Martinez Canillas wrote: As a quick-fix (hack) I wrote directly to the registers in gpio_probe() to enable GPIO banks. I now geht this: [0.214630] omap_gpio_probe, 1133, CM_CLKSEL_PER 0x48005040: 0x00ff [0.214660] omap_gpio_probe, 1136, CM_ICLKEN_PER 0x48005010: 0x0007 [0.214660] omap_gpio_probe, 1139, CM_FCLKEN_PER 0x48005000: 0x0007 to be more specific on this point, this is the patch to enable the gpio-clocks: -- Subject: [PATCH] HACK: enable gpio-clocks in gpio-omap probe() Without this patch setting trigger value from #interrupt-cell two (smsc911x) fails. --- drivers/gpio/gpio-omap.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 159f5c5..720b2e6 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1098,6 +1098,7 @@ static int omap_gpio_probe(struct platform_device *pdev) struct resource *res; struct gpio_bank *bank; int ret = 0; + void __iomem *tmp; match = of_match_device(of_match_ptr(omap_gpio_match), dev); @@ -1117,6 +1118,17 @@ static int omap_gpio_probe(struct platform_device *pdev) return -ENODEV; } + // TRM: Table 3-242. PER_CM Register Summary + tmp = ioremap(0x48005040, 4); //CM_CLKSEL_PER, GPT2 = sys clk + writel(0xFF, tmp); + iounmap(tmp); + tmp = ioremap(0x48005010, 4); //CM_ICLKEN_PER, ICKen GPT2 + writel(0x7, tmp); + iounmap(tmp); + tmp = ioremap(0x48005000, 4); //CM_FCLKEN_PER, GPIOX functional clock is enabled + writel(0x7, tmp); + iounmap(tmp); + bank-irq = res-start; bank-dev = dev; bank-dbck_flag = pdata-dbck_flag; Is there a better way to do this? A better way to hack this and leave the gpio bank on always would be ... diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index f1fbedb2..0fc75a2 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1181,8 +1181,6 @@ static int omap_gpio_probe(struct platform_device *pdev) if (bank-loses_context) bank-get_context_loss_count = pdata-get_context_loss_count; - pm_runtime_put(bank-dev); - list_add_tail(bank-node, omap_gpio_list); return ret; And it works for me. _But_ when I do enable regulator twl4030 (CONFIG_REGULATOR_TWL4030=y) in my config these registers get reset: [2.935455] smsc911x_open, 1537, CM_CLKSEL_PER 0x48005040: 0x00ff [2.942291] smsc911x_open, 1540, CM_ICLKEN_PER 0x48005010: 0x00040fff [2.949066] smsc911x_open, 1543, CM_FCLKEN_PER 0x48005000: 0x And the IRQ source for the network chip (smsc911x) is disabled :-( CONFIG_REGULATOR_TWL4030=y disables the gpio-clocks. Why is that? Well your hack is completely by-passing pm-runtime and so pm-runtime does not know that someone has enabled the bank. Therefore, the next time pm_runtime_get() is called followed by a pm_runtime_put() for the gpio bank it will disable the bank. By removing the pm_runtime_put() at the end of probe should always keep the bank enabled. Do you have any idea how to (quick) fix this? A quick hack is to call gpio_request() explicitly before calling to irq_set_type() is made. I've this patch just to make it work until we find a clean solution: diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 90c15ee..d594e1d 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -14,6 +14,7 @@ */ #undef DEBUG +#include linux/gpio.h #include linux/irq.h #include linux/kernel.h #include linux/init.h @@ -1528,6 +1529,11 @@ static int gpmc_probe_dt(struct platform_device *pdev) return ret; } + ret = gpio_request_one(176, GPIOF_IN, smsc911x irq); + if (ret) { + pr_err(Failed to request IRQ GPIO%d\n, 176); + return ret; + } + for_each_node_by_name(child, nand) { ret = gpmc_probe_nand_child(pdev, child); if (ret 0) { This solves the issue of the non-initialized GPIO bank before that makes the kernel to hang. Here it does not. A printk shows that I'm not using gpmc at all. So I added a gpmc node: + gpmc: gpmc@0x6E00 { + compatible = ti,omap3430-gpmc; + ti,hwmods = ti,gpmc; This should just be ... + ti,hwmods = gpmc; + reg = 0x6E00 0x2000; + gpmc,num-cs = 8; + gpmc,num-waitpins = 2; + #address-cells = 2; + #size-cells = 1; + ranges = 0 0 0x0 0x3FFF; + + }; But still, gpmc_probe_dt() isn't called. I maybe have to define some child nodes but currently I do configure the gpmc in u-boot and try to avoid
Re: [PATCH V3 2/2] dmaengine: OMAP: Register SDMA controller with Device Tree DMA driver
Vinod, On 03/20/2013 11:36 AM, Tony Lindgren wrote: * Jon Hunter jon-hun...@ti.com [130319 09:08]: Vinod, Tony, Benoit, On 02/26/2013 12:27 PM, Jon Hunter wrote: If the device-tree blob is present during boot, then register the SDMA controller with the device-tree DMA driver so that we can use device-tree to look-up DMA client information. Signed-off-by: Jon Hunter jon-hun...@ti.com Reviewed-by: Felipe Balbi ba...@ti.com Acked-by: Santosh Shilimkar santosh.shilim...@ti.com Tested-by: Santosh Shilimkar santosh.shilim...@ti.com --- arch/arm/mach-omap2/dma.c |4 drivers/dma/omap-dma.c| 38 -- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index dab9fc0..49fd0d5 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -28,6 +28,7 @@ #include linux/init.h #include linux/device.h #include linux/dma-mapping.h +#include linux/of.h #include linux/omap-dma.h #include soc.h @@ -304,6 +305,9 @@ static int __init omap2_system_dma_init(void) if (res) return res; + if (of_have_populated_dt()) + return res; + pdev = platform_device_register_full(omap_dma_dev_info); if (IS_ERR(pdev)) return PTR_ERR(pdev); AFAIK we don't currently have anything else touching this file.. diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index c4b4fd2..2ea3d7e 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -16,6 +16,8 @@ #include linux/platform_device.h #include linux/slab.h #include linux/spinlock.h +#include linux/of_dma.h +#include linux/of_device.h #include virt-dma.h @@ -67,6 +69,10 @@ static const unsigned es_bytes[] = { [OMAP_DMA_DATA_TYPE_S32] = 4, }; +static struct of_dma_filter_info omap_dma_info = { + .filter_fn = omap_dma_filter_fn, +}; + static inline struct omap_dmadev *to_omap_dma_dev(struct dma_device *d) { return container_of(d, struct omap_dmadev, ddev); @@ -621,8 +627,22 @@ static int omap_dma_probe(struct platform_device *pdev) pr_warn(OMAP-DMA: failed to register slave DMA engine device: %d\n, rc); omap_dma_free(od); - } else { - platform_set_drvdata(pdev, od); + return rc; + } + + platform_set_drvdata(pdev, od); + + if (pdev-dev.of_node) { + omap_dma_info.dma_cap = od-ddev.cap_mask; + + /* Device-tree DMA controller registration */ + rc = of_dma_controller_register(pdev-dev.of_node, + of_dma_simple_xlate, omap_dma_info); + if (rc) { + pr_warn(OMAP-DMA: failed to register DMA controller\n); + dma_async_device_unregister(od-ddev); + omap_dma_free(od); + } } dev_info(pdev-dev, OMAP DMA engine driver\n); @@ -634,18 +654,32 @@ static int omap_dma_remove(struct platform_device *pdev) { struct omap_dmadev *od = platform_get_drvdata(pdev); + if (pdev-dev.of_node) + of_dma_controller_free(pdev-dev.of_node); + dma_async_device_unregister(od-ddev); omap_dma_free(od); return 0; } +static const struct of_device_id omap_dma_match[] = { + { .compatible = ti,omap2420-sdma, }, + { .compatible = ti,omap2430-sdma, }, + { .compatible = ti,omap3430-sdma, }, + { .compatible = ti,omap3630-sdma, }, + { .compatible = ti,omap4430-sdma, }, + {}, +}; +MODULE_DEVICE_TABLE(of, omap_dma_match); + static struct platform_driver omap_dma_driver = { .probe = omap_dma_probe, .remove = omap_dma_remove, .driver = { .name = omap-dma-engine, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(omap_dma_match), }, }; Who's tree does it make most sense for this patch to go through? Benoit has queued up patch 1/2 and so I am not sure if this should go via Benoit tree to Tony or directly via Vinod's tree. What are your thoughts? OK It would be great if this could make v3.10. I suggest Vinod/Grant/Linus W queue this patch: Acked-by: Tony Lindgren t...@atomide.com Can you take this patch with Tony's ACK? Let me know if you want me to resend with the ACK. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 3/5] gpio/omap: Add DT support to GPIO driver
On 03/22/2013 10:33 AM, Stephen Warren wrote: On 03/22/2013 02:10 AM, Linus Walleij wrote: On Fri, Mar 15, 2013 at 12:21 PM, Javier Martinez Canillas martinez.jav...@gmail.com wrote: diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 159f5c5..f5feb43 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -807,6 +807,13 @@ static void gpio_unmask_irq(struct irq_data *d) spin_unlock_irqrestore(bank-lock, flags); } +static int gpio_irq_request(struct irq_data *d) +{ + struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + + return gpio_request(irq_to_gpio(bank, d-irq), gpio-irq); +} + static struct irq_chip gpio_irq_chip = { .name = GPIO, .irq_shutdown = gpio_irq_shutdown, @@ -815,6 +822,7 @@ static struct irq_chip gpio_irq_chip = { .irq_unmask = gpio_unmask_irq, .irq_set_type = gpio_irq_type, .irq_set_wake = gpio_wake_enable, + .irq_request= gpio_irq_request, }; This is just turning everything on it's head. The normal order of things is this sequence for GPIO 14 something like: gpio_request(14); int irq = gpio_to_irq(14); request_any_context_irq(irq); That doesn't make any sense at all. Drivers don't want to care whether the IRQ number they receive is a GPIO-that-can-act-like-an-IRQ or a pure dedicated IRQ input. To fully support the model you proprose, a driver would have to: if (gpio_is_valid(pdata-gpio)) { gpio_request_one(pdata-gpio, GPIOF_IN, foo irq); irq = gpio_to_irq(pdata-gpio); } else irq = pdata-irq; request_irq(...); which means complex code in each driver, plus requiring some indication in platform data and/or device tree re: whether the IRQ is hosted by a GPIO or not. I tend to agree with Stephen here. When we had discussed this previously you had mentioned about adding a platform function to request the gpio [1], but I could see this adding a bunch more platform files when we are trying to get rid of all the board-xxx.c files for OMAP. So if you don't like the approach suggested by Stephen and implemented by Javier, then may be we need to means to request/reserve gpios in the dts as you had suggested before [1]. So it seems to me that there are two options at the moment ... 1. Add a irq_chip request as suggested by Stephen. 2. Reserve/request gpios in the dts when registering a gpio chip. Cheers Jon [1] http://permalink.gmane.org/gmane.linux.ports.arm.omap/92327 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH V3 2/2] dmaengine: OMAP: Register SDMA controller with Device Tree DMA driver
Vinod, Tony, Benoit, On 02/26/2013 12:27 PM, Jon Hunter wrote: If the device-tree blob is present during boot, then register the SDMA controller with the device-tree DMA driver so that we can use device-tree to look-up DMA client information. Signed-off-by: Jon Hunter jon-hun...@ti.com Reviewed-by: Felipe Balbi ba...@ti.com Acked-by: Santosh Shilimkar santosh.shilim...@ti.com Tested-by: Santosh Shilimkar santosh.shilim...@ti.com --- arch/arm/mach-omap2/dma.c |4 drivers/dma/omap-dma.c| 38 -- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index dab9fc0..49fd0d5 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -28,6 +28,7 @@ #include linux/init.h #include linux/device.h #include linux/dma-mapping.h +#include linux/of.h #include linux/omap-dma.h #include soc.h @@ -304,6 +305,9 @@ static int __init omap2_system_dma_init(void) if (res) return res; + if (of_have_populated_dt()) + return res; + pdev = platform_device_register_full(omap_dma_dev_info); if (IS_ERR(pdev)) return PTR_ERR(pdev); diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index c4b4fd2..2ea3d7e 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -16,6 +16,8 @@ #include linux/platform_device.h #include linux/slab.h #include linux/spinlock.h +#include linux/of_dma.h +#include linux/of_device.h #include virt-dma.h @@ -67,6 +69,10 @@ static const unsigned es_bytes[] = { [OMAP_DMA_DATA_TYPE_S32] = 4, }; +static struct of_dma_filter_info omap_dma_info = { + .filter_fn = omap_dma_filter_fn, +}; + static inline struct omap_dmadev *to_omap_dma_dev(struct dma_device *d) { return container_of(d, struct omap_dmadev, ddev); @@ -621,8 +627,22 @@ static int omap_dma_probe(struct platform_device *pdev) pr_warn(OMAP-DMA: failed to register slave DMA engine device: %d\n, rc); omap_dma_free(od); - } else { - platform_set_drvdata(pdev, od); + return rc; + } + + platform_set_drvdata(pdev, od); + + if (pdev-dev.of_node) { + omap_dma_info.dma_cap = od-ddev.cap_mask; + + /* Device-tree DMA controller registration */ + rc = of_dma_controller_register(pdev-dev.of_node, + of_dma_simple_xlate, omap_dma_info); + if (rc) { + pr_warn(OMAP-DMA: failed to register DMA controller\n); + dma_async_device_unregister(od-ddev); + omap_dma_free(od); + } } dev_info(pdev-dev, OMAP DMA engine driver\n); @@ -634,18 +654,32 @@ static int omap_dma_remove(struct platform_device *pdev) { struct omap_dmadev *od = platform_get_drvdata(pdev); + if (pdev-dev.of_node) + of_dma_controller_free(pdev-dev.of_node); + dma_async_device_unregister(od-ddev); omap_dma_free(od); return 0; } +static const struct of_device_id omap_dma_match[] = { + { .compatible = ti,omap2420-sdma, }, + { .compatible = ti,omap2430-sdma, }, + { .compatible = ti,omap3430-sdma, }, + { .compatible = ti,omap3630-sdma, }, + { .compatible = ti,omap4430-sdma, }, + {}, +}; +MODULE_DEVICE_TABLE(of, omap_dma_match); + static struct platform_driver omap_dma_driver = { .probe = omap_dma_probe, .remove = omap_dma_remove, .driver = { .name = omap-dma-engine, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(omap_dma_match), }, }; Who's tree does it make most sense for this patch to go through? Benoit has queued up patch 1/2 and so I am not sure if this should go via Benoit tree to Tony or directly via Vinod's tree. What are your thoughts? It would be great if this could make v3.10. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 01/18] ARM: OMAP2+: Simplify code configuring ONENAND devices
The OMAP2+ code that configures the GPMC for ONENAND devices is copying structures between functions unnecessarily. Avoid this by passing pointers instead and simplify the code. A pointer to structure omap_onenand_platform_data is passed to the function omap2_onenand_calc_sync_timings(), but only the flags member of the structure is used. Simplify the code by only passing the flags member and not the entire structure. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc-onenand.c | 26 ++ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index 4c91752..db52c4b 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -47,10 +47,9 @@ static struct platform_device gpmc_onenand_device = { .resource = gpmc_onenand_resource, }; -static struct gpmc_timings omap2_onenand_calc_async_timings(void) +static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) { struct gpmc_device_timings dev_t; - struct gpmc_timings t; const int t_cer = 15; const int t_avdp = 12; @@ -76,9 +75,7 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void) dev_t.t_wpl = t_wpl * 1000; dev_t.t_wph = t_wph * 1000; - gpmc_calc_timings(t, dev_t); - - return t; + gpmc_calc_timings(t, dev_t); } static int gpmc_set_async_mode(int cs, struct gpmc_timings *t) @@ -158,12 +155,11 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg, return freq; } -static struct gpmc_timings -omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, - int freq) +static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, + unsigned int flags, + int freq) { struct gpmc_device_timings dev_t; - struct gpmc_timings t; const int t_cer = 15; const int t_avdp = 12; const int t_cez = 20; /* max of t_cez, t_oez */ @@ -172,9 +168,9 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; int div, gpmc_clk_ns; - if (cfg-flags ONENAND_SYNC_READ) + if (flags ONENAND_SYNC_READ) onenand_flags = ONENAND_FLAG_SYNCREAD; - else if (cfg-flags ONENAND_SYNC_READWRITE) + else if (flags ONENAND_SYNC_READWRITE) onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE; switch (freq) { @@ -265,9 +261,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, dev_t.cyc_aavdh_oe = 1; dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; - gpmc_calc_timings(t, dev_t); - - return t; + gpmc_calc_timings(t, dev_t); } static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) @@ -300,7 +294,7 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base) omap2_onenand_set_async_mode(onenand_base); - t = omap2_onenand_calc_async_timings(); + omap2_onenand_calc_async_timings(t); ret = gpmc_set_async_mode(gpmc_onenand_data-cs, t); if (ret 0) @@ -322,7 +316,7 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) set_onenand_cfg(onenand_base); } - t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq); + omap2_onenand_calc_sync_timings(t, gpmc_onenand_data-flags, freq); ret = gpmc_set_sync_mode(gpmc_onenand_data-cs, t); if (ret 0) -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 00/18] ARM: OMAP2+: GPMC clean-up and DT update
While adding device-tree support for NOR memories, it became apparent that there is no common way for configuring various GPMC settings for devices that interface to the GPMC. These settings include bus-width, synchronous/asynchronous mode, burst settings, wait monitoring etc. Therefore, to simplify the GPMC code and add device-tree support for NOR, it was first necessary to consolidate how these settings are programmed. Series based upon Mark Jackson's patch [1] and Ezequiel Garcia GPMC clean-up series [2]. Entire series available here [3]. V4 changes: - Updated to v3.9-rc3 and fixed merge issue reported in V3 by Ezequiel. - Fixed-up comments reported by Ezequiel. - Made use of of_property_read_bool() as suggested by Rob Herring. - Added -ps and -ns suffixes to GPMC DT timing properties as requested by Rob Herring to make it clearer what the timing values represent. V3 changes: - Rebased on RMK's IS_ERR_VALUE() patch and removed usage of IS_ERR_VALUE() from series. - Fixed BUG in NAND code introduced in V2 by making gpmc_settings structure a local variable (I forgot to initialise structure to zero). - Added fix from Javier to correct return value from gpmc_probe_nor(). V2 changes: - Made gpmc_settings structure local in gpmc_nand_init(). - Use resource_size() API in probe_nor(). - Add kernel-doc for gpmc_cs_program_settings() function. - Use of_platform_device_create() to register NOR devices in probe_nor(). - Add support for GPMC address-address-data multiplexing which required changing GPMC DT property gpmc,mux-add-data to store a 32-bit value and changing mux_add_data member of gpmc_settings to be a 32-bit type instead of bool. - Add detection for incorrect GPMC chip-select base addresses. - Cleaned-up code in gpmc_mem_init() and changed gpmc_mem_init() so that it would not return an error when the GPMC driver is being probed. V1 changes: - Clean-up/simplification of ONENAND initialisation code. - Add a new GPMC structure to unify storage of various GPMC settings (that are non-timing related) for client devices and add a new function to program these settings in a common way. - Migrate initialisation code for existing flash, usb and networking devices to use the new structure and function for GPMC settings. - Add device-tree support for NOR flash memories. - Add additional GPMC timing parameters to GPMC device-tree binding. - Update GPMC NAND and ONENAND device-tree support to retrieve GPMC settings from device-tree. Testing includes: - Boot testing on OMAP2420 H4, OMAP3430 SDP and OMAP4430 SDP with and without device-tree present. - OMAP2420 H4 board has NOR flash and OMAP3430 SDP has NOR, NAND and ONENAND flash. So verified that flash is detected on boot as expected. Note additional patches [4] are required for OMAP2420 H4 and OMAP3430 SDP dts files in order to enable flash memory support. - All of the above boards use GPMC for interfacing to a networking chip and so verified that networking is working wit this series. However, please note that networking is not currently supported on these boards when booting with DT and so networking is only tested without DT. [1] http://permalink.gmane.org/gmane.linux.ports.arm.omap/94765 [2] http://comments.gmane.org/gmane.linux.ports.arm.omap/93784 [3] https://github.com/jonhunter/linux/tree/omap-gpmc-for-v3.10 [4] https://github.com/jonhunter/linux/tree/omap-dt-for-v3.10 Javier Martinez Canillas (1): ARM: OMAP2+: return -ENODEV if GPMC child device creation fails Jon Hunter (17): ARM: OMAP2+: Simplify code configuring ONENAND devices ARM: OMAP2+: Add variable to store number of GPMC waitpins ARM: OMAP2+: Add structure for storing GPMC settings ARM: OMAP2+: Add function for configuring GPMC settings ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings() ARM: OMAP2+: Convert NAND to use gpmc_cs_program_settings() ARM: OMAP2+: Convert SMC91x to use gpmc_cs_program_settings() ARM: OMAP2+: Convert TUSB to use gpmc_cs_program_settings() ARM: OMAP2+: Don't configure of chip-select options in gpmc_cs_configure() ARM: OMAP2+: Add function to read GPMC settings from device-tree ARM: OMAP2+: Add additional GPMC timing parameters ARM: OMAP2+: Add device-tree support for NOR flash ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT ARM: OMAP2+: Convert ONENAND to retrieve GPMC settings from DT ARM: OMAP2+: Detect incorrectly aligned GPMC base address ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails Documentation/devicetree/bindings/bus/ti-gpmc.txt | 103 ++-- Documentation/devicetree/bindings/mtd/gpmc-nor.txt | 98 .../devicetree/bindings/mtd/gpmc-onenand.txt |3 + arch/arm/mach-omap2/gpmc-nand.c| 39 +- arch/arm/mach-omap2/gpmc-onenand.c | 110 +++-- arch/arm/mach-omap2/gpmc-smc91x.c | 30 +- arch/arm/mach
[PATCH V4 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins
The GPMC has wait-pin signals that can be assigned to a chip-select to monitor the ready signal of an external device. Add a variable to indicate the total number of wait-pins for a given device. This will allow us to detect if the wait-pin being selected is valid or not. When booting with device-tree read the number of wait-pins from the device-tree blob. When device-tree is not used set the number of wait-pins to 4 which is valid for OMAP2-5 devices. Newer devices that have less wait-pins (such as AM335x) only support booting with device-tree and so hard-coding the wait-pin number when not using device-tree is fine. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc.c | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 586dba7..8833c34 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -108,6 +108,8 @@ #defineGPMC_HAS_WR_ACCESS 0x1 #defineGPMC_HAS_WR_DATA_MUX_BUS0x2 +#define GPMC_NR_WAITPINS 4 + /* XXX: Only NAND irq has been considered,currently these are the only ones used */ #defineGPMC_NR_IRQ 2 @@ -153,6 +155,7 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); /* Define chip-selects as reserved by default until probe completes */ static unsigned int gpmc_cs_map = ((1 GPMC_CS_NUM) - 1); +static unsigned int gpmc_nr_waitpins; static struct device *gpmc_dev; static int gpmc_irq; static resource_size_t phys_base, mem_size; @@ -1294,6 +1297,13 @@ static int gpmc_probe_dt(struct platform_device *pdev) if (!of_id) return 0; + ret = of_property_read_u32(pdev-dev.of_node, gpmc,num-waitpins, + gpmc_nr_waitpins); + if (ret 0) { + pr_err(%s: number of wait pins not found!\n, __func__); + return ret; + } + for_each_node_by_name(child, nand) { ret = gpmc_probe_nand_child(pdev, child); if (ret 0) { @@ -1372,6 +1382,9 @@ static int gpmc_probe(struct platform_device *pdev) /* Now the GPMC is initialised, unreserve the chip-selects */ gpmc_cs_map = 0; + if (!pdev-dev.of_node) + gpmc_nr_waitpins = GPMC_NR_WAITPINS; + rc = gpmc_probe_dt(pdev); if (rc 0) { clk_disable_unprepare(gpmc_l3_clk); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 04/18] ARM: OMAP2+: Add function for configuring GPMC settings
The GPMC has various different configuration options such as bus-width, synchronous or asychronous mode selection, burst mode options etc. Currently, there is no common function for configuring these options and various devices set these options by either programming the GPMC CONFIG1 register directly or by calling gpmc_cs_configure() to set some of the options. Add a new function for configuring all of the GPMC options. Having a common function for configuring this options will simplify code and ease the migration to device-tree. Also add a new capability flag to detect devices that support the address-address-data multiplexing mode. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc.c | 100 arch/arm/mach-omap2/gpmc.h |6 +++ 2 files changed, 106 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 20747fb..ee5d0e9 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -107,6 +107,7 @@ #defineGPMC_HAS_WR_ACCESS 0x1 #defineGPMC_HAS_WR_DATA_MUX_BUS0x2 +#defineGPMC_HAS_MUX_AAD0x4 #define GPMC_NR_WAITPINS 4 @@ -1126,6 +1127,90 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t, return 0; } +/** + * gpmc_cs_program_settings - programs non-timing related settings + * @cs:GPMC chip-select to program + * @p: pointer to GPMC settings structure + * + * Programs non-timing related settings for a GPMC chip-select, such as + * bus-width, burst configuration, etc. Function should be called once + * for each chip-select that is being used and must be called before + * calling gpmc_cs_set_timings() as timing parameters in the CONFIG1 + * register will be initialised to zero by this function. Returns 0 on + * success and appropriate negative error code on failure. + */ +int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) +{ + u32 config1; + + if ((!p-device_width) || (p-device_width GPMC_DEVWIDTH_16BIT)) { + pr_err(%s: invalid width %d!, __func__, p-device_width); + return -EINVAL; + } + + /* Address-data multiplexing not supported for NAND devices */ + if (p-device_nand p-mux_add_data) { + pr_err(%s: invalid configuration!\n, __func__); + return -EINVAL; + } + + if ((p-mux_add_data GPMC_MUX_AD) || + ((p-mux_add_data == GPMC_MUX_AAD) +!(gpmc_capability GPMC_HAS_MUX_AAD))) { + pr_err(%s: invalid multiplex configuration!\n, __func__); + return -EINVAL; + } + + /* Page/burst mode supports lengths of 4, 8 and 16 bytes */ + if (p-burst_read || p-burst_write) { + switch (p-burst_len) { + case GPMC_BURST_4: + case GPMC_BURST_8: + case GPMC_BURST_16: + break; + default: + pr_err(%s: invalid page/burst-length (%d)\n, + __func__, p-burst_len); + return -EINVAL; + } + } + + if ((p-wait_on_read || p-wait_on_write) + (p-wait_pin gpmc_nr_waitpins)) { + pr_err(%s: invalid wait-pin (%d)\n, __func__, p-wait_pin); + return -EINVAL; + } + + config1 = GPMC_CONFIG1_DEVICESIZE((p-device_width - 1)); + + if (p-sync_read) + config1 |= GPMC_CONFIG1_READTYPE_SYNC; + if (p-sync_write) + config1 |= GPMC_CONFIG1_WRITETYPE_SYNC; + if (p-wait_on_read) + config1 |= GPMC_CONFIG1_WAIT_READ_MON; + if (p-wait_on_write) + config1 |= GPMC_CONFIG1_WAIT_WRITE_MON; + if (p-wait_on_read || p-wait_on_write) + config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p-wait_pin); + if (p-device_nand) + config1 |= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND); + if (p-mux_add_data) + config1 |= GPMC_CONFIG1_MUXTYPE(p-mux_add_data); + if (p-burst_read) + config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP; + if (p-burst_write) + config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP; + if (p-burst_read || p-burst_write) { + config1 |= GPMC_CONFIG1_PAGE_LEN(p-burst_len 3); + config1 |= p-burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0; + } + + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1); + + return 0; +} + #ifdef CONFIG_OF static struct of_device_id gpmc_dt_ids[] = { { .compatible = ti,omap2420-gpmc }, @@ -1372,8 +1457,23 @@ static int gpmc_probe(struct platform_device *pdev) gpmc_dev = pdev-dev; l = gpmc_read_reg(GPMC_REVISION); + + /* +* FIXME: Once device-tree migration is complete the below flags
[PATCH V4 03/18] ARM: OMAP2+: Add structure for storing GPMC settings
The GPMC has various different configuration options such as bus-width, synchronous or asychronous mode selection, burst mode options etc. Currently, there is no central structure for storing all these options when configuring the GPMC for a given device. Some of the options are stored in the GPMC timing structure and some are directly programmed into the GPMC configuration register. Add a new structure to store these options and convert code to use this structure. Adding this structure will allow us to create a common function for configuring these options. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc-onenand.c | 18 ++- arch/arm/mach-omap2/gpmc-smc91x.c |2 +- arch/arm/mach-omap2/gpmc.c | 45 +--- arch/arm/mach-omap2/gpmc.h | 28 -- arch/arm/mach-omap2/usb-tusb6010.c | 19 --- 5 files changed, 72 insertions(+), 40 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index db52c4b..e175ceb 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -47,6 +47,15 @@ static struct platform_device gpmc_onenand_device = { .resource = gpmc_onenand_resource, }; +static struct gpmc_settings onenand_async = { + .mux_add_data = GPMC_MUX_AD, +}; + +static struct gpmc_settings onenand_sync = { + .burst_read = true, + .mux_add_data = GPMC_MUX_AD, +}; + static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) { struct gpmc_device_timings dev_t; @@ -63,7 +72,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) memset(dev_t, 0, sizeof(dev_t)); - dev_t.mux = true; dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000; dev_t.t_avdp_w = dev_t.t_avdp_r; dev_t.t_aavdh = t_aavdh * 1000; @@ -75,7 +83,7 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) dev_t.t_wpl = t_wpl * 1000; dev_t.t_wph = t_wph * 1000; - gpmc_calc_timings(t, dev_t); + gpmc_calc_timings(t, onenand_async, dev_t); } static int gpmc_set_async_mode(int cs, struct gpmc_timings *t) @@ -235,10 +243,8 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, /* Set synchronous read timings */ memset(dev_t, 0, sizeof(dev_t)); - dev_t.mux = true; - dev_t.sync_read = true; if (onenand_flags ONENAND_FLAG_SYNCWRITE) { - dev_t.sync_write = true; + onenand_sync.sync_write = true; } else { dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; dev_t.t_wpl = t_wpl * 1000; @@ -261,7 +267,7 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, dev_t.cyc_aavdh_oe = 1; dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; - gpmc_calc_timings(t, dev_t); + gpmc_calc_timings(t, onenand_sync, dev_t); } static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c index 11d0b75..4b78338 100644 --- a/arch/arm/mach-omap2/gpmc-smc91x.c +++ b/arch/arm/mach-omap2/gpmc-smc91x.c @@ -104,7 +104,7 @@ static int smc91c96_gpmc_retime(void) dev_t.t_cez_w = t4_w * 1000; dev_t.t_wr_cycle = (t20 - t3) * 1000; - gpmc_calc_timings(t, dev_t); + gpmc_calc_timings(t, NULL, dev_t); return gpmc_cs_set_timings(gpmc_cfg-cs, t); } diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 8833c34..20747fb 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -817,9 +817,9 @@ static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) /* XXX: can the cycles be avoided ? */ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool mux) { - bool mux = dev_t-mux; u32 temp; /* adv_rd_off */ @@ -872,9 +872,9 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, } static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool mux) { - bool mux = dev_t-mux; u32 temp; /* adv_wr_off */ @@ -934,9 +934,9 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, } static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t
[PATCH V4 05/18] ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings()
Convert the OMAP2+ ONENAND code to use the gpmc_cs_program_settings() function for configuring the various GPMC options instead of directly programming the CONFIG1 register. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc-onenand.c | 61 +++- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index e175ceb..46aac83 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -48,18 +48,22 @@ static struct platform_device gpmc_onenand_device = { }; static struct gpmc_settings onenand_async = { + .device_width = GPMC_DEVWIDTH_16BIT, .mux_add_data = GPMC_MUX_AD, }; static struct gpmc_settings onenand_sync = { .burst_read = true, + .burst_wrap = true, + .burst_len = GPMC_BURST_16, + .device_width = GPMC_DEVWIDTH_16BIT, .mux_add_data = GPMC_MUX_AD, + .wait_pin = 0, }; static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) { struct gpmc_device_timings dev_t; - const int t_cer = 15; const int t_avdp = 12; const int t_aavdh = 7; @@ -86,16 +90,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) gpmc_calc_timings(t, onenand_async, dev_t); } -static int gpmc_set_async_mode(int cs, struct gpmc_timings *t) -{ - /* Configure GPMC for asynchronous read */ - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, - GPMC_CONFIG1_DEVICESIZE_16 | - GPMC_CONFIG1_MUXADDDATA); - - return gpmc_cs_set_timings(cs, t); -} - static void omap2_onenand_set_async_mode(void __iomem *onenand_base) { u32 reg; @@ -243,8 +237,11 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, /* Set synchronous read timings */ memset(dev_t, 0, sizeof(dev_t)); + if (onenand_flags ONENAND_FLAG_SYNCREAD) + onenand_sync.sync_read = true; if (onenand_flags ONENAND_FLAG_SYNCWRITE) { onenand_sync.sync_write = true; + onenand_sync.burst_write = true; } else { dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; dev_t.t_wpl = t_wpl * 1000; @@ -270,29 +267,6 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, gpmc_calc_timings(t, onenand_sync, dev_t); } -static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) -{ - unsigned sync_read = onenand_flags ONENAND_FLAG_SYNCREAD; - unsigned sync_write = onenand_flags ONENAND_FLAG_SYNCWRITE; - - /* Configure GPMC for synchronous read */ - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, - GPMC_CONFIG1_WRAPBURST_SUPP | - GPMC_CONFIG1_READMULTIPLE_SUPP | - (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) | - (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) | - (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) | - GPMC_CONFIG1_PAGE_LEN(2) | - (cpu_is_omap34xx() ? 0 : - (GPMC_CONFIG1_WAIT_READ_MON | -GPMC_CONFIG1_WAIT_PIN_SEL(0))) | - GPMC_CONFIG1_DEVICESIZE_16 | - GPMC_CONFIG1_DEVICETYPE_NOR | - GPMC_CONFIG1_MUXADDDATA); - - return gpmc_cs_set_timings(cs, t); -} - static int omap2_onenand_setup_async(void __iomem *onenand_base) { struct gpmc_timings t; @@ -302,7 +276,11 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base) omap2_onenand_calc_async_timings(t); - ret = gpmc_set_async_mode(gpmc_onenand_data-cs, t); + ret = gpmc_cs_program_settings(gpmc_onenand_data-cs, onenand_async); + if (ret 0) + return ret; + + ret = gpmc_cs_set_timings(gpmc_onenand_data-cs, t); if (ret 0) return ret; @@ -322,9 +300,20 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) set_onenand_cfg(onenand_base); } + /* +* FIXME: Appears to be legacy code from initial ONENAND commit. +* Unclear what boards this is for and if this can be removed. +*/ + if (!cpu_is_omap34xx()) + onenand_sync.wait_on_read = true; + omap2_onenand_calc_sync_timings(t, gpmc_onenand_data-flags, freq); - ret = gpmc_set_sync_mode(gpmc_onenand_data-cs, t); + ret = gpmc_cs_program_settings(gpmc_onenand_data-cs, onenand_sync); + if (ret 0) + return ret; + + ret = gpmc_cs_set_timings(gpmc_onenand_data-cs, t); if (ret 0) return ret; -- 1.7.10.4
[PATCH V4 06/18] ARM: OMAP2+: Convert NAND to use gpmc_cs_program_settings()
Convert the OMAP2+ NAND code to use the gpmc_cs_program_settings() function for configuring the various GPMC options instead of directly programming the CONFIG1 register. This moves the configuration of some GPMC options outside the nand_gpmc_retime() because these options should only need to be set once regardless of whether the gpmc timing is changing dynamically at runtime. The programming of where the wait-pin is also moved slightly, but this will not have any impact to existing devices as no boards are currently setting the dev_ready variable. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc-nand.c | 35 +++ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index e50e438..75feb95 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -74,14 +74,6 @@ static int omap2_nand_gpmc_retime( t.cs_wr_off = gpmc_t-cs_wr_off; t.wr_cycle = gpmc_t-wr_cycle; - /* Configure GPMC */ - if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16) - gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 1); - else - gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 0); - gpmc_cs_configure(gpmc_nand_data-cs, - GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND); - gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_WP, 0); err = gpmc_cs_set_timings(gpmc_nand_data-cs, t); if (err) return err; @@ -115,8 +107,11 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, struct gpmc_timings *gpmc_t) { int err = 0; + struct gpmc_settings s; struct device *dev = gpmc_nand_device.dev; + memset(s, 0, sizeof(struct gpmc_settings)); + gpmc_nand_device.dev.platform_data = gpmc_nand_data; err = gpmc_cs_request(gpmc_nand_data-cs, NAND_IO_SIZE, @@ -141,11 +136,27 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, dev_err(dev, Unable to set gpmc timings: %d\n, err); return err; } - } - /* Enable RD PIN Monitoring Reg */ - if (gpmc_nand_data-dev_ready) { - gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_RDY_BSY, 1); + s.device_nand = true; + + /* Enable RD PIN Monitoring Reg */ + if (gpmc_nand_data-dev_ready) { + s.wait_on_read = true; + s.wait_on_write = true; + } + + if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16) + s.device_width = GPMC_DEVWIDTH_16BIT; + else + s.device_width = GPMC_DEVWIDTH_8BIT; + + err = gpmc_cs_program_settings(gpmc_nand_data-cs, s); + if (err 0) + goto out_free_cs; + + err = gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_WP, 0); + if (err 0) + goto out_free_cs; } gpmc_update_nand_reg(gpmc_nand_data-reg, gpmc_nand_data-cs); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 08/18] ARM: OMAP2+: Convert TUSB to use gpmc_cs_program_settings()
Convert the OMAP2+ TUSB code to use the gpmc_cs_program_settings() function for configuring the various GPMC options instead of directly programming the CONFIG1 register. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/usb-tusb6010.c | 43 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index faaf96d..e832bc7 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include linux/err.h #include linux/string.h #include linux/types.h #include linux/errno.h @@ -27,12 +28,21 @@ static u8 async_cs, sync_cs; static unsignedrefclk_psec; static struct gpmc_settings tusb_async = { + .wait_on_read = true, + .wait_on_write = true, + .device_width = GPMC_DEVWIDTH_16BIT, .mux_add_data = GPMC_MUX_AD, }; static struct gpmc_settings tusb_sync = { + .burst_read = true, + .burst_write= true, .sync_read = true, .sync_write = true, + .wait_on_read = true, + .wait_on_write = true, + .burst_len = GPMC_BURST_16, + .device_width = GPMC_DEVWIDTH_16BIT, .mux_add_data = GPMC_MUX_AD, }; @@ -168,18 +178,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, return status; } tusb_resources[0].end = tusb_resources[0].start + 0x9ff; + tusb_async.wait_pin = waitpin; async_cs = async; - gpmc_cs_write_reg(async, GPMC_CS_CONFIG1, - GPMC_CONFIG1_PAGE_LEN(2) - | GPMC_CONFIG1_WAIT_READ_MON - | GPMC_CONFIG1_WAIT_WRITE_MON - | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) - | GPMC_CONFIG1_READTYPE_ASYNC - | GPMC_CONFIG1_WRITETYPE_ASYNC - | GPMC_CONFIG1_DEVICESIZE_16 - | GPMC_CONFIG1_DEVICETYPE_NOR - | GPMC_CONFIG1_MUXADDDATA); + status = gpmc_cs_program_settings(async_cs, tusb_async); + if (status 0) + return status; /* SYNC region, primarily for DMA */ status = gpmc_cs_request(sync, SZ_16M, (unsigned long *) @@ -189,21 +193,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, return status; } tusb_resources[1].end = tusb_resources[1].start + 0x9ff; + tusb_sync.wait_pin = waitpin; sync_cs = sync; - gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1, - GPMC_CONFIG1_READMULTIPLE_SUPP - | GPMC_CONFIG1_READTYPE_SYNC - | GPMC_CONFIG1_WRITEMULTIPLE_SUPP - | GPMC_CONFIG1_WRITETYPE_SYNC - | GPMC_CONFIG1_PAGE_LEN(2) - | GPMC_CONFIG1_WAIT_READ_MON - | GPMC_CONFIG1_WAIT_WRITE_MON - | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) - | GPMC_CONFIG1_DEVICESIZE_16 - | GPMC_CONFIG1_DEVICETYPE_NOR - | GPMC_CONFIG1_MUXADDDATA - /* fclk divider gets set later */ - ); + + status = gpmc_cs_program_settings(sync_cs, tusb_sync); + if (status 0) + return status; /* IRQ */ status = gpio_request_one(irq, GPIOF_IN, TUSB6010 irq); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 09/18] ARM: OMAP2+: Don't configure of chip-select options in gpmc_cs_configure()
With the addition of the gpmc_cs_program_settings(), we no longer need or use gpmc_cs_configure() to configure some of the GPMC chip-select options. So rename the function to gpmc_configure() and remove code that modifies options in the CONFIG1 register. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc-nand.c |2 +- arch/arm/mach-omap2/gpmc.c | 49 ++- arch/arm/mach-omap2/gpmc.h |5 +--- 3 files changed, 9 insertions(+), 47 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index 75feb95..12e9753 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -154,7 +154,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, if (err 0) goto out_free_cs; - err = gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_WP, 0); + err = gpmc_configure(GPMC_CONFIG_WP, 0); if (err 0) goto out_free_cs; } diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ee5d0e9..b22771b 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -550,16 +550,14 @@ void gpmc_cs_free(int cs) EXPORT_SYMBOL(gpmc_cs_free); /** - * gpmc_cs_configure - write request to configure gpmc - * @cs: chip select number + * gpmc_configure - write request to configure gpmc * @cmd: command type * @wval: value to write * @return status of the operation */ -int gpmc_cs_configure(int cs, int cmd, int wval) +int gpmc_configure(int cmd, int wval) { - int err = 0; - u32 regval = 0; + u32 regval; switch (cmd) { case GPMC_ENABLE_IRQ: @@ -579,47 +577,14 @@ int gpmc_cs_configure(int cs, int cmd, int wval) gpmc_write_reg(GPMC_CONFIG, regval); break; - case GPMC_CONFIG_RDY_BSY: - regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - if (wval) - regval |= WR_RD_PIN_MONITORING; - else - regval = ~WR_RD_PIN_MONITORING; - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); - break; - - case GPMC_CONFIG_DEV_SIZE: - regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - - /* clear 2 target bits */ - regval = ~GPMC_CONFIG1_DEVICESIZE(3); - - /* set the proper value */ - regval |= GPMC_CONFIG1_DEVICESIZE(wval); - - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); - break; - - case GPMC_CONFIG_DEV_TYPE: - regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - /* clear 4 target bits */ - regval = ~(GPMC_CONFIG1_DEVICETYPE(3) | - GPMC_CONFIG1_MUXTYPE(3)); - /* set the proper value */ - regval |= GPMC_CONFIG1_DEVICETYPE(wval); - if (wval == GPMC_DEVICETYPE_NOR) - regval |= GPMC_CONFIG1_MUXADDDATA; - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); - break; - default: - printk(KERN_ERR gpmc_configure_cs: Not supported\n); - err = -EINVAL; + pr_err(%s: command not supported\n, __func__); + return -EINVAL; } - return err; + return 0; } -EXPORT_SYMBOL(gpmc_cs_configure); +EXPORT_SYMBOL(gpmc_configure); void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) { diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h index ce6ae21..87d2a22 100644 --- a/arch/arm/mach-omap2/gpmc.h +++ b/arch/arm/mach-omap2/gpmc.h @@ -59,9 +59,6 @@ #define GPMC_CONFIG1_DEVICETYPE(val)((val 3) 10) #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) #define GPMC_CONFIG1_MUXTYPE(val) ((val 3) 8) -#define GPMC_CONFIG1_MUXNONMUX GPMC_CONFIG1_MUXTYPE(0) -#define GPMC_CONFIG1_MUXAAD GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AAD) -#define GPMC_CONFIG1_MUXADDDATA GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AD) #define GPMC_CONFIG1_TIME_PARA_GRAN (1 4) #define GPMC_CONFIG1_FCLK_DIV(val) (val 3) #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) @@ -227,6 +224,6 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); extern void gpmc_cs_free(int cs); extern void omap3_gpmc_save_context(void); extern void omap3_gpmc_restore_context(void); -extern int gpmc_cs_configure(int cs, int cmd, int wval); +extern int gpmc_configure(int cmd, int wval); #endif -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 15/18] ARM: OMAP2+: Detect incorrectly aligned GPMC base address
Each GPMC chip-select can be configured to map 16MB, 32MB, 64MB or 128MB of address space. The physical base address where a chip-select starts is also configurable and must be aligned on a boundary that is equal to or greater than the size of the address space mapped bt the chip-select. When enabling a GPMC chip-select, ensure that the base address is aligned to the appropriate boundary. Reported-by: Mark Jackson mpfj-l...@mimc.co.uk Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 94624bf..9797f46 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -403,11 +403,18 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) return 0; } -static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) +static int gpmc_cs_enable_mem(int cs, u32 base, u32 size) { u32 l; u32 mask; + /* +* Ensure that base address is aligned on a +* boundary equal to or greater than size. +*/ + if (base (size - 1)) + return -EINVAL; + mask = (1 GPMC_SECTION_SHIFT) - size; l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); l = ~0x3f; @@ -416,6 +423,8 @@ static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) l |= ((mask GPMC_CHUNK_SHIFT) 0x0f) 8; l |= GPMC_CONFIG7_CSVALID; gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); + + return 0; } static void gpmc_cs_disable_mem(int cs) @@ -526,7 +535,9 @@ static int gpmc_cs_remap(int cs, u32 base) ret = gpmc_cs_insert_mem(cs, base, size); if (ret 0) return ret; - gpmc_cs_enable_mem(cs, base, size); + ret = gpmc_cs_enable_mem(cs, base, size); + if (ret 0) + return ret; return 0; } @@ -556,7 +567,12 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) if (r 0) goto out; - gpmc_cs_enable_mem(cs, res-start, resource_size(res)); + r = gpmc_cs_enable_mem(cs, res-start, resource_size(res)); + if (r 0) { + release_resource(res); + goto out; + } + *base = res-start; gpmc_cs_set_reserved(cs, 1); out: -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 17/18] ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails
When the GPMC driver is probed, we call gpmc_mem_init() to see which chip-selects have already been configured and enabled by the boot-loader and allocate space for them. If we fail to allocate space for one chip-select, then we return failure from the probe and the GPMC driver will not be available. Rather than render the GPMC useless for all GPMC devices, if we fail to allocate space for one chip-select print a warning and disable the chip-select. This way other GPMC clients can still be used. There is no downside to this approach, because all GPMC clients need to request a chip-select before they can use the GPMC and on requesting a chip-select, if memory has not already been reserved for the chip-select then it will be. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc.c | 24 +++- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ebb88cf..9208d8e 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -785,9 +785,9 @@ static void gpmc_mem_exit(void) } -static int gpmc_mem_init(void) +static void gpmc_mem_init(void) { - int cs, rc; + int cs; /* * The first 1MB of GPMC address space is typically mapped to @@ -804,16 +804,12 @@ static int gpmc_mem_init(void) if (!gpmc_cs_mem_enabled(cs)) continue; gpmc_cs_get_memconf(cs, base, size); - rc = gpmc_cs_insert_mem(cs, base, size); - if (rc 0) { - while (--cs = 0) - if (gpmc_cs_mem_enabled(cs)) - gpmc_cs_delete_mem(cs); - return rc; + if (gpmc_cs_insert_mem(cs, base, size)) { + pr_warn(%s: disabling cs %d mapped at 0x%x-0x%x\n, + __func__, cs, base, base + size); + gpmc_cs_disable_mem(cs); } } - - return 0; } static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) @@ -1611,13 +1607,7 @@ static int gpmc_probe(struct platform_device *pdev) dev_info(gpmc_dev, GPMC revision %d.%d\n, GPMC_REVISION_MAJOR(l), GPMC_REVISION_MINOR(l)); - rc = gpmc_mem_init(); - if (rc 0) { - clk_disable_unprepare(gpmc_l3_clk); - clk_put(gpmc_l3_clk); - dev_err(gpmc_dev, failed to reserve memory\n); - return rc; - } + gpmc_mem_init(); if (gpmc_setup_irq() 0) dev_warn(gpmc_dev, gpmc_setup_irq failed\n); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 12/18] ARM: OMAP2+: Add device-tree support for NOR flash
NOR flash is not currently supported when booting with device-tree on OMAP2+ devices. Add support to detect and configure NOR devices when booting with device-tree. Add documentation for the TI GPMC NOR binding. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- Documentation/devicetree/bindings/mtd/gpmc-nor.txt | 98 + arch/arm/mach-omap2/gpmc.c | 115 2 files changed, 213 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt new file mode 100644 index 000..420b3ab --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt @@ -0,0 +1,98 @@ +Device tree bindings for NOR flash connect to TI GPMC + +NOR flash connected to the TI GPMC (found on OMAP boards) are represented as +child nodes of the GPMC controller with a name of nor. + +All timing relevant properties as well as generic GPMC child properties are +explained in a separate documents. Please refer to +Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Required properties: +- bank-width: Width of NOR flash in bytes. GPMC supports 8-bit and + 16-bit devices and so must be either 1 or 2 bytes. +- compatible: Documentation/devicetree/bindings/mtd/mtd-physmap.txt +- gpmc,cs-on-ns: Chip-select assertion time +- gpmc,cs-rd-off-ns: Chip-select de-assertion time for reads +- gpmc,cs-wr-off-ns: Chip-select de-assertion time for writes +- gpmc,oe-on-ns: Output-enable assertion time +- gpmc,oe-off-ns: Output-enable de-assertion time +- gpmc,we-on-nsWrite-enable assertion time +- gpmc,we-off-ns: Write-enable de-assertion time +- gpmc,access-ns: Start cycle to first data capture (read access) +- gpmc,rd-cycle-ns:Total read cycle time +- gpmc,wr-cycle-ns:Total write cycle time +- linux,mtd-name: Documentation/devicetree/bindings/mtd/mtd-physmap.txt +- reg: Chip-select, base address (relative to chip-select) + and size of NOR flash. Note that base address will be + typically 0 as this is the start of the chip-select. + +Optional properties: +- gpmc,XXX Additional GPMC timings and settings parameters. See + Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Optional properties for partiton table parsing: +- #address-cells: should be set to 1 +- #size-cells: should be set to 1 + +Example: + +gpmc: gpmc@6e00 { + compatible = ti,omap3430-gpmc, simple-bus; + ti,hwmods = gpmc; + reg = 0x6e00 0x1000; + interrupts = 20; + gpmc,num-cs = 8; + gpmc,num-waitpins = 4; + #address-cells = 2; + #size-cells = 1; + + ranges = 0 0 0x1000 0x0800; + + nor@0,0 { + compatible = cfi-flash; + linux,mtd-name= intel,pf48f6000m0y1be; + #address-cells = 1; + #size-cells = 1; + reg = 0 0 0x0800; + bank-width = 2; + + gpmc,mux-add-data; + gpmc,cs-on-ns = 0; + gpmc,cs-rd-off-ns = 186; + gpmc,cs-wr-off-ns = 186; + gpmc,adv-on-ns = 12; + gpmc,adv-rd-off-ns = 48; + gpmc,adv-wr-off-ns = 48; + gpmc,oe-on-ns = 54; + gpmc,oe-off-ns = 168; + gpmc,we-on-ns = 54; + gpmc,we-off-ns = 168; + gpmc,rd-cycle-ns = 186; + gpmc,wr-cycle-ns = 186; + gpmc,access-ns = 114; + gpmc,page-burst-access-ns = 6; + gpmc,bus-turnaround-ns = 12; + gpmc,cycle2cycle-delay-ns = 18; + gpmc,wr-data-mux-bus-ns = 90; + gpmc,wr-access-ns = 186; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + + partition@0 { + label = bootloader-nor; + reg = 0 0x4; + }; + partition@0x4 { + label = params-nor; + reg = 0x4 0x4; + }; + partition@0x8 { + label = kernel-nor; + reg = 0x8 0x20; + }; + partition@0x28 { + label = filesystem-nor; + reg = 0x24 0x7d8; + }; + }; +}; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index a54f14e..94624bf 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -26,6 +26,7 @@ #include linux/interrupt.h #include linux/platform_device.h #include linux/of.h +#include linux/of_address.h #include linux
[PATCH V4 18/18] ARM: OMAP2+: return -ENODEV if GPMC child device creation fails
From: Javier Martinez Canillas javier.marti...@collabora.co.uk gpmc_probe_nor_child() calls of_platform_device_create() to create a platform device for the NOR child. If this function fails the value of ret is returned to the caller but this value is zero since it was assigned the return of a previous call to gpmc_cs_program_settings() that had to succeed or otherwise gpmc_probe_nor_child() would have returned before. This means that if of_platform_device_create() fails, 0 will be returned to the caller instead of an appropriate error code. Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc.c |1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 9208d8e..615da97 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1495,6 +1495,7 @@ static int gpmc_probe_nor_child(struct platform_device *pdev, return 0; dev_err(pdev-dev, failed to create gpmc child %s\n, child-name); + ret = -ENODEV; err: gpmc_cs_free(cs); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 16/18] ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable
With commit 21cc2bd (ARM: OMAP2+: Remove apollon board support) the variable boot_rom_space is now not needed and the code surrounding this variable can be cleaned up and simplified. Remove unnecessary definitions and clean-up the comment as well. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- arch/arm/mach-omap2/gpmc.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 9797f46..ebb88cf 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -92,9 +92,7 @@ #define GPMC_CS_SIZE 0x30 #defineGPMC_BCH_SIZE 0x10 -#define GPMC_MEM_START 0x #define GPMC_MEM_END 0x3FFF -#define BOOT_ROM_SPACE 0x10/* 1MB */ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ #define GPMC_SECTION_SHIFT 28 /* 128 MB */ @@ -790,13 +788,13 @@ static void gpmc_mem_exit(void) static int gpmc_mem_init(void) { int cs, rc; - unsigned long boot_rom_space = 0; - /* never allocate the first page, to facilitate bug detection; -* even if we didn't boot from ROM. + /* +* The first 1MB of GPMC address space is typically mapped to +* the internal ROM. Never allocate the first page, to +* facilitate bug detection; even if we didn't boot from ROM. */ - boot_rom_space = BOOT_ROM_SPACE; - gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; + gpmc_mem_root.start = SZ_1M; gpmc_mem_root.end = GPMC_MEM_END; /* Reserve all regions that has been set up by bootloader */ -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V4 11/18] ARM: OMAP2+: Add additional GPMC timing parameters
Some of the GPMC timings parameters are currently missing from the GPMC device-tree binding. Add these parameters to the binding documentation as well as code to read them. Also add either -ps or -ns suffix to the GPMC timing properties to indicate whether the timing is in picoseconds or nanoseconds. The existing code in gpmc_read_timings_dt() is checking the value of of_property_read_u32() and only is successful storing the value read in the gpmc_timings structure. Checking the return value in this case is not necessary and we can simply read the value, if present, and store directly in the gpmc_timings structure. Therefore, simplify the code by removing these checks. The comment in the gpmc_read_timings_dt() function, only for OMAP3430 is also incorrect as it is applicable to all OMAP3+ devices. So correct this too. Signed-off-by: Jon Hunter jon-hun...@ti.com Tested-by: Ezequiel Garcia ezequiel.gar...@free-electrons.com --- Documentation/devicetree/bindings/bus/ti-gpmc.txt | 78 +++-- arch/arm/mach-omap2/gpmc.c| 94 ++--- 2 files changed, 98 insertions(+), 74 deletions(-) diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 6fde1cf..4b87ea1 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -35,35 +35,59 @@ Required properties: Timing properties for child nodes. All are optional and default to 0. - - gpmc,sync-clk: Minimum clock period for synchronous mode, in picoseconds - - Chip-select signal timings corresponding to GPMC_CONFIG2: - - gpmc,cs-on: Assertion time - - gpmc,cs-rd-off: Read deassertion time - - gpmc,cs-wr-off: Write deassertion time - - ADV signal timings corresponding to GPMC_CONFIG3: - - gpmc,adv-on:Assertion time - - gpmc,adv-rd-off:Read deassertion time - - gpmc,adv-wr-off:Write deassertion time - - WE signals timings corresponding to GPMC_CONFIG4: - - gpmc,we-on: Assertion time - - gpmc,we-off:Deassertion time - - OE signals timings corresponding to GPMC_CONFIG4: - - gpmc,oe-on: Assertion time - - gpmc,oe-off:Deassertion time - - Access time and cycle time timings corresponding to GPMC_CONFIG5: - - gpmc,page-burst-access: Multiple access word delay - - gpmc,access:Start-cycle to first data valid delay - - gpmc,rd-cycle: Total read cycle time - - gpmc,wr-cycle: Total write cycle time + - gpmc,sync-clk-ps: Minimum clock period for synchronous mode, in picoseconds + + Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2: + - gpmc,cs-on-ns: Assertion time + - gpmc,cs-rd-off-ns: Read deassertion time + - gpmc,cs-wr-off-ns: Write deassertion time + + ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3: + - gpmc,adv-on-ns: Assertion time + - gpmc,adv-rd-off-ns: Read deassertion time + - gpmc,adv-wr-off-ns: Write deassertion time + + WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: + - gpmc,we-on-ns Assertion time + - gpmc,we-off-ns: Deassertion time + + OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: + - gpmc,oe-on-ns: Assertion time + - gpmc,oe-off-ns: Deassertion time + + Access time and cycle time timings (in nanoseconds) corresponding to + GPMC_CONFIG5: + - gpmc,page-burst-access-ns: Multiple access word delay + - gpmc,access-ns: Start-cycle to first data valid delay + - gpmc,rd-cycle-ns: Total read cycle time + - gpmc,wr-cycle-ns: Total write cycle time + - gpmc,bus-turnaround-ns: Turn-around time between successive accesses + - gpmc,cycle2cycle-delay-ns: Delay between chip-select pulses + - gpmc,clk-activation-ns: GPMC clock activation time + - gpmc,wait-monitoring-ns:Start of wait monitoring with regard to valid + data + +Boolean timing parameters. If property is present parameter enabled and +disabled if omitted: + - gpmc,adv-extra-delay: ADV signal is delayed by half GPMC clock + - gpmc,cs-extra-delay:CS signal is delayed by half GPMC clock + - gpmc,cycle2cycle-diffcsen: Add cycle2cycle-delay between successive + accesses to a different CS + - gpmc,cycle2cycle-samecsen: Add cycle2cycle-delay between successive + accesses to the same CS + - gpmc,oe-extra-delay:OE signal is delayed by half GPMC clock + - gpmc,we-extra-delay:WE signal is delayed by half GPMC clock + - gpmc,time-para-granularity: Multiply all access times by 2 The following are only applicable to OMAP3+ and AM335x: - - gpmc,wr-access - - gpmc,wr-data-mux-bus + - gpmc,wr-access-ns: In synchronous write mode, for single or + burst accesses, defines the number
[PATCH 0/5] ARM: OMAP: DMTIMER updates for v3.10
Includes: - A couple fixes for DMTIMER context loss handling. - Populating DMTIMER errata when booting with device-tree. - A new function for requesting a DMTIMER by device-tree node. Based upon v3.9-rc3. Tested on OMAP5912 OSK, OMAP2420 H4, OMAP3430 SDP, OMAP4430 Blaze and AM335x EVM. Testing includes ... 1. Booting kernel on above boards 2. Testing of various DMTIMER request APIs 3. Testing the timer overflow and match interrupts. 4. Using different clock sources to operate the timer with. Jon Hunter (4): ARM: OMAP: Force dmtimer restore if context loss is not detectable ARM: OMAP: Add function to request timer by node ARM: dts: OMAP2+: Update DMTIMER compatibility property ARM: OMAP2+: Populate DMTIMER errata when using device-tree NeilBrown (1): ARM: OMAP: Simplify dmtimer context-loss handling .../devicetree/bindings/arm/omap/timer.txt | 17 +- arch/arm/boot/dts/am33xx.dtsi | 14 +- arch/arm/boot/dts/omap2.dtsi | 22 +- arch/arm/boot/dts/omap2420.dtsi|2 +- arch/arm/boot/dts/omap2430.dtsi|2 +- arch/arm/boot/dts/omap3.dtsi | 24 +- arch/arm/boot/dts/omap4.dtsi | 22 +- arch/arm/boot/dts/omap5.dtsi | 22 +- arch/arm/mach-omap2/timer.c|7 +- arch/arm/plat-omap/dmtimer.c | 241 arch/arm/plat-omap/include/plat/dmtimer.h |1 + 11 files changed, 220 insertions(+), 154 deletions(-) -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 2/5] ARM: OMAP: Force dmtimer restore if context loss is not detectable
When booting with device-tree the function pointer for detecting context loss is not populated. Ideally, the pm_runtime framework should be enhanced to allow a means for reporting context/state loss and we could avoid populating such function pointers altogether. In the interim until a generic non-device specific solution is in place, force a restore of the dmtimer when enabling the timer. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/plat-omap/dmtimer.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 5cae1dd..725d972 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -326,6 +326,8 @@ void omap_dm_timer_enable(struct omap_dm_timer *timer) omap_timer_restore_context(timer); timer-ctx_loss_count = c; } + } else { + omap_timer_restore_context(timer); } } } -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 1/5] ARM: OMAP: Simplify dmtimer context-loss handling
From: NeilBrown ne...@suse.de The context loss handling in dmtimer appears to assume that omap_dm_timer_set_load_start() or omap_dm_timer_start() and omap_dm_timer_stop() bracket all interactions. Only the first two restore the context and the last updates the context loss counter. However omap_dm_timer_set_load() or omap_dm_timer_set_match() can reasonably be called outside this bracketing, and the fact that they call omap_dm_timer_enable() / omap_dm_timer_disable() suggest that is expected. So if, after a transition into and out of off-mode which would cause the dm timer to loose all state, omap_dm_timer_set_match() is called before omap_dm_timer_start(), the value read from OMAP_TIMER_CTRL_REG will be 'wrong' and this wrong value will be stored context.tclr so a subsequent omap_dm_timer_start() can fail (As the control register is wrong). Simplify this be doing the restore-from-context in omap_dm_timer_enable() so that whenever the timer is enabled, the context is correct. Also update the ctx_loss_count at the same time as we notice it is wrong - these is no value in delaying this until the omap_dm_timer_disable() as it cannot change while the timer is enabled. Signed-off-by: NeilBrown ne...@suse.de [jon-hun...@ti.com: minor update to subject and changed variable name] Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/plat-omap/dmtimer.c | 32 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index a0daa2f..5cae1dd 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -315,7 +315,19 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free); void omap_dm_timer_enable(struct omap_dm_timer *timer) { + int c; + pm_runtime_get_sync(timer-pdev-dev); + + if (!(timer-capability OMAP_TIMER_ALWON)) { + if (timer-get_context_loss_count) { + c = timer-get_context_loss_count(timer-pdev-dev); + if (c != timer-ctx_loss_count) { + omap_timer_restore_context(timer); + timer-ctx_loss_count = c; + } + } + } } EXPORT_SYMBOL_GPL(omap_dm_timer_enable); @@ -410,13 +422,6 @@ int omap_dm_timer_start(struct omap_dm_timer *timer) omap_dm_timer_enable(timer); - if (!(timer-capability OMAP_TIMER_ALWON)) { - if (timer-get_context_loss_count - timer-get_context_loss_count(timer-pdev-dev) != - timer-ctx_loss_count) - omap_timer_restore_context(timer); - } - l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); if (!(l OMAP_TIMER_CTRL_ST)) { l |= OMAP_TIMER_CTRL_ST; @@ -441,12 +446,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer) __omap_dm_timer_stop(timer, timer-posted, rate); - if (!(timer-capability OMAP_TIMER_ALWON)) { - if (timer-get_context_loss_count) - timer-ctx_loss_count = - timer-get_context_loss_count(timer-pdev-dev); - } - /* * Since the register values are computed and written within * __omap_dm_timer_stop, we need to use read to retrieve the @@ -553,13 +552,6 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, omap_dm_timer_enable(timer); - if (!(timer-capability OMAP_TIMER_ALWON)) { - if (timer-get_context_loss_count - timer-get_context_loss_count(timer-pdev-dev) != - timer-ctx_loss_count) - omap_timer_restore_context(timer); - } - l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); if (autoreload) { l |= OMAP_TIMER_CTRL_AR; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 5/5] ARM: OMAP2+: Populate DMTIMER errata when using device-tree
Currently the DMTIMER errata flags are not being populated when using device-tree. Add static platform data to populate errata flags when using device-tree. Please note that DMTIMER erratum i767 is applicable to OMAP3-5 devices as well as AM335x devices. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/plat-omap/dmtimer.c | 45 ++ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index b50d478..5d0af13 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -783,6 +783,8 @@ int omap_dm_timers_active(void) } EXPORT_SYMBOL_GPL(omap_dm_timers_active); +static const struct of_device_id omap_timer_match[]; + /** * omap_dm_timer_probe - probe function called for every registered device * @pdev: pointer to current timer platform device @@ -796,7 +798,11 @@ static int omap_dm_timer_probe(struct platform_device *pdev) struct omap_dm_timer *timer; struct resource *mem, *irq; struct device *dev = pdev-dev; - struct dmtimer_platform_data *pdata = pdev-dev.platform_data; + const struct of_device_id *match; + const struct dmtimer_platform_data *pdata; + + match = of_match_device(of_match_ptr(omap_timer_match), dev); + pdata = match ? match-data : dev-platform_data; if (!pdata !dev-of_node) { dev_err(dev, %s: no platform data.\n, __func__); @@ -836,12 +842,14 @@ static int omap_dm_timer_probe(struct platform_device *pdev) timer-capability |= OMAP_TIMER_SECURE; } else { timer-id = pdev-id; - timer-errata = pdata-timer_errata; timer-capability = pdata-timer_capability; timer-reserved = omap_dm_timer_reserved_systimer(timer-id); timer-get_context_loss_count = pdata-get_context_loss_count; } + if (pdata) + timer-errata = pdata-timer_errata; + timer-irq = irq-start; timer-pdev = pdev; @@ -894,13 +902,34 @@ static int omap_dm_timer_remove(struct platform_device *pdev) return ret; } +static const struct dmtimer_platform_data omap3plus_pdata = { + .timer_errata = OMAP_TIMER_ERRATA_I103_I767, +}; + static const struct of_device_id omap_timer_match[] = { - { .compatible = ti,omap2420-timer, }, - { .compatible = ti,omap3430-timer, }, - { .compatible = ti,omap4430-timer, }, - { .compatible = ti,omap5430-timer, }, - { .compatible = ti,am335x-timer, }, - { .compatible = ti,am335x-timer-1ms, }, + { + .compatible = ti,omap2420-timer, + }, + { + .compatible = ti,omap3430-timer, + .data = omap3plus_pdata, + }, + { + .compatible = ti,omap4430-timer, + .data = omap3plus_pdata, + }, + { + .compatible = ti,omap5430-timer, + .data = omap3plus_pdata, + }, + { + .compatible = ti,am335x-timer, + .data = omap3plus_pdata, + }, + { + .compatible = ti,am335x-timer-1ms, + .data = omap3plus_pdata, + }, {}, }; MODULE_DEVICE_TABLE(of, omap_timer_match); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH 3/5] ARM: OMAP: Add function to request timer by node
Add a function so that OMAP dmtimers can be requested by device-tree node. This allows for devices, such as the internal DSP, or drivers, such as PWM, to reference a specific dmtimer node via the device-tree. Given that there are several APIs available for requesting dmtimers (by ID, by capability or by node) consolidate the code for all these functions into a single helper function that can be used by these request functions. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/plat-omap/dmtimer.c | 167 - arch/arm/plat-omap/include/plat/dmtimer.h |1 + 2 files changed, 94 insertions(+), 74 deletions(-) diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 725d972..05efb37 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -52,6 +52,13 @@ static u32 omap_reserved_systimers; static LIST_HEAD(omap_timer_list); static DEFINE_SPINLOCK(dm_timer_lock); +enum { + REQUEST_ANY = 0, + REQUEST_BY_ID, + REQUEST_BY_CAP, + REQUEST_BY_NODE, +}; + /** * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode * @timer: timer pointer over which read operation to perform @@ -178,29 +185,82 @@ int omap_dm_timer_reserve_systimer(int id) return 0; } -struct omap_dm_timer *omap_dm_timer_request(void) +static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data) { struct omap_dm_timer *timer = NULL, *t; + struct device_node *np = NULL; unsigned long flags; - int ret = 0; + u32 cap = 0; + int id = 0; + + switch (req_type) { + case REQUEST_BY_ID: + id = *(int *)data; + break; + case REQUEST_BY_CAP: + cap = *(u32 *)data; + break; + case REQUEST_BY_NODE: + np = (struct device_node *)data; + break; + default: + /* REQUEST_ANY */ + break; + } spin_lock_irqsave(dm_timer_lock, flags); list_for_each_entry(t, omap_timer_list, node) { if (t-reserved) continue; - timer = t; - timer-reserved = 1; - break; + switch (req_type) { + case REQUEST_BY_ID: + if (id == t-pdev-id) { + timer = t; + timer-reserved = 1; + goto found; + } + break; + case REQUEST_BY_CAP: + if (cap == (t-capability cap)) { + /* +* If timer is not NULL, we have already found +* one timer but it was not an exact match +* because it had more capabilites that what +* was required. Therefore, unreserve the last +* timer found and see if this one is a better +* match. +*/ + if (timer) + timer-reserved = 0; + timer = t; + timer-reserved = 1; + + /* Exit loop early if we find an exact match */ + if (t-capability == cap) + goto found; + } + break; + case REQUEST_BY_NODE: + if (np == t-pdev-dev.of_node) { + timer = t; + timer-reserved = 1; + goto found; + } + break; + default: + /* REQUEST_ANY */ + timer = t; + timer-reserved = 1; + goto found; + } } +found: spin_unlock_irqrestore(dm_timer_lock, flags); - if (timer) { - ret = omap_dm_timer_prepare(timer); - if (ret) { - timer-reserved = 0; - timer = NULL; - } + if (timer omap_dm_timer_prepare(timer)) { + timer-reserved = 0; + timer = NULL; } if (!timer) @@ -208,43 +268,23 @@ struct omap_dm_timer *omap_dm_timer_request(void) return timer; } + +struct omap_dm_timer *omap_dm_timer_request(void) +{ + return _omap_dm_timer_request(REQUEST_ANY, NULL); +} EXPORT_SYMBOL_GPL(omap_dm_timer_request); struct omap_dm_timer *omap_dm_timer_request_specific(int id) { - struct omap_dm_timer *timer = NULL, *t; - unsigned long flags; - int ret = 0
[PATCH 4/5] ARM: dts: OMAP2+: Update DMTIMER compatibility property
Update the DMTIMER compatibility property to reflect the register level compatibilty between devices and update the various OMAP/AM timer bindings with the appropriate compatibility string. By doing this we can add platform specific data applicable to specific timer versions to the driver. For example, errata flags can be populated for the timer versions that are impacted. Signed-off-by: Jon Hunter jon-hun...@ti.com --- .../devicetree/bindings/arm/omap/timer.txt | 17 -- arch/arm/boot/dts/am33xx.dtsi | 14 ++-- arch/arm/boot/dts/omap2.dtsi | 22 +- arch/arm/boot/dts/omap2420.dtsi|2 +- arch/arm/boot/dts/omap2430.dtsi|2 +- arch/arm/boot/dts/omap3.dtsi | 24 ++-- arch/arm/boot/dts/omap4.dtsi | 22 +- arch/arm/boot/dts/omap5.dtsi | 22 +- arch/arm/mach-omap2/timer.c|7 +- arch/arm/plat-omap/dmtimer.c |7 +- 10 files changed, 81 insertions(+), 58 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/omap/timer.txt b/Documentation/devicetree/bindings/arm/omap/timer.txt index 8732d4d..d02e27c 100644 --- a/Documentation/devicetree/bindings/arm/omap/timer.txt +++ b/Documentation/devicetree/bindings/arm/omap/timer.txt @@ -1,7 +1,20 @@ OMAP Timer bindings Required properties: -- compatible: Must be ti,omap2-timer for OMAP2+ controllers. +- compatible: Should be set to one of the below. Please note that + OMAP44xx devices have timer instances that are 100% + register compatible with OMAP3xxx devices as well as + newer timers that are not 100% register compatible. + So for OMAP44xx devices timer instances may use + different compatible strings. + + ti,omap2420-timer (applicable to OMAP24xx devices) + ti,omap3430-timer (applicable to OMAP3xxx/44xx devices) + ti,omap4430-timer (applicable to OMAP44xx devices) + ti,omap5430-timer (applicable to OMAP543x devices) + ti,am335x-timer (applicable to AM335x devices) + ti,am335x-timer-1ms (applicable to AM335x devices) + - reg: Contains timer register address range (base address and length). - interrupts: Contains the interrupt information for the timer. The @@ -22,7 +35,7 @@ Optional properties: Example: timer12: timer@48304000 { - compatible = ti,omap2-timer; + compatible = ti,omap3430-timer; reg = 0x48304000 0x400; interrupts = 95; ti,hwmods = timer12 diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 0957645..e82c58d 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -239,7 +239,7 @@ }; timer1: timer@44e31000 { - compatible = ti,omap2-timer; + compatible = ti,am335x-timer-1ms; reg = 0x44e31000 0x400; interrupts = 67; ti,hwmods = timer1; @@ -247,21 +247,21 @@ }; timer2: timer@4804 { - compatible = ti,omap2-timer; + compatible = ti,am335x-timer; reg = 0x4804 0x400; interrupts = 68; ti,hwmods = timer2; }; timer3: timer@48042000 { - compatible = ti,omap2-timer; + compatible = ti,am335x-timer; reg = 0x48042000 0x400; interrupts = 69; ti,hwmods = timer3; }; timer4: timer@48044000 { - compatible = ti,omap2-timer; + compatible = ti,am335x-timer; reg = 0x48044000 0x400; interrupts = 92; ti,hwmods = timer4; @@ -269,7 +269,7 @@ }; timer5: timer@48046000 { - compatible = ti,omap2-timer; + compatible = ti,am335x-timer; reg = 0x48046000 0x400; interrupts = 93; ti,hwmods = timer5; @@ -277,7 +277,7 @@ }; timer6: timer@48048000 { - compatible = ti,omap2-timer; + compatible = ti,am335x-timer; reg = 0x48048000 0x400; interrupts = 94; ti,hwmods = timer6
Re: [PATCH V3 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree
On 03/17/2013 12:24 AM, Ezequiel Garcia wrote: Hi Jon, I have some tiny nitpicks... On Fri, Mar 15, 2013 at 10:21:08AM -0500, Jon Hunter wrote: Adds a function to read the various GPMC chip-select settings from device-tree and store them in the gpmc_settings structure. Update the GPMC device-tree binding documentation to describe these options. Signed-off-by: Jon Hunter jon-hun...@ti.com --- Documentation/devicetree/bindings/bus/ti-gpmc.txt | 23 ++ arch/arm/mach-omap2/gpmc.c| 49 + arch/arm/mach-omap2/gpmc.h|2 + 3 files changed, 74 insertions(+) diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 5ddb2e9..6fde1cf 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -65,6 +65,29 @@ The following are only applicable to OMAP3+ and AM335x: - gpmc,wr-access - gpmc,wr-data-mux-bus +GPMC chip-select settings properties for child nodes. All are optional. + +- gpmc,burst-length Page/burst length. Must be 4, 8 or 16. +- gpmc,burst-wrap Enables wrap bursting +- gpmc,burst-read Enables read page/burst mode +- gpmc,burst-write Enables write page/burst mode +- gpmc,device-nand Device is NAND +- gpmc,device-width Total width of device(s) connected to a GPMC +chip-select in bytes. The GPMC supports 8-bit +and 16-bit devices and so this property must be +1 or 2. +- gpmc,mux-add-data Address and data multiplexing configuration. +Valid values are 1 for address-address-data +multiplexing mode and 2 for address-data +multiplexing mode. +- gpmc,sync-readEnables synchronous read. Defaults to asynchronous +is this is not set. +- gpmc,sync-write Enables synchronous writes. Defaults to asynchronous +is this is not set. +- gpmc,wait-pin Wait-pin used by client. Must be less than +gpmc,num-waitpins. +- gpmc,wait-on-read Enables wait monitoring on reads. +- gpmc,wait-on-writeEnables wait monitoring on writes. Example for an AM33xx board: diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 3ec1937..1e7eef3 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1190,6 +1190,55 @@ static struct of_device_id gpmc_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, gpmc_dt_ids); +/** + * gpmc_read_settings_dt - read gpmc settings from device-tree + * @np: pointer to device-tree node for a gpmc child device + * @p: pointer to gpmc settings structure + * + * Reads the GPMC settings for a GPMC child device from device-tree and + * stores them in the GPMC settings structure passed. The GPMC settings + * structure is initialise to zero by this function and so any previously s/initialise/initialized ? Thanks will add the d. However, initialise is correct British English ;-) + * stored settings will be clearer. s/clearer/cleared ? I'm not an english native speaker, so please bare with me if I'm wrong on these... You are right here too. Will fix thanks! Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH V3 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins
On 03/16/2013 03:59 PM, Ezequiel Garcia wrote: Hi Jon, On Fri, Mar 15, 2013 at 10:21:00AM -0500, Jon Hunter wrote: The GPMC has wait-pin signals that can be assigned to a chip-select to monitor the ready signal of an external device. Add a variable to indicate the total number of wait-pins for a given device. This will allow us to detect if the wait-pin being selected is valid or not. When booting with device-tree read the number of wait-pins from the device-tree blob. When device-tree is not used set the number of wait-pins to 4 which is valid for OMAP2-5 devices. Newer devices that have less wait-pins (such as AM335x) only support booting with device-tree and so hard-coding the wait-pin number when not using device-tree is fine. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc.c | 16 1 file changed, 16 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ef655d9..88a261c 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -108,6 +108,8 @@ #define GPMC_HAS_WR_ACCESS 0x1 #define GPMC_HAS_WR_DATA_MUX_BUS0x2 +#define GPMC_NR_WAITPINS4 + /* XXX: Only NAND irq has been considered,currently these are the only ones used */ #define GPMC_NR_IRQ 2 @@ -153,6 +155,7 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); /* Define chip-selects as reserved by default until probe completes */ static unsigned int gpmc_cs_map = ((1 GPMC_CS_NUM) - 1); +static unsigned int gpmc_nr_waitpins; static struct device *gpmc_dev; static int gpmc_irq; static resource_size_t phys_base, mem_size; @@ -1297,6 +1300,13 @@ static int gpmc_probe_dt(struct platform_device *pdev) if (!of_id) return 0; +ret = of_property_read_u32(pdev-dev.of_node, gpmc,num-waitpins, + gpmc_nr_waitpins); +if (ret 0) { +pr_err(%s: number of wait pins not found!\n, __func__); +return ret; +} + for_each_node_by_name(child, nand) { ret = gpmc_probe_nand_child(pdev, child); if (ret 0) { @@ -1372,6 +1382,12 @@ static int gpmc_probe(struct platform_device *pdev) if (gpmc_setup_irq() 0) dev_warn(gpmc_dev, gpmc_setup_irq failed\n); +/* Now the GPMC is initialised, unreserve the chip-selects */ +gpmc_cs_map = 0; The above seems to be a remanent of another patch. I think you already sent that one, right? Good catch. I will fix this up. Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters
On 03/18/2013 09:07 AM, Rob Herring wrote: On 03/15/2013 10:21 AM, Jon Hunter wrote: Some of the GPMC timings parameters are currently missing from the GPMC device-tree binding. Add these parameters to the binding documentation as well as code to read them. The existing code in gpmc_read_timings_dt() is checking the value of of_property_read_u32() and only is successful storing the value read in the gpmc_timings structure. Checking the return value in this case is not necessary and we can simply read the value, if present, and store directly in the gpmc_timings structure. Therefore, simplify the code by removing these checks. The comment in the gpmc_read_timings_dt() function, only for OMAP3430 is also incorrect as it is applicable to all OMAP3+ devices. So correct this too. Signed-off-by: Jon Hunter jon-hun...@ti.com --- Documentation/devicetree/bindings/bus/ti-gpmc.txt | 25 +- arch/arm/mach-omap2/gpmc.c| 93 ++--- 2 files changed, 66 insertions(+), 52 deletions(-) diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 6fde1cf..a63bd93 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -56,10 +56,27 @@ Timing properties for child nodes. All are optional and default to 0. - gpmc,oe-off: Deassertion time Access time and cycle time timings corresponding to GPMC_CONFIG5: - - gpmc,page-burst-access: Multiple access word delay - - gpmc,access: Start-cycle to first data valid delay - - gpmc,rd-cycle: Total read cycle time - - gpmc,wr-cycle: Total write cycle time + - gpmc,page-burst-access: Multiple access word delay + - gpmc,access: Start-cycle to first data valid delay + - gpmc,rd-cycle: Total read cycle time + - gpmc,wr-cycle: Total write cycle time + - gpmc,bus-turnaround: Turn-around time between successive accesses + - gpmc,cycle2cycle-delay: Delay between chip-select pulses + - gpmc,clk-activation: GPMC clock activation time + - gpmc,wait-monitoring:Start of wait monitoring with regard to valid +data What units are these in? If in nanoseconds, can you append -ns These are cycles. I can update the comment to reflect that. + +Boolean timing parameters. If property is present parameter enabled and +disabled if omitted: + - gpmc,adv-extra-delay:ADV signal is delayed by half GPMC clock + - gpmc,cs-extra-delay: CS signal is delayed by half GPMC clock + - gpmc,cycle2cycle-diffcsen: Add cycle2cycle-delay between successive +accesses to a different CS + - gpmc,cycle2cycle-samecsen: Add cycle2cycle-delay between successive +accesses to the same CS + - gpmc,oe-extra-delay: OE signal is delayed by half GPMC clock + - gpmc,we-extra-delay: WE signal is delayed by half GPMC clock + - gpmc,time-para-granularity: Multiply all access times by 2 The following are only applicable to OMAP3+ and AM335x: - gpmc,wr-access diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 85b1a35..c928a8c 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1274,67 +1274,64 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, struct gpmc_timings *gpmc_t) { -u32 val; - memset(gpmc_t, 0, sizeof(*gpmc_t)); /* minimum clock period for syncronous mode */ -if (!of_property_read_u32(np, gpmc,sync-clk, val)) -gpmc_t-sync_clk = val; +of_property_read_u32(np, gpmc,sync-clk, gpmc_t-sync_clk); /* chip select timtings */ -if (!of_property_read_u32(np, gpmc,cs-on, val)) -gpmc_t-cs_on = val; - -if (!of_property_read_u32(np, gpmc,cs-rd-off, val)) -gpmc_t-cs_rd_off = val; - -if (!of_property_read_u32(np, gpmc,cs-wr-off, val)) -gpmc_t-cs_wr_off = val; +of_property_read_u32(np, gpmc,cs-on, gpmc_t-cs_on); +of_property_read_u32(np, gpmc,cs-rd-off, gpmc_t-cs_rd_off); +of_property_read_u32(np, gpmc,cs-wr-off, gpmc_t-cs_wr_off); /* ADV signal timings */ -if (!of_property_read_u32(np, gpmc,adv-on, val)) -gpmc_t-adv_on = val; - -if (!of_property_read_u32(np, gpmc,adv-rd-off, val)) -gpmc_t-adv_rd_off = val; - -if (!of_property_read_u32(np, gpmc,adv-wr-off, val)) -gpmc_t-adv_wr_off = val; +of_property_read_u32(np, gpmc,adv-on, gpmc_t-adv_on); +of_property_read_u32(np, gpmc,adv-rd-off, gpmc_t-adv_rd_off); +of_property_read_u32(np, gpmc,adv-wr-off, gpmc_t-adv_wr_off
Re: [PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters
On 03/18/2013 09:32 AM, Jon Hunter wrote: On 03/18/2013 09:07 AM, Rob Herring wrote: On 03/15/2013 10:21 AM, Jon Hunter wrote: Some of the GPMC timings parameters are currently missing from the GPMC device-tree binding. Add these parameters to the binding documentation as well as code to read them. The existing code in gpmc_read_timings_dt() is checking the value of of_property_read_u32() and only is successful storing the value read in the gpmc_timings structure. Checking the return value in this case is not necessary and we can simply read the value, if present, and store directly in the gpmc_timings structure. Therefore, simplify the code by removing these checks. The comment in the gpmc_read_timings_dt() function, only for OMAP3430 is also incorrect as it is applicable to all OMAP3+ devices. So correct this too. Signed-off-by: Jon Hunter jon-hun...@ti.com --- Documentation/devicetree/bindings/bus/ti-gpmc.txt | 25 +- arch/arm/mach-omap2/gpmc.c| 93 ++--- 2 files changed, 66 insertions(+), 52 deletions(-) diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 6fde1cf..a63bd93 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -56,10 +56,27 @@ Timing properties for child nodes. All are optional and default to 0. - gpmc,oe-off:Deassertion time Access time and cycle time timings corresponding to GPMC_CONFIG5: - - gpmc,page-burst-access: Multiple access word delay - - gpmc,access:Start-cycle to first data valid delay - - gpmc,rd-cycle: Total read cycle time - - gpmc,wr-cycle: Total write cycle time + - gpmc,page-burst-access: Multiple access word delay + - gpmc,access:Start-cycle to first data valid delay + - gpmc,rd-cycle: Total read cycle time + - gpmc,wr-cycle: Total write cycle time + - gpmc,bus-turnaround:Turn-around time between successive accesses + - gpmc,cycle2cycle-delay: Delay between chip-select pulses + - gpmc,clk-activation:GPMC clock activation time + - gpmc,wait-monitoring: Start of wait monitoring with regard to valid + data What units are these in? If in nanoseconds, can you append -ns These are cycles. I can update the comment to reflect that. Sorry these are nanoseconds. I will update the properties to reflect that. Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V2 0/8] ARM: dts: Various OMAP2+ device-tree updates
Various OMAP device-tree updates for PMU, DMA, GPIO, GPMC and boards. The DMA, PMU and OMAP3430 SDP board changes have been sent before individually but re-sending here as a complete series for v3.10. This is based upon Benoit's for_3.10/dts branch [1]. Branch available here [2]. V2 changes: - Rebased on Benoit's for_3.10/dts branch - Squashed patches adding support for OMAP3430 SDP board and patch to add flash support for OMAP3430 SDP board. [1] http://git.kernel.org/cgit/linux/kernel/git/bcousson/linux-omap-dt.git/log/?h=for_3.10/dts [2] git://github.com/jonhunter/linux.git omap-dt-for-v3.10 Jon Hunter (8): ARM: OMAP2+: Prepare for device-tree PMU support ARM: dts: OMAP2+: Add PMU nodes ARM: dts: OMAP2+: Add SDMA controller bindings and nodes ARM: dts: Add GPMC node for OMAP2, OMAP4 and OMAP5 ARM: dts: Add OMAP2 gpio bindings ARM: dts: OMAP3+: Correct gpio #interrupts-cells property ARM: dts: OMAP3: Add reg and interrupt properties for gpio ARM: dts: OMAP3: Add support for OMAP3430 SDP board arch/arm/boot/dts/Makefile |1 + arch/arm/boot/dts/omap2.dtsi | 17 arch/arm/boot/dts/omap2420.dtsi | 55 + arch/arm/boot/dts/omap2430.dtsi | 66 arch/arm/boot/dts/omap3.dtsi | 70 +++-- arch/arm/boot/dts/omap3430-sdp.dts | 141 ++ arch/arm/boot/dts/omap4-panda-es.dts |2 + arch/arm/boot/dts/omap4.dtsi | 64 +-- arch/arm/boot/dts/omap4460.dtsi | 18 + arch/arm/boot/dts/omap5.dtsi | 68 ++-- arch/arm/mach-omap2/pmu.c| 14 +++- 11 files changed, 493 insertions(+), 23 deletions(-) create mode 100644 arch/arm/boot/dts/omap3430-sdp.dts create mode 100644 arch/arm/boot/dts/omap4460.dtsi -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V2 1/8] ARM: OMAP2+: Prepare for device-tree PMU support
If device-tree is present, then do not create the PMU device from within the OMAP specific PMU code. This is required to allow device-tree to create the PMU device from the PMU device-tree node. PMU is not currently supported for OMAP4430 (due to a dependency on having a cross-trigger interface driver) and so ensure that this indicated on boot with or without device-tree. Signed-off-by: Jon Hunter jon-hun...@ti.com Acked-by: Tony Lindgren t...@atomide.com --- arch/arm/mach-omap2/pmu.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c index 9debf82..9ace8ea 100644 --- a/arch/arm/mach-omap2/pmu.c +++ b/arch/arm/mach-omap2/pmu.c @@ -11,6 +11,8 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ +#include linux/of.h + #include asm/pmu.h #include soc.h @@ -63,6 +65,15 @@ static int __init omap_init_pmu(void) unsigned oh_num; char **oh_names; + /* XXX Remove this check when the CTI driver is available */ + if (cpu_is_omap443x()) { + pr_info(ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n); + return 0; + } + + if (of_have_populated_dt()) + return 0; + /* * To create an ARM-PMU device the following HWMODs * are required for the various OMAP2+ devices. @@ -75,9 +86,6 @@ static int __init omap_init_pmu(void) if (cpu_is_omap443x()) { oh_num = ARRAY_SIZE(omap4430_pmu_oh_names); oh_names = omap4430_pmu_oh_names; - /* XXX Remove the next two lines when CTI driver available */ - pr_info(ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n); - return 0; } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { oh_num = ARRAY_SIZE(omap3_pmu_oh_names); oh_names = omap3_pmu_oh_names; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V2 2/8] ARM: dts: OMAP2+: Add PMU nodes
Add PMU nodes for OMAP2, OMAP3 and OMAP4460 devices. Please note that the node for OMAP4460 has been placed in a separate header file for OMAP4460, because the node is not compatible with OMAP4430. The node for OMAP4430 is not included because PMU is not currently supported on OMAP4430 due to the absence of a cross-trigger interface driver. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/boot/dts/omap2.dtsi |5 + arch/arm/boot/dts/omap3.dtsi |6 ++ arch/arm/boot/dts/omap4-panda-es.dts |2 ++ arch/arm/boot/dts/omap4460.dtsi | 18 ++ 4 files changed, 31 insertions(+) create mode 100644 arch/arm/boot/dts/omap4460.dtsi diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index 761c4b6..27f5ea1 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi @@ -26,6 +26,11 @@ }; }; + pmu { + compatible = arm,arm1136-pmu; + interrupts = 3; + }; + soc { compatible = ti,omap-infra; mpu { diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index d9970de..0ec7d5c 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -26,6 +26,12 @@ }; }; + pmu { + compatible = arm,cortex-a8-pmu; + interrupts = 3; + ti,hwmods = debugss; + }; + /* * The soc node represents the soc top level view. It is uses for IPs * that are not memory mapped in the MPU view or for the MPU itself. diff --git a/arch/arm/boot/dts/omap4-panda-es.dts b/arch/arm/boot/dts/omap4-panda-es.dts index 73bc1a6..2a6e344 100644 --- a/arch/arm/boot/dts/omap4-panda-es.dts +++ b/arch/arm/boot/dts/omap4-panda-es.dts @@ -5,7 +5,9 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + /include/ omap4-panda.dts +/include/ omap4460.dtsi /* Audio routing is differnet between PandaBoard4430 and PandaBoardES */ sound { diff --git a/arch/arm/boot/dts/omap4460.dtsi b/arch/arm/boot/dts/omap4460.dtsi new file mode 100644 index 000..0a1d38b --- /dev/null +++ b/arch/arm/boot/dts/omap4460.dtsi @@ -0,0 +1,18 @@ +/* + * Device Tree Source for OMAP4460 SoC + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed as is without any warranty of any + * kind, whether express or implied. + */ + +/ { + pmu { + compatible = arm,cortex-a9-pmu; + interrupts = 0 54 0x4, +0 55 0x4; + ti,hwmods = debugss; + }; +}; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V2 4/8] ARM: dts: Add GPMC node for OMAP2, OMAP4 and OMAP5
Add the device-tree node for GPMC on OMAP2, OMAP4 and OMAP5 devices. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/boot/dts/omap2420.dtsi | 11 +++ arch/arm/boot/dts/omap2430.dtsi | 11 +++ arch/arm/boot/dts/omap4.dtsi| 11 +++ arch/arm/boot/dts/omap5.dtsi| 11 +++ 4 files changed, 44 insertions(+) diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi index af65609..d4ce6c2 100644 --- a/arch/arm/boot/dts/omap2420.dtsi +++ b/arch/arm/boot/dts/omap2420.dtsi @@ -29,6 +29,17 @@ pinctrl-single,function-mask = 0x3f; }; + gpmc: gpmc@6800a000 { + compatible = ti,omap2420-gpmc; + reg = 0x6800a000 0x1000; + #address-cells = 2; + #size-cells = 1; + interrupts = 20; + gpmc,num-cs = 8; + gpmc,num-waitpins = 4; + ti,hwmods = gpmc; + }; + mcbsp1: mcbsp@48074000 { compatible = ti,omap2420-mcbsp; reg = 0x48074000 0xff; diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi index c392445..832f184 100644 --- a/arch/arm/boot/dts/omap2430.dtsi +++ b/arch/arm/boot/dts/omap2430.dtsi @@ -29,6 +29,17 @@ pinctrl-single,function-mask = 0x3f; }; + gpmc: gpmc@6e00 { + compatible = ti,omap2430-gpmc; + reg = 0x6e00 0x1000; + #address-cells = 2; + #size-cells = 1; + interrupts = 20; + gpmc,num-cs = 8; + gpmc,num-waitpins = 4; + ti,hwmods = gpmc; + }; + mcbsp1: mcbsp@48074000 { compatible = ti,omap2430-mcbsp; reg = 0x48074000 0xff; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 6669311..bcd64f5 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -196,6 +196,17 @@ #interrupt-cells = 1; }; + gpmc: gpmc@5000 { + compatible = ti,omap4430-gpmc; + reg = 0x5000 0x1000; + #address-cells = 2; + #size-cells = 1; + interrupts = 0 20 0x4; + gpmc,num-cs = 8; + gpmc,num-waitpins = 4; + ti,hwmods = gpmc; + }; + uart1: serial@4806a000 { compatible = ti,omap4-uart; reg = 0x4806a000 0x100; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index f840499..61cbd1c 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -208,6 +208,17 @@ #interrupt-cells = 1; }; + gpmc: gpmc@5000 { + compatible = ti,omap4430-gpmc; + reg = 0x5000 0x1000; + #address-cells = 2; + #size-cells = 1; + interrupts = 0 20 0x4; + gpmc,num-cs = 8; + gpmc,num-waitpins = 4; + ti,hwmods = gpmc; + }; + i2c1: i2c@4807 { compatible = ti,omap4-i2c; reg = 0x4807 0x100; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V2 5/8] ARM: dts: Add OMAP2 gpio bindings
Add gpios bindings for OMAP2420 and OMAP2430 devices. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/boot/dts/omap2420.dtsi | 44 +++ arch/arm/boot/dts/omap2430.dtsi | 55 +++ 2 files changed, 99 insertions(+) diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi index d4ce6c2..eee902f 100644 --- a/arch/arm/boot/dts/omap2420.dtsi +++ b/arch/arm/boot/dts/omap2420.dtsi @@ -29,6 +29,50 @@ pinctrl-single,function-mask = 0x3f; }; + gpio1: gpio@48018000 { + compatible = ti,omap2-gpio; + reg = 0x48018000 0x200; + interrupts = 29; + ti,hwmods = gpio1; + #gpio-cells = 2; + gpio-controller; + #interrupt-cells = 2; + interrupt-controller; + }; + + gpio2: gpio@4801a000 { + compatible = ti,omap2-gpio; + reg = 0x4801a000 0x200; + interrupts = 30; + ti,hwmods = gpio2; + #gpio-cells = 2; + gpio-controller; + #interrupt-cells = 2; + interrupt-controller; + }; + + gpio3: gpio@4801c000 { + compatible = ti,omap2-gpio; + reg = 0x4801c000 0x200; + interrupts = 31; + ti,hwmods = gpio3; + #gpio-cells = 2; + gpio-controller; + #interrupt-cells = 2; + interrupt-controller; + }; + + gpio4: gpio@4801e000 { + compatible = ti,omap2-gpio; + reg = 0x4801e000 0x200; + interrupts = 32; + ti,hwmods = gpio4; + #gpio-cells = 2; + gpio-controller; + #interrupt-cells = 2; + interrupt-controller; + }; + gpmc: gpmc@6800a000 { compatible = ti,omap2420-gpmc; reg = 0x6800a000 0x1000; diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi index 832f184..fb74382 100644 --- a/arch/arm/boot/dts/omap2430.dtsi +++ b/arch/arm/boot/dts/omap2430.dtsi @@ -29,6 +29,61 @@ pinctrl-single,function-mask = 0x3f; }; + gpio1: gpio@4900c000 { + compatible = ti,omap2-gpio; + reg = 0x4900c000 0x200; + interrupts = 29; + ti,hwmods = gpio1; + #gpio-cells = 2; + gpio-controller; + #interrupt-cells = 2; + interrupt-controller; + }; + + gpio2: gpio@4900e000 { + compatible = ti,omap2-gpio; + reg = 0x4900e000 0x200; + interrupts = 30; + ti,hwmods = gpio2; + #gpio-cells = 2; + gpio-controller; + #interrupt-cells = 2; + interrupt-controller; + }; + + gpio3: gpio@4901 { + compatible = ti,omap2-gpio; + reg = 0x4901 0x200; + interrupts = 31; + ti,hwmods = gpio3; + #gpio-cells = 2; + gpio-controller; + #interrupt-cells = 2; + interrupt-controller; + }; + + gpio4: gpio@49012000 { + compatible = ti,omap2-gpio; + reg = 0x49012000 0x200; + interrupts = 32; + ti,hwmods = gpio4; + #gpio-cells = 2; + gpio-controller; + #interrupt-cells = 2; + interrupt-controller; + }; + + gpio5: gpio@480b6000 { + compatible = ti,omap2-gpio; + reg = 0x480b6000 0x200; + interrupts = 33; + ti,hwmods = gpio5; + #gpio-cells = 2; + gpio-controller; + #interrupt-cells = 2; + interrupt-controller; + }; + gpmc: gpmc@6e00 { compatible = ti,omap2430-gpmc; reg = 0x6e00 0x1000; -- 1.7.10.4 ___ devicetree-discuss mailing
[PATCH V2 7/8] ARM: dts: OMAP3: Add reg and interrupt properties for gpio
The OMAP3 gpio bindings are currently missing the reg and interrupt properties and so add these properties. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/boot/dts/omap3.dtsi | 12 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index badedc8..0cc65b5 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -113,6 +113,8 @@ gpio1: gpio@4831 { compatible = ti,omap3-gpio; + reg = 0x4831 0x200; + interrupts = 29; ti,hwmods = gpio1; gpio-controller; #gpio-cells = 2; @@ -122,6 +124,8 @@ gpio2: gpio@4905 { compatible = ti,omap3-gpio; + reg = 0x4905 0x200; + interrupts = 30; ti,hwmods = gpio2; gpio-controller; #gpio-cells = 2; @@ -131,6 +135,8 @@ gpio3: gpio@49052000 { compatible = ti,omap3-gpio; + reg = 0x49052000 0x200; + interrupts = 31; ti,hwmods = gpio3; gpio-controller; #gpio-cells = 2; @@ -140,6 +146,8 @@ gpio4: gpio@49054000 { compatible = ti,omap3-gpio; + reg = 0x49054000 0x200; + interrupts = 32; ti,hwmods = gpio4; gpio-controller; #gpio-cells = 2; @@ -149,6 +157,8 @@ gpio5: gpio@49056000 { compatible = ti,omap3-gpio; + reg = 0x49056000 0x200; + interrupts = 33; ti,hwmods = gpio5; gpio-controller; #gpio-cells = 2; @@ -158,6 +168,8 @@ gpio6: gpio@49058000 { compatible = ti,omap3-gpio; + reg = 0x49058000 0x200; + interrupts = 34; ti,hwmods = gpio6; gpio-controller; #gpio-cells = 2; -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V2 3/8] ARM: dts: OMAP2+: Add SDMA controller bindings and nodes
Add SDMA controller binding for OMAP2+ devices and populate DMA client information for SPI and MMC peripheral on OMAP3+ devices. Please note that OMAP24xx devices do not have SPI and MMC bindings available yet and so DMA client information is not populated. Signed-off-by: Jon Hunter jon-hun...@ti.com Reviewed-by: Felipe Balbi ba...@ti.com Acked-by: Santosh Shilimkar santosh.shilim...@ti.com Tested-by: Santosh Shilimkar santosh.shilim...@ti.com --- arch/arm/boot/dts/omap2.dtsi | 12 arch/arm/boot/dts/omap3.dtsi | 40 arch/arm/boot/dts/omap4.dtsi | 41 + arch/arm/boot/dts/omap5.dtsi | 41 + 4 files changed, 134 insertions(+) diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index 27f5ea1..84183f0 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi @@ -54,6 +54,18 @@ reg = 0x480FE000 0x1000; }; + sdma: dma-controller@48056000 { + compatible = ti,omap2430-sdma, ti,omap2420-sdma; + reg = 0x48056000 0x1000; + interrupts = 12, +13, +14, +15; + #dma-cells = 1; + #dma-channels = 32; + #dma-requests = 64; + }; + uart1: serial@4806a000 { compatible = ti,omap2-uart; ti,hwmods = uart1; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index 0ec7d5c..1dc72ea 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -81,6 +81,18 @@ reg = 0x4820 0x1000; }; + sdma: dma-controller@48056000 { + compatible = ti,omap3630-sdma, ti,omap3430-sdma; + reg = 0x48056000 0x1000; + interrupts = 12, +13, +14, +15; + #dma-cells = 1; + #dma-channels = 32; + #dma-requests = 96; + }; + omap3_pmx_core: pinmux@48002030 { compatible = ti,omap3-padconf, pinctrl-single; reg = 0x48002030 0x05cc; @@ -198,6 +210,16 @@ #size-cells = 0; ti,hwmods = mcspi1; ti,spi-num-cs = 4; + dmas = sdma 35, + sdma 36, + sdma 37, + sdma 38, + sdma 39, + sdma 40, + sdma 41, + sdma 42; + dma-names = tx0, rx0, tx1, rx1, + tx2, rx2, tx3, rx3; }; mcspi2: spi@4809a000 { @@ -206,6 +228,11 @@ #size-cells = 0; ti,hwmods = mcspi2; ti,spi-num-cs = 2; + dmas = sdma 43, + sdma 44, + sdma 45, + sdma 46; + dma-names = tx0, rx0, tx1, rx1; }; mcspi3: spi@480b8000 { @@ -214,6 +241,11 @@ #size-cells = 0; ti,hwmods = mcspi3; ti,spi-num-cs = 2; + dmas = sdma 15, + sdma 16, + sdma 23, + sdma 24; + dma-names = tx0, rx0, tx1, rx1; }; mcspi4: spi@480ba000 { @@ -222,22 +254,30 @@ #size-cells = 0; ti,hwmods = mcspi4; ti,spi-num-cs = 1; + dmas = sdma 70, sdma 71; + dma-names = tx0, rx0; }; mmc1: mmc@4809c000 { compatible = ti,omap3-hsmmc; ti,hwmods = mmc1; ti,dual-volt; + dmas = sdma 61, sdma 62; + dma-names = tx, rx; }; mmc2: mmc@480b4000 { compatible = ti,omap3-hsmmc; ti,hwmods = mmc2; + dmas = sdma 47, sdma 48; + dma-names = tx, rx; }; mmc3: mmc@480ad000 { compatible = ti,omap3-hsmmc; ti,hwmods = mmc3
[PATCH V2 8/8] ARM: dts: OMAP3: Add support for OMAP3430 SDP board
Adds basic device-tree support for OMAP3430 SDP board which has 256MB of RAM, 128MB ONENAND flash, 256MB NAND flash and uses the TWL4030 power management IC. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/boot/dts/Makefile |1 + arch/arm/boot/dts/omap3430-sdp.dts | 141 2 files changed, 142 insertions(+) create mode 100644 arch/arm/boot/dts/omap3430-sdp.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index de29da5..a38dcd4 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -115,6 +115,7 @@ dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \ imx28-tx28.dtb dtb-$(CONFIG_ARCH_NOMADIK) += ste-nomadik-s8815.dtb dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ + omap3430-sdp.dtb \ omap3-beagle.dtb \ omap3-beagle-xm.dtb \ omap3-evm.dtb \ diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts new file mode 100644 index 000..535a6f9 --- /dev/null +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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. + */ +/dts-v1/; + +/include/ omap3.dtsi + +/ { + model = TI OMAP3430 SDP; + compatible = ti,omap3430-sdp, ti,omap3; + + memory { + device_type = memory; + reg = 0x8000 0x1000; /* 256 MB */ + }; +}; + +i2c1 { + clock-frequency = 260; + + twl: twl@48 { + reg = 0x48; + interrupts = 7; /* SYS_NIRQ cascaded to intc */ + }; +}; + +/include/ twl4030.dtsi + +mmc1 { + vmmc-supply = vmmc1; + vmmc_aux-supply = vsim; + bus-width = 8; +}; + +mmc2 { + status = disabled; +}; + +mmc3 { + status = disabled; +}; + +gpmc { + ranges = 1 0 0x2800 0x0800, +2 0 0x2000 0x1000; + + nand@1,0 { + linux,mtd-name= micron,mt29f1g08abb; + #address-cells = 1; + #size-cells = 1; + reg = 1 0 0x0800; + nand-bus-width = 8; + + ti,nand-ecc-opt = sw; + gpmc,device-nand; + gpmc,cs-on = 0; + gpmc,cs-rd-off = 36; + gpmc,cs-wr-off = 36; + gpmc,adv-on = 6; + gpmc,adv-rd-off = 24; + gpmc,adv-wr-off = 36; + gpmc,oe-on = 6; + gpmc,oe-off = 48; + gpmc,we-on = 6; + gpmc,we-off = 30; + gpmc,rd-cycle = 72; + gpmc,wr-cycle = 72; + gpmc,access = 54; + gpmc,wr-access = 30; + + partition@0 { + label = xloader-nand; + reg = 0 0x8; + }; + partition@0x8 { + label = bootloader-nand; + reg = 0x8 0x14; + }; + partition@0x1c { + label = params-nand; + reg = 0x1c 0xc; + }; + partition@0x28 { + label = kernel-nand; + reg = 0x28 0x50; + }; + partition@0x78 { + label = filesystem-nand; + reg = 0x78 0x788; + }; + }; + + onenand@2,0 { + linux,mtd-name= samsung,kfm2g16q2m-deb8; + #address-cells = 1; + #size-cells = 1; + reg = 2 0 0x1000; + + gpmc,device-width = 2; + gpmc,mux-add-data = 2; + gpmc,cs-on = 0; + gpmc,cs-rd-off = 84; + gpmc,cs-wr-off = 72; + gpmc,adv-on = 0; + gpmc,adv-rd-off = 18; + gpmc,adv-wr-off = 18; + gpmc,oe-on = 30; + gpmc,oe-off = 84; + gpmc,we-on = 0; + gpmc,we-off = 42; + gpmc,rd-cycle = 108; + gpmc,wr-cycle = 96; + gpmc,access = 78; + gpmc,wr-data-mux-bus = 30; + + partition@0 { + label = xloader-onenand; + reg = 0 0x8; + }; + partition@0x8 { + label = bootloader-onenand; + reg = 0x8 0x4; + }; + partition@0xc { + label = params-onenand; + reg = 0xc 0x2; + }; + partition@0xe { + label = kernel-onenand; + reg = 0xe 0x20
Re: [PATCH 2/8] ARM: dts: OMAP36xx: move CPU OPP tables to device tree
On 03/15/2013 08:56 AM, Nishanth Menon wrote: On 16:44-20130314, Jon Hunter wrote: On 03/14/2013 03:58 PM, Nishanth Menon wrote: Add DT OPP table for OMAP36xx family of devices. This data is decoded by OF with of_init_opp_table() helper function. This overrides the default OMAP34xx CPU OPP table definition. Not sure I following the last sentence. The tables are in a different dtsi file and only the relevant file should be included, right? omap3630.dsi includes omap3.dtsi (which is meant for OMAP34xx). The opp tables introduced by this patch in omap36xx.dtsi will override the ones defined on omap3.dtsi. Will the following rephrase help clarify this? Original: This overrides the default OMAP34xx CPU OPP table definition. Suggested; This overrides the default OMAP34xx CPU OPP table definition in omap3.dtsi. Sorry, I just missed that the omap3430 opps were in omap3.dtsi and not omap34xx.dtsi. I guess I am not familiar with how the DTC overrides nodes, however, at least from a readability standpoint it would seem nice to have the omap3430 opps in a omap3430 specific dtsi and not omap3.dtsi. However, thats just my opinion. Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 0/8] ARM: OMAP3+: Switch to use DT based cpu0-cpufreq driver
On 03/15/2013 09:21 AM, Nishanth Menon wrote: On 10:48-20130315, Santosh Shilimkar wrote: On Friday 15 March 2013 02:28 AM, Nishanth Menon wrote: The following series arose from trying to use BeagleBoard-XM (OMAP3 variant) for doing CPU DVFS using cpufreq-cpu0. This series will eventually result in migrating the cpufreq support only through device tree (part of the effort to migrate away from non-DT configurations for OMAP). Unfortunately, as already known, we have a bunch of legacy code and mutually dependent device tree conversion that is pending. Key features pending: A) clock framework transition to DT - this should happen soon, so this series hacks the clock node for the time being as suggested in review of original series B) on processors that use voltage controller, voltage processor (VC/VP hardware loop using I2C_SR path) - we have started work on transitioning them to regulator framework driven by DT. C) Adaptive Body Bias and SmartReflex AVS conversion to DT. As a result of these pending features: - OMAP4 TWL6030 and TPS62361 which set voltage ONLY over I2C_SR have no regulators associated at the moment - fortunately, we boot at highest voltage, so things still work. - Missing ABB and AVS implies that for few of the SoCs (3630, OMAP4), I have not added those OPPs in DT yet - this also needs alignment with iMX, AM series like pending work, where certain OPPs need enabling based on efuse programmed bit sequences - since it is an add-on work, it is not addressed here. Thanks for looking into it. Yes, this should be the next stage to solve. Note: Somewhere in the future, when we have regulators driven off CCF and OMAP converted to CCF, we could remove the DT regulator requirements there as well. Key benefit of the series is to allow all relevant TI platforms now to use a single cpufreq driver and equivalent frameworks in addition be part of the transition to DT. As a result of this series, CPUFreq feature will not be available for non-DT boot systems. As commented by Jon on internal thread, I am also against the idea of dropping non-DT support now. Till we migrate to 100 % DT, it is best to keep support alive. Especial OMAP3 based devices. Why don't you take phased approach and have both supported for time being. Then once we move to DT only, we just drop the non-DT support as we plan to do for many more stuff. BTW, we are using only CPUFreq driver before this series as well. I guess you mean the common CPUFReq drivers used by other ARM SOCs. I had removed the entries for OPPs and clock nodes used by omap-cpufreq.c and deleted the omap-cpufreq.c as well - so the statement CPUFreq wont work in non-DT configuration was accurate. My intent was as follows: - This series is driven mainly from maintenance angle - having to maintain two different drivers (legacy omap-cpufreq.c and cpufreq-cpu0.c), ensuring the data is proper in both OPP tables in kernel and DT entries is sure to cause mayhem sometime. This is not just an pain for OMAP community, but for cpufreq community as well (since there is absolutely no reason other than OMAP legacy burden for making cpu0-cpufreq work in non-DT world). - as long as non-DT supported boot provides all features, there is no real feature incentive to move to DT. You are missing the point. Before you can migrate people over to DT, you need to be ready. IMO OMAP is still not quite ready unfortunately. But, that said, there is one path I see possible: - keep omap-cpufreq alive (BUT I will add a patch that will not let it init when in DT entries are present) - add DT entries for all relevant OMAPs - in DT mode, we will *only* support cpufreq-cpu0 - All future SoCs will continue to use cpufreq-cpu0 using DT, as was the alignment I believe. Yes that is what we are doing for other drivers and should be done here. Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH 2/8] ARM: dts: OMAP36xx: move CPU OPP tables to device tree
On 03/15/2013 09:38 AM, Nishanth Menon wrote: On 09:26-20130315, Jon Hunter wrote: On 03/15/2013 08:56 AM, Nishanth Menon wrote: On 16:44-20130314, Jon Hunter wrote: On 03/14/2013 03:58 PM, Nishanth Menon wrote: Add DT OPP table for OMAP36xx family of devices. This data is decoded by OF with of_init_opp_table() helper function. This overrides the default OMAP34xx CPU OPP table definition. Not sure I following the last sentence. The tables are in a different dtsi file and only the relevant file should be included, right? omap3630.dsi includes omap3.dtsi (which is meant for OMAP34xx). The opp tables introduced by this patch in omap36xx.dtsi will override the ones defined on omap3.dtsi. Will the following rephrase help clarify this? Original: This overrides the default OMAP34xx CPU OPP table definition. Suggested; This overrides the default OMAP34xx CPU OPP table definition in omap3.dtsi. Sorry, I just missed that the omap3430 opps were in omap3.dtsi and not omap34xx.dtsi. I guess I am not familiar with how the DTC overrides nodes, however, at least from a readability standpoint it would seem nice to have the omap3430 opps in a omap3430 specific dtsi and not omap3.dtsi. However, thats just my opinion. most of omap3630 is based off omap3430. I know from an readability point of view, it might have been good to split that to omap3-common.dtsi, omap34xx.dtsi, omap36xx.dtsi etc.. But there is no real need at this point in time to do that. Unless, ofcourse, we'd like to set that up as an standard for all OMAP SoCs... How would omap3-common.dtsi be any different from omap3.dtsi? I don't wish us to go nuts with creating dtsi files either, but having an omap3430.dtsi does not seem unreasonable to me, but that is just my opinion. Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 00/18] ARM: OMAP2+: GPMC clean-up and DT update
While adding device-tree support for NOR memories, it became apparent that there is no common way for configuring various GPMC settings for devices that interface to the GPMC. These settings include bus-width, synchronous/asynchronous mode, burst settings, wait monitoring etc. Therefore, to simplify the GPMC code and add device-tree support for NOR, it was first necessary to consolidate how these settings are programmed. Series based upon Mark Jackson's patch [1] and Ezequiel Garcia GPMC clean-up series [2]. Entire series available here [3]. V3 changes: - Rebased on RMK's IS_ERR_VALUE() patch and removed usage of IS_ERR_VALUE() from series. - Fixed BUG in NAND code introduced in V2 by making gpmc_settings structure a local variable (I forgot to initialise structure to zero). - Added fix from Javier to correct return value from gpmc_probe_nor(). V2 changes: - Made gpmc_settings structure local in gpmc_nand_init(). - Use resource_size() API in probe_nor(). - Add kernel-doc for gpmc_cs_program_settings() function. - Use of_platform_device_create() to register NOR devices in probe_nor(). - Add support for GPMC address-address-data multiplexing which required changing GPMC DT property gpmc,mux-add-data to store a 32-bit value and changing mux_add_data member of gpmc_settings to be a 32-bit type instead of bool. - Add detection for incorrect GPMC chip-select base addresses. - Cleaned-up code in gpmc_mem_init() and changed gpmc_mem_init() so that it would not return an error when the GPMC driver is being probed. V1 changes: - Clean-up/simplification of ONENAND initialisation code. - Add a new GPMC structure to unify storage of various GPMC settings (that are non-timing related) for client devices and add a new function to program these settings in a common way. - Migrate initialisation code for existing flash, usb and networking devices to use the new structure and function for GPMC settings. - Add device-tree support for NOR flash memories. - Add additional GPMC timing parameters to GPMC device-tree binding. - Update GPMC NAND and ONENAND device-tree support to retrieve GPMC settings from device-tree. Testing includes: - Boot testing on OMAP2420 H4, OMAP3430 SDP and OMAP4430 SDP with and without device-tree present. - OMAP2420 H4 board has NOR flash and OMAP3430 SDP has NOR, NAND and ONENAND flash. So verified that flash is detected on boot as expected. Note additional patches [4] are required for OMAP2420 H4 and OMAP3430 SDP dts files in order to enable flash memory support. - All of the above boards use GPMC for interfacing to a networking chip and so verified that networking is working wit this series. However, please note that networking is not currently supported on these boards when booting with DT and so networking is only tested without DT. [1] http://permalink.gmane.org/gmane.linux.ports.arm.omap/94765 [2] http://comments.gmane.org/gmane.linux.ports.arm.omap/93784 [3] https://github.com/jonhunter/linux/tree/omap-gpmc-for-v3.10 [4] https://github.com/jonhunter/linux/tree/omap-dt-for-v3.10 Javier Martinez Canillas (1): ARM: OMAP2+: return -ENODEV if GPMC child device creation fails Jon Hunter (17): ARM: OMAP2+: Simplify code configuring ONENAND devices ARM: OMAP2+: Add variable to store number of GPMC waitpins ARM: OMAP2+: Add structure for storing GPMC settings ARM: OMAP2+: Add function for configuring GPMC settings ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings() ARM: OMAP2+: Convert NAND to use gpmc_cs_program_settings() ARM: OMAP2+: Convert SMC91x to use gpmc_cs_program_settings() ARM: OMAP2+: Convert TUSB to use gpmc_cs_program_settings() ARM: OMAP2+: Don't configure of chip-select options in gpmc_cs_configure() ARM: OMAP2+: Add function to read GPMC settings from device-tree ARM: OMAP2+: Add device-tree support for NOR flash ARM: OMAP2+: Add additional GPMC timing parameters ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT ARM: OMAP2+: Convert ONENAND to retrieve GPMC settings from DT ARM: OMAP2+: Detect incorrectly aligned GPMC base address ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails Documentation/devicetree/bindings/bus/ti-gpmc.txt | 48 +- Documentation/devicetree/bindings/mtd/gpmc-nor.txt | 98 .../devicetree/bindings/mtd/gpmc-onenand.txt |3 + arch/arm/mach-omap2/gpmc-nand.c| 39 +- arch/arm/mach-omap2/gpmc-onenand.c | 110 ++-- arch/arm/mach-omap2/gpmc-smc91x.c | 30 +- arch/arm/mach-omap2/gpmc.c | 524 +++- arch/arm/mach-omap2/gpmc.h | 37 +- arch/arm/mach-omap2/usb-tusb6010.c | 62 ++- 9 files changed, 691 insertions(+), 260 deletions(-) create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt -- 1.7.10.4
[PATCH V3 01/18] ARM: OMAP2+: Simplify code configuring ONENAND devices
The OMAP2+ code that configures the GPMC for ONENAND devices is copying structures between functions unnecessarily. Avoid this by passing pointers instead and simplify the code. A pointer to structure omap_onenand_platform_data is passed to the function omap2_onenand_calc_sync_timings(), but only the flags member of the structure is used. Simplify the code by only passing the flags member and not the entire structure. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc-onenand.c | 26 ++ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index 4c91752..db52c4b 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -47,10 +47,9 @@ static struct platform_device gpmc_onenand_device = { .resource = gpmc_onenand_resource, }; -static struct gpmc_timings omap2_onenand_calc_async_timings(void) +static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) { struct gpmc_device_timings dev_t; - struct gpmc_timings t; const int t_cer = 15; const int t_avdp = 12; @@ -76,9 +75,7 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void) dev_t.t_wpl = t_wpl * 1000; dev_t.t_wph = t_wph * 1000; - gpmc_calc_timings(t, dev_t); - - return t; + gpmc_calc_timings(t, dev_t); } static int gpmc_set_async_mode(int cs, struct gpmc_timings *t) @@ -158,12 +155,11 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg, return freq; } -static struct gpmc_timings -omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, - int freq) +static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, + unsigned int flags, + int freq) { struct gpmc_device_timings dev_t; - struct gpmc_timings t; const int t_cer = 15; const int t_avdp = 12; const int t_cez = 20; /* max of t_cez, t_oez */ @@ -172,9 +168,9 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; int div, gpmc_clk_ns; - if (cfg-flags ONENAND_SYNC_READ) + if (flags ONENAND_SYNC_READ) onenand_flags = ONENAND_FLAG_SYNCREAD; - else if (cfg-flags ONENAND_SYNC_READWRITE) + else if (flags ONENAND_SYNC_READWRITE) onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE; switch (freq) { @@ -265,9 +261,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, dev_t.cyc_aavdh_oe = 1; dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; - gpmc_calc_timings(t, dev_t); - - return t; + gpmc_calc_timings(t, dev_t); } static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) @@ -300,7 +294,7 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base) omap2_onenand_set_async_mode(onenand_base); - t = omap2_onenand_calc_async_timings(); + omap2_onenand_calc_async_timings(t); ret = gpmc_set_async_mode(gpmc_onenand_data-cs, t); if (ret 0) @@ -322,7 +316,7 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) set_onenand_cfg(onenand_base); } - t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq); + omap2_onenand_calc_sync_timings(t, gpmc_onenand_data-flags, freq); ret = gpmc_set_sync_mode(gpmc_onenand_data-cs, t); if (ret 0) -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 02/18] ARM: OMAP2+: Add variable to store number of GPMC waitpins
The GPMC has wait-pin signals that can be assigned to a chip-select to monitor the ready signal of an external device. Add a variable to indicate the total number of wait-pins for a given device. This will allow us to detect if the wait-pin being selected is valid or not. When booting with device-tree read the number of wait-pins from the device-tree blob. When device-tree is not used set the number of wait-pins to 4 which is valid for OMAP2-5 devices. Newer devices that have less wait-pins (such as AM335x) only support booting with device-tree and so hard-coding the wait-pin number when not using device-tree is fine. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc.c | 16 1 file changed, 16 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ef655d9..88a261c 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -108,6 +108,8 @@ #defineGPMC_HAS_WR_ACCESS 0x1 #defineGPMC_HAS_WR_DATA_MUX_BUS0x2 +#define GPMC_NR_WAITPINS 4 + /* XXX: Only NAND irq has been considered,currently these are the only ones used */ #defineGPMC_NR_IRQ 2 @@ -153,6 +155,7 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM]; static DEFINE_SPINLOCK(gpmc_mem_lock); /* Define chip-selects as reserved by default until probe completes */ static unsigned int gpmc_cs_map = ((1 GPMC_CS_NUM) - 1); +static unsigned int gpmc_nr_waitpins; static struct device *gpmc_dev; static int gpmc_irq; static resource_size_t phys_base, mem_size; @@ -1297,6 +1300,13 @@ static int gpmc_probe_dt(struct platform_device *pdev) if (!of_id) return 0; + ret = of_property_read_u32(pdev-dev.of_node, gpmc,num-waitpins, + gpmc_nr_waitpins); + if (ret 0) { + pr_err(%s: number of wait pins not found!\n, __func__); + return ret; + } + for_each_node_by_name(child, nand) { ret = gpmc_probe_nand_child(pdev, child); if (ret 0) { @@ -1372,6 +1382,12 @@ static int gpmc_probe(struct platform_device *pdev) if (gpmc_setup_irq() 0) dev_warn(gpmc_dev, gpmc_setup_irq failed\n); + /* Now the GPMC is initialised, unreserve the chip-selects */ + gpmc_cs_map = 0; + + if (!pdev-dev.of_node) + gpmc_nr_waitpins = GPMC_NR_WAITPINS; + rc = gpmc_probe_dt(pdev); if (rc 0) { clk_disable_unprepare(gpmc_l3_clk); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 04/18] ARM: OMAP2+: Add function for configuring GPMC settings
The GPMC has various different configuration options such as bus-width, synchronous or asychronous mode selection, burst mode options etc. Currently, there is no common function for configuring these options and various devices set these options by either programming the GPMC CONFIG1 register directly or by calling gpmc_cs_configure() to set some of the options. Add a new function for configuring all of the GPMC options. Having a common function for configuring this options will simplify code and ease the migration to device-tree. Also add a new capability flag to detect devices that support the address-address-data multiplexing mode. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc.c | 100 arch/arm/mach-omap2/gpmc.h |6 +++ 2 files changed, 106 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 7cc07b5..760c26d 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -107,6 +107,7 @@ #defineGPMC_HAS_WR_ACCESS 0x1 #defineGPMC_HAS_WR_DATA_MUX_BUS0x2 +#defineGPMC_HAS_MUX_AAD0x4 #define GPMC_NR_WAITPINS 4 @@ -1129,6 +1130,90 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t, return 0; } +/** + * gpmc_cs_program_settings - programs non-timing related settings + * @cs:GPMC chip-select to program + * @p: pointer to GPMC settings structure + * + * Programs non-timing related settings for a GPMC chip-select, such as + * bus-width, burst configuration, etc. Function should be called once + * for each chip-select that is being used and must be called before + * calling gpmc_cs_set_timings() as timing parameters in the CONFIG1 + * register will be initialised to zero by this function. Returns 0 on + * success and appropriate negative error code on failure. + */ +int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) +{ + u32 config1; + + if ((!p-device_width) || (p-device_width GPMC_DEVWIDTH_16BIT)) { + pr_err(%s: invalid width %d!, __func__, p-device_width); + return -EINVAL; + } + + /* Address-data multiplexing not supported for NAND devices */ + if (p-device_nand p-mux_add_data) { + pr_err(%s: invalid configuration!\n, __func__); + return -EINVAL; + } + + if ((p-mux_add_data GPMC_MUX_AD) || + ((p-mux_add_data == GPMC_MUX_AAD) +!(gpmc_capability GPMC_HAS_MUX_AAD))) { + pr_err(%s: invalid multiplex configuration!\n, __func__); + return -EINVAL; + } + + /* Page/burst mode supports lengths of 4, 8 and 16 bytes */ + if (p-burst_read || p-burst_write) { + switch (p-burst_len) { + case GPMC_BURST_4: + case GPMC_BURST_8: + case GPMC_BURST_16: + break; + default: + pr_err(%s: invalid page/burst-length (%d)\n, + __func__, p-burst_len); + return -EINVAL; + } + } + + if ((p-wait_on_read || p-wait_on_write) + (p-wait_pin gpmc_nr_waitpins)) { + pr_err(%s: invalid wait-pin (%d)\n, __func__, p-wait_pin); + return -EINVAL; + } + + config1 = GPMC_CONFIG1_DEVICESIZE((p-device_width - 1)); + + if (p-sync_read) + config1 |= GPMC_CONFIG1_READTYPE_SYNC; + if (p-sync_write) + config1 |= GPMC_CONFIG1_WRITETYPE_SYNC; + if (p-wait_on_read) + config1 |= GPMC_CONFIG1_WAIT_READ_MON; + if (p-wait_on_write) + config1 |= GPMC_CONFIG1_WAIT_WRITE_MON; + if (p-wait_on_read || p-wait_on_write) + config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p-wait_pin); + if (p-device_nand) + config1 |= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND); + if (p-mux_add_data) + config1 |= GPMC_CONFIG1_MUXTYPE(p-mux_add_data); + if (p-burst_read) + config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP; + if (p-burst_write) + config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP; + if (p-burst_read || p-burst_write) { + config1 |= GPMC_CONFIG1_PAGE_LEN(p-burst_len 3); + config1 |= p-burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0; + } + + gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1); + + return 0; +} + #ifdef CONFIG_OF static struct of_device_id gpmc_dt_ids[] = { { .compatible = ti,omap2420-gpmc }, @@ -1375,8 +1460,23 @@ static int gpmc_probe(struct platform_device *pdev) gpmc_dev = pdev-dev; l = gpmc_read_reg(GPMC_REVISION); + + /* +* FIXME: Once device-tree migration is complete the below flags +* should be populated based upon the device-tree compatible
[PATCH V3 03/18] ARM: OMAP2+: Add structure for storing GPMC settings
The GPMC has various different configuration options such as bus-width, synchronous or asychronous mode selection, burst mode options etc. Currently, there is no central structure for storing all these options when configuring the GPMC for a given device. Some of the options are stored in the GPMC timing structure and some are directly programmed into the GPMC configuration register. Add a new structure to store these options and convert code to use this structure. Adding this structure will allow us to create a common function for configuring these options. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc-onenand.c | 18 ++- arch/arm/mach-omap2/gpmc-smc91x.c |2 +- arch/arm/mach-omap2/gpmc.c | 45 +--- arch/arm/mach-omap2/gpmc.h | 28 -- arch/arm/mach-omap2/usb-tusb6010.c | 19 --- 5 files changed, 72 insertions(+), 40 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index db52c4b..e175ceb 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -47,6 +47,15 @@ static struct platform_device gpmc_onenand_device = { .resource = gpmc_onenand_resource, }; +static struct gpmc_settings onenand_async = { + .mux_add_data = GPMC_MUX_AD, +}; + +static struct gpmc_settings onenand_sync = { + .burst_read = true, + .mux_add_data = GPMC_MUX_AD, +}; + static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) { struct gpmc_device_timings dev_t; @@ -63,7 +72,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) memset(dev_t, 0, sizeof(dev_t)); - dev_t.mux = true; dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000; dev_t.t_avdp_w = dev_t.t_avdp_r; dev_t.t_aavdh = t_aavdh * 1000; @@ -75,7 +83,7 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) dev_t.t_wpl = t_wpl * 1000; dev_t.t_wph = t_wph * 1000; - gpmc_calc_timings(t, dev_t); + gpmc_calc_timings(t, onenand_async, dev_t); } static int gpmc_set_async_mode(int cs, struct gpmc_timings *t) @@ -235,10 +243,8 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, /* Set synchronous read timings */ memset(dev_t, 0, sizeof(dev_t)); - dev_t.mux = true; - dev_t.sync_read = true; if (onenand_flags ONENAND_FLAG_SYNCWRITE) { - dev_t.sync_write = true; + onenand_sync.sync_write = true; } else { dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; dev_t.t_wpl = t_wpl * 1000; @@ -261,7 +267,7 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, dev_t.cyc_aavdh_oe = 1; dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; - gpmc_calc_timings(t, dev_t); + gpmc_calc_timings(t, onenand_sync, dev_t); } static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c index 11d0b75..4b78338 100644 --- a/arch/arm/mach-omap2/gpmc-smc91x.c +++ b/arch/arm/mach-omap2/gpmc-smc91x.c @@ -104,7 +104,7 @@ static int smc91c96_gpmc_retime(void) dev_t.t_cez_w = t4_w * 1000; dev_t.t_wr_cycle = (t20 - t3) * 1000; - gpmc_calc_timings(t, dev_t); + gpmc_calc_timings(t, NULL, dev_t); return gpmc_cs_set_timings(gpmc_cfg-cs, t); } diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 88a261c..7cc07b5 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -817,9 +817,9 @@ static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) /* XXX: can the cycles be avoided ? */ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool mux) { - bool mux = dev_t-mux; u32 temp; /* adv_rd_off */ @@ -872,9 +872,9 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, } static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool mux) { - bool mux = dev_t-mux; u32 temp; /* adv_wr_off */ @@ -934,9 +934,9 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, } static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, - struct gpmc_device_timings *dev_t) + struct gpmc_device_timings *dev_t, + bool mux) { - bool
[PATCH V3 05/18] ARM: OMAP2+: Convert ONENAND to use gpmc_cs_program_settings()
Convert the OMAP2+ ONENAND code to use the gpmc_cs_program_settings() function for configuring the various GPMC options instead of directly programming the CONFIG1 register. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc-onenand.c | 61 +++- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index e175ceb..46aac83 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -48,18 +48,22 @@ static struct platform_device gpmc_onenand_device = { }; static struct gpmc_settings onenand_async = { + .device_width = GPMC_DEVWIDTH_16BIT, .mux_add_data = GPMC_MUX_AD, }; static struct gpmc_settings onenand_sync = { .burst_read = true, + .burst_wrap = true, + .burst_len = GPMC_BURST_16, + .device_width = GPMC_DEVWIDTH_16BIT, .mux_add_data = GPMC_MUX_AD, + .wait_pin = 0, }; static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) { struct gpmc_device_timings dev_t; - const int t_cer = 15; const int t_avdp = 12; const int t_aavdh = 7; @@ -86,16 +90,6 @@ static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) gpmc_calc_timings(t, onenand_async, dev_t); } -static int gpmc_set_async_mode(int cs, struct gpmc_timings *t) -{ - /* Configure GPMC for asynchronous read */ - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, - GPMC_CONFIG1_DEVICESIZE_16 | - GPMC_CONFIG1_MUXADDDATA); - - return gpmc_cs_set_timings(cs, t); -} - static void omap2_onenand_set_async_mode(void __iomem *onenand_base) { u32 reg; @@ -243,8 +237,11 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, /* Set synchronous read timings */ memset(dev_t, 0, sizeof(dev_t)); + if (onenand_flags ONENAND_FLAG_SYNCREAD) + onenand_sync.sync_read = true; if (onenand_flags ONENAND_FLAG_SYNCWRITE) { onenand_sync.sync_write = true; + onenand_sync.burst_write = true; } else { dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; dev_t.t_wpl = t_wpl * 1000; @@ -270,29 +267,6 @@ static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, gpmc_calc_timings(t, onenand_sync, dev_t); } -static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) -{ - unsigned sync_read = onenand_flags ONENAND_FLAG_SYNCREAD; - unsigned sync_write = onenand_flags ONENAND_FLAG_SYNCWRITE; - - /* Configure GPMC for synchronous read */ - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, - GPMC_CONFIG1_WRAPBURST_SUPP | - GPMC_CONFIG1_READMULTIPLE_SUPP | - (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) | - (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) | - (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) | - GPMC_CONFIG1_PAGE_LEN(2) | - (cpu_is_omap34xx() ? 0 : - (GPMC_CONFIG1_WAIT_READ_MON | -GPMC_CONFIG1_WAIT_PIN_SEL(0))) | - GPMC_CONFIG1_DEVICESIZE_16 | - GPMC_CONFIG1_DEVICETYPE_NOR | - GPMC_CONFIG1_MUXADDDATA); - - return gpmc_cs_set_timings(cs, t); -} - static int omap2_onenand_setup_async(void __iomem *onenand_base) { struct gpmc_timings t; @@ -302,7 +276,11 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base) omap2_onenand_calc_async_timings(t); - ret = gpmc_set_async_mode(gpmc_onenand_data-cs, t); + ret = gpmc_cs_program_settings(gpmc_onenand_data-cs, onenand_async); + if (ret 0) + return ret; + + ret = gpmc_cs_set_timings(gpmc_onenand_data-cs, t); if (ret 0) return ret; @@ -322,9 +300,20 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) set_onenand_cfg(onenand_base); } + /* +* FIXME: Appears to be legacy code from initial ONENAND commit. +* Unclear what boards this is for and if this can be removed. +*/ + if (!cpu_is_omap34xx()) + onenand_sync.wait_on_read = true; + omap2_onenand_calc_sync_timings(t, gpmc_onenand_data-flags, freq); - ret = gpmc_set_sync_mode(gpmc_onenand_data-cs, t); + ret = gpmc_cs_program_settings(gpmc_onenand_data-cs, onenand_sync); + if (ret 0) + return ret; + + ret = gpmc_cs_set_timings(gpmc_onenand_data-cs, t); if (ret 0) return ret; -- 1.7.10.4 ___ devicetree-discuss mailing list
[PATCH V3 06/18] ARM: OMAP2+: Convert NAND to use gpmc_cs_program_settings()
Convert the OMAP2+ NAND code to use the gpmc_cs_program_settings() function for configuring the various GPMC options instead of directly programming the CONFIG1 register. This moves the configuration of some GPMC options outside the nand_gpmc_retime() because these options should only need to be set once regardless of whether the gpmc timing is changing dynamically at runtime. The programming of where the wait-pin is also moved slightly, but this will not have any impact to existing devices as no boards are currently setting the dev_ready variable. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc-nand.c | 35 +++ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index e50e438..75feb95 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -74,14 +74,6 @@ static int omap2_nand_gpmc_retime( t.cs_wr_off = gpmc_t-cs_wr_off; t.wr_cycle = gpmc_t-wr_cycle; - /* Configure GPMC */ - if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16) - gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 1); - else - gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_DEV_SIZE, 0); - gpmc_cs_configure(gpmc_nand_data-cs, - GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND); - gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_WP, 0); err = gpmc_cs_set_timings(gpmc_nand_data-cs, t); if (err) return err; @@ -115,8 +107,11 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, struct gpmc_timings *gpmc_t) { int err = 0; + struct gpmc_settings s; struct device *dev = gpmc_nand_device.dev; + memset(s, 0, sizeof(struct gpmc_settings)); + gpmc_nand_device.dev.platform_data = gpmc_nand_data; err = gpmc_cs_request(gpmc_nand_data-cs, NAND_IO_SIZE, @@ -141,11 +136,27 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, dev_err(dev, Unable to set gpmc timings: %d\n, err); return err; } - } - /* Enable RD PIN Monitoring Reg */ - if (gpmc_nand_data-dev_ready) { - gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_RDY_BSY, 1); + s.device_nand = true; + + /* Enable RD PIN Monitoring Reg */ + if (gpmc_nand_data-dev_ready) { + s.wait_on_read = true; + s.wait_on_write = true; + } + + if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16) + s.device_width = GPMC_DEVWIDTH_16BIT; + else + s.device_width = GPMC_DEVWIDTH_8BIT; + + err = gpmc_cs_program_settings(gpmc_nand_data-cs, s); + if (err 0) + goto out_free_cs; + + err = gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_WP, 0); + if (err 0) + goto out_free_cs; } gpmc_update_nand_reg(gpmc_nand_data-reg, gpmc_nand_data-cs); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 07/18] ARM: OMAP2+: Convert SMC91x to use gpmc_cs_program_settings()
Convert the OMAP2+ SMC91x code to use the gpmc_cs_program_settings() function for configuring the various GPMC options instead of directly programming the CONFIG1 register. Move configuration of the GPMC settings outside retime function and this does not need to be done if the timings are changed dynamically at runtime. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc-smc91x.c | 30 +- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c index 4b78338..61a0635 100644 --- a/arch/arm/mach-omap2/gpmc-smc91x.c +++ b/arch/arm/mach-omap2/gpmc-smc91x.c @@ -49,6 +49,10 @@ static struct platform_device gpmc_smc91x_device = { .resource = gpmc_smc91x_resources, }; +static struct gpmc_settings smc91x_settings = { + .device_width = GPMC_DEVWIDTH_16BIT, +}; + /* * Set the gpmc timings for smc91c96. The timings are taken * from the data sheet available at: @@ -67,18 +71,6 @@ static int smc91c96_gpmc_retime(void) const int t7 = 5; /* Figure 12.4 write */ const int t8 = 5; /* Figure 12.4 write */ const int t20 = 185;/* Figure 12.2 read and 12.4 write */ - u32 l; - - l = GPMC_CONFIG1_DEVICESIZE_16; - if (gpmc_cfg-flags GPMC_MUX_ADD_DATA) - l |= GPMC_CONFIG1_MUXADDDATA; - if (gpmc_cfg-flags GPMC_READ_MON) - l |= GPMC_CONFIG1_WAIT_READ_MON; - if (gpmc_cfg-flags GPMC_WRITE_MON) - l |= GPMC_CONFIG1_WAIT_WRITE_MON; - if (gpmc_cfg-wait_pin) - l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg-wait_pin); - gpmc_cs_write_reg(gpmc_cfg-cs, GPMC_CS_CONFIG1, l); /* * FIXME: Calculate the address and data bus muxed timings. @@ -104,7 +96,7 @@ static int smc91c96_gpmc_retime(void) dev_t.t_cez_w = t4_w * 1000; dev_t.t_wr_cycle = (t20 - t3) * 1000; - gpmc_calc_timings(t, NULL, dev_t); + gpmc_calc_timings(t, smc91x_settings, dev_t); return gpmc_cs_set_timings(gpmc_cfg-cs, t); } @@ -133,6 +125,18 @@ void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data) gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f; gpmc_smc91x_resources[1].flags |= (gpmc_cfg-flags IRQF_TRIGGER_MASK); + if (gpmc_cfg-flags GPMC_MUX_ADD_DATA) + smc91x_settings.mux_add_data = GPMC_MUX_AD; + if (gpmc_cfg-flags GPMC_READ_MON) + smc91x_settings.wait_on_read = true; + if (gpmc_cfg-flags GPMC_WRITE_MON) + smc91x_settings.wait_on_write = true; + if (gpmc_cfg-wait_pin) + smc91x_settings.wait_pin = gpmc_cfg-wait_pin; + ret = gpmc_cs_program_settings(gpmc_cfg-cs, smc91x_settings); + if (ret 0) + goto free1; + if (gpmc_cfg-retime) { ret = gpmc_cfg-retime(); if (ret != 0) -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 08/18] ARM: OMAP2+: Convert TUSB to use gpmc_cs_program_settings()
Convert the OMAP2+ TUSB code to use the gpmc_cs_program_settings() function for configuring the various GPMC options instead of directly programming the CONFIG1 register. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/usb-tusb6010.c | 43 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index faaf96d..e832bc7 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -8,6 +8,7 @@ * published by the Free Software Foundation. */ +#include linux/err.h #include linux/string.h #include linux/types.h #include linux/errno.h @@ -27,12 +28,21 @@ static u8 async_cs, sync_cs; static unsignedrefclk_psec; static struct gpmc_settings tusb_async = { + .wait_on_read = true, + .wait_on_write = true, + .device_width = GPMC_DEVWIDTH_16BIT, .mux_add_data = GPMC_MUX_AD, }; static struct gpmc_settings tusb_sync = { + .burst_read = true, + .burst_write= true, .sync_read = true, .sync_write = true, + .wait_on_read = true, + .wait_on_write = true, + .burst_len = GPMC_BURST_16, + .device_width = GPMC_DEVWIDTH_16BIT, .mux_add_data = GPMC_MUX_AD, }; @@ -168,18 +178,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, return status; } tusb_resources[0].end = tusb_resources[0].start + 0x9ff; + tusb_async.wait_pin = waitpin; async_cs = async; - gpmc_cs_write_reg(async, GPMC_CS_CONFIG1, - GPMC_CONFIG1_PAGE_LEN(2) - | GPMC_CONFIG1_WAIT_READ_MON - | GPMC_CONFIG1_WAIT_WRITE_MON - | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) - | GPMC_CONFIG1_READTYPE_ASYNC - | GPMC_CONFIG1_WRITETYPE_ASYNC - | GPMC_CONFIG1_DEVICESIZE_16 - | GPMC_CONFIG1_DEVICETYPE_NOR - | GPMC_CONFIG1_MUXADDDATA); + status = gpmc_cs_program_settings(async_cs, tusb_async); + if (status 0) + return status; /* SYNC region, primarily for DMA */ status = gpmc_cs_request(sync, SZ_16M, (unsigned long *) @@ -189,21 +193,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, return status; } tusb_resources[1].end = tusb_resources[1].start + 0x9ff; + tusb_sync.wait_pin = waitpin; sync_cs = sync; - gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1, - GPMC_CONFIG1_READMULTIPLE_SUPP - | GPMC_CONFIG1_READTYPE_SYNC - | GPMC_CONFIG1_WRITEMULTIPLE_SUPP - | GPMC_CONFIG1_WRITETYPE_SYNC - | GPMC_CONFIG1_PAGE_LEN(2) - | GPMC_CONFIG1_WAIT_READ_MON - | GPMC_CONFIG1_WAIT_WRITE_MON - | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) - | GPMC_CONFIG1_DEVICESIZE_16 - | GPMC_CONFIG1_DEVICETYPE_NOR - | GPMC_CONFIG1_MUXADDDATA - /* fclk divider gets set later */ - ); + + status = gpmc_cs_program_settings(sync_cs, tusb_sync); + if (status 0) + return status; /* IRQ */ status = gpio_request_one(irq, GPIOF_IN, TUSB6010 irq); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 09/18] ARM: OMAP2+: Don't configure of chip-select options in gpmc_cs_configure()
With the addition of the gpmc_cs_program_settings(), we no longer need or use gpmc_cs_configure() to configure some of the GPMC chip-select options. So rename the function to gpmc_configure() and remove code that modifies options in the CONFIG1 register. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc-nand.c |2 +- arch/arm/mach-omap2/gpmc.c | 49 ++- arch/arm/mach-omap2/gpmc.h |5 +--- 3 files changed, 9 insertions(+), 47 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index 75feb95..12e9753 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -154,7 +154,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, if (err 0) goto out_free_cs; - err = gpmc_cs_configure(gpmc_nand_data-cs, GPMC_CONFIG_WP, 0); + err = gpmc_configure(GPMC_CONFIG_WP, 0); if (err 0) goto out_free_cs; } diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 760c26d..3ec1937 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -550,16 +550,14 @@ void gpmc_cs_free(int cs) EXPORT_SYMBOL(gpmc_cs_free); /** - * gpmc_cs_configure - write request to configure gpmc - * @cs: chip select number + * gpmc_configure - write request to configure gpmc * @cmd: command type * @wval: value to write * @return status of the operation */ -int gpmc_cs_configure(int cs, int cmd, int wval) +int gpmc_configure(int cmd, int wval) { - int err = 0; - u32 regval = 0; + u32 regval; switch (cmd) { case GPMC_ENABLE_IRQ: @@ -579,47 +577,14 @@ int gpmc_cs_configure(int cs, int cmd, int wval) gpmc_write_reg(GPMC_CONFIG, regval); break; - case GPMC_CONFIG_RDY_BSY: - regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - if (wval) - regval |= WR_RD_PIN_MONITORING; - else - regval = ~WR_RD_PIN_MONITORING; - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); - break; - - case GPMC_CONFIG_DEV_SIZE: - regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - - /* clear 2 target bits */ - regval = ~GPMC_CONFIG1_DEVICESIZE(3); - - /* set the proper value */ - regval |= GPMC_CONFIG1_DEVICESIZE(wval); - - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); - break; - - case GPMC_CONFIG_DEV_TYPE: - regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - /* clear 4 target bits */ - regval = ~(GPMC_CONFIG1_DEVICETYPE(3) | - GPMC_CONFIG1_MUXTYPE(3)); - /* set the proper value */ - regval |= GPMC_CONFIG1_DEVICETYPE(wval); - if (wval == GPMC_DEVICETYPE_NOR) - regval |= GPMC_CONFIG1_MUXADDDATA; - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); - break; - default: - printk(KERN_ERR gpmc_configure_cs: Not supported\n); - err = -EINVAL; + pr_err(%s: command not supported\n, __func__); + return -EINVAL; } - return err; + return 0; } -EXPORT_SYMBOL(gpmc_cs_configure); +EXPORT_SYMBOL(gpmc_configure); void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) { diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h index ce6ae21..87d2a22 100644 --- a/arch/arm/mach-omap2/gpmc.h +++ b/arch/arm/mach-omap2/gpmc.h @@ -59,9 +59,6 @@ #define GPMC_CONFIG1_DEVICETYPE(val)((val 3) 10) #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) #define GPMC_CONFIG1_MUXTYPE(val) ((val 3) 8) -#define GPMC_CONFIG1_MUXNONMUX GPMC_CONFIG1_MUXTYPE(0) -#define GPMC_CONFIG1_MUXAAD GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AAD) -#define GPMC_CONFIG1_MUXADDDATA GPMC_CONFIG1_MUXTYPE(GPMC_MUX_AD) #define GPMC_CONFIG1_TIME_PARA_GRAN (1 4) #define GPMC_CONFIG1_FCLK_DIV(val) (val 3) #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) @@ -227,6 +224,6 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); extern void gpmc_cs_free(int cs); extern void omap3_gpmc_save_context(void); extern void omap3_gpmc_restore_context(void); -extern int gpmc_cs_configure(int cs, int cmd, int wval); +extern int gpmc_configure(int cmd, int wval); #endif -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 10/18] ARM: OMAP2+: Add function to read GPMC settings from device-tree
Adds a function to read the various GPMC chip-select settings from device-tree and store them in the gpmc_settings structure. Update the GPMC device-tree binding documentation to describe these options. Signed-off-by: Jon Hunter jon-hun...@ti.com --- Documentation/devicetree/bindings/bus/ti-gpmc.txt | 23 ++ arch/arm/mach-omap2/gpmc.c| 49 + arch/arm/mach-omap2/gpmc.h|2 + 3 files changed, 74 insertions(+) diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 5ddb2e9..6fde1cf 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -65,6 +65,29 @@ The following are only applicable to OMAP3+ and AM335x: - gpmc,wr-access - gpmc,wr-data-mux-bus +GPMC chip-select settings properties for child nodes. All are optional. + +- gpmc,burst-lengthPage/burst length. Must be 4, 8 or 16. +- gpmc,burst-wrap Enables wrap bursting +- gpmc,burst-read Enables read page/burst mode +- gpmc,burst-write Enables write page/burst mode +- gpmc,device-nand Device is NAND +- gpmc,device-widthTotal width of device(s) connected to a GPMC + chip-select in bytes. The GPMC supports 8-bit + and 16-bit devices and so this property must be + 1 or 2. +- gpmc,mux-add-dataAddress and data multiplexing configuration. + Valid values are 1 for address-address-data + multiplexing mode and 2 for address-data + multiplexing mode. +- gpmc,sync-read Enables synchronous read. Defaults to asynchronous + is this is not set. +- gpmc,sync-write Enables synchronous writes. Defaults to asynchronous + is this is not set. +- gpmc,wait-pinWait-pin used by client. Must be less than + gpmc,num-waitpins. +- gpmc,wait-on-readEnables wait monitoring on reads. +- gpmc,wait-on-write Enables wait monitoring on writes. Example for an AM33xx board: diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 3ec1937..1e7eef3 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1190,6 +1190,55 @@ static struct of_device_id gpmc_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, gpmc_dt_ids); +/** + * gpmc_read_settings_dt - read gpmc settings from device-tree + * @np:pointer to device-tree node for a gpmc child device + * @p: pointer to gpmc settings structure + * + * Reads the GPMC settings for a GPMC child device from device-tree and + * stores them in the GPMC settings structure passed. The GPMC settings + * structure is initialise to zero by this function and so any previously + * stored settings will be clearer. + */ +void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) +{ + memset(p, 0, sizeof(struct gpmc_settings)); + + if (of_find_property(np, gpmc,sync-read, NULL)) + p-sync_read = true; + if (of_find_property(np, gpmc,sync-write, NULL)) + p-sync_write = true; + + if (!of_property_read_u32(np, gpmc,burst-length, p-burst_len)) { + if (of_find_property(np, gpmc,burst-wrap, NULL)) + p-burst_wrap = true; + if (of_find_property(np, gpmc,burst-read, NULL)) + p-burst_read = true; + if (of_find_property(np, gpmc,burst-write, NULL)) + p-burst_write = true; + if (!p-burst_read !p-burst_write) + pr_warn(%s: page/burst-length set but not used!\n, + __func__); + } + + if (!of_property_read_u32(np, gpmc,wait-pin, p-wait_pin)) { + if (of_find_property(np, gpmc,wait-on-read, NULL)) + p-wait_on_read = true; + if (of_find_property(np, gpmc,wait-on-write, NULL)) + p-wait_on_write = true; + if (!p-wait_on_read !p-wait_on_write) + pr_warn(%s: read/write wait monitoring not enabled!\n, + __func__); + } + + of_property_read_u32(np, gpmc,device-width, p-device_width); + + if (of_find_property(np, gpmc,device-nand, NULL)) + p-device_nand = true; + + of_property_read_u32(np, gpmc,mux-add-data, p-mux_add_data); +} + static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, struct gpmc_timings *gpmc_t) { diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h index 87d2a22..707f6d5 100644 --- a/arch/arm/mach-omap2/gpmc.h +++ b/arch/arm/mach-omap2/gpmc.h @@ -225,5 +225,7 @@ extern void gpmc_cs_free(int cs); extern void omap3_gpmc_save_context(void
[PATCH V3 12/18] ARM: OMAP2+: Add additional GPMC timing parameters
Some of the GPMC timings parameters are currently missing from the GPMC device-tree binding. Add these parameters to the binding documentation as well as code to read them. The existing code in gpmc_read_timings_dt() is checking the value of of_property_read_u32() and only is successful storing the value read in the gpmc_timings structure. Checking the return value in this case is not necessary and we can simply read the value, if present, and store directly in the gpmc_timings structure. Therefore, simplify the code by removing these checks. The comment in the gpmc_read_timings_dt() function, only for OMAP3430 is also incorrect as it is applicable to all OMAP3+ devices. So correct this too. Signed-off-by: Jon Hunter jon-hun...@ti.com --- Documentation/devicetree/bindings/bus/ti-gpmc.txt | 25 +- arch/arm/mach-omap2/gpmc.c| 93 ++--- 2 files changed, 66 insertions(+), 52 deletions(-) diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 6fde1cf..a63bd93 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -56,10 +56,27 @@ Timing properties for child nodes. All are optional and default to 0. - gpmc,oe-off:Deassertion time Access time and cycle time timings corresponding to GPMC_CONFIG5: - - gpmc,page-burst-access: Multiple access word delay - - gpmc,access:Start-cycle to first data valid delay - - gpmc,rd-cycle: Total read cycle time - - gpmc,wr-cycle: Total write cycle time + - gpmc,page-burst-access: Multiple access word delay + - gpmc,access:Start-cycle to first data valid delay + - gpmc,rd-cycle: Total read cycle time + - gpmc,wr-cycle: Total write cycle time + - gpmc,bus-turnaround:Turn-around time between successive accesses + - gpmc,cycle2cycle-delay: Delay between chip-select pulses + - gpmc,clk-activation:GPMC clock activation time + - gpmc,wait-monitoring: Start of wait monitoring with regard to valid + data + +Boolean timing parameters. If property is present parameter enabled and +disabled if omitted: + - gpmc,adv-extra-delay: ADV signal is delayed by half GPMC clock + - gpmc,cs-extra-delay:CS signal is delayed by half GPMC clock + - gpmc,cycle2cycle-diffcsen: Add cycle2cycle-delay between successive + accesses to a different CS + - gpmc,cycle2cycle-samecsen: Add cycle2cycle-delay between successive + accesses to the same CS + - gpmc,oe-extra-delay:OE signal is delayed by half GPMC clock + - gpmc,we-extra-delay:WE signal is delayed by half GPMC clock + - gpmc,time-para-granularity: Multiply all access times by 2 The following are only applicable to OMAP3+ and AM335x: - gpmc,wr-access diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 85b1a35..c928a8c 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1274,67 +1274,64 @@ void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, struct gpmc_timings *gpmc_t) { - u32 val; - memset(gpmc_t, 0, sizeof(*gpmc_t)); /* minimum clock period for syncronous mode */ - if (!of_property_read_u32(np, gpmc,sync-clk, val)) - gpmc_t-sync_clk = val; + of_property_read_u32(np, gpmc,sync-clk, gpmc_t-sync_clk); /* chip select timtings */ - if (!of_property_read_u32(np, gpmc,cs-on, val)) - gpmc_t-cs_on = val; - - if (!of_property_read_u32(np, gpmc,cs-rd-off, val)) - gpmc_t-cs_rd_off = val; - - if (!of_property_read_u32(np, gpmc,cs-wr-off, val)) - gpmc_t-cs_wr_off = val; + of_property_read_u32(np, gpmc,cs-on, gpmc_t-cs_on); + of_property_read_u32(np, gpmc,cs-rd-off, gpmc_t-cs_rd_off); + of_property_read_u32(np, gpmc,cs-wr-off, gpmc_t-cs_wr_off); /* ADV signal timings */ - if (!of_property_read_u32(np, gpmc,adv-on, val)) - gpmc_t-adv_on = val; - - if (!of_property_read_u32(np, gpmc,adv-rd-off, val)) - gpmc_t-adv_rd_off = val; - - if (!of_property_read_u32(np, gpmc,adv-wr-off, val)) - gpmc_t-adv_wr_off = val; + of_property_read_u32(np, gpmc,adv-on, gpmc_t-adv_on); + of_property_read_u32(np, gpmc,adv-rd-off, gpmc_t-adv_rd_off); + of_property_read_u32(np, gpmc,adv-wr-off, gpmc_t-adv_wr_off); /* WE signal timings */ - if (!of_property_read_u32(np, gpmc,we-on, val)) - gpmc_t-we_on = val; - - if (!of_property_read_u32(np, gpmc,we-off, val)) - gpmc_t
[PATCH V3 11/18] ARM: OMAP2+: Add device-tree support for NOR flash
NOR flash is not currently supported when booting with device-tree on OMAP2+ devices. Add support to detect and configure NOR devices when booting with device-tree. Add documentation for the TI GPMC NOR binding. Signed-off-by: Jon Hunter jon-hun...@ti.com --- Documentation/devicetree/bindings/mtd/gpmc-nor.txt | 98 + arch/arm/mach-omap2/gpmc.c | 115 2 files changed, 213 insertions(+) create mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt new file mode 100644 index 000..8c638fc --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt @@ -0,0 +1,98 @@ +Device tree bindings for NOR flash connect to TI GPMC + +NOR flash connected to the TI GPMC (found on OMAP boards) are represented as +child nodes of the GPMC controller with a name of nor. + +All timing relevant properties as well as generic GPMC child properties are +explained in a separate documents. Please refer to +Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Required properties: +- bank-width: Width of NOR flash in bytes. GPMC supports 8-bit and + 16-bit devices and so must be either 1 or 2 bytes. +- compatible: Documentation/devicetree/bindings/mtd/mtd-physmap.txt +- gpmc,cs-on: Chip-select assertion time +- gpmc,cs-rd-off: Chip-select de-assertion time for reads +- gpmc,cs-wr-off: Chip-select de-assertion time for writes +- gpmc,oe-on: Output-enable assertion time +- gpmc,oe-off Output-enable de-assertion time +- gpmc,we-on: Write-enable assertion time +- gpmc,we-off: Write-enable de-assertion time +- gpmc,access: Start cycle to first data capture (read access) +- gpmc,rd-cycle: Total read cycle time +- gpmc,wr-cycle: Total write cycle time +- linux,mtd-name: Documentation/devicetree/bindings/mtd/mtd-physmap.txt +- reg: Chip-select, base address (relative to chip-select) + and size of NOR flash. Note that base address will be + typically 0 as this is the start of the chip-select. + +Optional properties: +- gpmc,XXX Additional GPMC timings and settings parameters. See + Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Optional properties for partiton table parsing: +- #address-cells: should be set to 1 +- #size-cells: should be set to 1 + +Example: + +gpmc: gpmc@6e00 { + compatible = ti,omap3430-gpmc, simple-bus; + ti,hwmods = gpmc; + reg = 0x6e00 0x1000; + interrupts = 20; + gpmc,num-cs = 8; + gpmc,num-waitpins = 4; + #address-cells = 2; + #size-cells = 1; + + ranges = 0 0 0x1000 0x0800; + + nor@0,0 { + compatible = cfi-flash; + linux,mtd-name= intel,pf48f6000m0y1be; + #address-cells = 1; + #size-cells = 1; + reg = 0 0 0x0800; + bank-width = 2; + + gpmc,mux-add-data; + gpmc,cs-on = 0; + gpmc,cs-rd-off = 186; + gpmc,cs-wr-off = 186; + gpmc,adv-on = 12; + gpmc,adv-rd-off = 48; + gpmc,adv-wr-off = 48; + gpmc,oe-on = 54; + gpmc,oe-off = 168; + gpmc,we-on = 54; + gpmc,we-off = 168; + gpmc,rd-cycle = 186; + gpmc,wr-cycle = 186; + gpmc,access = 114; + gpmc,page-burst-access = 6; + gpmc,bus-turnaround = 12; + gpmc,cycle2cycle-delay = 18; + gpmc,wr-data-mux-bus = 90; + gpmc,wr-access = 186; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + + partition@0 { + label = bootloader-nor; + reg = 0 0x4; + }; + partition@0x4 { + label = params-nor; + reg = 0x4 0x4; + }; + partition@0x8 { + label = kernel-nor; + reg = 0x8 0x20; + }; + partition@0x28 { + label = filesystem-nor; + reg = 0x24 0x7d8; + }; + }; +}; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 1e7eef3..85b1a35 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -26,6 +26,7 @@ #include linux/interrupt.h #include linux/platform_device.h #include linux/of.h +#include linux/of_address.h #include linux/of_mtd.h #include linux/of_device.h #include linux/mtd/nand.h @@ -499,6 +500,37 @@ static int gpmc_cs_delete_mem(int cs
[PATCH V3 14/18] ARM: OMAP2+: Convert ONENAND to retrieve GPMC settings from DT
When booting with device-tree, retrieve GPMC settings for ONENAND from the device-tree blob. This will allow us to remove all static settings stored in the gpmc-nand.c in the future once the migration to device-tree is complete. The user must now specify the ONENAND device width in the device-tree binding so that the GPMC can be programmed correctly. Therefore, update the device-tree binding documentation for ONENAND devices connected to the GPMC to reflect this. Please note that this does not include GPMC timings for ONENAND. The timings are being calculated at runtime. There is some legacy code that only enables read wait monitoring for non-OMAP3 devices. There are no known OMAP3 device issues that prevent this feature being enabled and so when booting with device-tree use the wait-monitoring settings described in the device-tree blob. Signed-off-by: Jon Hunter jon-hun...@ti.com --- .../devicetree/bindings/mtd/gpmc-onenand.txt |3 +++ arch/arm/mach-omap2/gpmc-onenand.c | 21 ++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt index deec9da..b752942 100644 --- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt @@ -10,6 +10,8 @@ Documentation/devicetree/bindings/bus/ti-gpmc.txt Required properties: - reg:The CS line the peripheral is connected to + - gpmc,device-width Width of the ONENAND device connected to the GPMC + in bytes. Must be 1 or 2. Optional properties: @@ -34,6 +36,7 @@ Example for an OMAP3430 board: onenand@0 { reg = 0 0 0; /* CS0, offset 0 */ + gpmc,device-width = 2; #address-cells = 1; #size-cells = 1; diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index 46aac83..64b5a83 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -272,6 +272,10 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base) struct gpmc_timings t; int ret; + if (gpmc_onenand_data-of_node) + gpmc_read_settings_dt(gpmc_onenand_data-of_node, + onenand_async); + omap2_onenand_set_async_mode(onenand_base); omap2_onenand_calc_async_timings(t); @@ -300,12 +304,17 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) set_onenand_cfg(onenand_base); } - /* -* FIXME: Appears to be legacy code from initial ONENAND commit. -* Unclear what boards this is for and if this can be removed. -*/ - if (!cpu_is_omap34xx()) - onenand_sync.wait_on_read = true; + if (gpmc_onenand_data-of_node) { + gpmc_read_settings_dt(gpmc_onenand_data-of_node, + onenand_sync); + } else { + /* +* FIXME: Appears to be legacy code from initial ONENAND commit. +* Unclear what boards this is for and if this can be removed. +*/ + if (!cpu_is_omap34xx()) + onenand_sync.wait_on_read = true; + } omap2_onenand_calc_sync_timings(t, gpmc_onenand_data-flags, freq); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 13/18] ARM: OMAP2+: Convert NAND to retrieve GPMC settings from DT
When booting with device-tree, retrieve GPMC settings for NAND from the device-tree blob. This will allow us to remove all static settings stored in the gpmc-nand.c in the future once the migration to device-tree is complete. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc-nand.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index 12e9753..d9c2719 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c @@ -137,12 +137,16 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, return err; } - s.device_nand = true; - - /* Enable RD PIN Monitoring Reg */ - if (gpmc_nand_data-dev_ready) { - s.wait_on_read = true; - s.wait_on_write = true; + if (gpmc_nand_data-of_node) { + gpmc_read_settings_dt(gpmc_nand_data-of_node, s); + } else { + s.device_nand = true; + + /* Enable RD PIN Monitoring Reg */ + if (gpmc_nand_data-dev_ready) { + s.wait_on_read = true; + s.wait_on_write = true; + } } if (gpmc_nand_data-devsize == NAND_BUSWIDTH_16) -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 15/18] ARM: OMAP2+: Detect incorrectly aligned GPMC base address
Each GPMC chip-select can be configured to map 16MB, 32MB, 64MB or 128MB of address space. The physical base address where a chip-select starts is also configurable and must be aligned on a boundary that is equal to or greater than the size of the address space mapped bt the chip-select. When enabling a GPMC chip-select, ensure that the base address is aligned to the appropriate boundary. Reported-by: Mark Jackson mpfj-l...@mimc.co.uk Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index c928a8c..a6f2b71 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -403,11 +403,18 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) return 0; } -static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) +static int gpmc_cs_enable_mem(int cs, u32 base, u32 size) { u32 l; u32 mask; + /* +* Ensure that base address is aligned on a +* boundary equal to or greater than size. +*/ + if (base (size - 1)) + return -EINVAL; + mask = (1 GPMC_SECTION_SHIFT) - size; l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); l = ~0x3f; @@ -416,6 +423,8 @@ static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) l |= ((mask GPMC_CHUNK_SHIFT) 0x0f) 8; l |= GPMC_CONFIG7_CSVALID; gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); + + return 0; } static void gpmc_cs_disable_mem(int cs) @@ -526,7 +535,9 @@ static int gpmc_cs_remap(int cs, u32 base) ret = gpmc_cs_insert_mem(cs, base, size); if (ret 0) return ret; - gpmc_cs_enable_mem(cs, base, size); + ret = gpmc_cs_enable_mem(cs, base, size); + if (ret 0) + return ret; return 0; } @@ -556,7 +567,12 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) if (r 0) goto out; - gpmc_cs_enable_mem(cs, res-start, resource_size(res)); + r = gpmc_cs_enable_mem(cs, res-start, resource_size(res)); + if (r 0) { + release_resource(res); + goto out; + } + *base = res-start; gpmc_cs_set_reserved(cs, 1); out: -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 16/18] ARM: OMAP2+: Remove unnecesssary GPMC definitions and variable
With commit 21cc2bd (ARM: OMAP2+: Remove apollon board support) the variable boot_rom_space is now not needed and the code surrounding this variable can be cleaned up and simplified. Remove unnecessary definitions and clean-up the comment as well. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index a6f2b71..5239d47 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -92,9 +92,7 @@ #define GPMC_CS_SIZE 0x30 #defineGPMC_BCH_SIZE 0x10 -#define GPMC_MEM_START 0x #define GPMC_MEM_END 0x3FFF -#define BOOT_ROM_SPACE 0x10/* 1MB */ #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ #define GPMC_SECTION_SHIFT 28 /* 128 MB */ @@ -790,13 +788,13 @@ static void gpmc_mem_exit(void) static int gpmc_mem_init(void) { int cs, rc; - unsigned long boot_rom_space = 0; - /* never allocate the first page, to facilitate bug detection; -* even if we didn't boot from ROM. + /* +* The first 1MB of GPMC address space is typically mapped to +* the internal ROM. Never allocate the first page, to +* facilitate bug detection; even if we didn't boot from ROM. */ - boot_rom_space = BOOT_ROM_SPACE; - gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; + gpmc_mem_root.start = SZ_1M; gpmc_mem_root.end = GPMC_MEM_END; /* Reserve all regions that has been set up by bootloader */ -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 17/18] ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails
When the GPMC driver is probed, we call gpmc_mem_init() to see which chip-selects have already been configured and enabled by the boot-loader and allocate space for them. If we fail to allocate space for one chip-select, then we return failure from the probe and the GPMC driver will not be available. Rather than render the GPMC useless for all GPMC devices, if we fail to allocate space for one chip-select print a warning and disable the chip-select. This way other GPMC clients can still be used. There is no downside to this approach, because all GPMC clients need to request a chip-select before they can use the GPMC and on requesting a chip-select, if memory has not already been reserved for the chip-select then it will be. Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc.c | 24 +++- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 5239d47..ee6601c 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -785,9 +785,9 @@ static void gpmc_mem_exit(void) } -static int gpmc_mem_init(void) +static void gpmc_mem_init(void) { - int cs, rc; + int cs; /* * The first 1MB of GPMC address space is typically mapped to @@ -804,16 +804,12 @@ static int gpmc_mem_init(void) if (!gpmc_cs_mem_enabled(cs)) continue; gpmc_cs_get_memconf(cs, base, size); - rc = gpmc_cs_insert_mem(cs, base, size); - if (rc 0) { - while (--cs = 0) - if (gpmc_cs_mem_enabled(cs)) - gpmc_cs_delete_mem(cs); - return rc; + if (gpmc_cs_insert_mem(cs, base, size)) { + pr_warn(%s: disabling cs %d mapped at 0x%x-0x%x\n, + __func__, cs, base, base + size); + gpmc_cs_disable_mem(cs); } } - - return 0; } static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) @@ -1620,13 +1616,7 @@ static int gpmc_probe(struct platform_device *pdev) dev_info(gpmc_dev, GPMC revision %d.%d\n, GPMC_REVISION_MAJOR(l), GPMC_REVISION_MINOR(l)); - rc = gpmc_mem_init(); - if (rc 0) { - clk_disable_unprepare(gpmc_l3_clk); - clk_put(gpmc_l3_clk); - dev_err(gpmc_dev, failed to reserve memory\n); - return rc; - } + gpmc_mem_init(); if (gpmc_setup_irq() 0) dev_warn(gpmc_dev, gpmc_setup_irq failed\n); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
[PATCH V3 18/18] ARM: OMAP2+: return -ENODEV if GPMC child device creation fails
From: Javier Martinez Canillas javier.marti...@collabora.co.uk gpmc_probe_nor_child() calls of_platform_device_create() to create a platform device for the NOR child. If this function fails the value of ret is returned to the caller but this value is zero since it was assigned the return of a previous call to gpmc_cs_program_settings() that had to succeed or otherwise gpmc_probe_nor_child() would have returned before. This means that if of_platform_device_create() fails, 0 will be returned to the caller instead of an appropriate error code. Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk Signed-off-by: Jon Hunter jon-hun...@ti.com --- arch/arm/mach-omap2/gpmc.c |1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ee6601c..d4ec5bb 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1504,6 +1504,7 @@ static int gpmc_probe_nor_child(struct platform_device *pdev, return 0; dev_err(pdev-dev, failed to create gpmc child %s\n, child-name); + ret = -ENODEV; err: gpmc_cs_free(cs); -- 1.7.10.4 ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss
Re: [PATCH v3 3/3] ARM: OMAP2+: Add GPMC DT support for Ethernet child nodes
On 03/14/2013 04:54 PM, Javier Martinez Canillas wrote: Besides being used to interface with external memory devices, the General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices such as ethernet controllers to OMAP2+ processors using the TI GPMC as a data bus. This patch allows an ethernet chip to be defined as an GPMC child device node. Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk --- Changes since v2: - remove optional #address-cells and #size-cells since are not relevant for ethernet chips; suggested by Jon Hunter. Changes since v1: - Improve the DT binding documentation explaining that even when the GPMC maximum bus address width is 16-bit, it supports devices with 32-bit registers address width and the device property especifying this has to be set accordingly; suggested by Jon Hunter. Documentation/devicetree/bindings/net/gpmc-eth.txt | 97 arch/arm/mach-omap2/gpmc.c |8 ++ 2 files changed, 105 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt new file mode 100644 index 000..24cb4e4 --- /dev/null +++ b/Documentation/devicetree/bindings/net/gpmc-eth.txt @@ -0,0 +1,97 @@ +Device tree bindings for Ethernet chip connected to TI GPMC + +Besides being used to interface with external memory devices, the +General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices +such as ethernet controllers to processors using the TI GPMC as a data bus. + +Ethernet controllers connected to TI GPMC are represented as child nodes of +the GPMC controller with an ethernet name. + +All timing relevant properties as well as generic GPMC child properties are +explained in a separate documents. Please refer to +Documentation/devicetree/bindings/bus/ti-gpmc.txt + +For the properties relevant to the ethernet controller connected to the GPMC +refer to the binding documentation of the device. For example, the documentation +for the SMSC 911x is Documentation/devicetree/bindings/net/smsc911x.txt + +Child nodes need to specify the GPMC bus address width using the bank-width +property but is possible that an ethernet controller also has a property to +specify the I/O registers address width. Even when the GPMC has a maximum 16-bit +address width, it supports devices with 32-bit word registers. +For example with an SMSC LAN911x/912x controller connected to the TI GPMC on an +OMAP2+ board, bank-width = 2; and reg-io-width = 4;. + +Required properties: +- bank-width:Address width of the device in bytes. GPMC supports 8-bit + and 16-bit devices and so must be either 1 or 2 bytes. +- compatible:Compatible string property for the ethernet child device. +- gpmc,cs-on:Chip-select assertion time +- gpmc,cs-rd-off:Chip-select de-assertion time for reads +- gpmc,cs-wr-off:Chip-select de-assertion time for writes +- gpmc,oe-on:Output-enable assertion time +- gpmc,oe-offOutput-enable de-assertion time +- gpmc,we-on:Write-enable assertion time +- gpmc,we-off: Write-enable de-assertion time +- gpmc,access: Start cycle to first data capture (read access) +- gpmc,rd-cycle: Total read cycle time +- gpmc,wr-cycle: Total write cycle time +- reg: Chip-select, base address (relative to chip-select) + and size of the memory mapped for the device. + Note that base address will be typically 0 as this + is the start of the chip-select. + +Optional properties: +- gpmc,XXX Additional GPMC timings and settings parameters. See + Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Example: + +gpmc: gpmc@6e00 { + compatible = ti,omap3430-gpmc; + ti,hwmods = gpmc; + reg = 0x6e00 0x1000; + interrupts = 20; + gpmc,num-cs = 8; + gpmc,num-waitpins = 4; + #address-cells = 2; + #size-cells = 1; + + ranges = 5 0 0x2c00 0x100; + + ethernet@5,0 { + compatible = smsc,lan9221, smsc,lan9115; + reg = 5 0 0xff; + bank-width = 2; + + gpmc,mux-add-data; + gpmc,cs-on = 0; + gpmc,cs-rd-off = 186; + gpmc,cs-wr-off = 186; + gpmc,adv-on = 12; + gpmc,adv-rd-off = 48; + gpmc,adv-wr-off = 48; + gpmc,oe-on = 54; + gpmc,oe-off = 168; + gpmc,we-on = 54; + gpmc,we-off = 168; + gpmc,rd-cycle = 186; + gpmc,wr-cycle = 186; + gpmc,access
Re: [PATCH v3 3/3] ARM: OMAP2+: Add GPMC DT support for Ethernet child nodes
Rob, Grant, On 03/15/2013 10:24 AM, Jon Hunter wrote: On 03/14/2013 04:54 PM, Javier Martinez Canillas wrote: Besides being used to interface with external memory devices, the General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices such as ethernet controllers to OMAP2+ processors using the TI GPMC as a data bus. This patch allows an ethernet chip to be defined as an GPMC child device node. Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk --- Changes since v2: - remove optional #address-cells and #size-cells since are not relevant for ethernet chips; suggested by Jon Hunter. Changes since v1: - Improve the DT binding documentation explaining that even when the GPMC maximum bus address width is 16-bit, it supports devices with 32-bit registers address width and the device property especifying this has to be set accordingly; suggested by Jon Hunter. Documentation/devicetree/bindings/net/gpmc-eth.txt | 97 arch/arm/mach-omap2/gpmc.c |8 ++ 2 files changed, 105 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt new file mode 100644 index 000..24cb4e4 --- /dev/null +++ b/Documentation/devicetree/bindings/net/gpmc-eth.txt @@ -0,0 +1,97 @@ +Device tree bindings for Ethernet chip connected to TI GPMC + +Besides being used to interface with external memory devices, the +General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices +such as ethernet controllers to processors using the TI GPMC as a data bus. + +Ethernet controllers connected to TI GPMC are represented as child nodes of +the GPMC controller with an ethernet name. + +All timing relevant properties as well as generic GPMC child properties are +explained in a separate documents. Please refer to +Documentation/devicetree/bindings/bus/ti-gpmc.txt + +For the properties relevant to the ethernet controller connected to the GPMC +refer to the binding documentation of the device. For example, the documentation +for the SMSC 911x is Documentation/devicetree/bindings/net/smsc911x.txt + +Child nodes need to specify the GPMC bus address width using the bank-width +property but is possible that an ethernet controller also has a property to +specify the I/O registers address width. Even when the GPMC has a maximum 16-bit +address width, it supports devices with 32-bit word registers. +For example with an SMSC LAN911x/912x controller connected to the TI GPMC on an +OMAP2+ board, bank-width = 2; and reg-io-width = 4;. + +Required properties: +- bank-width: Address width of the device in bytes. GPMC supports 8-bit +and 16-bit devices and so must be either 1 or 2 bytes. +- compatible: Compatible string property for the ethernet child device. +- gpmc,cs-on: Chip-select assertion time +- gpmc,cs-rd-off: Chip-select de-assertion time for reads +- gpmc,cs-wr-off: Chip-select de-assertion time for writes +- gpmc,oe-on: Output-enable assertion time +- gpmc,oe-off Output-enable de-assertion time +- gpmc,we-on: Write-enable assertion time +- gpmc,we-off: Write-enable de-assertion time +- gpmc,access: Start cycle to first data capture (read access) +- gpmc,rd-cycle:Total read cycle time +- gpmc,wr-cycle:Total write cycle time +- reg: Chip-select, base address (relative to chip-select) +and size of the memory mapped for the device. +Note that base address will be typically 0 as this +is the start of the chip-select. + +Optional properties: +- gpmc,XXX Additional GPMC timings and settings parameters. See +Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Example: + +gpmc: gpmc@6e00 { +compatible = ti,omap3430-gpmc; +ti,hwmods = gpmc; +reg = 0x6e00 0x1000; +interrupts = 20; +gpmc,num-cs = 8; +gpmc,num-waitpins = 4; +#address-cells = 2; +#size-cells = 1; + +ranges = 5 0 0x2c00 0x100; + +ethernet@5,0 { +compatible = smsc,lan9221, smsc,lan9115; +reg = 5 0 0xff; +bank-width = 2; + +gpmc,mux-add-data; +gpmc,cs-on = 0; +gpmc,cs-rd-off = 186; +gpmc,cs-wr-off = 186; +gpmc,adv-on = 12; +gpmc,adv-rd-off = 48; +gpmc,adv-wr-off = 48; +gpmc,oe-on = 54; +gpmc,oe-off = 168; +gpmc,we-on = 54; +gpmc,we-off = 168; +gpmc,rd-cycle = 186; +gpmc,wr-cycle = 186; +gpmc
Re: [PATCH 3/3] ARM: OMAP2+: Add GPMC DT support for Ethernet child nodes
Hi Javier, On 03/14/2013 10:09 AM, Javier Martinez Canillas wrote: Besides being used to interface with external memory devices, the General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices such as ethernet controllers to OMAP2+ processors using the TI GPMC as a data bus. This patch allows an ethernet chip to be defined as an GPMC child device node. Signed-off-by: Javier Martinez Canillas javier.marti...@collabora.co.uk --- Documentation/devicetree/bindings/net/gpmc-eth.txt | 90 arch/arm/mach-omap2/gpmc.c |8 ++ 2 files changed, 98 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt new file mode 100644 index 000..c45363c --- /dev/null +++ b/Documentation/devicetree/bindings/net/gpmc-eth.txt @@ -0,0 +1,90 @@ +Device tree bindings for Ethernet chip connected to TI GPMC + +Besides being used to interface with external memory devices, the +General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices +such as ethernet controllers to processors using the TI GPMC as a data bus. + +Ethernet controllers connected to TI GPMC are represented as child nodes of +the GPMC controller with an ethernet name. + +All timing relevant properties as well as generic GPMC child properties are +explained in a separate documents. Please refer to +Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Required properties: +- bank-width:Address width of the device in bytes. GPMC supports 8-bit + and 16-bit devices and so must be either 1 or 2 bytes. I am wondering if we should use reg-io-width here. The smsc driver is using this to determine the width of the device. And so I am wondering if this could cause problems. Obviously this complicates gpmc_probe_generic_child() a little, but may be would could pass the name of the width property to gpmc_probe_generic_child() as well. What do you think? +- compatible:Compatible string property for the ethernet child device. +- gpmc,cs-on:Chip-select assertion time +- gpmc,cs-rd-off:Chip-select de-assertion time for reads +- gpmc,cs-wr-off:Chip-select de-assertion time for writes +- gpmc,oe-on:Output-enable assertion time +- gpmc,oe-offOutput-enable de-assertion time +- gpmc,we-on:Write-enable assertion time +- gpmc,we-off: Write-enable de-assertion time +- gpmc,access: Start cycle to first data capture (read access) +- gpmc,rd-cycle: Total read cycle time +- gpmc,wr-cycle: Total write cycle time +- reg: Chip-select, base address (relative to chip-select) + and size of the memory mapped for the device. + Note that base address will be typically 0 as this + is the start of the chip-select. + +Optional properties: +- gpmc,XXX Additional GPMC timings and settings parameters. See + Documentation/devicetree/bindings/bus/ti-gpmc.txt + +Optional properties for partiton table parsing: +- #address-cells: should be set to 1 +- #size-cells: should be set to 1 + +Example: + +gpmc: gpmc@6e00 { + compatible = ti,omap3430-gpmc; + ti,hwmods = gpmc; + reg = 0x6e00 0x1000; + interrupts = 20; + gpmc,num-cs = 8; + gpmc,num-waitpins = 4; + #address-cells = 2; + #size-cells = 1; + + ranges = 5 0 0x2c00 0x100; + + ethernet@5,0 { + compatible = smsc,lan9221, smsc,lan9115; + reg = 5 0 0xff; + bank-width = 2; + + gpmc,mux-add-data; + gpmc,cs-on = 0; + gpmc,cs-rd-off = 186; + gpmc,cs-wr-off = 186; + gpmc,adv-on = 12; + gpmc,adv-rd-off = 48; + gpmc,adv-wr-off = 48; + gpmc,oe-on = 54; + gpmc,oe-off = 168; + gpmc,we-on = 54; + gpmc,we-off = 168; + gpmc,rd-cycle = 186; + gpmc,wr-cycle = 186; + gpmc,access = 114; + gpmc,page-burst-access = 6; + gpmc,bus-turnaround = 12; + gpmc,cycle2cycle-delay = 18; + gpmc,wr-data-mux-bus = 90; + gpmc,wr-access = 186; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + + interrupt-parent = gpio6; + interrupts = 16; + vmmc-supply = vddvario; + vmmc_aux-supply = vdd33a; + reg-io-width = 2; + + smsc,save-mac-address; + }; +}; diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 898b44d..2bc276b 100644
Re: [PATCH 5/9] ARM: dts: Add GPMC node for OMAP2, OMAP4 and OMAP5
On 03/14/2013 10:45 AM, Benoit Cousson wrote: On 03/11/2013 06:56 PM, Jon Hunter wrote: On 03/09/2013 06:42 AM, Ezequiel Garcia wrote: On Fri, Mar 8, 2013 at 10:25 PM, Javier Martinez Canillas jav...@dowhile0.org wrote: On Fri, Mar 8, 2013 at 10:41 PM, Jon Hunter jon-hun...@ti.com wrote: Yes you are correct. In general, I have been trying to stay some-what consistent with what hwmod was doing as this was being auto-generated by some hardware design specs and I believe they wanted to eventually get to the point where DT files would be auto-generated too for OMAP. Furthermore my understanding is that the smallest page that can be mapped by the kernel for ARM is 4kB. So if you declare it as 0x2d0 or 0x1000 it will map a 4kB page (I could be wrong here). I don't have any strong feelings here but will do what the consensus prefers. Yes, you are right here. I forget that ioremap() does a page-aligned mapping and since the minimum page size for ARM is 4KB as you said, there is no difference between using 0x2d0 and 0x1000. Sorry for the noise. Certainly, I don't have strong feelings about this. FWIW, mvebu maintainers imposes a minimal address space request policy. On the other side, it seems to me we shouldn't look at internal kernel implementation (i.e. ioremap page-alignment) to make this decision. I agree with that. I am not sure if Tony/Benoit have any comments on what they would like to do here to be consistent for the omap bindings. Yes, I full agree with that as well. The size should be purely HW related. So we should not take any assumption about the page size / alignment. Ok, what is best to use? The size from hwmod structures or the size from the documentation? Cheers Jon ___ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss