I'm working on a Cyclone V SOC FPGA from Altera with a double Cortex-A9 processor. The embedded system (linux-socfpga 4.16) is created with Buildroot-2018.05.
I use a "top" device tree at boot time for processor component and a device-tree overlay to configure the FPGA part of the component and load the associated drivers. The overlay will be attach to the base_fpga_region
of the top DT.
top device tree
/dts-v1/; / { model = "MY_PROJECT"; /* appended from boardinfo */ compatible = "altr,socfpga-cyclone5", "altr,socfpga"; /* appended from boardinfo */ #address-cells = <1>; #size-cells = <1>; cpus { [...] }; //end cpus memory { device_type = "memory"; reg = <0xffff0000 0x00010000>, <0x00000000 0x80000000>; }; //end memory reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; mem_dma_reserved { compatible = "shared-dma-pool"; no-map; reg = <0x78000000 0x8000000>; }; }; soc: soc { device_type = "soc"; ranges; #address-cells = <1>; #size-cells = <1>; compatible = "altr,avalon", "simple-bus"; bus-frequency = <0>; fpgabridge1: fpgabridge@1 { compatible = "altr,socfpga-lwhps2fpga-bridge"; resets = <&hps_rstmgr 97>; /* appended from boardinfo */ clocks = <&l4_main_clk>; /* appended from boardinfo */ #address-cells = <1>; #size-cells = <1>; ranges; bridge-enable = <1>; label = "lwhps2fpga"; reset-names = "lwhps2fpga"; reg = <0xff200000 0x200000>; reg-names = "axi_h2f_lw"; }; //end fpgabridge@1 (fpgabridge1) base_fpga_region: base_fpga_region { compatible = "fpga-region"; #address-cells = <0x2>; #size-cells = <0x1>; fpga-mgr = <&hps_fpgamgr>; fpga-bridges = <&fpgabridge1>; ranges = <0x0 0x0 0xff200000 0x200000>; }; //end base_fpga_region (base_fpga_region) etc......
Device tree overlay
/dts-v1/ /plugin/; /{ fragment@0 { target-path = "/soc/base_fpga_region"; #address-cells = <2>; #size-cells = <1>; __overlay__ { #address-cells = <2>; #size-cells = <1>; firmware-name = "my_project.rbf"; my_dma_0: dma@0x000000000 { compatible = "my_company,my_dma-0.1"; reg = <0x00000000 0x0000000 0x00000014>; memory-region = <&mem_dma_reserved>; }; //end dma@0x000000000 (my_dma_0) }; }; };
my problem is to link the mem_dma_reserved
from the top DT to the memory-region
in the overlay.
I assume that while converting dts to dtbo with the -@ option, the overlay shall get the phandle for mem_dma_reserved
with the __fixups__
option. I've created the dtbo file and converted it again in dts to see what is done during the compilation :
dtc -@ -I dts -O dtb -o overlay.dtbo overlay.dts dtc -I dtb -O dts -o overlay_recovery.dts overlay.dtbo
device tree overlay regenerated
/dts-v1/; / { fragment@0 { target-path = "/soc/base_fpga_region"; #address-cells = <0x2>; #size-cells = <0x1>; __overlay__ { #address-cells = <0x2>; #size-cells = <0x1>; firmware-name = "my_project.rbf"; dma@0x000000000 { compatible = "my_company,my_dma-0.1"; reg = <0x0 0x0 0x14>; memory-region = <0xffffffff>; // phandle converted to 0xffffffff, cannot resolve unless the __fixup__ function does it. linux,phandle = <0x2>; phandle = <0x2>; }; }; }; __symbols__ { my_dma_0 = "/fragment@0/__overlay__/dma@0x000000000"; }; __fixups__ { mem_dma_reserved = "/fragment@0/__overlay__/dma@0x000000000:memory-region:0"; }; };
We can see that the phandle for the memory-region is 0xFFFFFFFF because the overlay doesn't know about the <&mem_dma_reserved> node. the fixup part shall be able to get back the phandle at loading time, but it isn't working and I get this error :
[ 27.434730] OF: resolver: of_resolve_phandles: no symbols in root of device tree.
[ 27.440401] OF: resolver: overlay phandle fixup failed: -22
[ 27.445993] create_overlay: Failed to resolve tree
I have made the same regeneration from dtb to dts on the top DT. I have seen that the phandle of the reserved memory is actually 0x6. I have written <0x6> instead of <&mem_dma_reserved> in the device tree overlay and with this configuration, everything loads !
How can I make the overlay find the <&mem_dma_reserved> automatically without doing it by hand ?
EDIT
As pointed by ikwzm I have added in the top device tree the following lines :
reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; mem_dma_reserved: mem_dma_reserved { // add a label compatible = "shared-dma-pool"; no-map; reg = <0x78000000 0x8000000>; }; }; [...] // add the whole symbol block __symbols__ { mem_dma_reserved = "/reserved-memory/mem_dma_reserved "; };
The errors are now gone, but :
I was expecting the driver for my_dma to be loaded during the operation.
I checked that the device tree overlay is well taken into account with :
ls /sys/firmware/devicetree/base/soc/base_fpga_region/
my_dma_0
other_stuffcat /sys/firmware/devicetree/base/soc/base_fpga_region/my_dma_0/memory-region
//nothing//
The memory region doesn't seem to be attached.
What I have missed ?