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
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....
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...
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.
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.
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)?
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.
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.
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";
};
};
};
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.