GithubHelp home page GithubHelp logo

ezdma's People

Contributors

drogenlied avatar jeremytrimble avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ezdma's Issues

Use ezdma from kernel-space

Hi.
I'm writing a DMA driver for my hardware. I don't know about parameter was set on FPGA. Your code works well in user-space. I tried you your code in my driver, but it cannot run get_user_pages_fast with my buffer. I also followed dmatest.c in xilinx's kernel, it work but when I transmit with higher speed, it showed error: xilinx-dma 40410000.dma: Channel ef31b890 has errors 11 cdr 0 cdr msb 0 tdr 0 tdr msb 0.
Can you help me solve this error? Thank you.
Here is my code:

static int dma_read(struct dma_priv *priv, uint8_t __kernel *buffer,
                      size_t count, uint32_t timeout)
{
        struct dma_device *device = priv->chan->device;
        struct dma_async_tx_descriptor *rxd = NULL;
        dma_addr_t dma_src;
        struct scatterlist rx_sg[1];
        struct completion rx_cmp;
        int i, ret=0;
        if (down_interruptible(&priv->sem)) {
                return -ERESTARTSYS;
        }

        dma_src = dma_map_page(device->dev, virt_to_page(buffer),
                               offset_in_page(buffer), count, DMA_DEV_TO_MEM);
        if (dma_mapping_error(device->dev, dma_src)) {
                error("Mapping error\n");
                ret = -1;
                goto read_map_err;
        }
        sg_init_table(rx_sg, 1);
        sg_dma_address(&rx_sg[0]) = dma_src;
        sg_dma_len(&rx_sg[0]) = count;
        rxd = dmaengine_prep_slave_single(priv->chan, dma_src, count,
                                          DMA_FROM_DEVICE, DMA_PREP_INTERRUPT);
        if (!rxd) {
                error(" prep err\n");
                dma_unmap_single(device->dev, dma_src, count, DMA_MEM_TO_DEV);
                ret = -1;
                goto read_out;
        }
        init_completion(&priv->completion);
        rxd->callback = dma_tx_callback;
        rxd->callback_param = priv;

        priv->cookie = dmaengine_submit(rxd);
        if (dma_submit_error(priv->cookie)) {
                warn("submit error\n");
        }
        dma_async_issue_pending(priv->chan);
        wait_for_completion(&priv->completion);

        if (dma_async_is_tx_complete(priv->chan, priv->cookie, NULL, NULL)
                != DMA_COMPLETE) {
                error("DMA error\n");
                ret = -1;
                goto read_out;
        }
        ret = priv->bytes_xfered;
read_map_err:
        dma_unmap_single(device->dev, dma_src, count, DMA_MEM_TO_DEV);
read_out:
        up(&priv->sem);
        return ret;
}

Does ezdma support contiguous memory ?

Hello,

Taking a look in ezsdk code I see it use SG dma method.
Does it mean that it does not support dma_alloc_coherent (contiguous) memory allocation ?

Thank you,
Ran

read() throws error when transfer size is 1 MB

Hi Jeremy,

I am using ezdma with Xilinx AXI DMA. When I try to initiate a 1 MB read transfer, ezdma throws this error:
ezdma: loop_rx: dmaengine_prep_slave_sg() failed

I traced the error back to xilinx_dma_alloc_tx_segment() which is called by xilinx_dma_prep_slave_sg(). This function returns NULL (free_seg_list is empty?). I also tried to find the maximum possible size. It turns out to be 1 MB minus 8192 bytes.

Any idea on this? Is it a Xilinx driver issue or ezdma one?
Does it happen to have a relation with the maximum number of descriptors "XILINX_DMA_NUM_DESCS" defined in the Xilinx driver?

Best,
Farzad

userspace nodes for Debain rootfs

Hello all,

Im using petalinux-2018.3 to build image for zedboard.

When I use intrarmfs for rootfs im able to see my ezdma userspace nodes namely loopback_rx and tx.

However if I use SD card rootfs i.e. /dev/mmcblk0p2 then I dont see my ezdma usespace nodes.

Im attempting to use debian rootfs on the zed.

Has anyone been able to use their ezdma nodes on other rootfs other than intrarmFS??

What configuration were done to kernel with petalinux????

Thanks all

Trouble working with pl330

Hi Jeremy.

