Blame view

Documentation/DMA-ISA-LPC.txt 5.08 KB
5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
1
2
3
  ============================
  DMA with ISA and LPC devices
  ============================
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
4

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
5
  :Author: Pierre Ossman <drzeus@drzeus.cx>
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
6
7
8
9
  
  This document describes how to do DMA transfers using the old ISA DMA
  controller. Even though ISA is more or less dead today the LPC bus
  uses the same DMA system so it will be around for quite some time.
5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
10
11
  Headers and dependencies
  ------------------------
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
12

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
13
  To do ISA style DMA you need to include two headers::
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
14

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
15
16
  	#include <linux/dma-mapping.h>
  	#include <asm/dma.h>
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
17
18
  
  The first is the generic DMA API used to convert virtual addresses to
77f2ea2f8   Bjorn Helgaas   DMA-API: Clarify ...
19
  bus addresses (see Documentation/DMA-API.txt for details).
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
20
21
22
23
24
  
  The second contains the routines specific to ISA DMA transfers. Since
  this is not present on all platforms make sure you construct your
  Kconfig to be dependent on ISA_DMA_API (not ISA) so that nobody tries
  to build your driver on unsupported platforms.
5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
25
26
  Buffer allocation
  -----------------
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  
  The ISA DMA controller has some very strict requirements on which
  memory it can access so extra care must be taken when allocating
  buffers.
  
  (You usually need a special buffer for DMA transfers instead of
  transferring directly to and from your normal data structures.)
  
  The DMA-able address space is the lowest 16 MB of _physical_ memory.
  Also the transfer block may not cross page boundaries (which are 64
  or 128 KiB depending on which channel you use).
  
  In order to allocate a piece of memory that satisfies all these
  requirements you pass the flag GFP_DMA to kmalloc.
  
  Unfortunately the memory available for ISA DMA is scarce so unless you
  allocate the memory during boot-up it's a good idea to also pass
dcda9b047   Michal Hocko   mm, tree wide: re...
44
  __GFP_RETRY_MAYFAIL and __GFP_NOWARN to make the allocator try a bit harder.
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
45
46
47
  
  (This scarcity also means that you should allocate the buffer as
  early as possible and not release it until the driver is unloaded.)
5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
48
49
  Address translation
  -------------------
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
50

77f2ea2f8   Bjorn Helgaas   DMA-API: Clarify ...
51
  To translate the virtual address to a bus address, use the normal DMA
9a065fa8f   Christoph Hellwig   Documentation/DMA...
52
53
  API. Do _not_ use isa_virt_to_bus() even though it does the same
  thing. The reason for this is that the function isa_virt_to_bus()
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
54
55
56
57
58
59
60
  will require a Kconfig dependency to ISA, not just ISA_DMA_API which
  is really all you need. Remember that even though the DMA controller
  has its origins in ISA it is used elsewhere.
  
  Note: x86_64 had a broken DMA API when it came to ISA but has since
  been fixed. If your arch has problems then fix the DMA API instead of
  reverting to the ISA functions.
5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
61
62
  Channels
  --------
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  
  A normal ISA DMA controller has 8 channels. The lower four are for
  8-bit transfers and the upper four are for 16-bit transfers.
  
  (Actually the DMA controller is really two separate controllers where
  channel 4 is used to give DMA access for the second controller (0-3).
  This means that of the four 16-bits channels only three are usable.)
  
  You allocate these in a similar fashion as all basic resources:
  
  extern int request_dma(unsigned int dmanr, const char * device_id);
  extern void free_dma(unsigned int dmanr);
  
  The ability to use 16-bit or 8-bit transfers is _not_ up to you as a
  driver author but depends on what the hardware supports. Check your
  specs or test different channels.
5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
79
80
  Transfer data
  -------------
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  
  Now for the good stuff, the actual DMA transfer. :)
  
  Before you use any ISA DMA routines you need to claim the DMA lock
  using claim_dma_lock(). The reason is that some DMA operations are
  not atomic so only one driver may fiddle with the registers at a
  time.
  
  The first time you use the DMA controller you should call
  clear_dma_ff(). This clears an internal register in the DMA
  controller that is used for the non-atomic operations. As long as you
  (and everyone else) uses the locking functions then you only need to
  reset this once.
  
  Next, you tell the controller in which direction you intend to do the
  transfer using set_dma_mode(). Currently you have the options
  DMA_MODE_READ and DMA_MODE_WRITE.
  
  Set the address from where the transfer should start (this needs to
  be 16-bit aligned for 16-bit transfers) and how many bytes to
  transfer. Note that it's _bytes_. The DMA routines will do all the
  required translation to values that the DMA controller understands.
  
  The final step is enabling the DMA channel and releasing the DMA
  lock.
  
  Once the DMA transfer is finished (or timed out) you should disable
  the channel again. You should also check get_dma_residue() to make
fa00e7e15   Matt LaPlante   Fix typos in /Doc...
109
  sure that all data has been transferred.
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
110

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
111
  Example::
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
112

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
113
  	int flags, residue;
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
114

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
115
  	flags = claim_dma_lock();
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
116

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
117
  	clear_dma_ff();
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
118

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
119
120
121
  	set_dma_mode(channel, DMA_MODE_WRITE);
  	set_dma_addr(channel, phys_addr);
  	set_dma_count(channel, num_bytes);
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
122

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
123
  	dma_enable(channel);
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
124

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
125
  	release_dma_lock(flags);
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
126

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
127
  	while (!device_done());
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
128

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
129
  	flags = claim_dma_lock();
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
130

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
131
  	dma_disable(channel);
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
132

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
133
134
135
136
137
  	residue = dma_get_residue(channel);
  	if (residue != 0)
  		printk(KERN_ERR "driver: Incomplete DMA transfer!"
  			" %d bytes left!
  ", residue);
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
138

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
139
  	release_dma_lock(flags);
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
140

5d75cf6d3   Mauro Carvalho Chehab   DMA-ISA-LPC.txt: ...
141
142
  Suspend/resume
  --------------
ddb99f3d3   Pierre Ossman   [PATCH] ISA DMA A...
143
144
145
146
147
148
  
  It is the driver's responsibility to make sure that the machine isn't
  suspended while a DMA transfer is in progress. Also, all DMA settings
  are lost when the system suspends so if your driver relies on the DMA
  controller being in a certain state then you have to restore these
  registers upon resume.