I am attempting to configure memory-mapped regions for the NOR Flash and FRAM devices.
NOR Flash - 256MB window for XSPI1_A, CS0
Start address: 0x000020000000h
End address: 0x00002FFFFFFFh
NOR Flash - 256MB window for XSPI1_A, CS1
Start address: 0x000400000000h
End address: 0x00040FFFFFFFh
FRAM - 512KB window for XSPI1_B, CS1
Start address: 0x000410000000h
End address: 0x00041FFFFFFFh
I have configured the DTS (Device Tree Source) "reg" property for the flash and FRAM regions. However, during the DTB (Device Tree Blob) compilation, I encounter the following error:
"Device tree value out of range for 32-bit array element." This error occurs due to the use of 64-bit addresses in the "reg" property.
Could you please advise on how to configure a 64-bit address with the "reg" property in the device tree?
Device Tree Configuration:
```device-tree
&fspi {
status = "okay";
#address-cells = <2>;
#size-cells = <1>;
/* Memory-mapped regions for the Flash and FRAM devices */
reg = <0x0 0x20000000 0x0 0x10000000>, /* Flash region 1: 256MB */
<0x0 0x400000000 0x0 0x10000000>, /* Flash region 2: 256MB */
<0x0 0x410000000 0x0 0x80000>; /* FRAM region: 512KB */
flash@0 {
compatible = "jedec,spi-nor";
spi-max-frequency = <90000000>;
reg = <0x0 0x20000000 0x0 0x10000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <4>;
};
flash@1 {
compatible = "jedec,spi-nor";
spi-max-frequency = <90000000>;
reg = <0x0 0x400000000 0x0 0x10000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <4>;
};
fram@3 {
compatible = "jedec,spi-nor";
spi-max-frequency = <50000000>;
reg = <0x0 0x410000000 0x0 0x80000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <4>;
};
};
```
any update ?
@yipingwang I tried configuring reg property for FlexSPI Region #2 in device tree as below.
reg = <0x00 0x20c0000 0x00 0x10000>,
<0x04 0x10000000 0x00 0x00080000>; //512KB
I could see memory region listed in /proc/iomem after adding following code in the kenrel "drivers/spi/spi-nxp-fspi.c"
----------------------------------------------------
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fspi_mmap");
...
+ if (!devm_request_mem_region(dev, res->start, resource_size(res),res->name)) {
+ dev_err(dev, "fspi can't request region for resource %pR\n", res);
+ ret = -EBUSY;
+ goto err_put_ctrl;
+ }
----------------------------------------------------
$cat /proc/iomem
....
020c0000-020cffff : 20c0000.spi fspi_base
410000000-41007ffff : fspi_mmap
....
Question:
I could use ioremap in a custom driver to map physical memory at base address 0x410000000.
However, when I get the kernel panic when I try to use the virtual address (from ioremap).
[ 636.001611] Internal error: synchronous external abort: 96000210 [#1] PREEMPT SMP
Am I missing any configuration here? Does nxp-fspi driver supports memory mapped access of FlexSPI Region #2 from below system memory map ?
System memory map
0x0000_2000_0000 0x0000_2FFF_FFFF 256MB FlexSPI Region #1
0x0004_0000_0000 0x0004_0FFF_FFFF 256MB SPI Hole
Collapsed away by remapping logic to merge FlexSPI Region #1
0x0004_1000_0000 0x0004_FFFF_FFFF 3.75GB FlexSPI Region #2(256MB-4GB) 3.75GB
Please refer to fsl-lx2160a-rdb.dts for how to define fspi devices. No need to define memory mapped region.
&fspi {
status = "okay";
mt35xu512aba0: flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spansion,m25p80";
m25p,fast-read;
spi-max-frequency = <50000000>;
reg = <0>;
spi-rx-bus-width = <8>;
spi-tx-bus-width = <8>;
};
mt35xu512aba1: flash@1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "spansion,m25p80";
m25p,fast-read;
spi-max-frequency = <50000000>;
reg = <1>;
spi-rx-bus-width = <8>;
spi-tx-bus-width = <8>;
};
};
System memory map
CCSR Block address map
0x20C_0000 - 0x20C_FFFF QSPI (Flex SPI)
Please refer to fsl-lx2160a.dtsi
fspi: spi@20c0000 {
compatible = "nxp,lx2160a-fspi";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x20c0000 0x0 0x10000>,
<0x0 0x20000000 0x0 0x10000000>;
reg-names = "fspi_base", "fspi_mmap";
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen 4 3>, <&clockgen 4 3>;
clock-names = "fspi_en", "fspi";
status = "disabled";
};
You could define reg device node as the following.
reg = <0x0 0x20c0000 0x0 0x10000>,
<0x4 0x10000000 0x0 0x30000000>;
You could refer to Documentation/devicetree/bindings/spi/spi-nxp-fspi.txt for details.
Thanks @yipingwang
I could configure reg property for FlexSPI Region #2 in device tree as you suggested below.
reg = <0x00 0x20c0000 0x00 0x10000>,
<0x04 0x10000000 0x00 0x30000000>;
However, I don't see this memory-mapped region listed in /proc/iomem.
I'm trying to access this memory-mapped region (physical address) and use ioremap to map it into the kernel's virtual address space and then read from or write to it using ioread and iowrite functions.
Is there any additional configuration needed in device tree for this?
I'm using below dts configuration,
You could refer to nxp_fspi_read_ahb function in drivers/spi/spi-nxp-fspi.c.
static int nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op)
{
u32 start = op->addr.val;
u32 len = op->data.nbytes;
/* if necessary, ioremap before AHB read */
if ((!f->ahb_addr) || start < f->memmap_start ||
start + len > f->memmap_start + f->memmap_len) {
if (f->ahb_addr)
iounmap(f->ahb_addr);
f->memmap_start = start;
f->memmap_len = len > NXP_FSPI_MIN_IOMAP ?
len : NXP_FSPI_MIN_IOMAP;
f->ahb_addr = ioremap_wc(f->memmap_phy + f->memmap_start,
f->memmap_len);
if (!f->ahb_addr) {
dev_err(f->dev, "failed to alloc memory\n");
return -ENOMEM;
}
}
/* Read out the data directly from the AHB buffer. */
memcpy_fromio(op->data.buf.in,
f->ahb_addr + start - f->memmap_start, len);
return 0;
}
@yipingwang Whenever you have the opportunity, please share your thoughts on this.