This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

am335x: GPMC with two NAND flash in Device Tree

Hello;
I am developing Device tree description for a custom board using AM335x SoC equipped with two NAND flash chips connected to the GPMC. Do I understand it correctly that since only one NAND chip is configured in the U-boot, it is not possible to use two NAND chips in FDT Linux? My understanding comes from this document: https://git.kernel.org/cgit/linux/kernel/git/tmlind/linux-omap.git/tree/Documentation/devicetree/bindings/bus/ti-gpmc.txt#n30

When I try to define the NAND flash chips as follows:

&gpmc {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&nandflash_pins_s0>;
	ranges = <0 0 0x08000000 0x01000000   /* CS0 0 @addr 0x08000000, size 0x01000000 */
		  1 0 0x09000000 0x01000000>; /* CS1 */
	nand@0,0 {
		reg = <0 0 0x01000000>; /* CS0 */
		ti,nand-ecc-opt = "bch8";
		ti,elm-id = <&elm>;
		nand-bus-width = <8>;
		/* ...
		   ...
		*/	};
	nand@1,0 {
		reg = <1 0 0x01000000>; /* CS1 */
		ti,nand-ecc-opt = "bch8";
		ti,elm-id = <&elm>;
		nand-bus-width = <8>;
		/* ...
		   ...
		*/
	};
};

I get the following messages in kernel log during boot:

