aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/at_hdmac_regs.h
diff options
context:
space:
mode:
authorNicolas Ferre <nicolas.ferre@atmel.com>2009-07-03 13:24:33 -0400
committerDan Williams <dan.j.williams@intel.com>2009-07-23 01:41:27 -0400
commitdc78baa2b90b289590911b40b6800f77d0dc935a (patch)
treedb54dedb1e13a413190ad637ccaf6f5557dc9c10 /drivers/dma/at_hdmac_regs.h
parentf1aef8b6e6abf32a3a269542f95a19e2cb319f6c (diff)
dmaengine: at_hdmac: new driver for the Atmel AHB DMA Controller
This AHB DMA Controller (aka HDMA or DMAC on AT91 systems) is availlable on at91sam9rl chip. It will be used on other products in the future. This first release covers only the memory-to-memory tranfer type. This is the only tranfer type supported by this chip. On other products, it will be used also for peripheral DMA transfer (slave API support to come). I used dmatest client without problem in different configurations to test it. Full documentation for this controller can be found in the SAM9RL datasheet: http://www.atmel.com/dyn/products/product_card.asp?part_id=4243 Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com> Acked-by: Maciej Sosnowski <maciej.sosnowski@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma/at_hdmac_regs.h')
-rw-r--r--drivers/dma/at_hdmac_regs.h386
1 files changed, 386 insertions, 0 deletions
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
new file mode 100644
index 000000000000..ad2d4f402bf7
--- /dev/null
+++ b/drivers/dma/at_hdmac_regs.h
@@ -0,0 +1,386 @@
1/*
2 * Header file for the Atmel AHB DMA Controller driver
3 *
4 * Copyright (C) 2008 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11#ifndef AT_HDMAC_REGS_H
12#define AT_HDMAC_REGS_H
13
14#include <mach/at_hdmac.h>
15
16#define AT_DMA_MAX_NR_CHANNELS 8
17
18
19#define AT_DMA_GCFG 0x00 /* Global Configuration Register */
20#define AT_DMA_IF_BIGEND(i) (0x1 << (i)) /* AHB-Lite Interface i in Big-endian mode */
21#define AT_DMA_ARB_CFG (0x1 << 4) /* Arbiter mode. */
22#define AT_DMA_ARB_CFG_FIXED (0x0 << 4)
23#define AT_DMA_ARB_CFG_ROUND_ROBIN (0x1 << 4)
24
25#define AT_DMA_EN 0x04 /* Controller Enable Register */
26#define AT_DMA_ENABLE (0x1 << 0)
27
28#define AT_DMA_SREQ 0x08 /* Software Single Request Register */
29#define AT_DMA_SSREQ(x) (0x1 << ((x) << 1)) /* Request a source single transfer on channel x */
30#define AT_DMA_DSREQ(x) (0x1 << (1 + ((x) << 1))) /* Request a destination single transfer on channel x */
31
32#define AT_DMA_CREQ 0x0C /* Software Chunk Transfer Request Register */
33#define AT_DMA_SCREQ(x) (0x1 << ((x) << 1)) /* Request a source chunk transfer on channel x */
34#define AT_DMA_DCREQ(x) (0x1 << (1 + ((x) << 1))) /* Request a destination chunk transfer on channel x */
35
36#define AT_DMA_LAST 0x10 /* Software Last Transfer Flag Register */
37#define AT_DMA_SLAST(x) (0x1 << ((x) << 1)) /* This src rq is last tx of buffer on channel x */
38#define AT_DMA_DLAST(x) (0x1 << (1 + ((x) << 1))) /* This dst rq is last tx of buffer on channel x */
39
40#define AT_DMA_SYNC 0x14 /* Request Synchronization Register */
41#define AT_DMA_SYR(h) (0x1 << (h)) /* Synchronize handshake line h */
42
43/* Error, Chained Buffer transfer completed and Buffer transfer completed Interrupt registers */
44#define AT_DMA_EBCIER 0x18 /* Enable register */
45#define AT_DMA_EBCIDR 0x1C /* Disable register */
46#define AT_DMA_EBCIMR 0x20 /* Mask Register */
47#define AT_DMA_EBCISR 0x24 /* Status Register */
48#define AT_DMA_CBTC_OFFSET 8
49#define AT_DMA_ERR_OFFSET 16
50#define AT_DMA_BTC(x) (0x1 << (x))
51#define AT_DMA_CBTC(x) (0x1 << (AT_DMA_CBTC_OFFSET + (x)))
52#define AT_DMA_ERR(x) (0x1 << (AT_DMA_ERR_OFFSET + (x)))
53
54#define AT_DMA_CHER 0x28 /* Channel Handler Enable Register */
55#define AT_DMA_ENA(x) (0x1 << (x))
56#define AT_DMA_SUSP(x) (0x1 << ( 8 + (x)))
57#define AT_DMA_KEEP(x) (0x1 << (24 + (x)))
58
59#define AT_DMA_CHDR 0x2C /* Channel Handler Disable Register */
60#define AT_DMA_DIS(x) (0x1 << (x))
61#define AT_DMA_RES(x) (0x1 << ( 8 + (x)))
62
63#define AT_DMA_CHSR 0x30 /* Channel Handler Status Register */
64#define AT_DMA_EMPT(x) (0x1 << (16 + (x)))
65#define AT_DMA_STAL(x) (0x1 << (24 + (x)))
66
67
68#define AT_DMA_CH_REGS_BASE 0x3C /* Channel registers base address */
69#define ch_regs(x) (AT_DMA_CH_REGS_BASE + (x) * 0x28) /* Channel x base addr */
70
71/* Hardware register offset for each channel */
72#define ATC_SADDR_OFFSET 0x00 /* Source Address Register */
73#define ATC_DADDR_OFFSET 0x04 /* Destination Address Register */
74#define ATC_DSCR_OFFSET 0x08 /* Descriptor Address Register */
75#define ATC_CTRLA_OFFSET 0x0C /* Control A Register */
76#define ATC_CTRLB_OFFSET 0x10 /* Control B Register */
77#define ATC_CFG_OFFSET 0x14 /* Configuration Register */
78#define ATC_SPIP_OFFSET 0x18 /* Src PIP Configuration Register */
79#define ATC_DPIP_OFFSET 0x1C /* Dst PIP Configuration Register */
80
81
82/* Bitfield definitions */
83
84/* Bitfields in DSCR */
85#define ATC_DSCR_IF(i) (0x3 & (i)) /* Dsc feched via AHB-Lite Interface i */
86
87/* Bitfields in CTRLA */
88#define ATC_BTSIZE_MAX 0xFFFFUL /* Maximum Buffer Transfer Size */
89#define ATC_BTSIZE(x) (ATC_BTSIZE_MAX & (x)) /* Buffer Transfer Size */
90#define ATC_SCSIZE_MASK (0x7 << 16) /* Source Chunk Transfer Size */
91#define ATC_SCSIZE_1 (0x0 << 16)
92#define ATC_SCSIZE_4 (0x1 << 16)
93#define ATC_SCSIZE_8 (0x2 << 16)
94#define ATC_SCSIZE_16 (0x3 << 16)
95#define ATC_SCSIZE_32 (0x4 << 16)
96#define ATC_SCSIZE_64 (0x5 << 16)
97#define ATC_SCSIZE_128 (0x6 << 16)
98#define ATC_SCSIZE_256 (0x7 << 16)
99#define ATC_DCSIZE_MASK (0x7 << 20) /* Destination Chunk Transfer Size */
100#define ATC_DCSIZE_1 (0x0 << 20)
101#define ATC_DCSIZE_4 (0x1 << 20)
102#define ATC_DCSIZE_8 (0x2 << 20)
103#define ATC_DCSIZE_16 (0x3 << 20)
104#define ATC_DCSIZE_32 (0x4 << 20)
105#define ATC_DCSIZE_64 (0x5 << 20)
106#define ATC_DCSIZE_128 (0x6 << 20)
107#define ATC_DCSIZE_256 (0x7 << 20)
108#define ATC_SRC_WIDTH_MASK (0x3 << 24) /* Source Single Transfer Size */
109#define ATC_SRC_WIDTH_BYTE (0x0 << 24)
110#define ATC_SRC_WIDTH_HALFWORD (0x1 << 24)
111#define ATC_SRC_WIDTH_WORD (0x2 << 24)
112#define ATC_DST_WIDTH_MASK (0x3 << 28) /* Destination Single Transfer Size */
113#define ATC_DST_WIDTH_BYTE (0x0 << 28)
114#define ATC_DST_WIDTH_HALFWORD (0x1 << 28)
115#define ATC_DST_WIDTH_WORD (0x2 << 28)
116#define ATC_DONE (0x1 << 31) /* Tx Done (only written back in descriptor) */
117
118/* Bitfields in CTRLB */
119#define ATC_SIF(i) (0x3 & (i)) /* Src tx done via AHB-Lite Interface i */
120#define ATC_DIF(i) ((0x3 & (i)) << 4) /* Dst tx done via AHB-Lite Interface i */
121#define ATC_SRC_PIP (0x1 << 8) /* Source Picture-in-Picture enabled */
122#define ATC_DST_PIP (0x1 << 12) /* Destination Picture-in-Picture enabled */
123#define ATC_SRC_DSCR_DIS (0x1 << 16) /* Src Descriptor fetch disable */
124#define ATC_DST_DSCR_DIS (0x1 << 20) /* Dst Descriptor fetch disable */
125#define ATC_FC_MASK (0x7 << 21) /* Choose Flow Controller */
126#define ATC_FC_MEM2MEM (0x0 << 21) /* Mem-to-Mem (DMA) */
127#define ATC_FC_MEM2PER (0x1 << 21) /* Mem-to-Periph (DMA) */
128#define ATC_FC_PER2MEM (0x2 << 21) /* Periph-to-Mem (DMA) */
129#define ATC_FC_PER2PER (0x3 << 21) /* Periph-to-Periph (DMA) */
130#define ATC_FC_PER2MEM_PER (0x4 << 21) /* Periph-to-Mem (Peripheral) */
131#define ATC_FC_MEM2PER_PER (0x5 << 21) /* Mem-to-Periph (Peripheral) */
132#define ATC_FC_PER2PER_PER (0x6 << 21) /* Periph-to-Periph (Src Peripheral) */
133#define ATC_SRC_ADDR_MODE_MASK (0x3 << 24)
134#define ATC_SRC_ADDR_MODE_INCR (0x0 << 24) /* Incrementing Mode */
135#define ATC_SRC_ADDR_MODE_DECR (0x1 << 24) /* Decrementing Mode */
136#define ATC_SRC_ADDR_MODE_FIXED (0x2 << 24) /* Fixed Mode */
137#define ATC_DST_ADDR_MODE_MASK (0x3 << 28)
138#define ATC_DST_ADDR_MODE_INCR (0x0 << 28) /* Incrementing Mode */
139#define ATC_DST_ADDR_MODE_DECR (0x1 << 28) /* Decrementing Mode */
140#define ATC_DST_ADDR_MODE_FIXED (0x2 << 28) /* Fixed Mode */
141#define ATC_IEN (0x1 << 30) /* BTC interrupt enable (active low) */
142#define ATC_AUTO (0x1 << 31) /* Auto multiple buffer tx enable */
143
144/* Bitfields in CFG */
145#define ATC_SRC_PER(h) (0xFU & (h)) /* Channel src rq associated with periph handshaking ifc h */
146#define ATC_DST_PER(h) ((0xFU & (h)) << 4) /* Channel dst rq associated with periph handshaking ifc h */
147#define ATC_SRC_REP (0x1 << 8) /* Source Replay Mod */
148#define ATC_SRC_H2SEL (0x1 << 9) /* Source Handshaking Mod */
149#define ATC_SRC_H2SEL_SW (0x0 << 9)
150#define ATC_SRC_H2SEL_HW (0x1 << 9)
151#define ATC_DST_REP (0x1 << 12) /* Destination Replay Mod */
152#define ATC_DST_H2SEL (0x1 << 13) /* Destination Handshaking Mod */
153#define ATC_DST_H2SEL_SW (0x0 << 13)
154#define ATC_DST_H2SEL_HW (0x1 << 13)
155#define ATC_SOD (0x1 << 16) /* Stop On Done */
156#define ATC_LOCK_IF (0x1 << 20) /* Interface Lock */
157#define ATC_LOCK_B (0x1 << 21) /* AHB Bus Lock */
158#define ATC_LOCK_IF_L (0x1 << 22) /* Master Interface Arbiter Lock */
159#define ATC_LOCK_IF_L_CHUNK (0x0 << 22)
160#define ATC_LOCK_IF_L_BUFFER (0x1 << 22)
161#define ATC_AHB_PROT_MASK (0x7 << 24) /* AHB Protection */
162#define ATC_FIFOCFG_MASK (0x3 << 28) /* FIFO Request Configuration */
163#define ATC_FIFOCFG_LARGESTBURST (0x0 << 28)
164#define ATC_FIFOCFG_HALFFIFO (0x1 << 28)
165#define ATC_FIFOCFG_ENOUGHSPACE (0x2 << 28)
166
167/* Bitfields in SPIP */
168#define ATC_SPIP_HOLE(x) (0xFFFFU & (x))
169#define ATC_SPIP_BOUNDARY(x) ((0x3FF & (x)) << 16)
170
171/* Bitfields in DPIP */
172#define ATC_DPIP_HOLE(x) (0xFFFFU & (x))
173#define ATC_DPIP_BOUNDARY(x) ((0x3FF & (x)) << 16)
174
175
176/*-- descriptors -----------------------------------------------------*/
177
178/* LLI == Linked List Item; aka DMA buffer descriptor */
179struct at_lli {
180 /* values that are not changed by hardware */
181 dma_addr_t saddr;
182 dma_addr_t daddr;
183 /* value that may get written back: */
184 u32 ctrla;
185 /* more values that are not changed by hardware */
186 u32 ctrlb;
187 dma_addr_t dscr; /* chain to next lli */
188};
189
190/**
191 * struct at_desc - software descriptor
192 * @at_lli: hardware lli structure
193 * @txd: support for the async_tx api
194 * @desc_node: node on the channed descriptors list
195 * @len: total transaction bytecount
196 */
197struct at_desc {
198 /* FIRST values the hardware uses */
199 struct at_lli lli;
200
201 /* THEN values for driver housekeeping */
202 struct dma_async_tx_descriptor txd;
203 struct list_head desc_node;
204 size_t len;
205};
206
207static inline struct at_desc *
208txd_to_at_desc(struct dma_async_tx_descriptor *txd)
209{
210 return container_of(txd, struct at_desc, txd);
211}
212
213
214/*-- Channels --------------------------------------------------------*/
215
216/**
217 * struct at_dma_chan - internal representation of an Atmel HDMAC channel
218 * @chan_common: common dmaengine channel object members
219 * @device: parent device
220 * @ch_regs: memory mapped register base
221 * @mask: channel index in a mask
222 * @error_status: transmit error status information from irq handler
223 * to tasklet (use atomic operations)
224 * @tasklet: bottom half to finish transaction work
225 * @lock: serializes enqueue/dequeue operations to descriptors lists
226 * @completed_cookie: identifier for the most recently completed operation
227 * @active_list: list of descriptors dmaengine is being running on
228 * @queue: list of descriptors ready to be submitted to engine
229 * @free_list: list of descriptors usable by the channel
230 * @descs_allocated: records the actual size of the descriptor pool
231 */
232struct at_dma_chan {
233 struct dma_chan chan_common;
234 struct at_dma *device;
235 void __iomem *ch_regs;
236 u8 mask;
237 unsigned long error_status;
238 struct tasklet_struct tasklet;
239
240 spinlock_t lock;
241
242 /* these other elements are all protected by lock */
243 dma_cookie_t completed_cookie;
244 struct list_head active_list;
245 struct list_head queue;
246 struct list_head free_list;
247 unsigned int descs_allocated;
248};
249
250#define channel_readl(atchan, name) \
251 __raw_readl((atchan)->ch_regs + ATC_##name##_OFFSET)
252
253#define channel_writel(atchan, name, val) \
254 __raw_writel((val), (atchan)->ch_regs + ATC_##name##_OFFSET)
255
256static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan)
257{
258 return container_of(dchan, struct at_dma_chan, chan_common);
259}
260
261
262/*-- Controller ------------------------------------------------------*/
263
264/**
265 * struct at_dma - internal representation of an Atmel HDMA Controller
266 * @chan_common: common dmaengine dma_device object members
267 * @ch_regs: memory mapped register base
268 * @clk: dma controller clock
269 * @all_chan_mask: all channels availlable in a mask
270 * @dma_desc_pool: base of DMA descriptor region (DMA address)
271 * @chan: channels table to store at_dma_chan structures
272 */
273struct at_dma {
274 struct dma_device dma_common;
275 void __iomem *regs;
276 struct clk *clk;
277
278 u8 all_chan_mask;
279
280 struct dma_pool *dma_desc_pool;
281 /* AT THE END channels table */
282 struct at_dma_chan chan[0];
283};
284
285#define dma_readl(atdma, name) \
286 __raw_readl((atdma)->regs + AT_DMA_##name)
287#define dma_writel(atdma, name, val) \
288 __raw_writel((val), (atdma)->regs + AT_DMA_##name)
289
290static inline struct at_dma *to_at_dma(struct dma_device *ddev)
291{
292 return container_of(ddev, struct at_dma, dma_common);
293}
294
295
296/*-- Helper functions ------------------------------------------------*/
297
298static struct device *chan2dev(struct dma_chan *chan)
299{
300 return &chan->dev->device;
301}
302static struct device *chan2parent(struct dma_chan *chan)
303{
304 return chan->dev->device.parent;
305}
306
307#if defined(VERBOSE_DEBUG)
308static void vdbg_dump_regs(struct at_dma_chan *atchan)
309{
310 struct at_dma *atdma = to_at_dma(atchan->chan_common.device);
311
312 dev_err(chan2dev(&atchan->chan_common),
313 " channel %d : imr = 0x%x, chsr = 0x%x\n",
314 atchan->chan_common.chan_id,
315 dma_readl(atdma, EBCIMR),
316 dma_readl(atdma, CHSR));
317
318 dev_err(chan2dev(&atchan->chan_common),
319 " channel: s0x%x d0x%x ctrl0x%x:0x%x l0x%x\n",
320 channel_readl(atchan, SADDR),
321 channel_readl(atchan, DADDR),
322 channel_readl(atchan, CTRLA),
323 channel_readl(atchan, CTRLB),
324 channel_readl(atchan, DSCR));
325}
326#else
327static void vdbg_dump_regs(struct at_dma_chan *atchan) {}
328#endif
329
330static void atc_dump_lli(struct at_dma_chan *atchan, struct at_lli *lli)
331{
332 dev_printk(KERN_CRIT, chan2dev(&atchan->chan_common),
333 " desc: s0x%x d0x%x ctrl0x%x:0x%x l0x%x\n",
334 lli->saddr, lli->daddr,
335 lli->ctrla, lli->ctrlb, lli->dscr);
336}
337
338
339static void atc_setup_irq(struct at_dma_chan *atchan, int on)
340{
341 struct at_dma *atdma = to_at_dma(atchan->chan_common.device);
342 u32 ebci;
343
344 /* enable interrupts on buffer chain completion & error */
345 ebci = AT_DMA_CBTC(atchan->chan_common.chan_id)
346 | AT_DMA_ERR(atchan->chan_common.chan_id);
347 if (on)
348 dma_writel(atdma, EBCIER, ebci);
349 else
350 dma_writel(atdma, EBCIDR, ebci);
351}
352
353static inline void atc_enable_irq(struct at_dma_chan *atchan)
354{
355 atc_setup_irq(atchan, 1);
356}
357
358static inline void atc_disable_irq(struct at_dma_chan *atchan)
359{
360 atc_setup_irq(atchan, 0);
361}
362
363
364/**
365 * atc_chan_is_enabled - test if given channel is enabled
366 * @atchan: channel we want to test status
367 */
368static inline int atc_chan_is_enabled(struct at_dma_chan *atchan)
369{
370 struct at_dma *atdma = to_at_dma(atchan->chan_common.device);
371
372 return !!(dma_readl(atdma, CHSR) & atchan->mask);
373}
374
375
376/**
377 * set_desc_eol - set end-of-link to descriptor so it will end transfer
378 * @desc: descriptor, signle or at the end of a chain, to end chain on
379 */
380static void set_desc_eol(struct at_desc *desc)
381{
382 desc->lli.ctrlb |= ATC_SRC_DSCR_DIS | ATC_DST_DSCR_DIS;
383 desc->lli.dscr = 0;
384}
385
386#endif /* AT_HDMAC_REGS_H */