diff options
Diffstat (limited to 'Documentation/DMA-ISA-LPC.txt')
| -rw-r--r-- | Documentation/DMA-ISA-LPC.txt | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/Documentation/DMA-ISA-LPC.txt b/Documentation/DMA-ISA-LPC.txt new file mode 100644 index 000000000000..705f6be92bdb --- /dev/null +++ b/Documentation/DMA-ISA-LPC.txt | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | DMA with ISA and LPC devices | ||
| 2 | ============================ | ||
| 3 | |||
| 4 | Pierre Ossman <drzeus@drzeus.cx> | ||
| 5 | |||
| 6 | This document describes how to do DMA transfers using the old ISA DMA | ||
| 7 | controller. Even though ISA is more or less dead today the LPC bus | ||
| 8 | uses the same DMA system so it will be around for quite some time. | ||
| 9 | |||
| 10 | Part I - Headers and dependencies | ||
| 11 | --------------------------------- | ||
| 12 | |||
| 13 | To do ISA style DMA you need to include two headers: | ||
| 14 | |||
| 15 | #include <linux/dma-mapping.h> | ||
| 16 | #include <asm/dma.h> | ||
| 17 | |||
| 18 | The first is the generic DMA API used to convert virtual addresses to | ||
| 19 | physical addresses (see Documentation/DMA-API.txt for details). | ||
| 20 | |||
| 21 | The second contains the routines specific to ISA DMA transfers. Since | ||
| 22 | this is not present on all platforms make sure you construct your | ||
| 23 | Kconfig to be dependent on ISA_DMA_API (not ISA) so that nobody tries | ||
| 24 | to build your driver on unsupported platforms. | ||
| 25 | |||
| 26 | Part II - Buffer allocation | ||
| 27 | --------------------------- | ||
| 28 | |||
| 29 | The ISA DMA controller has some very strict requirements on which | ||
| 30 | memory it can access so extra care must be taken when allocating | ||
| 31 | buffers. | ||
| 32 | |||
| 33 | (You usually need a special buffer for DMA transfers instead of | ||
| 34 | transferring directly to and from your normal data structures.) | ||
| 35 | |||
| 36 | The DMA-able address space is the lowest 16 MB of _physical_ memory. | ||
| 37 | Also the transfer block may not cross page boundaries (which are 64 | ||
| 38 | or 128 KiB depending on which channel you use). | ||
| 39 | |||
| 40 | In order to allocate a piece of memory that satisfies all these | ||
| 41 | requirements you pass the flag GFP_DMA to kmalloc. | ||
| 42 | |||
| 43 | Unfortunately the memory available for ISA DMA is scarce so unless you | ||
| 44 | allocate the memory during boot-up it's a good idea to also pass | ||
| 45 | __GFP_REPEAT and __GFP_NOWARN to make the allocater try a bit harder. | ||
| 46 | |||
| 47 | (This scarcity also means that you should allocate the buffer as | ||
| 48 | early as possible and not release it until the driver is unloaded.) | ||
| 49 | |||
| 50 | Part III - Address translation | ||
| 51 | ------------------------------ | ||
| 52 | |||
| 53 | To translate the virtual address to a physical use the normal DMA | ||
| 54 | API. Do _not_ use isa_virt_to_phys() even though it does the same | ||
| 55 | thing. The reason for this is that the function isa_virt_to_phys() | ||
| 56 | will require a Kconfig dependency to ISA, not just ISA_DMA_API which | ||
| 57 | is really all you need. Remember that even though the DMA controller | ||
| 58 | has its origins in ISA it is used elsewhere. | ||
| 59 | |||
| 60 | Note: x86_64 had a broken DMA API when it came to ISA but has since | ||
| 61 | been fixed. If your arch has problems then fix the DMA API instead of | ||
| 62 | reverting to the ISA functions. | ||
| 63 | |||
| 64 | Part IV - Channels | ||
| 65 | ------------------ | ||
| 66 | |||
| 67 | A normal ISA DMA controller has 8 channels. The lower four are for | ||
| 68 | 8-bit transfers and the upper four are for 16-bit transfers. | ||
| 69 | |||
| 70 | (Actually the DMA controller is really two separate controllers where | ||
| 71 | channel 4 is used to give DMA access for the second controller (0-3). | ||
| 72 | This means that of the four 16-bits channels only three are usable.) | ||
| 73 | |||
| 74 | You allocate these in a similar fashion as all basic resources: | ||
| 75 | |||
| 76 | extern int request_dma(unsigned int dmanr, const char * device_id); | ||
| 77 | extern void free_dma(unsigned int dmanr); | ||
| 78 | |||
| 79 | The ability to use 16-bit or 8-bit transfers is _not_ up to you as a | ||
| 80 | driver author but depends on what the hardware supports. Check your | ||
| 81 | specs or test different channels. | ||
| 82 | |||
| 83 | Part V - Transfer data | ||
| 84 | ---------------------- | ||
| 85 | |||
| 86 | Now for the good stuff, the actual DMA transfer. :) | ||
| 87 | |||
| 88 | Before you use any ISA DMA routines you need to claim the DMA lock | ||
| 89 | using claim_dma_lock(). The reason is that some DMA operations are | ||
| 90 | not atomic so only one driver may fiddle with the registers at a | ||
| 91 | time. | ||
| 92 | |||
| 93 | The first time you use the DMA controller you should call | ||
| 94 | clear_dma_ff(). This clears an internal register in the DMA | ||
| 95 | controller that is used for the non-atomic operations. As long as you | ||
| 96 | (and everyone else) uses the locking functions then you only need to | ||
| 97 | reset this once. | ||
| 98 | |||
| 99 | Next, you tell the controller in which direction you intend to do the | ||
| 100 | transfer using set_dma_mode(). Currently you have the options | ||
| 101 | DMA_MODE_READ and DMA_MODE_WRITE. | ||
| 102 | |||
| 103 | Set the address from where the transfer should start (this needs to | ||
| 104 | be 16-bit aligned for 16-bit transfers) and how many bytes to | ||
| 105 | transfer. Note that it's _bytes_. The DMA routines will do all the | ||
| 106 | required translation to values that the DMA controller understands. | ||
| 107 | |||
| 108 | The final step is enabling the DMA channel and releasing the DMA | ||
| 109 | lock. | ||
| 110 | |||
| 111 | Once the DMA transfer is finished (or timed out) you should disable | ||
| 112 | the channel again. You should also check get_dma_residue() to make | ||
| 113 | sure that all data has been transfered. | ||
| 114 | |||
| 115 | Example: | ||
| 116 | |||
| 117 | int flags, residue; | ||
| 118 | |||
| 119 | flags = claim_dma_lock(); | ||
| 120 | |||
| 121 | clear_dma_ff(); | ||
| 122 | |||
| 123 | set_dma_mode(channel, DMA_MODE_WRITE); | ||
| 124 | set_dma_addr(channel, phys_addr); | ||
| 125 | set_dma_count(channel, num_bytes); | ||
| 126 | |||
| 127 | dma_enable(channel); | ||
| 128 | |||
| 129 | release_dma_lock(flags); | ||
| 130 | |||
| 131 | while (!device_done()); | ||
| 132 | |||
| 133 | flags = claim_dma_lock(); | ||
| 134 | |||
| 135 | dma_disable(channel); | ||
| 136 | |||
| 137 | residue = dma_get_residue(channel); | ||
| 138 | if (residue != 0) | ||
| 139 | printk(KERN_ERR "driver: Incomplete DMA transfer!" | ||
| 140 | " %d bytes left!\n", residue); | ||
| 141 | |||
| 142 | release_dma_lock(flags); | ||
| 143 | |||
| 144 | Part VI - Suspend/resume | ||
| 145 | ------------------------ | ||
| 146 | |||
| 147 | It is the driver's responsibility to make sure that the machine isn't | ||
| 148 | suspended while a DMA transfer is in progress. Also, all DMA settings | ||
| 149 | are lost when the system suspends so if your driver relies on the DMA | ||
| 150 | controller being in a certain state then you have to restore these | ||
| 151 | registers upon resume. | ||
