IFC NAND not working in Kernel

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IFC NAND not working in Kernel

2,784 Views
pranavmadhu
Contributor IV

Hi,

I'm having a custom LS1021a board. We have a 1GB NAND Flash mounted on IFC  AD0-AD7 line. We are able to access the NAND from u-boot, but it fails on linux. The dmesg for its driver is

[   71.345016] fsl-ifc 153000000010000.ifc: Freescale Integrated Flash Controller

[   71.345037] fsl-ifc 153000000010000.ifc: failed to get memory region

[   97.042203] fsl,ifc-nand 0.ifc: fsl_ifc_nand_probe: failed to get resource

[   97.049056] fsl,ifc-nand: probe of 0.ifc failed with error -22

The device tree modification for ifc is provided below

ls1021a.dtsi

----------------

        ifc: ifc@1530000 {

            compatible = "fsl,ifc-nand","simple-bus","fsl,ls1021a-ifc", "fsl,ifc";

            reg = <0x0 0x1530000 0x0 0x10000>;

            interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;

            status="disabled";

            ranges=<0x0 0x0 0x0 0x7e800000 0x00010000>;

            flash@0,0 {

                            #address-cells = <1>;

                            #size-cells = <1>;

                            compatible = "fsl,ifc-nand";

                            reg = <0x0 0x0 0x10000>;

                            bank-width = <2>;

                            device-width = <1>;

                              partition@0 {

                                   /* 32MB for user data */

                                   reg = <0x0 0x02000000>;

                                   label = "NAND Data";

                              };

                    };

          };

ls1021a-iot.dts

--------------------

&ifc {

    status = "okay";

    compatible = "fsl,ifc-nand";

    #address-cells = <1>;

    #size-cells = <1>;

    reg = <0x0 0x0 0x10000>;

/*    ranges = < 0x1 0x0 0x0 0xffa00000 0x00010000 >;*/

    partition@0 {

        reg = <0x0 0x40000000>;

        label = "NAND Configuration";

    };

};

and the driver file

fsl_ifc_nand.c

------------------

static const struct of_device_id fsl_ifc_nand_match[] = {

    {

        .compatible = "fsl,ifc-nand",

    },

    {}

};

static struct platform_driver fsl_ifc_nand_driver = {

    .driver = {

        .name    = "fsl,ifc-nand",

        .owner = THIS_MODULE,

        .of_match_table = fsl_ifc_nand_match,

    },

    .probe       = fsl_ifc_nand_probe,

    .remove      = fsl_ifc_nand_remove,

};

Can anyone help me in solving this issue?

Thanks in Advance,

Pranav Madhu

Labels (1)
9 Replies

1,631 Views
nikhilprakash
Contributor IV

Hi Pranav,

Have you checked the ranges and reg values given in the dts and dtsi????Also make sure you have given the correct compatibles....

0 Kudos

1,631 Views
pranavmadhu
Contributor IV

Yes Nikhil, thanks for your effort. I've also modified device tree as

ls1021a.dtsi

----------------

ifc: ifc@1530000 {

            compatible = "fsl,ifc","simple-bus","fsl-ifc";

            reg = <0x1530000 0x10000>;

            interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;

            status="okay";

        };

ls1021a-iot.dts

--------------------

&ifc {

    status = "okay";

    compatible = "fsl,ifc-nand","fsl-ifc","fsl,ifc","fsl,ls1021a-ifc";

    #address-cells = <1>;

    #size-cells = <1>;

    /*reg = <0x0 0x0 0x10000>;*/

    ranges=<0x0 0x0 0x7e800000 0x00010000>;

    flash@0,0 {

                   #address-cells = <1>;

                   #size-cells = <1>;

                   compatible = "fsl,ifc-nand";

                   reg = <0x0 0x10000>;

                  bank-width = <2>;

                   device-width = <1>;

                   partition@0 {

            /* 32MB for user data */

            reg = <0x0 0x02000000>;

            label = "NAND Data";

                   };

           };

};

tried on board, but no progress...

1,631 Views
scottwood
NXP Employee
NXP Employee

The compatible on the IFC node should be "fsl,ifc", "simple-bus" and nothing else.  Do not label the main IFC node as being a NAND chip.

1,631 Views
pranavmadhu
Contributor IV

Hi Scott Wood,

Thanks for your reply.

I've modified the dts as well as dtsi file as

ls1021a.dtsi

----------------

ifc: ifc@1530000 {

            compatible = "fsl,ifc","simple-bus";

            reg = <0x1530000 0x10000>;

            interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;

            status="okay";

        };

ls1021aiot.dts

------------------

&ifc {

    status = "okay";

    compatible = "fsl,ifc","simple-bus";

    #address-cells = <2>;

    #size-cells = <1>;

    reg = <0x1530000 0x10000>;

    ranges=<0x0 0x0 0x0 0x60000000 0x1000000>;

    flash@0,0 {

                   #address-cells = <1>;

                   #size-cells = <1>;

                   compatible = "fsl,ifc-nand";

                   reg = <0x0 0x10000>;

                  bank-width = <2>;

                   device-width = <1>;

                   partition@0 {

                      /* 32MB for user data */

                      reg = <0x0 0x02000000>;

                      label = "NAND Data";

                   };

           };

     };

But still ifc probe function fails.

dmesg:

