ikwzm / udmabuf

User space mappable dma buffer device driver for Linux.
BSD 2-Clause "Simplified" License
560 stars 168 forks source link

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

Closed mrbietola closed 4 years ago

mrbietola commented 4 years ago

`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.

ikwzm commented 4 years ago

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";
                };
        };
mrbietola commented 4 years ago

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>; }; `

mrbietola commented 4 years ago

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

ikwzm commented 4 years ago

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.
mrbietola commented 4 years ago

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

ikwzm commented 4 years ago

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

mrbietola commented 4 years ago

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