ikwzm / udmabuf

User space mappable dma buffer device driver for Linux.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't set physical address in device tree for Zynq MPSoC

mrbietola opened this issue · comments

`reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
rproc_0_reserved: rproc@3ed00000 {
no-map;
reg = <0x0 0x3ed00000 0x0 0x1000000>;
};

	image_buf0: image_buf@0 {
		compatible = "shared-dma-pool";
		reusable;
		reg = <0x0 0x6fc00000 0x0 0x0100000>;
		alignment = <0x0 0x1000>; 
		label = "image_buf0";

	};



};

udmabuf@0 {
compatible = "ikwzm,udmabuf-0.10.a";
device-name = "udmabuf0";
size = <0x0 0x0100000>;
memory-region = <&image_buf0>;
};`
When kernel boot i see
[ 0.000000] Reserved memory: incorrect alignment of CMA region
[ 0.000000] cma: Reserved 256 MiB at 0x000000005fc00000
When insmod the driver i see that the physical address is different from what i set in device tree

[ 127.914295] udmabuf udmabuf@0: of_reserved_mem_device_init failed. return=-22
[ 127.921580] udmabuf udmabuf@0: driver installed.
[ 127.926204] udmabuf: probe of udmabuf@0 failed with error -22
[ 127.932553] udmabuf udmabuf.0: DMA mask not set
[ 127.937692] udmabuf udmabuf0: driver version = 1.4.5
[ 127.942653] udmabuf udmabuf0: major number = 240
[ 127.947439] udmabuf udmabuf0: minor number = 0
[ 127.952052] udmabuf udmabuf0: phys address = 0x000000005fd00000
[ 127.958140] udmabuf udmabuf0: buffer size = 1048576
[ 127.963274] udmabuf udmabuf0: dma device = udmabuf.0
[ 127.968582] udmabuf udmabuf0: dma coherent = 0
[ 127.973195] udmabuf udmabuf.0: driver installed.

Thank you for the issue.

The Linux CMA region has alignment constraints.
For MPSoC, the address and size that can be specified in the regs property of reserved-memory must be in units of 0x00400000 (4MiB).

Try setting the size to 0x00400000 as follows:

       reserved-memory {
                #address-cells = <2>;
                #size-cells = <2>;
                ranges;
                rproc0_reserved: rproc@3ed00000 {
                        no-map;
                        reg = <0x0 0x3ed00000 0x0 0x01000000>;
                };
                image_buf0: image_buf@0 {
                        compatible = "shared-dma-pool";
                        reusable;
                        reg = <0x0 0x6fc00000 0x0 0x00400000>; # 0x00100000 -> 0x00400000
                        alignment = <0x0 0x1000>;
                        label = "image_buf0";
                };
        };

Thanks for the quick response, i didn't know about this limitation. In the meantime i figured out a different solution that works, hope it makes sense to you, i'm really not an expert on this. I redefined the default CMA and assigned 1 MB to udmabuf. When i insmod the driver it loads at 0x6fd00000 instead of 0x6fc00000 don't know why, but works.
`reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;

	image_buf0: image_buf@0 {
		compatible = "shared-dma-pool";
		reusable;
		reg = <0x0 0x6fc00000 0x0 0x10000000>;
		linux,cma-default;
		label = "image_buf0";
	};
};

udmabuf@0 {
compatible = "ikwzm,udmabuf-0.10.a,reserved-memory";
device-name = "udmabuf0";
size = <0x0 0x0100000>;
memory-region = <&image_buf0>;
};
`

I tried with your suggested modification, the driver is loaded but at a different phisical address, the message i get from kernel are

[ 0.000000] Reserved memory: created CMA memory pool at 0x000000006fc00000, size 4 MiB
[ 0.000000] OF: reserved mem: initialized node image_buf@0, compatible id shared-dma-pool
[ 0.000000] cma: Reserved 256 MiB at 0x000000005fc00000

when i load the driver

[ 40.751861] udmabuf udmabuf.0: DMA mask not set
[ 40.757027] udmabuf udmabuf0: driver version = 1.4.5
[ 40.762006] udmabuf udmabuf0: major number = 241
[ 40.766793] udmabuf udmabuf0: minor number = 0
[ 40.771414] udmabuf udmabuf0: phys address = 0x000000005fd00000
[ 40.777505] udmabuf udmabuf0: buffer size = 1048576
[ 40.782647] udmabuf udmabuf0: dma device = udmabuf.0
[ 40.787952] udmabuf udmabuf0: dma coherent = 0
[ 40.792565] udmabuf udmabuf.0: driver installed.

look like reserved 1MB over the default cma region and not in the area reserved by device tree.
Is this expected? I need the physical address fixed because i would like to transfer data from PL

uum...

I also tried it and successfully assigned it as follows: . .

        reserved-memory {
                #address-cells = <2>;
                #size-cells = <2>;
                ranges;
                rproc0_reserved: rproc@3ed00000 {
                        no-map;
                        reg = <0x0 0x3ed00000 0x0 0x01000000>;
                };
                image_buf0: image_buf@0 {
                        compatible = "shared-dma-pool";
                        reusable;
                        reg = <0x0 0x6fc00000 0x0 0x10000000>;
                        alignment = <0x0 0x1000>;
                        label = "image_buf0";
                };
        };
        udmabuf@0 {
                compatible = "ikwzm,udmabuf-0.10.a";
                device-name = "udmabuf0";
                size = <0x01000000>;
                memory-region = <&image_buf0>;
      };
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 4.19.0-xlnx-v2019.1-zynqmp-fpga (ichiro@Jabberwock) (gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04)) #2 SMP Wed Jul 17 15:19:07 DST 2019
[    0.000000] Machine model: Avnet Ultra96 Rev1
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] Reserved memory: created CMA memory pool at 0x000000006fc00000, size 256 MiB
[    0.000000] OF: reserved mem: initialized node image_buf@0, compatible id shared-dma-pool
[    0.000000] cma: Reserved 256 MiB at 0x000000005fc00000
    

[   85.053707] udmabuf udmabuf@0: assigned reserved memory node image_buf@0
[   85.068624] udmabuf udmabuf0: driver version = 1.4.5
[   85.073590] udmabuf udmabuf0: major number   = 240
[   85.078389] udmabuf udmabuf0: minor number   = 0
[   85.083013] udmabuf udmabuf0: phys address   = 0x000000006fc00000
[   85.089103] udmabuf udmabuf0: buffer size    = 16777216
[   85.094327] udmabuf udmabuf0: dma device     = udmabuf@0
[   85.099641] udmabuf udmabuf0: dma coherent   = 0
[   85.104256] udmabuf udmabuf@0: driver installed.

so it's something about my configuration. I have a different petalinux
[ 0.000000] Linux version 4.19.0-xilinx-v2019.2 (oe-user@oe-host) (gcc version 8.2.0 (GCC)) #1 SMP Fri Nov 22 08:21:25 UTC 2019

in my case i get also the wrong major number (i have 241) and every time i rmmod the driver and insert back the major number decrements by 1.
Maybe i should update the filesystem as well as the image.ub? I did a lot of tries and i always update only the image.
To build the udmabuf module i had to replace your makefile with the makefile generated by petalinux, don't know if this is the cause.
Thanks for your support

The major number of udmabuf is assigned dynamically from the Linux Kernel. It varies depending on the number and order of device drivers installed.

i had some corruption of filesystem by my side, creating a new petalinux project works as you described.
Now i would like to implement the hardware coherency between PL and PS using the driver.
Thanks for your help