aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/amba
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@stericsson.com>2010-09-28 09:57:37 -0400
committerDan Williams <dan.j.williams@intel.com>2010-09-29 19:13:51 -0400
commite8689e63d4d2046079f2db9d494ac05c6885ac0c (patch)
tree29196d65697acc7fd49af9e00f2068413e29b771 /include/linux/amba
parentb30a3f6257ed2105259b404d419b4964e363928c (diff)
dmaengine: driver for the ARM PL080/PL081 PrimeCells v5
This creates a DMAengine driver for the ARM PL080/PL081 PrimeCells based on the implementation earlier submitted by Peter Pearse. This is working like a charm for memcpy and slave DMA to the PL011 PrimeCell on the PB11MPCore. This DMA controller is used in mostly unmodified form in the ARM RealView and Versatile platforms, in the ST-Ericsson Nomadik, and in the ST SPEAr platform. It has been converted to use the header from the Samsung PL080 derivate instead of its own defintions. The Samsungs have a custom driver in their mach-* folders though, atleast we can share the register definitions. Cc: Peter Pearse <peter.pearse@arm.com> Cc: Ben Dooks <ben-linux@fluff.org> Cc: Kukjin Kim <kgene.kim@samsung.com> Cc: Alessandro Rubini <rubini@unipv.it> Acked-by: Viresh Kumar <viresh.kumar@st.com> Signed-off-by: Linus Walleij <linus.walleij@stericsson.com> [GFP_KERNEL to GFP_NOWAIT in pl08x_prep_dma_memcpy] Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'include/linux/amba')
-rw-r--r--include/linux/amba/pl08x.h222
1 files changed, 222 insertions, 0 deletions
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
new file mode 100644
index 000000000000..521a0f8974ac
--- /dev/null
+++ b/include/linux/amba/pl08x.h
@@ -0,0 +1,222 @@
1/*
2 * linux/amba/pl08x.h - ARM PrimeCell DMA Controller driver
3 *
4 * Copyright (C) 2005 ARM Ltd
5 * Copyright (C) 2010 ST-Ericsson SA
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * pl08x information required by platform code
12 *
13 * Please credit ARM.com
14 * Documentation: ARM DDI 0196D
15 *
16 */
17
18#ifndef AMBA_PL08X_H
19#define AMBA_PL08X_H
20
21/* We need sizes of structs from this header */
22#include <linux/dmaengine.h>
23#include <linux/interrupt.h>
24
25/**
26 * struct pl08x_channel_data - data structure to pass info between
27 * platform and PL08x driver regarding channel configuration
28 * @bus_id: name of this device channel, not just a device name since
29 * devices may have more than one channel e.g. "foo_tx"
30 * @min_signal: the minimum DMA signal number to be muxed in for this
31 * channel (for platforms supporting muxed signals). If you have
32 * static assignments, make sure this is set to the assigned signal
33 * number, PL08x have 16 possible signals in number 0 thru 15 so
34 * when these are not enough they often get muxed (in hardware)
35 * disabling simultaneous use of the same channel for two devices.
36 * @max_signal: the maximum DMA signal number to be muxed in for
37 * the channel. Set to the same as min_signal for
38 * devices with static assignments
39 * @muxval: a number usually used to poke into some mux regiser to
40 * mux in the signal to this channel
41 * @cctl_opt: default options for the channel control register
42 * @addr: source/target address in physical memory for this DMA channel,
43 * can be the address of a FIFO register for burst requests for example.
44 * This can be left undefined if the PrimeCell API is used for configuring
45 * this.
46 * @circular_buffer: whether the buffer passed in is circular and
47 * shall simply be looped round round (like a record baby round
48 * round round round)
49 * @single: the device connected to this channel will request single
50 * DMA transfers, not bursts. (Bursts are default.)
51 */
52struct pl08x_channel_data {
53 char *bus_id;
54 int min_signal;
55 int max_signal;
56 u32 muxval;
57 u32 cctl;
58 u32 ccfg;
59 dma_addr_t addr;
60 bool circular_buffer;
61 bool single;
62};
63
64/**
65 * Struct pl08x_bus_data - information of source or destination
66 * busses for a transfer
67 * @addr: current address
68 * @maxwidth: the maximum width of a transfer on this bus
69 * @buswidth: the width of this bus in bytes: 1, 2 or 4
70 * @fill_bytes: bytes required to fill to the next bus memory
71 * boundary
72 */
73struct pl08x_bus_data {
74 dma_addr_t addr;
75 u8 maxwidth;
76 u8 buswidth;
77 u32 fill_bytes;
78};
79
80/**
81 * struct pl08x_phy_chan - holder for the physical channels
82 * @id: physical index to this channel
83 * @lock: a lock to use when altering an instance of this struct
84 * @signal: the physical signal (aka channel) serving this
85 * physical channel right now
86 * @serving: the virtual channel currently being served by this
87 * physical channel
88 */
89struct pl08x_phy_chan {
90 unsigned int id;
91 void __iomem *base;
92 spinlock_t lock;
93 int signal;
94 struct pl08x_dma_chan *serving;
95 u32 csrc;
96 u32 cdst;
97 u32 clli;
98 u32 cctl;
99 u32 ccfg;
100};
101
102/**
103 * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
104 * @llis_bus: DMA memory address (physical) start for the LLIs
105 * @llis_va: virtual memory address start for the LLIs
106 */
107struct pl08x_txd {
108 struct dma_async_tx_descriptor tx;
109 struct list_head node;
110 enum dma_data_direction direction;
111 struct pl08x_bus_data srcbus;
112 struct pl08x_bus_data dstbus;
113 int len;
114 dma_addr_t llis_bus;
115 void *llis_va;
116 struct pl08x_channel_data *cd;
117 bool active;
118 /*
119 * Settings to be put into the physical channel when we
120 * trigger this txd
121 */
122 u32 csrc;
123 u32 cdst;
124 u32 clli;
125 u32 cctl;
126};
127
128/**
129 * struct pl08x_dma_chan_state - holds the PL08x specific virtual
130 * channel states
131 * @PL08X_CHAN_IDLE: the channel is idle
132 * @PL08X_CHAN_RUNNING: the channel has allocated a physical transport
133 * channel and is running a transfer on it
134 * @PL08X_CHAN_PAUSED: the channel has allocated a physical transport
135 * channel, but the transfer is currently paused
136 * @PL08X_CHAN_WAITING: the channel is waiting for a physical transport
137 * channel to become available (only pertains to memcpy channels)
138 */
139enum pl08x_dma_chan_state {
140 PL08X_CHAN_IDLE,
141 PL08X_CHAN_RUNNING,
142 PL08X_CHAN_PAUSED,
143 PL08X_CHAN_WAITING,
144};
145
146/**
147 * struct pl08x_dma_chan - this structure wraps a DMA ENGINE channel
148 * @chan: wrappped abstract channel
149 * @phychan: the physical channel utilized by this channel, if there is one
150 * @tasklet: tasklet scheduled by the IRQ to handle actual work etc
151 * @name: name of channel
152 * @cd: channel platform data
153 * @runtime_addr: address for RX/TX according to the runtime config
154 * @runtime_direction: current direction of this channel according to
155 * runtime config
156 * @lc: last completed transaction on this channel
157 * @desc_list: queued transactions pending on this channel
158 * @at: active transaction on this channel
159 * @lockflags: sometimes we let a lock last between two function calls,
160 * especially prep/submit, and then we need to store the IRQ flags
161 * in the channel state, here
162 * @lock: a lock for this channel data
163 * @host: a pointer to the host (internal use)
164 * @state: whether the channel is idle, paused, running etc
165 * @slave: whether this channel is a device (slave) or for memcpy
166 * @waiting: a TX descriptor on this channel which is waiting for
167 * a physical channel to become available
168 */
169struct pl08x_dma_chan {
170 struct dma_chan chan;
171 struct pl08x_phy_chan *phychan;
172 struct tasklet_struct tasklet;
173 char *name;
174 struct pl08x_channel_data *cd;
175 dma_addr_t runtime_addr;
176 enum dma_data_direction runtime_direction;
177 atomic_t last_issued;
178 dma_cookie_t lc;
179 struct list_head desc_list;
180 struct pl08x_txd *at;
181 unsigned long lockflags;
182 spinlock_t lock;
183 void *host;
184 enum pl08x_dma_chan_state state;
185 bool slave;
186 struct pl08x_txd *waiting;
187};
188
189/**
190 * struct pl08x_platform_data - the platform configuration for the
191 * PL08x PrimeCells.
192 * @slave_channels: the channels defined for the different devices on the
193 * platform, all inclusive, including multiplexed channels. The available
194 * physical channels will be multiplexed around these signals as they
195 * are requested, just enumerate all possible channels.
196 * @get_signal: request a physical signal to be used for a DMA
197 * transfer immediately: if there is some multiplexing or similar blocking
198 * the use of the channel the transfer can be denied by returning
199 * less than zero, else it returns the allocated signal number
200 * @put_signal: indicate to the platform that this physical signal is not
201 * running any DMA transfer and multiplexing can be recycled
202 * @bus_bit_lli: Bit[0] of the address indicated which AHB bus master the
203 * LLI addresses are on 0/1 Master 1/2.
204 */
205struct pl08x_platform_data {
206 struct pl08x_channel_data *slave_channels;
207 unsigned int num_slave_channels;
208 struct pl08x_channel_data memcpy_channel;
209 int (*get_signal)(struct pl08x_dma_chan *);
210 void (*put_signal)(struct pl08x_dma_chan *);
211};
212
213#ifdef CONFIG_AMBA_PL08X
214bool pl08x_filter_id(struct dma_chan *chan, void *chan_id);
215#else
216static inline bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
217{
218 return false;
219}
220#endif
221
222#endif /* AMBA_PL08X_H */