[   31.108798] PTP clock support registered

[   31.109129] fsl-ifc 153000000010000.ifc: Freescale Integrated Flash Controller

[   31.109150] fsl-ifc 153000000010000.ifc: failed to get memory region

[   31.109315] Advanced Linux Sound Architecture Driver Initialized.

1,631 Views
scottwood
NXP Employee
NXP Employee

reg on the ifc node should be <0 0x1530000 0 0x10000>.  Where did you get this device tree from (or, what example did you base it on)?

1,631 Views
pranavmadhu
Contributor IV

Hi Scott Wood,

I've modified the device tree like this as I read in a document

"Power.org ePAPR" as

'Property: reg

Value type: <prop-encoded-array> encoded as arbitrary number of (address,length) pairs.

Description:

The reg property describes the address of the device's resources within the address space defined by

its parent bus. Most commonly this means the offsets and lengths of memory-mapped IO register

blocks, but may have a different meaning on some bus types. Addresses in the address space defined

by root node are cpu real addresses.

The value is a <prop-encoded-array>, composed of an arbitrary number of pairs of address

and length, <address length>. The number of <u32> cells required to specify the address

and length are bus-specific and are specified by the #address-cells and #size-cells properties

in the parent of the device node. If the parent node specifies a value of 0 for #size-cells, the

length field in the value of reg shall be omitted.

Example:

Suppose a device within a system-on-a-chip had two blocks of registers—a 32-byte block at

offset 0x3000 in the SOC and a 256-byte block at offset 0xFE00. The reg property would be

encoded as follows (assuming #address-cells and #size-cells values of 1):

reg = <0x3000 0x20 0xFE00 0x100>;'

So that we modified the register value as <0x1530000 0x10000> as the ifc controller is on offset 0x1530000 and length 0xffff

Now I modified the dts and dtsi files as

dtsi:

ifc: ifc@1530000 {

            compatible = "fsl,ifc","simple-bus";

            reg = <0x0 0x1530000 0x0 0x10000>;

            interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;

            status="okay";

        };

dts:

&ifc {

    status = "okay";

    compatible = "fsl,ifc","simple-bus";

    #address-cells = <2>;

    #size-cells = <1>;

    reg = <0x0 0x1530000 0x0 0x10000>;

    ranges=<0x0 0x0 0x0 0x60000000 0x1000000>;

    flash@0,0 {

                   #address-cells = <1>;

                   #size-cells = <1>;

                   compatible = "fsl,ifc-nand";

                   reg = <0x0 0x10000>;

                  bank-width = <2>;

                   device-width = <1>;

                   partition@0 {

                      /* 32MB for user data */

                      reg = <0x0 0x02000000>;

                      label = "NAND Data";

                   };

           };

};

also I've provided some prints in the init and probe functions on driver file driver/memory/fsl_ifc.c. After changing the register value, I didn't get the kernel prints.

Thanks in Advance.

0 Kudos

1,631 Views
scottwood
NXP Employee
NXP Employee

Note the "assuming #address-cells and #size-cells values of 1".  Since this chip supports more than 32 physical address bits, #address-cells and #size-cells are both 2.

Are you saying you inserted a debugging print in the drivers/memory/fsl_ifc.c driver, and it's not getting probed?  The prints you saw previously indicate the driver does get probed; I don't see how fixing the reg could suddenly make it not get probed at all.

The NAND node's reg is still wrong, because #address-cells = 2.  It should be <0 0 0x10000> (also, bank-width and device-width are NOR properties that don't belong on a NAND node).  That shouldn't prevent the drivers/memory/fsl_ifc.c driver from probing, though.

1,631 Views
pranavmadhu
Contributor IV

Thank you Scott Wood,

Afrer modifying the device tree, the probe function as well as the ctrl_init functions are executing, and the mapping in the driver fsl_ifc.c is successful, but now it is not entering into the if loop (shown below, it is in fsl_ifc_ctrl_probe function)

fsl_ifc.c

-----------

if (fsl_ifc_ctrl_dev->nand_irq) {

                ret = request_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_nand_irq,

                                0, "fsl-ifc-nand", fsl_ifc_ctrl_dev);

The new dts and dtsi files are

ls1021a.dtsi

-----------------

ifc: ifc@1530000 {

compatible = "fsl,ifc","simple-bus";

interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;

status="okay";

};

ls1021a-iot.dts

--------------------

&ifc {

status = "okay";

compatible = "fsl,ifc","simple-bus";

#address-cells = <2>;

#size-cells = <2>;

reg = <0x1530000 0x0 0x0 0x10000>;

ranges= <0x0 0x0 0x60000000 0x10000>;

flash@0,0 {

               #address-cells = <1>;

               #size-cells = <1>;

               compatible = "fsl,ifc-nand";

               reg = <0x0 0x0 0x10000>;

              bank-width = <2>;

               device-width = <1>;

               partition@0 {

/* 32MB for user data */

reg = <0x0 0x02000000>;

label = "NAND Data";

               };

       };

};

0 Kudos

1,631 Views
scottwood
NXP Employee
NXP Employee

It's normal for nand_irq to be zero.  It's only used on certain chips where the IFC has two different IRQs.  On ls1021a NAND uses the main IFC IRQ.  Both IRQs use the same handler so it does not matter which one the hardware uses.