Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12606 Discussions

mSGDMA, Qsys, and Linux Integration

Altera_Forum
Honored Contributor II
10,246 Views

So I've been trying to get the Modular SG-DMA working in a Qsys project tied with Linux. I can get it to show up in the device tree, be recognized by Linux in /sys, and it looks like the memory mapping works. 

 

Below is a clip from the msgdma in my device tree: 

 

msgdma_0: msgdma@0x100000020 { 

compatible = "altr,msgdma-14.1", "altr,msgdma-1.0"; 

reg = <0x00000001 0x00000020 0x00000020>, 

<0x00000001 0x00000010 0x00000010>; 

reg-names = "csr", "descriptor_slave"; 

interrupt-parent = <&hps_0_arm_gic_0>; 

interrupts = <0 41 4>; 

clocks = <&clk_0>; 

}; //end msgdma@0x100000020 (msgdma_0) 

 

Now the interesting part of all this is that there are no drivers for altr,msgdma-1.0 available in the 3.10-ltsi. While direct memory mapping will probably work to write to the descriptor, has anyone had any luck with writing mSGDMA descriptors from the HPS? It looks like people have been able to use the Altera DMA Controller, no problem, but the mSGDMA provides a wider bus width and more configurable options that could be highly beneficial for an FPGA-to-HPS bridge. 

 

Thanks!
0 Kudos
27 Replies
Altera_Forum
Honored Contributor II
433 Views

 

--- Quote Start ---  

Everything works, except I can't turn off park mode on the mSGDMA module without freezing Linux. I think that the DMAs really would benefit from a generic UIO kernel driver being available to handle things such as resets, etc. Waiting to hear back from Altera about the best method to reset a module in park mode. 

--- Quote End ---  

 

 

I am having similar problems in my ST to MM design for transferring video. I use the standard CVI module for generating data packets which are fed directly to a mSGDMA write only core. I connected the MM write master to a f2h_sdram bridge. Write address is just outside and above kernel space (dedicated lowest 512M to Linux). Writing data works just fine but oddly spaced though due to the endian reversal of the core. I'll work around that in my user-space program, no problem here. 

 

I found that setting the descriptor length field did not guarantee stable transfer lengths at all. I simply assumed that I would get an interrupt after completion of a video frame transfer so I could stop the current and issue a new descriptor. But video is cut up in line based blocks that make very little sense to me. Closer inspection in SignalTap showed erratic address increments and early-done signals. Sometime a "done" condition coincided with a jump of 1000h in address space. First I thought this might be due to timing problems but TimeQuest reveals absolutely no problems. 

 

For further investigation I whipped up a simple kernel module to catch the vsync interrupt of my sensor to start new descriptors at exactly the right time. It was then that I found that the EOP from CVI triggered an end of the current descriptor. After that (descriptor fifo essentially empty) the erratic behaviour started. So I figured a might be a good idea to start partial transfers and check the amount of bytes transferred the reponse port, while keeping the length field of the descriptor at max of 0xFFFFFFFF. The interrupt I wrote for the mSGDMA handler works allright but once an interrupt was triggered (outside park mode) the kernel hangs. I thought writing a zero to bit 9 of the CSR status register would be enough, but it's not. IRQ line remains active and drives the kernel to a panic state due to stack overflow. I am not seeing any interrupts in park mode so this might explain why derim is having problems... Once it's in park mode everything runs smooth but sync is lost. 

 

Anyway, the question is: how do a clear the interrupt condition, or more likely, how do handle/clear events that lead to an interrupt?
0 Kudos
Altera_Forum
Honored Contributor II
433 Views

 

--- Quote Start ---  

Anyway, the question is: how do a clear the interrupt condition, or more likely, how do handle/clear events that lead to an interrupt? 

--- Quote End ---  

 

 

That's a fascinating issue. I had to build a valid signal controller that only sends the number of valids desired along with a clock-crossing FIF, and I still don't trust the module quite yet. 

 

I'm just clearing interrupts from userspace right now, writing a 1 to the correct status register in the prefetcher, and that works fine for the speed that I'm running at. This really should be done in a simple kernel module, though, which is what I'd recommend. The Altera Workshops now up on rocketboard provide some great examples on that. 

 

Now clearing events that led to an interrupt... I wonder if something is happening where the response port isn't lining up correctly with the EOP and other packet signals. I'm not using packets, but I wonder if someone else might have some idea about this.
0 Kudos
Altera_Forum
Honored Contributor II
433 Views

OK, the *only* way to reset the IRQ line seems to be a reset to the mSGDMA core. That works, everything else fails. 