I'm hoping to use ezdma in a project for work, but I'm not getting very far. It's likely that the problem stems from my lack of experience with the Linux DMA engine, and the usual difficulty of finding relevant documentation. I'm using the PL330 DMAC on a Zynq 70xx. The example you provide uses the AXI DMA IP, which has a very different device-tree node.
I have to manually load (modprobe or insmod) the driver, which is a bit of a red flag. And when I do, ezdma_probe() is never called, and of course the /dev/* nodes are never created.
Have you tried ezdma with the Pl330, or do you know of anyone who has?
Here's some debug output that shows what little is happening in the driver on "modprobe ezdma."

Mar 30 01:56:48 snoodle-01 kernel: [ 5216.552188] ezdma: ezdma_driver_init()
Mar 30 01:56:48 snoodle-01 kernel: [ 5216.552214] ezdma: allocated chrdev region: Major: 246, Minor: 0-8
Mar 30 01:56:48 snoodle-01 kernel: [ 5216.552506] ezdma: platform_driver_register(ezdma) returned 0

Thanks,

-Nick

DMA transactions read() or write() with size bigger than 32 kB DMA transactions, Is Possible??

Hi jeremy, in using your ezdma driver to work with DMA transactions. If make a read() and write() with 1KB, the drivers works very well. This is your loopback example. But in my application, in need to write() a 40kB and read() only 1 kB. Using your driver with this constraints, the make the Scatter Gatter table, starts the DMA transactions but the system halts waiting the DMA interrupt.
This is the output Linux console. I`m using the hardware loopback

ezdma: loop_tx: sg_alloc_table() returned 0
ezdma: loop_tx: get_user_pages_fast() returned 11, expected 11
ezdma: loop_tx: sgl[0]: page: dfbe1360, len: 4000, offset: 96
ezdma: loop_tx: sgl[1]: page: dfba0fc0, len: 4096, offset: 0
ezdma: loop_tx: sgl[2]: page: dfba05c0, len: 4096, offset: 0
ezdma: loop_tx: sgl[3]: page: dfbb2f40, len: 4096, offset: 0
ezdma: loop_tx: sgl[4]: page: dfbd8420, len: 4096, offset: 0
ezdma: loop_tx: sgl[5]: page: dfbb6780, len: 4096, offset: 0
ezdma: loop_tx: sgl[6]: page: dfbb3880, len: 4096, offset: 0
ezdma: loop_tx: sgl[7]: page: dfbb03a0, len: 4096, offset: 0
ezdma: loop_tx: sgl[8]: page: dfbb46e0, len: 4096, offset: 0
ezdma: loop_tx: sgl[9]: page: dfbafb60, len: 4096, offset: 0
ezdma: loop_tx: sgl[10]: page: dfbedec0, len: 96, offset: 0
ezdma: loop_tx: dma_map_sg() returned 11, expected 11
ezdma: loop_tx: issued pending for TX

The same app with only 10kB (only write() ) the driver works very good.
ezdma: loop_tx: sg_alloc_table() returned 0
ezdma: loop_tx: get_user_pages_fast() returned 3, expected 3
ezdma: loop_tx: sgl[0]: page: dfbb7920, len: 4000, offset: 96
ezdma: loop_tx: sgl[1]: page: dfbbd900, len: 4096, offset: 0
ezdma: loop_tx: sgl[2]: page: dfb9b5c0, len: 2144, offset: 0
ezdma: loop_tx: dma_map_sg() returned 3, expected 3
ezdma: loop_tx: issued pending for TX
ezdma: loop_tx: callback fired for TX
But if execute 3 times the app the systems halts waiting DMA interrupt.
I need some help to work with bigger sizes of DMA transactions,
Thank you

zynq Ultrscale +

Any tips/advice on how to go about getting this driver to work for the xilinx zynq ultrscale+ devices?

Physical Addresses

Hi Jeremy,

I don't have an issue but three questions about your code which I am looking at for educational purposes.
1.
I want to report the physical addresses of the pages so I entered the following right after the dmap_map_sg() function

printk("Physical Address: 0x%08lX", sg_dma_address(table.sgl));

The value reported makes sense but this seems to only get the address of the first page. Any idea how I can print out the physical address for each of the pages in the scatterlist?

2.I am having a hard time understanding the following piece of code

//sg_set_page( sgl, p_info->inflight.pinned_pages[i], len, offset );
sg_set_page( sg, p_info->inflight.pinned_pages[i], len, offset );
left_to_map -= len;

my main confusion comes from the fact that sg is not used again in the function, can you explain how this works?

  1. If I wanted to adapt your driver for the CDMA core, would the flow work the same except that I would set up two scatterlists? one for the source bufferand one for the destination buffer

Problem stopping an uncompleted read or write operation

Hi Jeremy,
First of all, congratulations, your driver works very well!. However, I have an annoying problem if I have to stop an uncompleted DMA operation (either write or read).
I have a sample project in Vivado 2016.2 and a Zedboard hardware (AXI-DMA connected to a loopback AXI-Stream FIFO), with a AD Kernel 4.4 running on Linaro Debian distribution.

The loopback ezdma_speed_test is working:

sudo ./ezdma_speed_test
sent 100000 4096-byte packets in 17.003143051 sec: 22.974 MB/s

But, if I launch a read operation and the FIFO is empty, then, the device read function is waiting the DMA transaction to finish, as expected. In that situation, if I cancel the read operation, by hitting for instance, CTRL+C, then, ezdma driver tries to cancel the DMA operation of the xilinx-dma driver (by calling xilinx_dma_terminate_all() ), but it says that "cannot stop channel" and triggers a Kernel panic. Take a look to this Kernel crash (and system hangs!):

sudo ./ezdma_read
Receiving 100000 4096-byte packets
^C <<< CTRL+C is hit here to stop the process >>>
BUG: scheduling while atomic: ezdma_receive/2588/0x00000002
Modules linked in: ezdma(O)
CPU: 1 PID: 2588 Comm: ezdma_receive Tainted: G O 4.4.0-g6515388-dirty #7
Hardware name: Xilinx Zynq Platform
[] (unwind_backtrace) from [] (show_stack+0x10/0x14)
[] (show_stack) from [] (dump_stack+0x80/0xcc)
[] (dump_stack) from [] (__schedule_bug+0x44/0x60)
[] (__schedule_bug) from [] (__schedule+0x88/0x4c4)
[] (__schedule) from [] (schedule+0xb0/0xcc)
[] (schedule) from [] (schedule_hrtimeout_range_clock+0xc4/0x100)
[] (schedule_hrtimeout_range_clock) from [] (usleep_range+0x44/0x4c)
[] (usleep_range) from [] (xilinx_dma_terminate_all+0x98/0x154)
[] (xilinx_dma_terminate_all) from [] (ezdma_read+0x148/0x188 [ezdma])
[] (ezdma_read [ezdma]) from [] (__vfs_read+0x20/0xcc)
[] (__vfs_read) from [] (vfs_read+0x84/0xec)
[] (vfs_read) from [] (SyS_read+0x40/0x80)
[] (SyS_read) from [] (ret_fast_syscall+0x0/0x3c)
xilinx-dma 40400000.dma: Cannot stop channel df7614d0: 10008
Kernel panic - not syncing: Aiee, killing interrupt handler!

This is normal? is there a way to cancel a pending DMA operation gracefully?

Thank you for your time!
Javier.

Status?

At risk of abusing the issues system, I'm curious to know what the current status is of this driver.

I too would very much like to have such a device driver for pushing data from user-space over DMA. Have you made any more attempts to get it added to the mainline kernel tree?

Cheers,
Henry

Kernel error with dma size of 65 KB

I've been using 32 KB dma transactions to reliably transfer streaming data. I can read 1 or 100,000 dma dma blocks reliable. However, when increasing the read size by a factor of 2 (to 65KB), I get a kernel error:

[ 3052.666641] xilinx-vdma 40450000.axidma: Channel de8e5810 has errors 200, cdr 780 tdr 1f502900
[ 3053.667960] xilinx-vdma 40450000.axidma: Cannot start channel de8e5810: 10209

It appears that the error is sourced somewhere in the xilinx dma driver. When this happens, the dma also hangs, never returning (data continues streaming, though now it is just dropped in the fpga fabric buffering). I have two 128 KB FIFOs going into the DMA so it isn't that I'm overrunning those. Do you have any ideas of what can be done to increase the dma size?

module built using petalinux

Hi jeremy,

I use petalinux v2016.3 to contain the source code of ezdma.c in my created module. Once the linux on board booted, I typed "insmod /lib/modules/'uname -r'/extra/ezdma.ko" or "modprobe ezdma", but the terminal outputs:
"ezdma: allocated chrdev region: Major: 244 , Minor: 0-8
probing ezdma
ezdma: couldn't find dma channel: loop_tx, deferring...
ezdma: loop_tx (TX) available
ezdma: couldn't find dma channel: loop_rx, deferring...
ezdma: loop_rx (RX) available"

I debug the source and found some errors occured in the code segment:
/* Get the named DMA channel */
p_info->chan = dma_request_slave_channel(
&pdev->dev, p_dma_name);

    if ( !p_info->chan )
    {
        printk( KERN_WARNING KBUILD_MODNAME 
                ": couldn't find dma channel: %s, deferring...\n",
                p_info->name);

        outer_rv = -EPROBE_DEFER;
    }

