DMAManager
Jeffrey Lee (213) 6048 posts |
After a certain amount of messing I’ve managed to get DMA working on the beagleboard. Apart from a few fixes that need applying to the code that handles interrupt driven buffer-type DMA channels (i.e. the original code was completely broken), there are a couple of other bits in DMAManager that I’ve either changed already or am planning on changing. For your information, these changes are:
As I move forward with these changes I’ll also get some docs added to the wiki (IIRC the HAL DMA docs were the one thing I missed out when I did my first pass on the docs) For the OMAP side of things, although the current implementation is just a single-buffered buffer-type channel, I think I can get double buffering working by linking two DMA channels together (the OMAP doesn’t support proper DMA lists, but channels can be linked together so that when one completes another will automatically begin). And although there’s no mention of it in the manual, it looks like it might be possible to get the DMA controller to reprogram itself, which could be used for implementing arbitrary-length list-type HAL devices (since DMAManager doesn’t cope very well with list channels which have list length limits). |
Adrian Lees (168) 23 posts |
One thing DMAManager almost certainly doesn’t handle (efficiently) at the moment is 2D DMAs of the sort required for rectangular copy operations, if not faster method can be found. This just requires the addition of a pitch parameter and line count, in practice. Also, as you may have spotted in the SDMA docs, it’s rather a quirky beast with regards to its addressing, particular for overlapping left-to-right, but the necessary parameters including the order in which reads/writes must be performed can all be calculated from knowledge of the physical addresses, line length, line count and knowledge of the alignments, I believe. Hence it shouldn’t be necessary to pollute the API, thankfully. Having gained the understanding of its behaviour already, I’m willing to write the code for the above translations, if that’s easier. I’d be surprised if the SDMA block can reprogram itself, since I suspect the OMAP is based around the AXI network, not a true bus architecture, which would require the architects to have anticipated such (ab?)use. I’ll look into that, though, along with the DMAManager API. I have a feeling it didn’t cope with the kind of operations I needed in Cino/Geminus with the IOP321 so I had to use direct hardware access, risking conflicts. |
Jeffrey Lee (213) 6048 posts |
I’d wager that understanding SDMA is a lot easier than understanding the DMAManager source code ;) At the moment DMAManager only handles memory-to-device and device-to-memory transfers. The “memory” part is just a contiguous area of logical memory, which then gets translated to a table of the corresponding physical addresses. And I’m fairly certain that the transfer always gets split into page-sized chunks, even if the physical addresses are contiguous. The “device” part is (for the HAL version) a fixed address for all the data to be written to/read from. For devices which don’t produce interrupts it copies all the data to/from an intermediate bounce buffer, which further adds to the complexity of the code. And although DMAManager doesn’t currently support it, the HAL API which it uses does allow for memory-to-memory transfers (i.e. copy one block of memory from one place to another). I think the best way of adding support for rectangle copies (and fills?) to DMAManager would be to just restrict the API to only allow contiguous areas of physical memory to be used. Otherwise it would just get bogged down in code which validates the transfer, to check if the hardware can perform it directly. |
Jeffrey Lee (213) 6048 posts |
My DMAManager changes are now checked in (details here), along with all my other pending bits. Apart from the mass of bug fixes and the two API revisions mentioned above, I’ve made one further revision: DMAManager now passes the address of the channel being deallocated to ‘Deallocate’, in addition to the logical channel number. Apart from simplifying the OMAP3 implementation a bit, it also allows for situations where the same logical channel number is allocated multiple times (e.g. for memory-to-memory transfers, the current OMAP3 implementation uses logical channel 0 for CPU-synchronised memory-to-memory transfers, and 1+ for device-triggered device-to-device transfers. Thus once DMAManager actually gains support for memory-to-memory transfers it’s conceivable that multiple clients could allocate logical channel 0 multiple times, and each be given a different physical channel in return). Although now DMAManager always passes the channel device ptr in R2, to ensure compatability I’ve stipulated that this behaviour is only to be expected for API version 1+. With regards to the API, I’ve now added the relevant pages to the wiki. As with most of the other HAL docs, at the moment it’s basically just a copy of what was already in CVS, except for the bits I’ve updated to mention the different API versions. So in other words, it isn’t very good as a standalone reference. |
Ben Avison (25) 445 posts |
I’m not that surprised, actually. I started HALising the DMAManager targetting two ARM7TDMI / ARM9 platforms whose DMA controllers were relatively similar in principle to the OMAP one, but Pace cancelled those projects before the code was ever tried out. It’s only really previously been used on the Iyonix for ADFS, which has the two extremes – the relatively advanced list-based UDMA controller for hard discs, and the prehistoric ISA-type DMA controller for floppies (which required the bounce buffer).
Au contraire – I distinctly recall checking contiguous pages were amalgamated where possible when I was testing UDMA on Iyonix. Had to use a test program to deliberately scramble the order of physical RAM pages in the application slot to test the other case as I recall. Ah yes, I think I see the code – look at the function BuildPartialDescriptorTable. |