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.

NAND configuration problem on AM335x

Dear community,

I have got some problem configuring NAND flash on my custom board for AM335x processor.

The thing is that the configuration works on using Linux build from custom board supplier. However the Linux version was used very old (3.12), and I have used TI mainline linux 4.2. I would like to boot from NAND flash but fail on configuration.

I have copied all device tree bindings from the version that is working, however fail with GPMC with following dmesg messages:

[ 1.309402] mtdoops: mtd device (mtddev=name/number) must be supplied
[ 1.318071] omap2-nand 50000000.gpmc: Failed to get GPMC->NAND interface

For bootloader I use Barebox bootloader and it is able to detect NAND and allocate all required partitions, however linux kernel fails.

Any suggestions about what might be wrong?

Looking forward to Your replies,

King regards,

Ilja.

  • Hi,

    I will ask the software team to comment. However my first suggestion is that you use the officially released Linux SDK, which can be downloaded from here: software-dl.ti.com/.../index_FDS.html
  • I am currently using ti-processor-sdk-linux-am335x-evm-02.00.00.00 sdk. Do you think there might be essential changes that can help to solve NAND issue?

    Best regards,
    Ilja
  • No, your version should be fine. I have asked the software team to help.
  • Currently I have a different problem with nand, which looks like this:

    [ 1.797298] omap-gpmc 50000000.gpmc: GPMC revision 6.0
    [ 1.802853] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
    [ 1.810106] omap-gpmc 50000000.gpmc: cannot request GPMC CS 0
    [ 1.816232] omap-gpmc 50000000.gpmc: failed to probe DT children
    [ 1.822987] mmc0: new high speed SDHC card at address 1234
    [ 1.829989] mmcblk0: mmc0:1234 SA08G 7.21 GiB
    [ 1.836478] omap-gpmc: probe of 50000000.gpmc failed with error -16

    I am checking with the working custom linux which is (v3.12) and the boot sequence is different:
    [ 1.797298] omap-gpmc 50000000.gpmc: GPMC revision 6.0
    [ 1.802853] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
    nand: ONFI param page 0 valid
    nand: ONFI flash detected

    I am still wondering if there is a device tree issue or maybe kernel configuration.

    Any suggestion would be great,

    Best regards,
    Ilja
  • Hi Ilja,

    Can you execute of_dump from barebox, & share the output (your DTS configuration)?

    Best Regars,
    Yordan
  • Here is the last part of the device tree:


    elm@48080000 {
    compatible = "ti,am3352-elm";
    reg = <0x48080000 0x2000>;
    interrupts = <0x4>;
    ti,hwmods = "elm";
    status = "disabled";
    linux,phandle = <0x34>;
    phandle = <0x34>;
    };
    lcdc@4830e000 {
    compatible = "ti,am33xx-tilcdc";
    reg = <0x4830e000 0x1000>;
    interrupt-parent = <0x1>;
    interrupts = <0x24>;
    ti,hwmods = "lcdc";
    status = "disabled";
    };
    tscadc@44e0d000 {
    compatible = "ti,am3359-tscadc";
    reg = <0x44e0d000 0x1000>;
    interrupt-parent = <0x1>;
    interrupts = <0x10>;
    ti,hwmods = "adc_tsc";
    status = "disabled";
    tsc {
    compatible = "ti,am3359-tsc";
    };
    adc {
    #io-channel-cells = <0x1>;
    compatible = "ti,am3359-adc";
    };
    };
    gpmc@50000000 {
    compatible = "ti,am3352-gpmc";
    ti,hwmods = "gpmc";
    ti,no-idle-on-init;
    reg = <0x50000000 0x2000>;
    interrupts = <0x64>;
    gpmc,num-cs = <0x7>;
    gpmc,num-waitpins = <0x2>;
    #address-cells = <0x2>;
    #size-cells = <0x1>;
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <0x33>;
    ranges = <0x0 0x0 0x8000000 0x10000000>;
    nand@0,0 {
    reg = <0x0 0x0 0x0>;
    nand-bus-width = <0x8>;
    ti,nand-ecc-opt = "bch8";
    gpmc,device-nand = "true";
    gpmc,device-width = <0x1>;
    gpmc,sync-clk-ps = <0x0>;
    gpmc,cs-on-ns = <0x0>;
    gpmc,cs-rd-off-ns = <0x1e>;
    gpmc,cs-wr-off-ns = <0x1e>;
    gpmc,adv-on-ns = <0x0>;
    gpmc,adv-rd-off-ns = <0x1e>;
    gpmc,adv-wr-off-ns = <0x1e>;
    gpmc,we-on-ns = <0x0>;
    gpmc,we-off-ns = <0x14>;
    gpmc,oe-on-ns = <0xa>;
    gpmc,oe-off-ns = <0x1e>;
    gpmc,access-ns = <0x1e>;
    gpmc,rd-cycle-ns = <0x1e>;
    gpmc,wr-cycle-ns = <0x1e>;
    gpmc,wait-pin = <0x1>;
    gpmc,wait-on-read = "true";

    gpmc,wait-on-write = "true";
    gpmc,bus-turnaround-ns = <0x0>;
    gpmc,cycle2cycle-delay-ns = <0x32>;
    gpmc,cycle2cycle-diffcsen;
    gpmc,clk-activation-ns = <0x0>;
    gpmc,wait-monitoring-ns = <0x0>;
    gpmc,wr-access-ns = <0x0>;
    gpmc,wr-data-mux-bus-ns = <0x0>;
    #address-cells = <0x1>;
    #size-cells = <0x1>;
    elm_id = <0x34>;
    partition@0 {
    label = "xload";
    reg = <0x0 0x20000>;
    };
    partition@1 {
    label = "xload_backup1";
    reg = <0x20000 0x20000>;
    };
    partition@2 {
    label = "xload_backup2";
    reg = <0x40000 0x20000>;
    };
    partition@3 {
    label = "xload_backup3";
    reg = <0x60000 0x20000>;
    };
    partition@4 {
    label = "barebox";
    reg = <0x80000 0x80000>;
    };
    partition@5 {
    label = "bareboxenv";
    reg = <0x100000 0x40000>;
    };
    partition@6 {
    label = "oftree";
    reg = <0x140000 0x40000>;
    };
    partition@7 {
    label = "kernel";
    reg = <0x180000 0x800000>;
    };
    partition@8 {
    label = "root";
    reg = <0x980000 0x0>;
    };
    };
    };

    sham@53100000 {
    compatible = "ti,omap4-sham";
    ti,hwmods = "sham";
    reg = <0x53100000 0x200>;
    interrupts = <0x6d>;
    dmas = <0x25 0x24>;
    dma-names = "rx";
    };
    aes@53500000 {
    compatible = "ti,omap4-aes";
    ti,hwmods = "aes";
    reg = <0x53500000 0xa0>;
    interrupts = <0x67>;
    dmas = <0x25 0x6 0x25 0x5>;
    dma-names = "tx", "rx";
    };
    mcasp@48038000 {
    compatible = "ti,am33xx-mcasp-audio";
    ti,hwmods = "mcasp0";
    reg = <0x48038000 0x2000 0x46000000 0x400000>;
    reg-names = "mpu", "dat";
    interrupts = <0x50 0x51>;
    interrupt-names = "tx", "rx";
    status = "disabled";
    dmas = <0x25 0x8 0x25 0x9>;
    dma-names = "tx", "rx";
    };
    mcasp@4803C000 {
    compatible = "ti,am33xx-mcasp-audio";
    ti,hwmods = "mcasp1";
    reg = <0x4803c000 0x2000 0x46400000 0x400000>;
    reg-names = "mpu", "dat";
    interrupts = <0x52 0x53>;
    interrupt-names = "tx", "rx";
    status = "disabled";
    dmas = <0x25 0xa 0x25 0xb>;
    dma-names = "tx", "rx";
    };
    rng@48310000 {
    compatible = "ti,omap4-rng";
    ti,hwmods = "rng";
    reg = <0x48310000 0x2000>;
    interrupts = <0x6f>;
    };
    };
    };
  • Hi Ilja,

    The first thing I notice is:
    pinctrl-names = "default";
    pinctrl-0 = <0x33>;

    pinctrl-0=<0x33> is not valid input for GPMC pins. You need to have something like:
    pinctrl-names="default";
    pinctrl-0 = <&nandflash_pins_default>;

    Where nandflash_pins_default are defined like:
    nandflash_pins_default: nandflash_pins_default {
    pinctrl-single,pins = <
    0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
    0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
    0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
    0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
    0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
    0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
    0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
    0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
    0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
    0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */
    0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
    0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
    0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
    0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
    0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
    >;
    };
    Above sample of code is taken from am335x-evm.dts. Have a look at your schematic & configure the appropriate pins, as shown.

    Then, try using the following additional settings in the gpmc node:
    nand@0,0 {
    reg = <0x0 0x0 0x4>; /*equvalent to: CS0, offset 0, IO size 4 */
    Use: ti,elm-id = <&elm>; where
    &elm {
    status = "okay";
    };
    Also the full dtsi elm node is:
    elm: elm@48080000 {
    compatible = "ti,am3352-elm";
    reg = <0x48080000 0x2000>;
    interrupts = <4>;
    ti,hwmods = "elm";
    status = "disabled";
    };
    Also verify that your timing parameters match the requirements in your NAND chip datasheet.

    Best Regards,
    Yordan
  • Dear Yordan,
    Thank you very much for your reply.

    Well first of all, the of_dumb has been done from Barebox, where the NAND is detected and configured. From barebox I can see all the partitions, upload filesystem, kernel etc. So this is weird, if pinctrl-0 = <0x33>; in barebox and it still works. Here is what barebox detects:
    nand: ONFI param page 0 valid
    nand: ONFI flash detected
    nand: NAND device: Manufacturer ID: 0x2c, Chip ID: 0xdc (Micron MT29F4G08ABADAH4), 512MiB, page size: 2048, OOB size: 64


    The problem occurs when I boot kernel. As I wrote before, the NAND can be configured from kernel on the older(3.12.xx) linux versions which are custom from the supplier. When I use old zImage and DTB, the nand configures fine.
    I have taken all device tree sources and checked kernel configuration for my newer linux version and here I fail with detecting.
    The timing has been taken from the sources of custom kernel device tree.
    am335x-phycore-som.dtsi:
    /* This is a dummy node. Will be set by a bootloader */
    memory {
    device_type = "memory";
    reg = <0x80000000 0x20000000>; /* 512 MB */
    };

    &am33xx_pinmux {
    nandflash_pins: pinmux_nandflash {
    pinctrl-single,pins = <
    0x0 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
    0x4 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
    0x8 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
    0xc (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
    0x10 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
    0x14 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
    0x18 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
    0x1c (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
    0x70 (PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
    0x7c (PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
    0x90 (PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
    0x94 (PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
    0x98 (PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
    0x9c (PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
    >;
    };
    };

    &elm {
    status = "okay";
    };

    &gpmc {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&nandflash_pins>;
    ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */
    nandflash: nand@0,0 {
    reg = <0 0 0>; /* CS0, offset 0 */
    nand-bus-width = <8>;
    ti,nand-ecc-opt = "bch8";
    gpmc,device-nand = "true";
    gpmc,device-width = <1>;
    gpmc,sync-clk-ps = <0>;
    gpmc,cs-on-ns = <0>;
    gpmc,cs-rd-off-ns = <30>;
    gpmc,cs-wr-off-ns = <30>;
    gpmc,adv-on-ns = <0>;
    gpmc,adv-rd-off-ns = <30>;
    gpmc,adv-wr-off-ns = <30>;
    gpmc,we-on-ns = <0>;
    gpmc,we-off-ns = <20>;
    gpmc,oe-on-ns = <10>;
    gpmc,oe-off-ns = <30>;
    gpmc,access-ns = <30>;
    gpmc,rd-cycle-ns = <30>;
    gpmc,wr-cycle-ns = <30>;
    gpmc,wait-pin = <1>;
    gpmc,wait-on-read = "true";
    gpmc,wait-on-write = "true";
    gpmc,bus-turnaround-ns = <0>;
    gpmc,cycle2cycle-delay-ns = <50>;
    gpmc,cycle2cycle-diffcsen;
    gpmc,clk-activation-ns = <0>;
    gpmc,wait-monitoring-ns = <0>;
    gpmc,wr-access-ns = <0>;
    gpmc,wr-data-mux-bus-ns = <0>;

    ti,elm_id = <&elm>;

    #address-cells = <1>;
    #size-cells = <1>;
    };
    };

    am335x-phycore-rdk.dts:
    &nandflash {
    status = "okay";
    partition@0 {
    label = "xload";
    reg = <0x0 0x20000>;
    };

    partition@1 {
    label = "xload_backup1";
    reg = <0x20000 0x20000>;
    };

    partition@2 {
    label = "xload_backup2";
    reg = <0x40000 0x20000>;
    };

    partition@3 {
    label = "xload_backup3";
    reg = <0x60000 0x20000>;
    };

    partition@4 {
    label = "barebox";
    reg = <0x80000 0x80000>;
    };

    partition@5 {
    label = "bareboxenv";
    reg = <0x100000 0x40000>;
    };

    partition@6 {
    label = "oftree";
    reg = <0x140000 0x40000>;

    };

    partition@7 {
    label = "kernel";
    reg = <0x180000 0x800000>;
    };

    partition@8 {
    label = "root";
    /*
    * setting size to 0x0 here, size will be extended to
    * end of nand flash while booting.
    */
    reg = <0x980000 0x0>;
    };
    };

    am33xx.dtsi:
    elm: elm@48080000 {
    compatible = "ti,am3352-elm";
    reg = <0x48080000 0x2000>;
    interrupts = <4>;
    ti,hwmods = "elm";
    status = "disabled";
    };
    gpmc: gpmc@50000000 {
    compatible = "ti,am3352-gpmc";
    ti,hwmods = "gpmc";
    ti,no-idle-on-init;
    reg = <0x50000000 0x2000>;
    interrupts = <100>;
    gpmc,num-cs = <7>;
    gpmc,num-waitpins = <2>;
    #address-cells = <2>;
    #size-cells = <1>;
    gpio-controller;
    #gpio-cells = <2>;
    interrupt-controller;
    #interrupt-cells = <2>;
    status = "disabled";
    };

    Here is what happens at booting stage:
    [ 1.784869] omap-gpmc 50000000.gpmc: GPMC revision 6.0
    [ 1.790433] gpmc_mem_init: disabling cs 0 mapped at 0x0-0x1000000
    [ 1.797705] omap-gpmc 50000000.gpmc: cannot request GPMC CS 0
    [ 1.803859] omap-gpmc 50000000.gpmc: failed to probe DT children

    consecuently, nand is not detected, and UBI rootfs from nand cannot be booted. everything is freezes.

    I have checked the configuration multiple times, and still the driver fails to probe gpmc, especially with CS 0 pin. And again, it doesn't happen with custom builds.

    Any suggestions? Is there a way to tell linux kernel to leave nand configuration the same way as it already configured in Barebox?

    BR,
    Ilja.