[    2.492863] omap-gpmc 50000000.gpmc: GPMC revision 6.0
[    2.500541] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1
[    2.507375] nand: Micron MT29F1G08ABADAH4
[    2.511602] nand: 128MiB, SLC, page size: 2048, OOB size: 64
[    2.517610] nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme
[    2.540205] kobject (c08a4b10): tried to init an initialized object, something is seriously wrong.
[    2.549824] CPU: 0 PID: 6 Comm: kworker/u2:0 Tainted: G        W     3.15.0-rc5-12766-g8e7bffa-dirty #22
[    2.559881] Workqueue: deferwq deferred_probe_work_func
[    2.565492] [<c00147dc>] (unwind_backtrace) from [<c00119a8>] (show_stack+0x10/0x14)
[    2.573719] [<c00119a8>] (show_stack) from [<c057a8c0>] (dump_stack+0x80/0x9c)
[    2.581340] [<c057a8c0>] (dump_stack) from [<c02fa080>] (kobject_init+0x74/0x94)
[    2.589199] [<c02fa080>] (kobject_init) from [<c0376cf8>] (device_initialize+0x20/0xc4)
[    2.597692] [<c0376cf8>] (device_initialize) from [<c037bd6c>] (platform_device_register+0x10/0x24)
[    2.607283] [<c037bd6c>] (platform_device_register) from [<c00388d4>] (gpmc_nand_init+0x118/0x224)
[    2.616789] [<c00388d4>] (gpmc_nand_init) from [<c00246f8>] (gpmc_probe+0x52c/0x834)
[    2.625004] [<c00246f8>] (gpmc_probe) from [<c037b738>] (platform_drv_probe+0x18/0x48)
[    2.633394] [<c037b738>] (platform_drv_probe) from [<c037a3dc>] (driver_probe_device+0x10c/0x238)
[    2.642795] [<c037a3dc>] (driver_probe_device) from [<c0378ac4>] (bus_for_each_drv+0x44/0x8c)
[    2.651769] [<c0378ac4>] (bus_for_each_drv) from [<c037a298>] (device_attach+0x74/0x8c)
[    2.660247] [<c037a298>] (device_attach) from [<c0379968>] (bus_probe_device+0x88/0xb0)
[    2.668724] [<c0379968>] (bus_probe_device) from [<c0379d6c>] (deferred_probe_work_func+0x64/0x94)
[    2.678211] [<c0379d6c>] (deferred_probe_work_func) from [<c0057654>] (process_one_work+0x1b4/0x4bc)
[    2.687877] [<c0057654>] (process_one_work) from [<c0057d3c>] (worker_thread+0x11c/0x398)
[    2.696547] [<c0057d3c>] (worker_thread) from [<c005e318>] (kthread+0xc8/0xe4)
[    2.704209] [<c005e318>] (kthread) from [<c000e808>] (ret_from_fork+0x14/0x2c)
[    2.711845] ------------[ cut here ]------------
[    2.716781] WARNING: CPU: 0 PID: 6 at /tmp/linux-omap/kernel/resource.c:638 __insert_resource+0x124/0x130()
[    2.730086] Modules linked in:
[    2.733369] CPU: 0 PID: 6 Comm: kworker/u2:0 Tainted: G        W     3.15.0-rc5-12766-g8e7bffa-dirty #22
[    2.743397] Workqueue: deferwq deferred_probe_work_func
[    2.748921] [<c00147dc>] (unwind_backtrace) from [<c00119a8>] (show_stack+0x10/0x14)
[    2.757135] [<c00119a8>] (show_stack) from [<c057a8c0>] (dump_stack+0x80/0x9c)
[    2.764797] [<c057a8c0>] (dump_stack) from [<c003f79c>] (warn_slowpath_common+0x6c/0x90)
[    2.773368] [<c003f79c>] (warn_slowpath_common) from [<c003f7dc>] (warn_slowpath_null+0x1c/0x24)
[    2.782669] [<c003f7dc>] (warn_slowpath_null) from [<c0044e40>] (__insert_resource+0x124/0x130)
[    2.791831] [<c0044e40>] (__insert_resource) from [<c0045ac4>] (insert_resource_conflict+0x24/0x3c)
[    2.801408] [<c0045ac4>] (insert_resource_conflict) from [<c0045ae4>] (insert_resource+0x8/0x18)
[    2.810711] [<c0045ae4>] (insert_resource) from [<c037b8b8>] (platform_device_add+0x88/0x210)
[    2.819741] [<c037b8b8>] (platform_device_add) from [<c00388d4>] (gpmc_nand_init+0x118/0x224)
[    2.828773] [<c00388d4>] (gpmc_nand_init) from [<c00246f8>] (gpmc_probe+0x52c/0x834)
[    2.836982] [<c00246f8>] (gpmc_probe) from [<c037b738>] (platform_drv_probe+0x18/0x48)
[    2.845371] [<c037b738>] (platform_drv_probe) from [<c037a3dc>] (driver_probe_device+0x10c/0x238)
[    2.854763] [<c037a3dc>] (driver_probe_device) from [<c0378ac4>] (bus_for_each_drv+0x44/0x8c)
[    2.863789] [<c0378ac4>] (bus_for_each_drv) from [<c037a298>] (device_attach+0x74/0x8c)
[    2.872215] [<c037a298>] (device_attach) from [<c0379968>] (bus_probe_device+0x88/0xb0)
[    2.880692] [<c0379968>] (bus_probe_device) from [<c0379d6c>] (deferred_probe_work_func+0x64/0x94)
[    2.890176] [<c0379d6c>] (deferred_probe_work_func) from [<c0057654>] (process_one_work+0x1b4/0x4bc)
[    2.899842] [<c0057654>] (process_one_work) from [<c0057d3c>] (worker_thread+0x11c/0x398)
[    2.908505] [<c0057d3c>] (worker_thread) from [<c005e318>] (kthread+0xc8/0xe4)
[    2.916165] [<c005e318>] (kthread) from [<c000e808>] (ret_from_fork+0x14/0x2c)
[    2.923813] ---[ end trace aabf67c205bfd88e ]---
[    2.928684] omap2-nand omap2-nand.0: failed to claim resource 0
[    2.934968] omap2-nand omap2-nand.0: Unable to register NAND device

The kernel I am using is 3.15-rc5 from the kernel.org linux-omap repository.

Am I doing something wrong or the GPMC driver is lacking the capability of defining multiple NAND flash chips entirely in Device tree?

