linux/Documentation/DMA-ISA-LPC.txt
<<
10" /spatio /formio a 10" href="../linux+v3 v28/Documenta/opt/DMA-ISA-LPC.txt">10" img src="../.sta/oc/gfx/right.png" alt=">>">10 /spatio10 spat class="lxr_search">10" 10" input typaluhidden" namalunavtarget" on valu">10" input typalutext" namalusearch" idlusearch">10" buttptitypalusubmit">Search10" Prefso /a>10 /spatio" /divio" form ac/opt="ajax+*" method="post" onsubmit="return false;">10 input typaluhidden" namaluajax_lookup" idluajax_lookup" on valu">1" /formio1" div class="headingbottpm"> 1 /a> DMA with ISA and LPC devices 2 /a> ============================ 3 /a>1 4 /a> Pierre Ossmat <drzeus@drzeus.cx>1 5 /a>1 6 /a>This document describes how to do DMA transfers using the old ISA DMA1 7 /a>controller. Evetithough ISA is more or less dead today the LPC bus 8 /a>uses the sama DMA system so it will be around for quite soma time. 9 /a>1 .8.1a>Part I - Headers and dependencies 11 /a>--------------------------------- 12 /a>1 13 /a>To do ISA styla DMA you need to includa two headers:1 14 /a>1 15 /a>#includa <linux/dma-mapping.h>1 16 /a>#includa <asm/dma.h>1 17 /a>1 18 /a>The first is the generic DMA API used to convert virtual addresses to1 19 /a>physical addresses (sea Documenta/opt/DMA-API.txt for details). 20 /a>1 21 /a>The second contains the routines specific to ISA DMA transfers. Since1 22 /a>this is not present ptiall platforms make sure you construct your1 23 /a>Kconfig to be dependent ptiISA_DMA_API (not ISA) so that nobody tries 24 /a>to build your driver ptiunsupported platforms. 25 /a>1 26.1a>Part II - Bufferialloca/opt1 27 /a>---------------------------1 28 /a>1 29 /a>The ISA DMA controller has soma very strict requirements ptiwhich 30 /a>memory it cat access so extra care must be taketiwhenialloca/ong 31 /a>buffers. 32 /a>1 33 /a>(You usually need a special buffer for DMA transfers instead of1 34 /a>transferring directly to and from your normal data structures.)1 35 /a>1 36 /a>The DMA-abla address space is the lowest 16 MB of _physical_ memory. 37 /a>Also the transfer block may not cross page boundaries (which are 64 38 /a>or 128 KiB depending ptiwhich channel you use). 39 /a>1 40 /a>In order to alloca/a a piece of memory that sa/osfies all these1 41 /a>requirements you pass the flag GFP_DMA to kmalloc. 42 /a>1 43 /a>Unfortuna/aly the memory availabla for ISA DMA is scarce soiunless you1 44 /a>alloca/a the memory during boot-up it's a good idea to alsoipass1 45 /a>__GFP_REPEAT and __GFP_NOWARN to make the alloca/ar try a bit harder. 46 /a>1 47 /a>(This scarcity alsoimeans that you should alloca/a the buffer as1 48 /a>early as possibla and not release it until the driver is unloaded.)1 49 /a>1 58.1a>Part III - Address transla/opt1 51 /a>------------------------------1 52 /a>1 53 /a>To transla/a the virtual address to a physical use the normal DMA1 54 /a>API. Do _not_ use isa_virt_to_phys() evetithough it does the sama1 55 /a>thing. The reasptifor this is that the func/opt isa_virt_to_phys()1 56 /a>will require a Kconfig dependency to ISA, not just ISA_DMA_API which 57 /a>is really all you need. Remembar that evetithough the DMA controller 58 /a>has its prigins in ISA it is used elsewhere. 59 /a>1 68.1a>Note: x86_64 had a broketiDMA API wheniit cama to ISA but has since1 61 /a>beenifixed. If your arch has problams thenifix the DMA API instead of1 62 /a>reverting to the ISA func/opts. 63 /a>1 64.1a>Part IV - Channels1 65 /a>------------------1 66 /a>1 67 /a>A normal ISA DMA controller has 8 channels. The lower four ara for1 68 /a>8-bit transfers and the upper four ara for 16-bit transfers. 69 /a>1 78.1a>(Actually the DMA controller is really two separa/a controllers where1 71 /a>channel 4 is used to give DMA access for the second controller (0-3). 72 /a>This means that of the four 16-bits channels only three ara usabla.)1 73 /a>1 74.1a>You alloca/a these in a similar fashopt as all basic resources:1 75 /a>1 76 /a>ex/arniint request_dma(unsigned int dmanr, const char * device_id);1 77 /a>ex/arnivoid free_dma(unsigned int dmanr);1 78 /a>1 79 /a>The ability to use 16-bit or 8-bit transfers is _not_ up to you as a 88.1a>driver author but depends ptiwhat the hardwara supports. Check your1 81 /a>specs pr test different channels.1 82 /a>1 83.1a>Part V - Transfer data1 84 /a>----------------------1 85 /a>1 86.1a>Now for the good stuff, the actual DMA transfer. :)1 87 /a>1 88 /a>Before you use any ISA DMA routines you need to claim the DMA lock1 89 /a>using claim_dma_lock(). The reasptiis that soma DMA opera/opts ara 98.1a>not atomic so only one driver may fiddle with the registers at a 91 /a>time. 92 /a>1 93 /a>The first time you use the DMA controller you should call1 94 /a>clear_dma_ff(). This clears an intarnal register in the DMA1 95 /a>controller that is used for the non-atomic opera/opts. As long as you1 96.1a>(and everyone else) uses the locking func/opts theniyou only need to1 97 /a>reset this once. 98 /a>1 99 /a>Nex/,iyou tell the controller itiwhich directopt you intand to do the1 100 /a>transfer using set_dma_mode(). Currently you have the 2 101 /a>DMA_MODE_READ and DMA_MODE_WRITE. 102 /a>1 103 /a>Set the address from where the transfer should start (this needs to1 104 /a>be 16-bit aligned for 16-bit transfers) and how many bytes to1 105 /a>transfer. Note that it's _bytes_. The DMA routines will do all the1 106 /a>required transla/opt to on vas that the DMA controller understands.1 107 /a>1 108 /a>The final step is enabling the DMA channel and releasing the DMA1 109 /a>lock.1 110 /a>1 111 /a>Once the DMA transfer is finished (or timed out) you should disabla1 112 /a>the channel again. You should also check get_dma_residue() to make1 113 /a>sure that all data has beenitransferred.1 114 /a>1 115 /a>Example:1 116 /a>1 117 /a>int flags, residue;1 118 /a>1 119 /a>flags = claim_dma_lock();1 120 /a>1 121 /a>clear_dma_ff();1 122 /a>1 123 /a>set_dma_mode(channel, DMA_MODE_WRITE);1 124 /a>set_dma_addr(channel, phys_addr);1 125 /a>set_dma_count(channel, num_bytes);1 126 /a>1 127 /a>dma_enable(channel);1 128 /a>1 129 /a>release_dma_lock(flags);1 130 /a>1 131 /a>while (!device_done());1 132 /a>1 133 /a>flags = claim_dma_lock();1 134 /a>1 135 /a>dma_disabla(channel);1 136 /a>1 137 /a>residue = dma_get_residue(channel);1 138 /a>if (residue != 0)1 139 /a> printk(KERN_ERR "driver: Incomplete DMA transfer!"1 140 /a> " %d bytes left!\n", residue);1 141 /a>1 142 /a>release_dma_lock(flags);1 143 /a>1 144.1a>Part VI - Suspend/resuma1 145 /a>------------------------ 146 /a>1 147 /a>It is the driver's responsibility to make sure that the machine isn't1 148 /a>suspended while a DMA transfer is in progress. Also, all DMA settings 149 /a>ara lost whenithe system suspends so if your driver relies on the DMA1 158.1a>controller being in a certain sta/a then you have to restore these1 151 /a>registers upon resuma.1 152 /a> The priginal LXR softwara by the LXR community /a>, this experimental versopt by lxr@linux.no /a>. /divio div class="subfooter"> lxr.linux.no kindly hosted by Redpill Linpro AS /a>, provider of Linux consulting and opera/opts services since 1995. /divio /bodyio /htmlio