the function "dma_request_slave_channel( &pdev->dev, p_dma_name)" returned an unexpected value assigned to "p_info->chan". I can not find either "loop_tx" or "loop_rx" in dir "/dev/". I wondered what's the problem, and what steps might I forgot to exec? Thank you!

Transferring very large DMA buffers

Hi Jeremy,
I'm trying to DMA very large buffers (512M byte if I can) into memory. I seem to run into a memory problem for sg_alloc_table if I try to create a DMA buffer > 1Mbyte. I believe I just have too many entries in the sg table.
My AXI DMA core is configured with 23bit addressing for the scatter/gather engine which should allow for individual DMA blocks of up to 8MByte each, so it should be possible to describe the 512 MByte buffer with just 64 chained entries. Looking at the ezdma driver it seems like you are allocating blocks of 4096 bytes for each of the scatterlist entries. Is there a way to allocate 8Mbyte blocks for each of the scatterlist entries so I can reduce the number of them?

Thanks Mike.

Loopback Devicetree Troubles

I'm not sure if this is the right place to ask this, but I wasn't able to find your email anywhere.

Anyway, we'd like to use this driver to stream data from the PL on the Zedboard into the linux userspace. We are initially trying to get your loopback example running on the Zedboard, however we're having trouble getting the devicetree working. Currently we get the following error:

ezdma: allocated chrdev region: Major: 245, Minor: 0-8
probing ezdma
ezdma: couldn't find dma channel: loop_tx, deferring...
ezdma: loop_tx (TX) available
ezdma: couldn't find dma channel: loop_rx, deferring...
ezdma: loop_rx (RX) available
platform ezdma0: Driver ezdma requests probe deferral

Our dma device in the device tree looks like:

/ {
	amba_pl: amba_pl {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "simple-bus";
		ranges ;
		axi_dma_1: axidma@40400000 {
			#dma-cells = <1>;
			compatible = "xlnx,axi-dma";
			interrupt-parent = <&intc>;
			interrupts = <0 29 4 0 30 4>;
			reg = <0x40400000 0x10000>;
			xlnx,include-sg ;
			loop_tx: dma-channel@40400000 {
				compatible = "xlnx,axi-dma-mm2s-channel";
				interrupts = <0 29 4>;
				xlnx,datawidth = <0x20>;
				xlnx,device-id = <0x1>;
			};
			loop_rx: dma-channel@40400030 {
				compatible = "xlnx,axi-dma-s2mm-channel";
				interrupts = <0 30 4>;
				xlnx,datawidth = <0x20>;
				xlnx,device-id = <0x1>;
			};
		};
	};
	ezdma0 {
        compatible = "ezdma";

        dmas = <&axi_dma_1 0 &axi_dma_1 1>;
        dma-names = "loop_tx", "loop_rx";   // used when obtaining reference to above DMA core using dma_request_slave_channel()
        ezdma,dirs = <2 1>;                 // direction of DMA channel: 1 = RX (dev->cpu), 2 = TX (cpu->dev)
    };
};

I was hoping you may be able to help figure out why the driver can't find the device as we defined in our devicetree. If this is the wrong forum for this issue please let me know how I should contact you. Thanks!!

dma_map_sg fails

I'm running your driver on an xilinx embedded linux (built w/ petalinux 2017.3) and a Zynq Ultrascale device, and when I run the speed test /loopback test, dma_map_sg returns 0 and errors out. My HW is an AXI-DMA looped back through an AXI-4 Stream Data Fifo.

The AXI DMA hw (vivado gui) properties are:
Width of Buffer Length Register: 14 bits
Address Width: 32 bits
Max burst size: 128
Stream Data width: 32
Allow unalligned transfers is unchecked.
Enable Scatter Gather Engine is checked.

I tried changing the packet size to a smaller value such that there is only a single entry in the SG table, but I get the same error. I am currently trying see about comparing addresses between the userspace test program and the driver/module.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.