Thank you for any suggestions;

  • Moving to Sitara Forum.

    I'll ask the factory team for details on the bootloader related comment inside the gpmc device tree bindings document.

    Have you checked the am335x-evm.dts default device tree for gpmc configuration reference?

    Best regards,
    Miroslav

  • OK; Thanks;

    I have definitely checked all the am335*.dts present in kernel, however none of those has more than single device/chip connected to the GPMC. I need to connect two flash chips at the same time.

    Regards;
    Rostislav Lisovy

  • I have not set up a device tree for two devices on GPMC, but take a look at the omap3-sdp.dts as an example. It has NOR, NAND, and OneNAND on 3 different chip selects on the GPMC. Maybe this could be a good example?

    As for u-boot, maybe take a look in arch/arm/cpu/armv7/omap-common/mem-common.c. Under the ifdef for NAND, add another entry for the second chip select.

    Steve K.

  • Dear Steve;

    Thank you for the hint. It looks quite like something I would like to achieve. At the same time it almost proves my DT definition is correct however does not work :-(

    I would like to avoid any u-boot modification right now (my task is to do create the Device tree).

    Regards;
    Rostislav Lisovy

  • Hello Miroslav;
    Do you have some new information?

    Best regards;
    Rostislav Lisovy

  • Rostislav, I don't. I believe that if someone else from the factory team has any suggestions, they will post them directly here.

    Best regards,
    Miroslav

  • The following patch solves the issue: https://lkml.org/lkml/2014/6/4/382

    Rostislav;

  • Hi, Rostislav,

    Are succeeded with two flashes on GPMC? Could you share your *dts file or just part with GPMC? I am trying with no success for days.
  • Hi Linas;

    I am not sure at which state it is right now, but approx. half a year ago the patch was merged into the Linux kernel (you can check my patches in kernel git).

    I am not sure whether this will work with the newest kernel, however it worked for me at the time of development:

    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&nandflash_pins_s0>;
    	ranges = <0 0 0x08000000 0x01000000 	/* CS0 0 @addr 0x08000000, size 0x01000000 */
    		  1 0 0x09000000 0x01000000>; 	/* CS1 0 @addr 0x09000000, size 0x01000000 */
    	nand@0,0 {
    		reg = <0 0 0x01000000>; /* CS0 */
    		ti,nand-ecc-opt = "bch8";
    		ti,elm-id = <&elm>;
    		nand-bus-width = <8>;
    		gpmc,device-width = <1>;
    		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-on-ns = <0>;
    		gpmc,we-off-ns = <40>;
    		gpmc,oe-on-ns = <0>;
    		gpmc,oe-off-ns = <54>;
    		gpmc,access-ns = <64>;
    		gpmc,rd-cycle-ns = <82>;
    		gpmc,wr-cycle-ns = <82>;
    		gpmc,wait-on-read = "true";
    		gpmc,wait-on-write = "true";
    		gpmc,bus-turnaround-ns = <0>;
    		gpmc,cycle2cycle-delay-ns = <0>;
    		gpmc,clk-activation-ns = <0>;
    		gpmc,wait-monitoring-ns = <0>;
    		gpmc,wr-access-ns = <40>;
    		gpmc,wr-data-mux-bus-ns = <0>;
    	};
    	nand@1,0 {
    		reg = <1 0 0x01000000>; /* CS1 */
    		ti,nand-ecc-opt = "bch8";
    		ti,elm-id = <&elm>;
    		nand-bus-width = <8>;
    		gpmc,device-width = <1>;
    		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-on-ns = <0>;
    		gpmc,we-off-ns = <40>;
    		gpmc,oe-on-ns = <0>;
    		gpmc,oe-off-ns = <54>;
    		gpmc,access-ns = <64>;
    		gpmc,rd-cycle-ns = <82>;
    		gpmc,wr-cycle-ns = <82>;
    		gpmc,wait-on-read = "true";
    		gpmc,wait-on-write = "true";
    		gpmc,bus-turnaround-ns = <0>;
    		gpmc,cycle2cycle-delay-ns = <0>;
    		gpmc,clk-activation-ns = <0>;
    		gpmc,wait-monitoring-ns = <0>;
    		gpmc,wr-access-ns = <40>;
    		gpmc,wr-data-mux-bus-ns = <0>;
    	};