Is there anybody out there who can confirm that a s/w reset to the core is the only way the clear the IRQ line from the CSR slave? Note that I just use the write core without prefetcher or dispatcher. During packet video from CVI the kernel module monitors per completed transfer the amount of bytes sent and stops the dma core when a complete frame is transferred. The vsync of my sensor then triggers the start of a new frame. 

 

All works well now but I would really appreciate a less brutal way of clearing an interrupt request because that means I have to re-issue a descriptor after each interrupt. The FIFO structure and park-mode seem redundant now.... 

 

Arjan
0 Kudos
Altera_Forum
Honored Contributor II
433 Views

 

--- Quote Start ---  

OK, the *only* way to reset the IRQ line seems to be a reset to the mSGDMA core. That works, everything else fails. 

Is there anybody out there who can confirm that a s/w reset to the core is the only way the clear the IRQ line from the CSR slave? Note that I just use the write core without prefetcher or dispatcher. During packet video from CVI the kernel module monitors per completed transfer the amount of bytes sent and stops the dma core when a complete frame is transferred. The vsync of my sensor then triggers the start of a new frame. 

 

All works well now but I would really appreciate a less brutal way of clearing an interrupt request because that means I have to re-issue a descriptor after each interrupt. The FIFO structure and park-mode seem redundant now.... 

 

Arjan 

--- Quote End ---  

 

 

To get a grasp of this-- you're saying that writing a 1 to the status register doesn't work, and you need to trigger a s/w reset to the descriptor to clear any interrupts? I've never seen that-- I've been able to reset IRQ lines both with and without a prefetcher by writing to the status register. Now, if you're in park mode, this does get more complicated as the reset takes a finite amount of time, so you could be triggering an interrupt immediately after clearing it, creating a loop where the interrupt never seems to clear. 

 

I was wondering about the sender to the DMS, though-- is that packet-based, or in some way counting bytes being sent to the DMA separately from the kernel module? Without counting bytes in firmware, you're relying on the DMA alone. I found this leads to some odd behavior as the DMA has a FIFO associated with it that will fill asynchronously; meaning that if your firmware gets out of sync with your DMA operations, you could have stale data left in the buffer, and never be receiving your EOP, or always receving an EOP based on old data. 

 

I've found it much better to run in park mode and start and stop the module sending data to the DMA instead of the DMA itself as it better controls the data flow. What did they do in the SDI design example? I've only looked at the TSE design example, which also uses DMAs.
0 Kudos
Altera_Forum
Honored Contributor II
433 Views

I could not get a clear on the IRQ pin by writing to CSR status, 1 or 0. Only resetting the unit cleared the IRQ line, it was clearly visible in SignalTap. Of course I am making a mistake somewhere but I found a suitable work around for now. I let the data valid lines of CVI determine the packet size. I have no issues with transfer length when the fifo buffer in CVI is greater than the amount of pixels in one line. I removed the EOP interrupt enable and just let the DMA controller run freely using one descriptor written in the vsync ISR but the mSGDMA unit must be reset first. No problem, time enough during vsync anyway. The transfer length is stable as expected. 

 

I did find the TSE example but did not dig into that because it involved a Yocto patch and it seemed to be a set of binaries rather then useful source. Could be wrong about that because I did not look at the content of the ZIPs.
0 Kudos
Altera_Forum
Honored Contributor II
433 Views

 

--- Quote Start ---  

I could not get a clear on the IRQ pin by writing to CSR status, 1 or 0. Only resetting the unit cleared the IRQ line, it was clearly visible in SignalTap. Of course I am making a mistake somewhere but I found a suitable work around for now. I let the data valid lines of CVI determine the packet size. I have no issues with transfer length when the fifo buffer in CVI is greater than the amount of pixels in one line. I removed the EOP interrupt enable and just let the DMA controller run freely using one descriptor written in the vsync ISR but the mSGDMA unit must be reset first. No problem, time enough during vsync anyway. The transfer length is stable as expected. 

 

I did find the TSE example but did not dig into that because it involved a Yocto patch and it seemed to be a set of binaries rather then useful source. Could be wrong about that because I did not look at the content of the ZIPs. 

--- Quote End ---  

 

 

Glad you worked something out-- I had to do the same. I'm still waiting to hear back from Altera on some of the issues I'm seeing, but overall, a working design is always better than a broken one :D 

 

The TSE sources are actually in the Yocto patch, when I last looked. Either there or up on the Altera projects Github. But even reading examples takes time away from actual development!
0 Kudos
Altera_Forum
Honored Contributor II
433 Views

I'm still waiting to hear back from Altera on the Park issue, but now I'm running in to odd issues with the hardware reset of the modules. I can actually do a hardware reset, but I'm finding that after doing a manual reset of just the modules, and then initializing park mode, they behave different than when they come up with the reset of the system. 

 

To be fair, I'm still debugging this, but thought this worth mention.
0 Kudos
Reply