aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-spear3xx/spear300.c26
-rw-r--r--arch/arm/mach-spear3xx/spear310.c26
-rw-r--r--arch/arm/mach-spear3xx/spear320.c26
-rw-r--r--arch/arm/mach-spear3xx/spear3xx.c3
-rw-r--r--arch/arm/mach-spear6xx/spear6xx.c51
-rw-r--r--arch/arm/plat-spear/include/plat/pl080.h6
-rw-r--r--arch/arm/plat-spear/pl080.c10
-rw-r--r--drivers/dma/Kconfig1
-rw-r--r--drivers/dma/amba-pl08x.c941
-rw-r--r--drivers/dma/sa11x0-dma.c153
-rw-r--r--include/linux/amba/pl08x.h156
11 files changed, 614 insertions, 785 deletions
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 0f882ecb7d81..6ec300549960 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -120,182 +120,156 @@ struct pl08x_channel_data spear300_dma_info[] = {
120 .min_signal = 2, 120 .min_signal = 2,
121 .max_signal = 2, 121 .max_signal = 2,
122 .muxval = 0, 122 .muxval = 0,
123 .cctl = 0,
124 .periph_buses = PL08X_AHB1, 123 .periph_buses = PL08X_AHB1,
125 }, { 124 }, {
126 .bus_id = "uart0_tx", 125 .bus_id = "uart0_tx",
127 .min_signal = 3, 126 .min_signal = 3,
128 .max_signal = 3, 127 .max_signal = 3,
129 .muxval = 0, 128 .muxval = 0,
130 .cctl = 0,
131 .periph_buses = PL08X_AHB1, 129 .periph_buses = PL08X_AHB1,
132 }, { 130 }, {
133 .bus_id = "ssp0_rx", 131 .bus_id = "ssp0_rx",
134 .min_signal = 8, 132 .min_signal = 8,
135 .max_signal = 8, 133 .max_signal = 8,
136 .muxval = 0, 134 .muxval = 0,
137 .cctl = 0,
138 .periph_buses = PL08X_AHB1, 135 .periph_buses = PL08X_AHB1,
139 }, { 136 }, {
140 .bus_id = "ssp0_tx", 137 .bus_id = "ssp0_tx",
141 .min_signal = 9, 138 .min_signal = 9,
142 .max_signal = 9, 139 .max_signal = 9,
143 .muxval = 0, 140 .muxval = 0,
144 .cctl = 0,
145 .periph_buses = PL08X_AHB1, 141 .periph_buses = PL08X_AHB1,
146 }, { 142 }, {
147 .bus_id = "i2c_rx", 143 .bus_id = "i2c_rx",
148 .min_signal = 10, 144 .min_signal = 10,
149 .max_signal = 10, 145 .max_signal = 10,
150 .muxval = 0, 146 .muxval = 0,
151 .cctl = 0,
152 .periph_buses = PL08X_AHB1, 147 .periph_buses = PL08X_AHB1,
153 }, { 148 }, {
154 .bus_id = "i2c_tx", 149 .bus_id = "i2c_tx",
155 .min_signal = 11, 150 .min_signal = 11,
156 .max_signal = 11, 151 .max_signal = 11,
157 .muxval = 0, 152 .muxval = 0,
158 .cctl = 0,
159 .periph_buses = PL08X_AHB1, 153 .periph_buses = PL08X_AHB1,
160 }, { 154 }, {
161 .bus_id = "irda", 155 .bus_id = "irda",
162 .min_signal = 12, 156 .min_signal = 12,
163 .max_signal = 12, 157 .max_signal = 12,
164 .muxval = 0, 158 .muxval = 0,
165 .cctl = 0,
166 .periph_buses = PL08X_AHB1, 159 .periph_buses = PL08X_AHB1,
167 }, { 160 }, {
168 .bus_id = "adc", 161 .bus_id = "adc",
169 .min_signal = 13, 162 .min_signal = 13,
170 .max_signal = 13, 163 .max_signal = 13,
171 .muxval = 0, 164 .muxval = 0,
172 .cctl = 0,
173 .periph_buses = PL08X_AHB1, 165 .periph_buses = PL08X_AHB1,
174 }, { 166 }, {
175 .bus_id = "to_jpeg", 167 .bus_id = "to_jpeg",
176 .min_signal = 14, 168 .min_signal = 14,
177 .max_signal = 14, 169 .max_signal = 14,
178 .muxval = 0, 170 .muxval = 0,
179 .cctl = 0,
180 .periph_buses = PL08X_AHB1, 171 .periph_buses = PL08X_AHB1,
181 }, { 172 }, {
182 .bus_id = "from_jpeg", 173 .bus_id = "from_jpeg",
183 .min_signal = 15, 174 .min_signal = 15,
184 .max_signal = 15, 175 .max_signal = 15,
185 .muxval = 0, 176 .muxval = 0,
186 .cctl = 0,
187 .periph_buses = PL08X_AHB1, 177 .periph_buses = PL08X_AHB1,
188 }, { 178 }, {
189 .bus_id = "ras0_rx", 179 .bus_id = "ras0_rx",
190 .min_signal = 0, 180 .min_signal = 0,
191 .max_signal = 0, 181 .max_signal = 0,
192 .muxval = 1, 182 .muxval = 1,
193 .cctl = 0,
194 .periph_buses = PL08X_AHB1, 183 .periph_buses = PL08X_AHB1,
195 }, { 184 }, {
196 .bus_id = "ras0_tx", 185 .bus_id = "ras0_tx",
197 .min_signal = 1, 186 .min_signal = 1,
198 .max_signal = 1, 187 .max_signal = 1,
199 .muxval = 1, 188 .muxval = 1,
200 .cctl = 0,
201 .periph_buses = PL08X_AHB1, 189 .periph_buses = PL08X_AHB1,
202 }, { 190 }, {
203 .bus_id = "ras1_rx", 191 .bus_id = "ras1_rx",
204 .min_signal = 2, 192 .min_signal = 2,
205 .max_signal = 2, 193 .max_signal = 2,
206 .muxval = 1, 194 .muxval = 1,
207 .cctl = 0,
208 .periph_buses = PL08X_AHB1, 195 .periph_buses = PL08X_AHB1,
209 }, { 196 }, {
210 .bus_id = "ras1_tx", 197 .bus_id = "ras1_tx",
211 .min_signal = 3, 198 .min_signal = 3,
212 .max_signal = 3, 199 .max_signal = 3,
213 .muxval = 1, 200 .muxval = 1,
214 .cctl = 0,
215 .periph_buses = PL08X_AHB1, 201 .periph_buses = PL08X_AHB1,
216 }, { 202 }, {
217 .bus_id = "ras2_rx", 203 .bus_id = "ras2_rx",
218 .min_signal = 4, 204 .min_signal = 4,
219 .max_signal = 4, 205 .max_signal = 4,
220 .muxval = 1, 206 .muxval = 1,
221 .cctl = 0,
222 .periph_buses = PL08X_AHB1, 207 .periph_buses = PL08X_AHB1,
223 }, { 208 }, {
224 .bus_id = "ras2_tx", 209 .bus_id = "ras2_tx",
225 .min_signal = 5, 210 .min_signal = 5,
226 .max_signal = 5, 211 .max_signal = 5,
227 .muxval = 1, 212 .muxval = 1,
228 .cctl = 0,
229 .periph_buses = PL08X_AHB1, 213 .periph_buses = PL08X_AHB1,
230 }, { 214 }, {
231 .bus_id = "ras3_rx", 215 .bus_id = "ras3_rx",
232 .min_signal = 6, 216 .min_signal = 6,
233 .max_signal = 6, 217 .max_signal = 6,
234 .muxval = 1, 218 .muxval = 1,
235 .cctl = 0,
236 .periph_buses = PL08X_AHB1, 219 .periph_buses = PL08X_AHB1,
237 }, { 220 }, {
238 .bus_id = "ras3_tx", 221 .bus_id = "ras3_tx",
239 .min_signal = 7, 222 .min_signal = 7,
240 .max_signal = 7, 223 .max_signal = 7,
241 .muxval = 1, 224 .muxval = 1,
242 .cctl = 0,
243 .periph_buses = PL08X_AHB1, 225 .periph_buses = PL08X_AHB1,
244 }, { 226 }, {
245 .bus_id = "ras4_rx", 227 .bus_id = "ras4_rx",
246 .min_signal = 8, 228 .min_signal = 8,
247 .max_signal = 8, 229 .max_signal = 8,
248 .muxval = 1, 230 .muxval = 1,
249 .cctl = 0,
250 .periph_buses = PL08X_AHB1, 231 .periph_buses = PL08X_AHB1,
251 }, { 232 }, {
252 .bus_id = "ras4_tx", 233 .bus_id = "ras4_tx",
253 .min_signal = 9, 234 .min_signal = 9,
254 .max_signal = 9, 235 .max_signal = 9,
255 .muxval = 1, 236 .muxval = 1,
256 .cctl = 0,
257 .periph_buses = PL08X_AHB1, 237 .periph_buses = PL08X_AHB1,
258 }, { 238 }, {
259 .bus_id = "ras5_rx", 239 .bus_id = "ras5_rx",
260 .min_signal = 10, 240 .min_signal = 10,
261 .max_signal = 10, 241 .max_signal = 10,
262 .muxval = 1, 242 .muxval = 1,
263 .cctl = 0,
264 .periph_buses = PL08X_AHB1, 243 .periph_buses = PL08X_AHB1,
265 }, { 244 }, {
266 .bus_id = "ras5_tx", 245 .bus_id = "ras5_tx",
267 .min_signal = 11, 246 .min_signal = 11,
268 .max_signal = 11, 247 .max_signal = 11,
269 .muxval = 1, 248 .muxval = 1,
270 .cctl = 0,
271 .periph_buses = PL08X_AHB1, 249 .periph_buses = PL08X_AHB1,
272 }, { 250 }, {
273 .bus_id = "ras6_rx", 251 .bus_id = "ras6_rx",
274 .min_signal = 12, 252 .min_signal = 12,
275 .max_signal = 12, 253 .max_signal = 12,
276 .muxval = 1, 254 .muxval = 1,
277 .cctl = 0,
278 .periph_buses = PL08X_AHB1, 255 .periph_buses = PL08X_AHB1,
279 }, { 256 }, {
280 .bus_id = "ras6_tx", 257 .bus_id = "ras6_tx",
281 .min_signal = 13, 258 .min_signal = 13,
282 .max_signal = 13, 259 .max_signal = 13,
283 .muxval = 1, 260 .muxval = 1,
284 .cctl = 0,
285 .periph_buses = PL08X_AHB1, 261 .periph_buses = PL08X_AHB1,
286 }, { 262 }, {
287 .bus_id = "ras7_rx", 263 .bus_id = "ras7_rx",
288 .min_signal = 14, 264 .min_signal = 14,
289 .max_signal = 14, 265 .max_signal = 14,
290 .muxval = 1, 266 .muxval = 1,
291 .cctl = 0,
292 .periph_buses = PL08X_AHB1, 267 .periph_buses = PL08X_AHB1,
293 }, { 268 }, {
294 .bus_id = "ras7_tx", 269 .bus_id = "ras7_tx",
295 .min_signal = 15, 270 .min_signal = 15,
296 .max_signal = 15, 271 .max_signal = 15,
297 .muxval = 1, 272 .muxval = 1,
298 .cctl = 0,
299 .periph_buses = PL08X_AHB1, 273 .periph_buses = PL08X_AHB1,
300 }, 274 },
301}; 275};
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index bbcf4571d361..1d0e435b9045 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -205,182 +205,156 @@ struct pl08x_channel_data spear310_dma_info[] = {
205 .min_signal = 2, 205 .min_signal = 2,
206 .max_signal = 2, 206 .max_signal = 2,
207 .muxval = 0, 207 .muxval = 0,
208 .cctl = 0,
209 .periph_buses = PL08X_AHB1, 208 .periph_buses = PL08X_AHB1,
210 }, { 209 }, {
211 .bus_id = "uart0_tx", 210 .bus_id = "uart0_tx",
212 .min_signal = 3, 211 .min_signal = 3,
213 .max_signal = 3, 212 .max_signal = 3,
214 .muxval = 0, 213 .muxval = 0,
215 .cctl = 0,
216 .periph_buses = PL08X_AHB1, 214 .periph_buses = PL08X_AHB1,
217 }, { 215 }, {
218 .bus_id = "ssp0_rx", 216 .bus_id = "ssp0_rx",
219 .min_signal = 8, 217 .min_signal = 8,
220 .max_signal = 8, 218 .max_signal = 8,
221 .muxval = 0, 219 .muxval = 0,
222 .cctl = 0,
223 .periph_buses = PL08X_AHB1, 220 .periph_buses = PL08X_AHB1,
224 }, { 221 }, {
225 .bus_id = "ssp0_tx", 222 .bus_id = "ssp0_tx",
226 .min_signal = 9, 223 .min_signal = 9,
227 .max_signal = 9, 224 .max_signal = 9,
228 .muxval = 0, 225 .muxval = 0,
229 .cctl = 0,
230 .periph_buses = PL08X_AHB1, 226 .periph_buses = PL08X_AHB1,
231 }, { 227 }, {
232 .bus_id = "i2c_rx", 228 .bus_id = "i2c_rx",
233 .min_signal = 10, 229 .min_signal = 10,
234 .max_signal = 10, 230 .max_signal = 10,
235 .muxval = 0, 231 .muxval = 0,
236 .cctl = 0,
237 .periph_buses = PL08X_AHB1, 232 .periph_buses = PL08X_AHB1,
238 }, { 233 }, {
239 .bus_id = "i2c_tx", 234 .bus_id = "i2c_tx",
240 .min_signal = 11, 235 .min_signal = 11,
241 .max_signal = 11, 236 .max_signal = 11,
242 .muxval = 0, 237 .muxval = 0,
243 .cctl = 0,
244 .periph_buses = PL08X_AHB1, 238 .periph_buses = PL08X_AHB1,
245 }, { 239 }, {
246 .bus_id = "irda", 240 .bus_id = "irda",
247 .min_signal = 12, 241 .min_signal = 12,
248 .max_signal = 12, 242 .max_signal = 12,
249 .muxval = 0, 243 .muxval = 0,
250 .cctl = 0,
251 .periph_buses = PL08X_AHB1, 244 .periph_buses = PL08X_AHB1,
252 }, { 245 }, {
253 .bus_id = "adc", 246 .bus_id = "adc",
254 .min_signal = 13, 247 .min_signal = 13,
255 .max_signal = 13, 248 .max_signal = 13,
256 .muxval = 0, 249 .muxval = 0,
257 .cctl = 0,
258 .periph_buses = PL08X_AHB1, 250 .periph_buses = PL08X_AHB1,
259 }, { 251 }, {
260 .bus_id = "to_jpeg", 252 .bus_id = "to_jpeg",
261 .min_signal = 14, 253 .min_signal = 14,
262 .max_signal = 14, 254 .max_signal = 14,
263 .muxval = 0, 255 .muxval = 0,
264 .cctl = 0,
265 .periph_buses = PL08X_AHB1, 256 .periph_buses = PL08X_AHB1,
266 }, { 257 }, {
267 .bus_id = "from_jpeg", 258 .bus_id = "from_jpeg",
268 .min_signal = 15, 259 .min_signal = 15,
269 .max_signal = 15, 260 .max_signal = 15,
270 .muxval = 0, 261 .muxval = 0,
271 .cctl = 0,
272 .periph_buses = PL08X_AHB1, 262 .periph_buses = PL08X_AHB1,
273 }, { 263 }, {
274 .bus_id = "uart1_rx", 264 .bus_id = "uart1_rx",
275 .min_signal = 0, 265 .min_signal = 0,
276 .max_signal = 0, 266 .max_signal = 0,
277 .muxval = 1, 267 .muxval = 1,
278 .cctl = 0,
279 .periph_buses = PL08X_AHB1, 268 .periph_buses = PL08X_AHB1,
280 }, { 269 }, {
281 .bus_id = "uart1_tx", 270 .bus_id = "uart1_tx",
282 .min_signal = 1, 271 .min_signal = 1,
283 .max_signal = 1, 272 .max_signal = 1,
284 .muxval = 1, 273 .muxval = 1,
285 .cctl = 0,
286 .periph_buses = PL08X_AHB1, 274 .periph_buses = PL08X_AHB1,
287 }, { 275 }, {
288 .bus_id = "uart2_rx", 276 .bus_id = "uart2_rx",
289 .min_signal = 2, 277 .min_signal = 2,
290 .max_signal = 2, 278 .max_signal = 2,
291 .muxval = 1, 279 .muxval = 1,
292 .cctl = 0,
293 .periph_buses = PL08X_AHB1, 280 .periph_buses = PL08X_AHB1,
294 }, { 281 }, {
295 .bus_id = "uart2_tx", 282 .bus_id = "uart2_tx",
296 .min_signal = 3, 283 .min_signal = 3,
297 .max_signal = 3, 284 .max_signal = 3,
298 .muxval = 1, 285 .muxval = 1,
299 .cctl = 0,
300 .periph_buses = PL08X_AHB1, 286 .periph_buses = PL08X_AHB1,
301 }, { 287 }, {
302 .bus_id = "uart3_rx", 288 .bus_id = "uart3_rx",
303 .min_signal = 4, 289 .min_signal = 4,
304 .max_signal = 4, 290 .max_signal = 4,
305 .muxval = 1, 291 .muxval = 1,
306 .cctl = 0,
307 .periph_buses = PL08X_AHB1, 292 .periph_buses = PL08X_AHB1,
308 }, { 293 }, {
309 .bus_id = "uart3_tx", 294 .bus_id = "uart3_tx",
310 .min_signal = 5, 295 .min_signal = 5,
311 .max_signal = 5, 296 .max_signal = 5,
312 .muxval = 1, 297 .muxval = 1,
313 .cctl = 0,
314 .periph_buses = PL08X_AHB1, 298 .periph_buses = PL08X_AHB1,
315 }, { 299 }, {
316 .bus_id = "uart4_rx", 300 .bus_id = "uart4_rx",
317 .min_signal = 6, 301 .min_signal = 6,
318 .max_signal = 6, 302 .max_signal = 6,
319 .muxval = 1, 303 .muxval = 1,
320 .cctl = 0,
321 .periph_buses = PL08X_AHB1, 304 .periph_buses = PL08X_AHB1,
322 }, { 305 }, {
323 .bus_id = "uart4_tx", 306 .bus_id = "uart4_tx",
324 .min_signal = 7, 307 .min_signal = 7,
325 .max_signal = 7, 308 .max_signal = 7,
326 .muxval = 1, 309 .muxval = 1,
327 .cctl = 0,
328 .periph_buses = PL08X_AHB1, 310 .periph_buses = PL08X_AHB1,
329 }, { 311 }, {
330 .bus_id = "uart5_rx", 312 .bus_id = "uart5_rx",
331 .min_signal = 8, 313 .min_signal = 8,
332 .max_signal = 8, 314 .max_signal = 8,
333 .muxval = 1, 315 .muxval = 1,
334 .cctl = 0,
335 .periph_buses = PL08X_AHB1, 316 .periph_buses = PL08X_AHB1,
336 }, { 317 }, {
337 .bus_id = "uart5_tx", 318 .bus_id = "uart5_tx",
338 .min_signal = 9, 319 .min_signal = 9,
339 .max_signal = 9, 320 .max_signal = 9,
340 .muxval = 1, 321 .muxval = 1,
341 .cctl = 0,
342 .periph_buses = PL08X_AHB1, 322 .periph_buses = PL08X_AHB1,
343 }, { 323 }, {
344 .bus_id = "ras5_rx", 324 .bus_id = "ras5_rx",
345 .min_signal = 10, 325 .min_signal = 10,
346 .max_signal = 10, 326 .max_signal = 10,
347 .muxval = 1, 327 .muxval = 1,
348 .cctl = 0,
349 .periph_buses = PL08X_AHB1, 328 .periph_buses = PL08X_AHB1,
350 }, { 329 }, {
351 .bus_id = "ras5_tx", 330 .bus_id = "ras5_tx",
352 .min_signal = 11, 331 .min_signal = 11,
353 .max_signal = 11, 332 .max_signal = 11,
354 .muxval = 1, 333 .muxval = 1,
355 .cctl = 0,
356 .periph_buses = PL08X_AHB1, 334 .periph_buses = PL08X_AHB1,
357 }, { 335 }, {
358 .bus_id = "ras6_rx", 336 .bus_id = "ras6_rx",
359 .min_signal = 12, 337 .min_signal = 12,
360 .max_signal = 12, 338 .max_signal = 12,
361 .muxval = 1, 339 .muxval = 1,
362 .cctl = 0,
363 .periph_buses = PL08X_AHB1, 340 .periph_buses = PL08X_AHB1,
364 }, { 341 }, {
365 .bus_id = "ras6_tx", 342 .bus_id = "ras6_tx",
366 .min_signal = 13, 343 .min_signal = 13,
367 .max_signal = 13, 344 .max_signal = 13,
368 .muxval = 1, 345 .muxval = 1,
369 .cctl = 0,
370 .periph_buses = PL08X_AHB1, 346 .periph_buses = PL08X_AHB1,
371 }, { 347 }, {
372 .bus_id = "ras7_rx", 348 .bus_id = "ras7_rx",
373 .min_signal = 14, 349 .min_signal = 14,
374 .max_signal = 14, 350 .max_signal = 14,
375 .muxval = 1, 351 .muxval = 1,
376 .cctl = 0,
377 .periph_buses = PL08X_AHB1, 352 .periph_buses = PL08X_AHB1,
378 }, { 353 }, {
379 .bus_id = "ras7_tx", 354 .bus_id = "ras7_tx",
380 .min_signal = 15, 355 .min_signal = 15,
381 .max_signal = 15, 356 .max_signal = 15,
382 .muxval = 1, 357 .muxval = 1,
383 .cctl = 0,
384 .periph_buses = PL08X_AHB1, 358 .periph_buses = PL08X_AHB1,
385 }, 359 },
386}; 360};
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 88d483bcd66a..fd823c624575 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -213,182 +213,156 @@ struct pl08x_channel_data spear320_dma_info[] = {
213 .min_signal = 2, 213 .min_signal = 2,
214 .max_signal = 2, 214 .max_signal = 2,
215 .muxval = 0, 215 .muxval = 0,
216 .cctl = 0,
217 .periph_buses = PL08X_AHB1, 216 .periph_buses = PL08X_AHB1,
218 }, { 217 }, {
219 .bus_id = "uart0_tx", 218 .bus_id = "uart0_tx",
220 .min_signal = 3, 219 .min_signal = 3,
221 .max_signal = 3, 220 .max_signal = 3,
222 .muxval = 0, 221 .muxval = 0,
223 .cctl = 0,
224 .periph_buses = PL08X_AHB1, 222 .periph_buses = PL08X_AHB1,
225 }, { 223 }, {
226 .bus_id = "ssp0_rx", 224 .bus_id = "ssp0_rx",
227 .min_signal = 8, 225 .min_signal = 8,
228 .max_signal = 8, 226 .max_signal = 8,
229 .muxval = 0, 227 .muxval = 0,
230 .cctl = 0,
231 .periph_buses = PL08X_AHB1, 228 .periph_buses = PL08X_AHB1,
232 }, { 229 }, {
233 .bus_id = "ssp0_tx", 230 .bus_id = "ssp0_tx",
234 .min_signal = 9, 231 .min_signal = 9,
235 .max_signal = 9, 232 .max_signal = 9,
236 .muxval = 0, 233 .muxval = 0,
237 .cctl = 0,
238 .periph_buses = PL08X_AHB1, 234 .periph_buses = PL08X_AHB1,
239 }, { 235 }, {
240 .bus_id = "i2c0_rx", 236 .bus_id = "i2c0_rx",
241 .min_signal = 10, 237 .min_signal = 10,
242 .max_signal = 10, 238 .max_signal = 10,
243 .muxval = 0, 239 .muxval = 0,
244 .cctl = 0,
245 .periph_buses = PL08X_AHB1, 240 .periph_buses = PL08X_AHB1,
246 }, { 241 }, {
247 .bus_id = "i2c0_tx", 242 .bus_id = "i2c0_tx",
248 .min_signal = 11, 243 .min_signal = 11,
249 .max_signal = 11, 244 .max_signal = 11,
250 .muxval = 0, 245 .muxval = 0,
251 .cctl = 0,
252 .periph_buses = PL08X_AHB1, 246 .periph_buses = PL08X_AHB1,
253 }, { 247 }, {
254 .bus_id = "irda", 248 .bus_id = "irda",
255 .min_signal = 12, 249 .min_signal = 12,
256 .max_signal = 12, 250 .max_signal = 12,
257 .muxval = 0, 251 .muxval = 0,
258 .cctl = 0,
259 .periph_buses = PL08X_AHB1, 252 .periph_buses = PL08X_AHB1,
260 }, { 253 }, {
261 .bus_id = "adc", 254 .bus_id = "adc",
262 .min_signal = 13, 255 .min_signal = 13,
263 .max_signal = 13, 256 .max_signal = 13,
264 .muxval = 0, 257 .muxval = 0,
265 .cctl = 0,
266 .periph_buses = PL08X_AHB1, 258 .periph_buses = PL08X_AHB1,
267 }, { 259 }, {
268 .bus_id = "to_jpeg", 260 .bus_id = "to_jpeg",
269 .min_signal = 14, 261 .min_signal = 14,
270 .max_signal = 14, 262 .max_signal = 14,
271 .muxval = 0, 263 .muxval = 0,
272 .cctl = 0,
273 .periph_buses = PL08X_AHB1, 264 .periph_buses = PL08X_AHB1,
274 }, { 265 }, {
275 .bus_id = "from_jpeg", 266 .bus_id = "from_jpeg",
276 .min_signal = 15, 267 .min_signal = 15,
277 .max_signal = 15, 268 .max_signal = 15,
278 .muxval = 0, 269 .muxval = 0,
279 .cctl = 0,
280 .periph_buses = PL08X_AHB1, 270 .periph_buses = PL08X_AHB1,
281 }, { 271 }, {
282 .bus_id = "ssp1_rx", 272 .bus_id = "ssp1_rx",
283 .min_signal = 0, 273 .min_signal = 0,
284 .max_signal = 0, 274 .max_signal = 0,
285 .muxval = 1, 275 .muxval = 1,
286 .cctl = 0,
287 .periph_buses = PL08X_AHB2, 276 .periph_buses = PL08X_AHB2,
288 }, { 277 }, {
289 .bus_id = "ssp1_tx", 278 .bus_id = "ssp1_tx",
290 .min_signal = 1, 279 .min_signal = 1,
291 .max_signal = 1, 280 .max_signal = 1,
292 .muxval = 1, 281 .muxval = 1,
293 .cctl = 0,
294 .periph_buses = PL08X_AHB2, 282 .periph_buses = PL08X_AHB2,
295 }, { 283 }, {
296 .bus_id = "ssp2_rx", 284 .bus_id = "ssp2_rx",
297 .min_signal = 2, 285 .min_signal = 2,
298 .max_signal = 2, 286 .max_signal = 2,
299 .muxval = 1, 287 .muxval = 1,
300 .cctl = 0,
301 .periph_buses = PL08X_AHB2, 288 .periph_buses = PL08X_AHB2,
302 }, { 289 }, {
303 .bus_id = "ssp2_tx", 290 .bus_id = "ssp2_tx",
304 .min_signal = 3, 291 .min_signal = 3,
305 .max_signal = 3, 292 .max_signal = 3,
306 .muxval = 1, 293 .muxval = 1,
307 .cctl = 0,
308 .periph_buses = PL08X_AHB2, 294 .periph_buses = PL08X_AHB2,
309 }, { 295 }, {
310 .bus_id = "uart1_rx", 296 .bus_id = "uart1_rx",
311 .min_signal = 4, 297 .min_signal = 4,
312 .max_signal = 4, 298 .max_signal = 4,
313 .muxval = 1, 299 .muxval = 1,
314 .cctl = 0,
315 .periph_buses = PL08X_AHB2, 300 .periph_buses = PL08X_AHB2,
316 }, { 301 }, {
317 .bus_id = "uart1_tx", 302 .bus_id = "uart1_tx",
318 .min_signal = 5, 303 .min_signal = 5,
319 .max_signal = 5, 304 .max_signal = 5,
320 .muxval = 1, 305 .muxval = 1,
321 .cctl = 0,
322 .periph_buses = PL08X_AHB2, 306 .periph_buses = PL08X_AHB2,
323 }, { 307 }, {
324 .bus_id = "uart2_rx", 308 .bus_id = "uart2_rx",
325 .min_signal = 6, 309 .min_signal = 6,
326 .max_signal = 6, 310 .max_signal = 6,
327 .muxval = 1, 311 .muxval = 1,
328 .cctl = 0,
329 .periph_buses = PL08X_AHB2, 312 .periph_buses = PL08X_AHB2,
330 }, { 313 }, {
331 .bus_id = "uart2_tx", 314 .bus_id = "uart2_tx",
332 .min_signal = 7, 315 .min_signal = 7,
333 .max_signal = 7, 316 .max_signal = 7,
334 .muxval = 1, 317 .muxval = 1,
335 .cctl = 0,
336 .periph_buses = PL08X_AHB2, 318 .periph_buses = PL08X_AHB2,
337 }, { 319 }, {
338 .bus_id = "i2c1_rx", 320 .bus_id = "i2c1_rx",
339 .min_signal = 8, 321 .min_signal = 8,
340 .max_signal = 8, 322 .max_signal = 8,
341 .muxval = 1, 323 .muxval = 1,
342 .cctl = 0,
343 .periph_buses = PL08X_AHB2, 324 .periph_buses = PL08X_AHB2,
344 }, { 325 }, {
345 .bus_id = "i2c1_tx", 326 .bus_id = "i2c1_tx",
346 .min_signal = 9, 327 .min_signal = 9,
347 .max_signal = 9, 328 .max_signal = 9,
348 .muxval = 1, 329 .muxval = 1,
349 .cctl = 0,
350 .periph_buses = PL08X_AHB2, 330 .periph_buses = PL08X_AHB2,
351 }, { 331 }, {
352 .bus_id = "i2c2_rx", 332 .bus_id = "i2c2_rx",
353 .min_signal = 10, 333 .min_signal = 10,
354 .max_signal = 10, 334 .max_signal = 10,
355 .muxval = 1, 335 .muxval = 1,
356 .cctl = 0,
357 .periph_buses = PL08X_AHB2, 336 .periph_buses = PL08X_AHB2,
358 }, { 337 }, {
359 .bus_id = "i2c2_tx", 338 .bus_id = "i2c2_tx",
360 .min_signal = 11, 339 .min_signal = 11,
361 .max_signal = 11, 340 .max_signal = 11,
362 .muxval = 1, 341 .muxval = 1,
363 .cctl = 0,
364 .periph_buses = PL08X_AHB2, 342 .periph_buses = PL08X_AHB2,
365 }, { 343 }, {
366 .bus_id = "i2s_rx", 344 .bus_id = "i2s_rx",
367 .min_signal = 12, 345 .min_signal = 12,
368 .max_signal = 12, 346 .max_signal = 12,
369 .muxval = 1, 347 .muxval = 1,
370 .cctl = 0,
371 .periph_buses = PL08X_AHB2, 348 .periph_buses = PL08X_AHB2,
372 }, { 349 }, {
373 .bus_id = "i2s_tx", 350 .bus_id = "i2s_tx",
374 .min_signal = 13, 351 .min_signal = 13,
375 .max_signal = 13, 352 .max_signal = 13,
376 .muxval = 1, 353 .muxval = 1,
377 .cctl = 0,
378 .periph_buses = PL08X_AHB2, 354 .periph_buses = PL08X_AHB2,
379 }, { 355 }, {
380 .bus_id = "rs485_rx", 356 .bus_id = "rs485_rx",
381 .min_signal = 14, 357 .min_signal = 14,
382 .max_signal = 14, 358 .max_signal = 14,
383 .muxval = 1, 359 .muxval = 1,
384 .cctl = 0,
385 .periph_buses = PL08X_AHB2, 360 .periph_buses = PL08X_AHB2,
386 }, { 361 }, {
387 .bus_id = "rs485_tx", 362 .bus_id = "rs485_tx",
388 .min_signal = 15, 363 .min_signal = 15,
389 .max_signal = 15, 364 .max_signal = 15,
390 .muxval = 1, 365 .muxval = 1,
391 .cctl = 0,
392 .periph_buses = PL08X_AHB2, 366 .periph_buses = PL08X_AHB2,
393 }, 367 },
394}; 368};
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 0f41bd1c47c3..d6cd8403fe66 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -46,7 +46,8 @@ struct pl022_ssp_controller pl022_plat_data = {
46struct pl08x_platform_data pl080_plat_data = { 46struct pl08x_platform_data pl080_plat_data = {
47 .memcpy_channel = { 47 .memcpy_channel = {
48 .bus_id = "memcpy", 48 .bus_id = "memcpy",
49 .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ 49 .cctl_memcpy =
50 (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
50 PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ 51 PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
51 PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ 52 PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
52 PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ 53 PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 2e2e3596583e..b59ae5369e7b 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -36,336 +36,288 @@ static struct pl08x_channel_data spear600_dma_info[] = {
36 .min_signal = 0, 36 .min_signal = 0,
37 .max_signal = 0, 37 .max_signal = 0,
38 .muxval = 0, 38 .muxval = 0,
39 .cctl = 0,
40 .periph_buses = PL08X_AHB1, 39 .periph_buses = PL08X_AHB1,
41 }, { 40 }, {
42 .bus_id = "ssp1_tx", 41 .bus_id = "ssp1_tx",
43 .min_signal = 1, 42 .min_signal = 1,
44 .max_signal = 1, 43 .max_signal = 1,
45 .muxval = 0, 44 .muxval = 0,
46 .cctl = 0,
47 .periph_buses = PL08X_AHB1, 45 .periph_buses = PL08X_AHB1,
48 }, { 46 }, {
49 .bus_id = "uart0_rx", 47 .bus_id = "uart0_rx",
50 .min_signal = 2, 48 .min_signal = 2,
51 .max_signal = 2, 49 .max_signal = 2,
52 .muxval = 0, 50 .muxval = 0,
53 .cctl = 0,
54 .periph_buses = PL08X_AHB1, 51 .periph_buses = PL08X_AHB1,
55 }, { 52 }, {
56 .bus_id = "uart0_tx", 53 .bus_id = "uart0_tx",
57 .min_signal = 3, 54 .min_signal = 3,
58 .max_signal = 3, 55 .max_signal = 3,
59 .muxval = 0, 56 .muxval = 0,
60 .cctl = 0,
61 .periph_buses = PL08X_AHB1, 57 .periph_buses = PL08X_AHB1,
62 }, { 58 }, {
63 .bus_id = "uart1_rx", 59 .bus_id = "uart1_rx",
64 .min_signal = 4, 60 .min_signal = 4,
65 .max_signal = 4, 61 .max_signal = 4,
66 .muxval = 0, 62 .muxval = 0,
67 .cctl = 0,
68 .periph_buses = PL08X_AHB1, 63 .periph_buses = PL08X_AHB1,
69 }, { 64 }, {
70 .bus_id = "uart1_tx", 65 .bus_id = "uart1_tx",
71 .min_signal = 5, 66 .min_signal = 5,
72 .max_signal = 5, 67 .max_signal = 5,
73 .muxval = 0, 68 .muxval = 0,
74 .cctl = 0,
75 .periph_buses = PL08X_AHB1, 69 .periph_buses = PL08X_AHB1,
76 }, { 70 }, {
77 .bus_id = "ssp2_rx", 71 .bus_id = "ssp2_rx",
78 .min_signal = 6, 72 .min_signal = 6,
79 .max_signal = 6, 73 .max_signal = 6,
80 .muxval = 0, 74 .muxval = 0,
81 .cctl = 0,
82 .periph_buses = PL08X_AHB2, 75 .periph_buses = PL08X_AHB2,
83 }, { 76 }, {
84 .bus_id = "ssp2_tx", 77 .bus_id = "ssp2_tx",
85 .min_signal = 7, 78 .min_signal = 7,
86 .max_signal = 7, 79 .max_signal = 7,
87 .muxval = 0, 80 .muxval = 0,
88 .cctl = 0,
89 .periph_buses = PL08X_AHB2, 81 .periph_buses = PL08X_AHB2,
90 }, { 82 }, {
91 .bus_id = "ssp0_rx", 83 .bus_id = "ssp0_rx",
92 .min_signal = 8, 84 .min_signal = 8,
93 .max_signal = 8, 85 .max_signal = 8,
94 .muxval = 0, 86 .muxval = 0,
95 .cctl = 0,
96 .periph_buses = PL08X_AHB1, 87 .periph_buses = PL08X_AHB1,
97 }, { 88 }, {
98 .bus_id = "ssp0_tx", 89 .bus_id = "ssp0_tx",
99 .min_signal = 9, 90 .min_signal = 9,
100 .max_signal = 9, 91 .max_signal = 9,
101 .muxval = 0, 92 .muxval = 0,
102 .cctl = 0,
103 .periph_buses = PL08X_AHB1, 93 .periph_buses = PL08X_AHB1,
104 }, { 94 }, {
105 .bus_id = "i2c_rx", 95 .bus_id = "i2c_rx",
106 .min_signal = 10, 96 .min_signal = 10,
107 .max_signal = 10, 97 .max_signal = 10,
108 .muxval = 0, 98 .muxval = 0,
109 .cctl = 0,
110 .periph_buses = PL08X_AHB1, 99 .periph_buses = PL08X_AHB1,
111 }, { 100 }, {
112 .bus_id = "i2c_tx", 101 .bus_id = "i2c_tx",
113 .min_signal = 11, 102 .min_signal = 11,
114 .max_signal = 11, 103 .max_signal = 11,
115 .muxval = 0, 104 .muxval = 0,
116 .cctl = 0,
117 .periph_buses = PL08X_AHB1, 105 .periph_buses = PL08X_AHB1,
118 }, { 106 }, {
119 .bus_id = "irda", 107 .bus_id = "irda",
120 .min_signal = 12, 108 .min_signal = 12,
121 .max_signal = 12, 109 .max_signal = 12,
122 .muxval = 0, 110 .muxval = 0,
123 .cctl = 0,
124 .periph_buses = PL08X_AHB1, 111 .periph_buses = PL08X_AHB1,
125 }, { 112 }, {
126 .bus_id = "adc", 113 .bus_id = "adc",
127 .min_signal = 13, 114 .min_signal = 13,
128 .max_signal = 13, 115 .max_signal = 13,
129 .muxval = 0, 116 .muxval = 0,
130 .cctl = 0,
131 .periph_buses = PL08X_AHB2, 117 .periph_buses = PL08X_AHB2,
132 }, { 118 }, {
133 .bus_id = "to_jpeg", 119 .bus_id = "to_jpeg",
134 .min_signal = 14, 120 .min_signal = 14,
135 .max_signal = 14, 121 .max_signal = 14,
136 .muxval = 0, 122 .muxval = 0,
137 .cctl = 0,
138 .periph_buses = PL08X_AHB1, 123 .periph_buses = PL08X_AHB1,
139 }, { 124 }, {
140 .bus_id = "from_jpeg", 125 .bus_id = "from_jpeg",
141 .min_signal = 15, 126 .min_signal = 15,
142 .max_signal = 15, 127 .max_signal = 15,
143 .muxval = 0, 128 .muxval = 0,
144 .cctl = 0,
145 .periph_buses = PL08X_AHB1, 129 .periph_buses = PL08X_AHB1,
146 }, { 130 }, {
147 .bus_id = "ras0_rx", 131 .bus_id = "ras0_rx",
148 .min_signal = 0, 132 .min_signal = 0,
149 .max_signal = 0, 133 .max_signal = 0,
150 .muxval = 1, 134 .muxval = 1,
151 .cctl = 0,
152 .periph_buses = PL08X_AHB1, 135 .periph_buses = PL08X_AHB1,
153 }, { 136 }, {
154 .bus_id = "ras0_tx", 137 .bus_id = "ras0_tx",
155 .min_signal = 1, 138 .min_signal = 1,
156 .max_signal = 1, 139 .max_signal = 1,
157 .muxval = 1, 140 .muxval = 1,
158 .cctl = 0,
159 .periph_buses = PL08X_AHB1, 141 .periph_buses = PL08X_AHB1,
160 }, { 142 }, {
161 .bus_id = "ras1_rx", 143 .bus_id = "ras1_rx",
162 .min_signal = 2, 144 .min_signal = 2,
163 .max_signal = 2, 145 .max_signal = 2,
164 .muxval = 1, 146 .muxval = 1,
165 .cctl = 0,
166 .periph_buses = PL08X_AHB1, 147 .periph_buses = PL08X_AHB1,
167 }, { 148 }, {
168 .bus_id = "ras1_tx", 149 .bus_id = "ras1_tx",
169 .min_signal = 3, 150 .min_signal = 3,
170 .max_signal = 3, 151 .max_signal = 3,
171 .muxval = 1, 152 .muxval = 1,
172 .cctl = 0,
173 .periph_buses = PL08X_AHB1, 153 .periph_buses = PL08X_AHB1,
174 }, { 154 }, {
175 .bus_id = "ras2_rx", 155 .bus_id = "ras2_rx",
176 .min_signal = 4, 156 .min_signal = 4,
177 .max_signal = 4, 157 .max_signal = 4,
178 .muxval = 1, 158 .muxval = 1,
179 .cctl = 0,
180 .periph_buses = PL08X_AHB1, 159 .periph_buses = PL08X_AHB1,
181 }, { 160 }, {
182 .bus_id = "ras2_tx", 161 .bus_id = "ras2_tx",
183 .min_signal = 5, 162 .min_signal = 5,
184 .max_signal = 5, 163 .max_signal = 5,
185 .muxval = 1, 164 .muxval = 1,
186 .cctl = 0,
187 .periph_buses = PL08X_AHB1, 165 .periph_buses = PL08X_AHB1,
188 }, { 166 }, {
189 .bus_id = "ras3_rx", 167 .bus_id = "ras3_rx",
190 .min_signal = 6, 168 .min_signal = 6,
191 .max_signal = 6, 169 .max_signal = 6,
192 .muxval = 1, 170 .muxval = 1,
193 .cctl = 0,
194 .periph_buses = PL08X_AHB1, 171 .periph_buses = PL08X_AHB1,
195 }, { 172 }, {
196 .bus_id = "ras3_tx", 173 .bus_id = "ras3_tx",
197 .min_signal = 7, 174 .min_signal = 7,
198 .max_signal = 7, 175 .max_signal = 7,
199 .muxval = 1, 176 .muxval = 1,
200 .cctl = 0,
201 .periph_buses = PL08X_AHB1, 177 .periph_buses = PL08X_AHB1,
202 }, { 178 }, {
203 .bus_id = "ras4_rx", 179 .bus_id = "ras4_rx",
204 .min_signal = 8, 180 .min_signal = 8,
205 .max_signal = 8, 181 .max_signal = 8,
206 .muxval = 1, 182 .muxval = 1,
207 .cctl = 0,
208 .periph_buses = PL08X_AHB1, 183 .periph_buses = PL08X_AHB1,
209 }, { 184 }, {
210 .bus_id = "ras4_tx", 185 .bus_id = "ras4_tx",
211 .min_signal = 9, 186 .min_signal = 9,
212 .max_signal = 9, 187 .max_signal = 9,
213 .muxval = 1, 188 .muxval = 1,
214 .cctl = 0,
215 .periph_buses = PL08X_AHB1, 189 .periph_buses = PL08X_AHB1,
216 }, { 190 }, {
217 .bus_id = "ras5_rx", 191 .bus_id = "ras5_rx",
218 .min_signal = 10, 192 .min_signal = 10,
219 .max_signal = 10, 193 .max_signal = 10,
220 .muxval = 1, 194 .muxval = 1,
221 .cctl = 0,
222 .periph_buses = PL08X_AHB1, 195 .periph_buses = PL08X_AHB1,
223 }, { 196 }, {
224 .bus_id = "ras5_tx", 197 .bus_id = "ras5_tx",
225 .min_signal = 11, 198 .min_signal = 11,
226 .max_signal = 11, 199 .max_signal = 11,
227 .muxval = 1, 200 .muxval = 1,
228 .cctl = 0,
229 .periph_buses = PL08X_AHB1, 201 .periph_buses = PL08X_AHB1,
230 }, { 202 }, {
231 .bus_id = "ras6_rx", 203 .bus_id = "ras6_rx",
232 .min_signal = 12, 204 .min_signal = 12,
233 .max_signal = 12, 205 .max_signal = 12,
234 .muxval = 1, 206 .muxval = 1,
235 .cctl = 0,
236 .periph_buses = PL08X_AHB1, 207 .periph_buses = PL08X_AHB1,
237 }, { 208 }, {
238 .bus_id = "ras6_tx", 209 .bus_id = "ras6_tx",
239 .min_signal = 13, 210 .min_signal = 13,
240 .max_signal = 13, 211 .max_signal = 13,
241 .muxval = 1, 212 .muxval = 1,
242 .cctl = 0,
243 .periph_buses = PL08X_AHB1, 213 .periph_buses = PL08X_AHB1,
244 }, { 214 }, {
245 .bus_id = "ras7_rx", 215 .bus_id = "ras7_rx",
246 .min_signal = 14, 216 .min_signal = 14,
247 .max_signal = 14, 217 .max_signal = 14,
248 .muxval = 1, 218 .muxval = 1,
249 .cctl = 0,
250 .periph_buses = PL08X_AHB1, 219 .periph_buses = PL08X_AHB1,
251 }, { 220 }, {
252 .bus_id = "ras7_tx", 221 .bus_id = "ras7_tx",
253 .min_signal = 15, 222 .min_signal = 15,
254 .max_signal = 15, 223 .max_signal = 15,
255 .muxval = 1, 224 .muxval = 1,
256 .cctl = 0,
257 .periph_buses = PL08X_AHB1, 225 .periph_buses = PL08X_AHB1,
258 }, { 226 }, {
259 .bus_id = "ext0_rx", 227 .bus_id = "ext0_rx",
260 .min_signal = 0, 228 .min_signal = 0,
261 .max_signal = 0, 229 .max_signal = 0,
262 .muxval = 2, 230 .muxval = 2,
263 .cctl = 0,
264 .periph_buses = PL08X_AHB2, 231 .periph_buses = PL08X_AHB2,
265 }, { 232 }, {
266 .bus_id = "ext0_tx", 233 .bus_id = "ext0_tx",
267 .min_signal = 1, 234 .min_signal = 1,
268 .max_signal = 1, 235 .max_signal = 1,
269 .muxval = 2, 236 .muxval = 2,
270 .cctl = 0,
271 .periph_buses = PL08X_AHB2, 237 .periph_buses = PL08X_AHB2,
272 }, { 238 }, {
273 .bus_id = "ext1_rx", 239 .bus_id = "ext1_rx",
274 .min_signal = 2, 240 .min_signal = 2,
275 .max_signal = 2, 241 .max_signal = 2,
276 .muxval = 2, 242 .muxval = 2,
277 .cctl = 0,
278 .periph_buses = PL08X_AHB2, 243 .periph_buses = PL08X_AHB2,
279 }, { 244 }, {
280 .bus_id = "ext1_tx", 245 .bus_id = "ext1_tx",
281 .min_signal = 3, 246 .min_signal = 3,
282 .max_signal = 3, 247 .max_signal = 3,
283 .muxval = 2, 248 .muxval = 2,
284 .cctl = 0,
285 .periph_buses = PL08X_AHB2, 249 .periph_buses = PL08X_AHB2,
286 }, { 250 }, {
287 .bus_id = "ext2_rx", 251 .bus_id = "ext2_rx",
288 .min_signal = 4, 252 .min_signal = 4,
289 .max_signal = 4, 253 .max_signal = 4,
290 .muxval = 2, 254 .muxval = 2,
291 .cctl = 0,
292 .periph_buses = PL08X_AHB2, 255 .periph_buses = PL08X_AHB2,
293 }, { 256 }, {
294 .bus_id = "ext2_tx", 257 .bus_id = "ext2_tx",
295 .min_signal = 5, 258 .min_signal = 5,
296 .max_signal = 5, 259 .max_signal = 5,
297 .muxval = 2, 260 .muxval = 2,
298 .cctl = 0,
299 .periph_buses = PL08X_AHB2, 261 .periph_buses = PL08X_AHB2,
300 }, { 262 }, {
301 .bus_id = "ext3_rx", 263 .bus_id = "ext3_rx",
302 .min_signal = 6, 264 .min_signal = 6,
303 .max_signal = 6, 265 .max_signal = 6,
304 .muxval = 2, 266 .muxval = 2,
305 .cctl = 0,
306 .periph_buses = PL08X_AHB2, 267 .periph_buses = PL08X_AHB2,
307 }, { 268 }, {
308 .bus_id = "ext3_tx", 269 .bus_id = "ext3_tx",
309 .min_signal = 7, 270 .min_signal = 7,
310 .max_signal = 7, 271 .max_signal = 7,
311 .muxval = 2, 272 .muxval = 2,
312 .cctl = 0,
313 .periph_buses = PL08X_AHB2, 273 .periph_buses = PL08X_AHB2,
314 }, { 274 }, {
315 .bus_id = "ext4_rx", 275 .bus_id = "ext4_rx",
316 .min_signal = 8, 276 .min_signal = 8,
317 .max_signal = 8, 277 .max_signal = 8,
318 .muxval = 2, 278 .muxval = 2,
319 .cctl = 0,
320 .periph_buses = PL08X_AHB2, 279 .periph_buses = PL08X_AHB2,
321 }, { 280 }, {
322 .bus_id = "ext4_tx", 281 .bus_id = "ext4_tx",
323 .min_signal = 9, 282 .min_signal = 9,
324 .max_signal = 9, 283 .max_signal = 9,
325 .muxval = 2, 284 .muxval = 2,
326 .cctl = 0,
327 .periph_buses = PL08X_AHB2, 285 .periph_buses = PL08X_AHB2,
328 }, { 286 }, {
329 .bus_id = "ext5_rx", 287 .bus_id = "ext5_rx",
330 .min_signal = 10, 288 .min_signal = 10,
331 .max_signal = 10, 289 .max_signal = 10,
332 .muxval = 2, 290 .muxval = 2,
333 .cctl = 0,
334 .periph_buses = PL08X_AHB2, 291 .periph_buses = PL08X_AHB2,
335 }, { 292 }, {
336 .bus_id = "ext5_tx", 293 .bus_id = "ext5_tx",
337 .min_signal = 11, 294 .min_signal = 11,
338 .max_signal = 11, 295 .max_signal = 11,
339 .muxval = 2, 296 .muxval = 2,
340 .cctl = 0,
341 .periph_buses = PL08X_AHB2, 297 .periph_buses = PL08X_AHB2,
342 }, { 298 }, {
343 .bus_id = "ext6_rx", 299 .bus_id = "ext6_rx",
344 .min_signal = 12, 300 .min_signal = 12,
345 .max_signal = 12, 301 .max_signal = 12,
346 .muxval = 2, 302 .muxval = 2,
347 .cctl = 0,
348 .periph_buses = PL08X_AHB2, 303 .periph_buses = PL08X_AHB2,
349 }, { 304 }, {
350 .bus_id = "ext6_tx", 305 .bus_id = "ext6_tx",
351 .min_signal = 13, 306 .min_signal = 13,
352 .max_signal = 13, 307 .max_signal = 13,
353 .muxval = 2, 308 .muxval = 2,
354 .cctl = 0,
355 .periph_buses = PL08X_AHB2, 309 .periph_buses = PL08X_AHB2,
356 }, { 310 }, {
357 .bus_id = "ext7_rx", 311 .bus_id = "ext7_rx",
358 .min_signal = 14, 312 .min_signal = 14,
359 .max_signal = 14, 313 .max_signal = 14,
360 .muxval = 2, 314 .muxval = 2,
361 .cctl = 0,
362 .periph_buses = PL08X_AHB2, 315 .periph_buses = PL08X_AHB2,
363 }, { 316 }, {
364 .bus_id = "ext7_tx", 317 .bus_id = "ext7_tx",
365 .min_signal = 15, 318 .min_signal = 15,
366 .max_signal = 15, 319 .max_signal = 15,
367 .muxval = 2, 320 .muxval = 2,
368 .cctl = 0,
369 .periph_buses = PL08X_AHB2, 321 .periph_buses = PL08X_AHB2,
370 }, 322 },
371}; 323};
@@ -373,7 +325,8 @@ static struct pl08x_channel_data spear600_dma_info[] = {
373struct pl08x_platform_data pl080_plat_data = { 325struct pl08x_platform_data pl080_plat_data = {
374 .memcpy_channel = { 326 .memcpy_channel = {
375 .bus_id = "memcpy", 327 .bus_id = "memcpy",
376 .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \ 328 .cctl_memcpy =
329 (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
377 PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \ 330 PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
378 PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \ 331 PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
379 PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \ 332 PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
diff --git a/arch/arm/plat-spear/include/plat/pl080.h b/arch/arm/plat-spear/include/plat/pl080.h
index 2bc6b54460a8..eb6590ded40d 100644
--- a/arch/arm/plat-spear/include/plat/pl080.h
+++ b/arch/arm/plat-spear/include/plat/pl080.h
@@ -14,8 +14,8 @@
14#ifndef __PLAT_PL080_H 14#ifndef __PLAT_PL080_H
15#define __PLAT_PL080_H 15#define __PLAT_PL080_H
16 16
17struct pl08x_dma_chan; 17struct pl08x_channel_data;
18int pl080_get_signal(struct pl08x_dma_chan *ch); 18int pl080_get_signal(const struct pl08x_channel_data *cd);
19void pl080_put_signal(struct pl08x_dma_chan *ch); 19void pl080_put_signal(const struct pl08x_channel_data *cd, int signal);
20 20
21#endif /* __PLAT_PL080_H */ 21#endif /* __PLAT_PL080_H */
diff --git a/arch/arm/plat-spear/pl080.c b/arch/arm/plat-spear/pl080.c
index 12cf27f935f9..cfa1199d0f4a 100644
--- a/arch/arm/plat-spear/pl080.c
+++ b/arch/arm/plat-spear/pl080.c
@@ -27,9 +27,8 @@ struct {
27 unsigned char val; 27 unsigned char val;
28} signals[16] = {{0, 0}, }; 28} signals[16] = {{0, 0}, };
29 29
30int pl080_get_signal(struct pl08x_dma_chan *ch) 30int pl080_get_signal(const struct pl08x_channel_data *cd)
31{ 31{
32 const struct pl08x_channel_data *cd = ch->cd;
33 unsigned int signal = cd->min_signal, val; 32 unsigned int signal = cd->min_signal, val;
34 unsigned long flags; 33 unsigned long flags;
35 34
@@ -63,18 +62,17 @@ int pl080_get_signal(struct pl08x_dma_chan *ch)
63 return signal; 62 return signal;
64} 63}
65 64
66void pl080_put_signal(struct pl08x_dma_chan *ch) 65void pl080_put_signal(const struct pl08x_channel_data *cd, int signal)
67{ 66{
68 const struct pl08x_channel_data *cd = ch->cd;
69 unsigned long flags; 67 unsigned long flags;
70 68
71 spin_lock_irqsave(&lock, flags); 69 spin_lock_irqsave(&lock, flags);
72 70
73 /* if signal is not used */ 71 /* if signal is not used */
74 if (!signals[cd->min_signal].busy) 72 if (!signals[signal].busy)
75 BUG(); 73 BUG();
76 74
77 signals[cd->min_signal].busy--; 75 signals[signal].busy--;
78 76
79 spin_unlock_irqrestore(&lock, flags); 77 spin_unlock_irqrestore(&lock, flags);
80} 78}
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8be3bf68c0bd..6f93365d9d04 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -53,6 +53,7 @@ config AMBA_PL08X
53 bool "ARM PrimeCell PL080 or PL081 support" 53 bool "ARM PrimeCell PL080 or PL081 support"
54 depends on ARM_AMBA && EXPERIMENTAL 54 depends on ARM_AMBA && EXPERIMENTAL
55 select DMA_ENGINE 55 select DMA_ENGINE
56 select DMA_VIRTUAL_CHANNELS
56 help 57 help
57 Platform has a PL08x DMAC device 58 Platform has a PL08x DMAC device
58 which can provide DMA engine support 59 which can provide DMA engine support
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 49ecbbb8932d..6fbeebb9486f 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -86,10 +86,12 @@
86#include <asm/hardware/pl080.h> 86#include <asm/hardware/pl080.h>
87 87
88#include "dmaengine.h" 88#include "dmaengine.h"
89#include "virt-dma.h"
89 90
90#define DRIVER_NAME "pl08xdmac" 91#define DRIVER_NAME "pl08xdmac"
91 92
92static struct amba_driver pl08x_amba_driver; 93static struct amba_driver pl08x_amba_driver;
94struct pl08x_driver_data;
93 95
94/** 96/**
95 * struct vendor_data - vendor-specific config parameters for PL08x derivatives 97 * struct vendor_data - vendor-specific config parameters for PL08x derivatives
@@ -119,6 +121,123 @@ struct pl08x_lli {
119}; 121};
120 122
121/** 123/**
124 * struct pl08x_bus_data - information of source or destination
125 * busses for a transfer
126 * @addr: current address
127 * @maxwidth: the maximum width of a transfer on this bus
128 * @buswidth: the width of this bus in bytes: 1, 2 or 4
129 */
130struct pl08x_bus_data {
131 dma_addr_t addr;
132 u8 maxwidth;
133 u8 buswidth;
134};
135
136/**
137 * struct pl08x_phy_chan - holder for the physical channels
138 * @id: physical index to this channel
139 * @lock: a lock to use when altering an instance of this struct
140 * @serving: the virtual channel currently being served by this physical
141 * channel
142 * @locked: channel unavailable for the system, e.g. dedicated to secure
143 * world
144 */
145struct pl08x_phy_chan {
146 unsigned int id;
147 void __iomem *base;
148 spinlock_t lock;
149 struct pl08x_dma_chan *serving;
150 bool locked;
151};
152
153/**
154 * struct pl08x_sg - structure containing data per sg
155 * @src_addr: src address of sg
156 * @dst_addr: dst address of sg
157 * @len: transfer len in bytes
158 * @node: node for txd's dsg_list
159 */
160struct pl08x_sg {
161 dma_addr_t src_addr;
162 dma_addr_t dst_addr;
163 size_t len;
164 struct list_head node;
165};
166
167/**
168 * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
169 * @vd: virtual DMA descriptor
170 * @dsg_list: list of children sg's
171 * @llis_bus: DMA memory address (physical) start for the LLIs
172 * @llis_va: virtual memory address start for the LLIs
173 * @cctl: control reg values for current txd
174 * @ccfg: config reg values for current txd
175 * @done: this marks completed descriptors, which should not have their
176 * mux released.
177 */
178struct pl08x_txd {
179 struct virt_dma_desc vd;
180 struct list_head dsg_list;
181 dma_addr_t llis_bus;
182 struct pl08x_lli *llis_va;
183 /* Default cctl value for LLIs */
184 u32 cctl;
185 /*
186 * Settings to be put into the physical channel when we
187 * trigger this txd. Other registers are in llis_va[0].
188 */
189 u32 ccfg;
190 bool done;
191};
192
193/**
194 * struct pl08x_dma_chan_state - holds the PL08x specific virtual channel
195 * states
196 * @PL08X_CHAN_IDLE: the channel is idle
197 * @PL08X_CHAN_RUNNING: the channel has allocated a physical transport
198 * channel and is running a transfer on it
199 * @PL08X_CHAN_PAUSED: the channel has allocated a physical transport
200 * channel, but the transfer is currently paused
201 * @PL08X_CHAN_WAITING: the channel is waiting for a physical transport
202 * channel to become available (only pertains to memcpy channels)
203 */
204enum pl08x_dma_chan_state {
205 PL08X_CHAN_IDLE,
206 PL08X_CHAN_RUNNING,
207 PL08X_CHAN_PAUSED,
208 PL08X_CHAN_WAITING,
209};
210
211/**
212 * struct pl08x_dma_chan - this structure wraps a DMA ENGINE channel
213 * @vc: wrappped virtual channel
214 * @phychan: the physical channel utilized by this channel, if there is one
215 * @name: name of channel
216 * @cd: channel platform data
217 * @runtime_addr: address for RX/TX according to the runtime config
218 * @at: active transaction on this channel
219 * @lock: a lock for this channel data
220 * @host: a pointer to the host (internal use)
221 * @state: whether the channel is idle, paused, running etc
222 * @slave: whether this channel is a device (slave) or for memcpy
223 * @signal: the physical DMA request signal which this channel is using
224 * @mux_use: count of descriptors using this DMA request signal setting
225 */
226struct pl08x_dma_chan {
227 struct virt_dma_chan vc;
228 struct pl08x_phy_chan *phychan;
229 const char *name;
230 const struct pl08x_channel_data *cd;
231 struct dma_slave_config cfg;
232 struct pl08x_txd *at;
233 struct pl08x_driver_data *host;
234 enum pl08x_dma_chan_state state;
235 bool slave;
236 int signal;
237 unsigned mux_use;
238};
239
240/**
122 * struct pl08x_driver_data - the local state holder for the PL08x 241 * struct pl08x_driver_data - the local state holder for the PL08x
123 * @slave: slave engine for this instance 242 * @slave: slave engine for this instance
124 * @memcpy: memcpy engine for this instance 243 * @memcpy: memcpy engine for this instance
@@ -128,7 +247,6 @@ struct pl08x_lli {
128 * @pd: platform data passed in from the platform/machine 247 * @pd: platform data passed in from the platform/machine
129 * @phy_chans: array of data for the physical channels 248 * @phy_chans: array of data for the physical channels
130 * @pool: a pool for the LLI descriptors 249 * @pool: a pool for the LLI descriptors
131 * @pool_ctr: counter of LLIs in the pool
132 * @lli_buses: bitmask to or in to LLI pointer selecting AHB port for LLI 250 * @lli_buses: bitmask to or in to LLI pointer selecting AHB port for LLI
133 * fetches 251 * fetches
134 * @mem_buses: set to indicate memory transfers on AHB2. 252 * @mem_buses: set to indicate memory transfers on AHB2.
@@ -143,10 +261,8 @@ struct pl08x_driver_data {
143 struct pl08x_platform_data *pd; 261 struct pl08x_platform_data *pd;
144 struct pl08x_phy_chan *phy_chans; 262 struct pl08x_phy_chan *phy_chans;
145 struct dma_pool *pool; 263 struct dma_pool *pool;
146 int pool_ctr;
147 u8 lli_buses; 264 u8 lli_buses;
148 u8 mem_buses; 265 u8 mem_buses;
149 spinlock_t lock;
150}; 266};
151 267
152/* 268/*
@@ -162,12 +278,51 @@ struct pl08x_driver_data {
162 278
163static inline struct pl08x_dma_chan *to_pl08x_chan(struct dma_chan *chan) 279static inline struct pl08x_dma_chan *to_pl08x_chan(struct dma_chan *chan)
164{ 280{
165 return container_of(chan, struct pl08x_dma_chan, chan); 281 return container_of(chan, struct pl08x_dma_chan, vc.chan);
166} 282}
167 283
168static inline struct pl08x_txd *to_pl08x_txd(struct dma_async_tx_descriptor *tx) 284static inline struct pl08x_txd *to_pl08x_txd(struct dma_async_tx_descriptor *tx)
169{ 285{
170 return container_of(tx, struct pl08x_txd, tx); 286 return container_of(tx, struct pl08x_txd, vd.tx);
287}
288
289/*
290 * Mux handling.
291 *
292 * This gives us the DMA request input to the PL08x primecell which the
293 * peripheral described by the channel data will be routed to, possibly
294 * via a board/SoC specific external MUX. One important point to note
295 * here is that this does not depend on the physical channel.
296 */
297static int pl08x_request_mux(struct pl08x_dma_chan *plchan)
298{
299 const struct pl08x_platform_data *pd = plchan->host->pd;
300 int ret;
301
302 if (plchan->mux_use++ == 0 && pd->get_signal) {
303 ret = pd->get_signal(plchan->cd);
304 if (ret < 0) {
305 plchan->mux_use = 0;
306 return ret;
307 }
308
309 plchan->signal = ret;
310 }
311 return 0;
312}
313
314static void pl08x_release_mux(struct pl08x_dma_chan *plchan)
315{
316 const struct pl08x_platform_data *pd = plchan->host->pd;
317
318 if (plchan->signal >= 0) {
319 WARN_ON(plchan->mux_use == 0);
320
321 if (--plchan->mux_use == 0 && pd->put_signal) {
322 pd->put_signal(plchan->cd, plchan->signal);
323 plchan->signal = -1;
324 }
325 }
171} 326}
172 327
173/* 328/*
@@ -189,20 +344,25 @@ static int pl08x_phy_channel_busy(struct pl08x_phy_chan *ch)
189 * been set when the LLIs were constructed. Poke them into the hardware 344 * been set when the LLIs were constructed. Poke them into the hardware
190 * and start the transfer. 345 * and start the transfer.
191 */ 346 */
192static void pl08x_start_txd(struct pl08x_dma_chan *plchan, 347static void pl08x_start_next_txd(struct pl08x_dma_chan *plchan)
193 struct pl08x_txd *txd)
194{ 348{
195 struct pl08x_driver_data *pl08x = plchan->host; 349 struct pl08x_driver_data *pl08x = plchan->host;
196 struct pl08x_phy_chan *phychan = plchan->phychan; 350 struct pl08x_phy_chan *phychan = plchan->phychan;
197 struct pl08x_lli *lli = &txd->llis_va[0]; 351 struct virt_dma_desc *vd = vchan_next_desc(&plchan->vc);
352 struct pl08x_txd *txd = to_pl08x_txd(&vd->tx);
353 struct pl08x_lli *lli;
198 u32 val; 354 u32 val;
199 355
356 list_del(&txd->vd.node);
357
200 plchan->at = txd; 358 plchan->at = txd;
201 359
202 /* Wait for channel inactive */ 360 /* Wait for channel inactive */
203 while (pl08x_phy_channel_busy(phychan)) 361 while (pl08x_phy_channel_busy(phychan))
204 cpu_relax(); 362 cpu_relax();
205 363
364 lli = &txd->llis_va[0];
365
206 dev_vdbg(&pl08x->adev->dev, 366 dev_vdbg(&pl08x->adev->dev,
207 "WRITE channel %d: csrc=0x%08x, cdst=0x%08x, " 367 "WRITE channel %d: csrc=0x%08x, cdst=0x%08x, "
208 "clli=0x%08x, cctl=0x%08x, ccfg=0x%08x\n", 368 "clli=0x%08x, cctl=0x%08x, ccfg=0x%08x\n",
@@ -311,10 +471,8 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan)
311{ 471{
312 struct pl08x_phy_chan *ch; 472 struct pl08x_phy_chan *ch;
313 struct pl08x_txd *txd; 473 struct pl08x_txd *txd;
314 unsigned long flags;
315 size_t bytes = 0; 474 size_t bytes = 0;
316 475
317 spin_lock_irqsave(&plchan->lock, flags);
318 ch = plchan->phychan; 476 ch = plchan->phychan;
319 txd = plchan->at; 477 txd = plchan->at;
320 478
@@ -354,18 +512,6 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan)
354 } 512 }
355 } 513 }
356 514
357 /* Sum up all queued transactions */
358 if (!list_empty(&plchan->pend_list)) {
359 struct pl08x_txd *txdi;
360 list_for_each_entry(txdi, &plchan->pend_list, node) {
361 struct pl08x_sg *dsg;
362 list_for_each_entry(dsg, &txd->dsg_list, node)
363 bytes += dsg->len;
364 }
365 }
366
367 spin_unlock_irqrestore(&plchan->lock, flags);
368
369 return bytes; 515 return bytes;
370} 516}
371 517
@@ -391,7 +537,6 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,
391 537
392 if (!ch->locked && !ch->serving) { 538 if (!ch->locked && !ch->serving) {
393 ch->serving = virt_chan; 539 ch->serving = virt_chan;
394 ch->signal = -1;
395 spin_unlock_irqrestore(&ch->lock, flags); 540 spin_unlock_irqrestore(&ch->lock, flags);
396 break; 541 break;
397 } 542 }
@@ -404,25 +549,114 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,
404 return NULL; 549 return NULL;
405 } 550 }
406 551
407 pm_runtime_get_sync(&pl08x->adev->dev);
408 return ch; 552 return ch;
409} 553}
410 554
555/* Mark the physical channel as free. Note, this write is atomic. */
411static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x, 556static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x,
412 struct pl08x_phy_chan *ch) 557 struct pl08x_phy_chan *ch)
413{ 558{
414 unsigned long flags; 559 ch->serving = NULL;
560}
561
562/*
563 * Try to allocate a physical channel. When successful, assign it to
564 * this virtual channel, and initiate the next descriptor. The
565 * virtual channel lock must be held at this point.
566 */
567static void pl08x_phy_alloc_and_start(struct pl08x_dma_chan *plchan)
568{
569 struct pl08x_driver_data *pl08x = plchan->host;
570 struct pl08x_phy_chan *ch;
415 571
416 spin_lock_irqsave(&ch->lock, flags); 572 ch = pl08x_get_phy_channel(pl08x, plchan);
573 if (!ch) {
574 dev_dbg(&pl08x->adev->dev, "no physical channel available for xfer on %s\n", plchan->name);
575 plchan->state = PL08X_CHAN_WAITING;
576 return;
577 }
417 578
418 /* Stop the channel and clear its interrupts */ 579 dev_dbg(&pl08x->adev->dev, "allocated physical channel %d for xfer on %s\n",
419 pl08x_terminate_phy_chan(pl08x, ch); 580 ch->id, plchan->name);
420 581
421 pm_runtime_put(&pl08x->adev->dev); 582 plchan->phychan = ch;
583 plchan->state = PL08X_CHAN_RUNNING;
584 pl08x_start_next_txd(plchan);
585}
422 586
423 /* Mark it as free */ 587static void pl08x_phy_reassign_start(struct pl08x_phy_chan *ch,
424 ch->serving = NULL; 588 struct pl08x_dma_chan *plchan)
425 spin_unlock_irqrestore(&ch->lock, flags); 589{
590 struct pl08x_driver_data *pl08x = plchan->host;
591
592 dev_dbg(&pl08x->adev->dev, "reassigned physical channel %d for xfer on %s\n",
593 ch->id, plchan->name);
594
595 /*
596 * We do this without taking the lock; we're really only concerned
597 * about whether this pointer is NULL or not, and we're guaranteed
598 * that this will only be called when it _already_ is non-NULL.
599 */
600 ch->serving = plchan;
601 plchan->phychan = ch;
602 plchan->state = PL08X_CHAN_RUNNING;
603 pl08x_start_next_txd(plchan);
604}
605
606/*
607 * Free a physical DMA channel, potentially reallocating it to another
608 * virtual channel if we have any pending.
609 */
610static void pl08x_phy_free(struct pl08x_dma_chan *plchan)
611{
612 struct pl08x_driver_data *pl08x = plchan->host;
613 struct pl08x_dma_chan *p, *next;
614
615 retry:
616 next = NULL;
617
618 /* Find a waiting virtual channel for the next transfer. */
619 list_for_each_entry(p, &pl08x->memcpy.channels, vc.chan.device_node)
620 if (p->state == PL08X_CHAN_WAITING) {
621 next = p;
622 break;
623 }
624
625 if (!next) {
626 list_for_each_entry(p, &pl08x->slave.channels, vc.chan.device_node)
627 if (p->state == PL08X_CHAN_WAITING) {
628 next = p;
629 break;
630 }
631 }
632
633 /* Ensure that the physical channel is stopped */
634 pl08x_terminate_phy_chan(pl08x, plchan->phychan);
635
636 if (next) {
637 bool success;
638
639 /*
640 * Eww. We know this isn't going to deadlock
641 * but lockdep probably doesn't.
642 */
643 spin_lock(&next->vc.lock);
644 /* Re-check the state now that we have the lock */
645 success = next->state == PL08X_CHAN_WAITING;
646 if (success)
647 pl08x_phy_reassign_start(plchan->phychan, next);
648 spin_unlock(&next->vc.lock);
649
650 /* If the state changed, try to find another channel */
651 if (!success)
652 goto retry;
653 } else {
654 /* No more jobs, so free up the physical channel */
655 pl08x_put_phy_channel(pl08x, plchan->phychan);
656 }
657
658 plchan->phychan = NULL;
659 plchan->state = PL08X_CHAN_IDLE;
426} 660}
427 661
428/* 662/*
@@ -585,8 +819,6 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
585 return 0; 819 return 0;
586 } 820 }
587 821
588 pl08x->pool_ctr++;
589
590 bd.txd = txd; 822 bd.txd = txd;
591 bd.lli_bus = (pl08x->lli_buses & PL08X_AHB2) ? PL080_LLI_LM_AHB2 : 0; 823 bd.lli_bus = (pl08x->lli_buses & PL08X_AHB2) ? PL080_LLI_LM_AHB2 : 0;
592 cctl = txd->cctl; 824 cctl = txd->cctl;
@@ -802,18 +1034,14 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
802 return num_llis; 1034 return num_llis;
803} 1035}
804 1036
805/* You should call this with the struct pl08x lock held */
806static void pl08x_free_txd(struct pl08x_driver_data *pl08x, 1037static void pl08x_free_txd(struct pl08x_driver_data *pl08x,
807 struct pl08x_txd *txd) 1038 struct pl08x_txd *txd)
808{ 1039{
809 struct pl08x_sg *dsg, *_dsg; 1040 struct pl08x_sg *dsg, *_dsg;
810 1041
811 /* Free the LLI */
812 if (txd->llis_va) 1042 if (txd->llis_va)
813 dma_pool_free(pl08x->pool, txd->llis_va, txd->llis_bus); 1043 dma_pool_free(pl08x->pool, txd->llis_va, txd->llis_bus);
814 1044
815 pl08x->pool_ctr--;
816
817 list_for_each_entry_safe(dsg, _dsg, &txd->dsg_list, node) { 1045 list_for_each_entry_safe(dsg, _dsg, &txd->dsg_list, node) {
818 list_del(&dsg->node); 1046 list_del(&dsg->node);
819 kfree(dsg); 1047 kfree(dsg);
@@ -822,133 +1050,75 @@ static void pl08x_free_txd(struct pl08x_driver_data *pl08x,
822 kfree(txd); 1050 kfree(txd);
823} 1051}
824 1052
825static void pl08x_free_txd_list(struct pl08x_driver_data *pl08x, 1053static void pl08x_unmap_buffers(struct pl08x_txd *txd)
826 struct pl08x_dma_chan *plchan)
827{ 1054{
828 struct pl08x_txd *txdi = NULL; 1055 struct device *dev = txd->vd.tx.chan->device->dev;
829 struct pl08x_txd *next; 1056 struct pl08x_sg *dsg;
830 1057
831 if (!list_empty(&plchan->pend_list)) { 1058 if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
832 list_for_each_entry_safe(txdi, 1059 if (txd->vd.tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
833 next, &plchan->pend_list, node) { 1060 list_for_each_entry(dsg, &txd->dsg_list, node)
834 list_del(&txdi->node); 1061 dma_unmap_single(dev, dsg->src_addr, dsg->len,
835 pl08x_free_txd(pl08x, txdi); 1062 DMA_TO_DEVICE);
1063 else {
1064 list_for_each_entry(dsg, &txd->dsg_list, node)
1065 dma_unmap_page(dev, dsg->src_addr, dsg->len,
1066 DMA_TO_DEVICE);
836 } 1067 }
837 } 1068 }
1069 if (!(txd->vd.tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
1070 if (txd->vd.tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
1071 list_for_each_entry(dsg, &txd->dsg_list, node)
1072 dma_unmap_single(dev, dsg->dst_addr, dsg->len,
1073 DMA_FROM_DEVICE);
1074 else
1075 list_for_each_entry(dsg, &txd->dsg_list, node)
1076 dma_unmap_page(dev, dsg->dst_addr, dsg->len,
1077 DMA_FROM_DEVICE);
1078 }
838} 1079}
839 1080
840/* 1081static void pl08x_desc_free(struct virt_dma_desc *vd)
841 * The DMA ENGINE API
842 */
843static int pl08x_alloc_chan_resources(struct dma_chan *chan)
844{ 1082{
845 return 0; 1083 struct pl08x_txd *txd = to_pl08x_txd(&vd->tx);
846} 1084 struct pl08x_dma_chan *plchan = to_pl08x_chan(vd->tx.chan);
847 1085
848static void pl08x_free_chan_resources(struct dma_chan *chan) 1086 if (!plchan->slave)
849{ 1087 pl08x_unmap_buffers(txd);
1088
1089 if (!txd->done)
1090 pl08x_release_mux(plchan);
1091
1092 pl08x_free_txd(plchan->host, txd);
850} 1093}
851 1094
852/* 1095static void pl08x_free_txd_list(struct pl08x_driver_data *pl08x,
853 * This should be called with the channel plchan->lock held 1096 struct pl08x_dma_chan *plchan)
854 */
855static int prep_phy_channel(struct pl08x_dma_chan *plchan,
856 struct pl08x_txd *txd)
857{ 1097{
858 struct pl08x_driver_data *pl08x = plchan->host; 1098 LIST_HEAD(head);
859 struct pl08x_phy_chan *ch; 1099 struct pl08x_txd *txd;
860 int ret;
861
862 /* Check if we already have a channel */
863 if (plchan->phychan) {
864 ch = plchan->phychan;
865 goto got_channel;
866 }
867 1100
868 ch = pl08x_get_phy_channel(pl08x, plchan); 1101 vchan_get_all_descriptors(&plchan->vc, &head);
869 if (!ch) {
870 /* No physical channel available, cope with it */
871 dev_dbg(&pl08x->adev->dev, "no physical channel available for xfer on %s\n", plchan->name);
872 return -EBUSY;
873 }
874 1102
875 /* 1103 while (!list_empty(&head)) {
876 * OK we have a physical channel: for memcpy() this is all we 1104 txd = list_first_entry(&head, struct pl08x_txd, vd.node);
877 * need, but for slaves the physical signals may be muxed! 1105 list_del(&txd->vd.node);
878 * Can the platform allow us to use this channel? 1106 pl08x_desc_free(&txd->vd);
879 */
880 if (plchan->slave && pl08x->pd->get_signal) {
881 ret = pl08x->pd->get_signal(plchan);
882 if (ret < 0) {
883 dev_dbg(&pl08x->adev->dev,
884 "unable to use physical channel %d for transfer on %s due to platform restrictions\n",
885 ch->id, plchan->name);
886 /* Release physical channel & return */
887 pl08x_put_phy_channel(pl08x, ch);
888 return -EBUSY;
889 }
890 ch->signal = ret;
891 } 1107 }
892
893 plchan->phychan = ch;
894 dev_dbg(&pl08x->adev->dev, "allocated physical channel %d and signal %d for xfer on %s\n",
895 ch->id,
896 ch->signal,
897 plchan->name);
898
899got_channel:
900 /* Assign the flow control signal to this channel */
901 if (txd->direction == DMA_MEM_TO_DEV)
902 txd->ccfg |= ch->signal << PL080_CONFIG_DST_SEL_SHIFT;
903 else if (txd->direction == DMA_DEV_TO_MEM)
904 txd->ccfg |= ch->signal << PL080_CONFIG_SRC_SEL_SHIFT;
905
906 plchan->phychan_hold++;
907
908 return 0;
909} 1108}
910 1109
911static void release_phy_channel(struct pl08x_dma_chan *plchan) 1110/*
1111 * The DMA ENGINE API
1112 */
1113static int pl08x_alloc_chan_resources(struct dma_chan *chan)
912{ 1114{
913 struct pl08x_driver_data *pl08x = plchan->host; 1115 return 0;
914
915 if ((plchan->phychan->signal >= 0) && pl08x->pd->put_signal) {
916 pl08x->pd->put_signal(plchan);
917 plchan->phychan->signal = -1;
918 }
919 pl08x_put_phy_channel(pl08x, plchan->phychan);
920 plchan->phychan = NULL;
921} 1116}
922 1117
923static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx) 1118static void pl08x_free_chan_resources(struct dma_chan *chan)
924{ 1119{
925 struct pl08x_dma_chan *plchan = to_pl08x_chan(tx->chan); 1120 /* Ensure all queued descriptors are freed */
926 struct pl08x_txd *txd = to_pl08x_txd(tx); 1121 vchan_free_chan_resources(to_virt_chan(chan));
927 unsigned long flags;
928 dma_cookie_t cookie;
929
930 spin_lock_irqsave(&plchan->lock, flags);
931 cookie = dma_cookie_assign(tx);
932
933 /* Put this onto the pending list */
934 list_add_tail(&txd->node, &plchan->pend_list);
935
936 /*
937 * If there was no physical channel available for this memcpy,
938 * stack the request up and indicate that the channel is waiting
939 * for a free physical channel.
940 */
941 if (!plchan->slave && !plchan->phychan) {
942 /* Do this memcpy whenever there is a channel ready */
943 plchan->state = PL08X_CHAN_WAITING;
944 plchan->waiting = txd;
945 } else {
946 plchan->phychan_hold--;
947 }
948
949 spin_unlock_irqrestore(&plchan->lock, flags);
950
951 return cookie;
952} 1122}
953 1123
954static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt( 1124static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt(
@@ -968,23 +1138,53 @@ static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
968 dma_cookie_t cookie, struct dma_tx_state *txstate) 1138 dma_cookie_t cookie, struct dma_tx_state *txstate)
969{ 1139{
970 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1140 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1141 struct virt_dma_desc *vd;
1142 unsigned long flags;
971 enum dma_status ret; 1143 enum dma_status ret;
1144 size_t bytes = 0;
972 1145
973 ret = dma_cookie_status(chan, cookie, txstate); 1146 ret = dma_cookie_status(chan, cookie, txstate);
974 if (ret == DMA_SUCCESS) 1147 if (ret == DMA_SUCCESS)
975 return ret; 1148 return ret;
976 1149
977 /* 1150 /*
1151 * There's no point calculating the residue if there's
1152 * no txstate to store the value.
1153 */
1154 if (!txstate) {
1155 if (plchan->state == PL08X_CHAN_PAUSED)
1156 ret = DMA_PAUSED;
1157 return ret;
1158 }
1159
1160 spin_lock_irqsave(&plchan->vc.lock, flags);
1161 ret = dma_cookie_status(chan, cookie, txstate);
1162 if (ret != DMA_SUCCESS) {
1163 vd = vchan_find_desc(&plchan->vc, cookie);
1164 if (vd) {
1165 /* On the issued list, so hasn't been processed yet */
1166 struct pl08x_txd *txd = to_pl08x_txd(&vd->tx);
1167 struct pl08x_sg *dsg;
1168
1169 list_for_each_entry(dsg, &txd->dsg_list, node)
1170 bytes += dsg->len;
1171 } else {
1172 bytes = pl08x_getbytes_chan(plchan);
1173 }
1174 }
1175 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1176
1177 /*
978 * This cookie not complete yet 1178 * This cookie not complete yet
979 * Get number of bytes left in the active transactions and queue 1179 * Get number of bytes left in the active transactions and queue
980 */ 1180 */
981 dma_set_residue(txstate, pl08x_getbytes_chan(plchan)); 1181 dma_set_residue(txstate, bytes);
982 1182
983 if (plchan->state == PL08X_CHAN_PAUSED) 1183 if (plchan->state == PL08X_CHAN_PAUSED && ret == DMA_IN_PROGRESS)
984 return DMA_PAUSED; 1184 ret = DMA_PAUSED;
985 1185
986 /* Whether waiting or running, we're in progress */ 1186 /* Whether waiting or running, we're in progress */
987 return DMA_IN_PROGRESS; 1187 return ret;
988} 1188}
989 1189
990/* PrimeCell DMA extension */ 1190/* PrimeCell DMA extension */
@@ -1080,38 +1280,14 @@ static u32 pl08x_burst(u32 maxburst)
1080 return burst_sizes[i].reg; 1280 return burst_sizes[i].reg;
1081} 1281}
1082 1282
1083static int dma_set_runtime_config(struct dma_chan *chan, 1283static u32 pl08x_get_cctl(struct pl08x_dma_chan *plchan,
1084 struct dma_slave_config *config) 1284 enum dma_slave_buswidth addr_width, u32 maxburst)
1085{ 1285{
1086 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1286 u32 width, burst, cctl = 0;
1087 struct pl08x_driver_data *pl08x = plchan->host;
1088 enum dma_slave_buswidth addr_width;
1089 u32 width, burst, maxburst;
1090 u32 cctl = 0;
1091
1092 if (!plchan->slave)
1093 return -EINVAL;
1094
1095 /* Transfer direction */
1096 plchan->runtime_direction = config->direction;
1097 if (config->direction == DMA_MEM_TO_DEV) {
1098 addr_width = config->dst_addr_width;
1099 maxburst = config->dst_maxburst;
1100 } else if (config->direction == DMA_DEV_TO_MEM) {
1101 addr_width = config->src_addr_width;
1102 maxburst = config->src_maxburst;
1103 } else {
1104 dev_err(&pl08x->adev->dev,
1105 "bad runtime_config: alien transfer direction\n");
1106 return -EINVAL;
1107 }
1108 1287
1109 width = pl08x_width(addr_width); 1288 width = pl08x_width(addr_width);
1110 if (width == ~0) { 1289 if (width == ~0)
1111 dev_err(&pl08x->adev->dev, 1290 return ~0;
1112 "bad runtime_config: alien address width\n");
1113 return -EINVAL;
1114 }
1115 1291
1116 cctl |= width << PL080_CONTROL_SWIDTH_SHIFT; 1292 cctl |= width << PL080_CONTROL_SWIDTH_SHIFT;
1117 cctl |= width << PL080_CONTROL_DWIDTH_SHIFT; 1293 cctl |= width << PL080_CONTROL_DWIDTH_SHIFT;
@@ -1128,28 +1304,23 @@ static int dma_set_runtime_config(struct dma_chan *chan,
1128 cctl |= burst << PL080_CONTROL_SB_SIZE_SHIFT; 1304 cctl |= burst << PL080_CONTROL_SB_SIZE_SHIFT;
1129 cctl |= burst << PL080_CONTROL_DB_SIZE_SHIFT; 1305 cctl |= burst << PL080_CONTROL_DB_SIZE_SHIFT;
1130 1306
1131 plchan->device_fc = config->device_fc; 1307 return pl08x_cctl(cctl);
1308}
1132 1309
1133 if (plchan->runtime_direction == DMA_DEV_TO_MEM) { 1310static int dma_set_runtime_config(struct dma_chan *chan,
1134 plchan->src_addr = config->src_addr; 1311 struct dma_slave_config *config)
1135 plchan->src_cctl = pl08x_cctl(cctl) | PL080_CONTROL_DST_INCR | 1312{
1136 pl08x_select_bus(plchan->cd->periph_buses, 1313 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1137 pl08x->mem_buses);
1138 } else {
1139 plchan->dst_addr = config->dst_addr;
1140 plchan->dst_cctl = pl08x_cctl(cctl) | PL080_CONTROL_SRC_INCR |
1141 pl08x_select_bus(pl08x->mem_buses,
1142 plchan->cd->periph_buses);
1143 }
1144 1314
1145 dev_dbg(&pl08x->adev->dev, 1315 if (!plchan->slave)
1146 "configured channel %s (%s) for %s, data width %d, " 1316 return -EINVAL;
1147 "maxburst %d words, LE, CCTL=0x%08x\n", 1317
1148 dma_chan_name(chan), plchan->name, 1318 /* Reject definitely invalid configurations */
1149 (config->direction == DMA_DEV_TO_MEM) ? "RX" : "TX", 1319 if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
1150 addr_width, 1320 config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
1151 maxburst, 1321 return -EINVAL;
1152 cctl); 1322
1323 plchan->cfg = *config;
1153 1324
1154 return 0; 1325 return 0;
1155} 1326}
@@ -1163,95 +1334,19 @@ static void pl08x_issue_pending(struct dma_chan *chan)
1163 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1334 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1164 unsigned long flags; 1335 unsigned long flags;
1165 1336
1166 spin_lock_irqsave(&plchan->lock, flags); 1337 spin_lock_irqsave(&plchan->vc.lock, flags);
1167 /* Something is already active, or we're waiting for a channel... */ 1338 if (vchan_issue_pending(&plchan->vc)) {
1168 if (plchan->at || plchan->state == PL08X_CHAN_WAITING) { 1339 if (!plchan->phychan && plchan->state != PL08X_CHAN_WAITING)
1169 spin_unlock_irqrestore(&plchan->lock, flags); 1340 pl08x_phy_alloc_and_start(plchan);
1170 return;
1171 }
1172
1173 /* Take the first element in the queue and execute it */
1174 if (!list_empty(&plchan->pend_list)) {
1175 struct pl08x_txd *next;
1176
1177 next = list_first_entry(&plchan->pend_list,
1178 struct pl08x_txd,
1179 node);
1180 list_del(&next->node);
1181 plchan->state = PL08X_CHAN_RUNNING;
1182
1183 pl08x_start_txd(plchan, next);
1184 } 1341 }
1185 1342 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1186 spin_unlock_irqrestore(&plchan->lock, flags);
1187}
1188
1189static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan,
1190 struct pl08x_txd *txd)
1191{
1192 struct pl08x_driver_data *pl08x = plchan->host;
1193 unsigned long flags;
1194 int num_llis, ret;
1195
1196 num_llis = pl08x_fill_llis_for_desc(pl08x, txd);
1197 if (!num_llis) {
1198 spin_lock_irqsave(&plchan->lock, flags);
1199 pl08x_free_txd(pl08x, txd);
1200 spin_unlock_irqrestore(&plchan->lock, flags);
1201 return -EINVAL;
1202 }
1203
1204 spin_lock_irqsave(&plchan->lock, flags);
1205
1206 /*
1207 * See if we already have a physical channel allocated,
1208 * else this is the time to try to get one.
1209 */
1210 ret = prep_phy_channel(plchan, txd);
1211 if (ret) {
1212 /*
1213 * No physical channel was available.
1214 *
1215 * memcpy transfers can be sorted out at submission time.
1216 *
1217 * Slave transfers may have been denied due to platform
1218 * channel muxing restrictions. Since there is no guarantee
1219 * that this will ever be resolved, and the signal must be
1220 * acquired AFTER acquiring the physical channel, we will let
1221 * them be NACK:ed with -EBUSY here. The drivers can retry
1222 * the prep() call if they are eager on doing this using DMA.
1223 */
1224 if (plchan->slave) {
1225 pl08x_free_txd_list(pl08x, plchan);
1226 pl08x_free_txd(pl08x, txd);
1227 spin_unlock_irqrestore(&plchan->lock, flags);
1228 return -EBUSY;
1229 }
1230 } else
1231 /*
1232 * Else we're all set, paused and ready to roll, status
1233 * will switch to PL08X_CHAN_RUNNING when we call
1234 * issue_pending(). If there is something running on the
1235 * channel already we don't change its state.
1236 */
1237 if (plchan->state == PL08X_CHAN_IDLE)
1238 plchan->state = PL08X_CHAN_PAUSED;
1239
1240 spin_unlock_irqrestore(&plchan->lock, flags);
1241
1242 return 0;
1243} 1343}
1244 1344
1245static struct pl08x_txd *pl08x_get_txd(struct pl08x_dma_chan *plchan, 1345static struct pl08x_txd *pl08x_get_txd(struct pl08x_dma_chan *plchan)
1246 unsigned long flags)
1247{ 1346{
1248 struct pl08x_txd *txd = kzalloc(sizeof(*txd), GFP_NOWAIT); 1347 struct pl08x_txd *txd = kzalloc(sizeof(*txd), GFP_NOWAIT);
1249 1348
1250 if (txd) { 1349 if (txd) {
1251 dma_async_tx_descriptor_init(&txd->tx, &plchan->chan);
1252 txd->tx.flags = flags;
1253 txd->tx.tx_submit = pl08x_tx_submit;
1254 INIT_LIST_HEAD(&txd->node);
1255 INIT_LIST_HEAD(&txd->dsg_list); 1350 INIT_LIST_HEAD(&txd->dsg_list);
1256 1351
1257 /* Always enable error and terminal interrupts */ 1352 /* Always enable error and terminal interrupts */
@@ -1274,7 +1369,7 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy(
1274 struct pl08x_sg *dsg; 1369 struct pl08x_sg *dsg;
1275 int ret; 1370 int ret;
1276 1371
1277 txd = pl08x_get_txd(plchan, flags); 1372 txd = pl08x_get_txd(plchan);
1278 if (!txd) { 1373 if (!txd) {
1279 dev_err(&pl08x->adev->dev, 1374 dev_err(&pl08x->adev->dev,
1280 "%s no memory for descriptor\n", __func__); 1375 "%s no memory for descriptor\n", __func__);
@@ -1290,14 +1385,13 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy(
1290 } 1385 }
1291 list_add_tail(&dsg->node, &txd->dsg_list); 1386 list_add_tail(&dsg->node, &txd->dsg_list);
1292 1387
1293 txd->direction = DMA_NONE;
1294 dsg->src_addr = src; 1388 dsg->src_addr = src;
1295 dsg->dst_addr = dest; 1389 dsg->dst_addr = dest;
1296 dsg->len = len; 1390 dsg->len = len;
1297 1391
1298 /* Set platform data for m2m */ 1392 /* Set platform data for m2m */
1299 txd->ccfg |= PL080_FLOW_MEM2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1393 txd->ccfg |= PL080_FLOW_MEM2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1300 txd->cctl = pl08x->pd->memcpy_channel.cctl & 1394 txd->cctl = pl08x->pd->memcpy_channel.cctl_memcpy &
1301 ~(PL080_CONTROL_DST_AHB2 | PL080_CONTROL_SRC_AHB2); 1395 ~(PL080_CONTROL_DST_AHB2 | PL080_CONTROL_SRC_AHB2);
1302 1396
1303 /* Both to be incremented or the code will break */ 1397 /* Both to be incremented or the code will break */
@@ -1307,11 +1401,13 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy(
1307 txd->cctl |= pl08x_select_bus(pl08x->mem_buses, 1401 txd->cctl |= pl08x_select_bus(pl08x->mem_buses,
1308 pl08x->mem_buses); 1402 pl08x->mem_buses);
1309 1403
1310 ret = pl08x_prep_channel_resources(plchan, txd); 1404 ret = pl08x_fill_llis_for_desc(plchan->host, txd);
1311 if (ret) 1405 if (!ret) {
1406 pl08x_free_txd(pl08x, txd);
1312 return NULL; 1407 return NULL;
1408 }
1313 1409
1314 return &txd->tx; 1410 return vchan_tx_prep(&plchan->vc, &txd->vd, flags);
1315} 1411}
1316 1412
1317static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( 1413static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
@@ -1324,36 +1420,40 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
1324 struct pl08x_txd *txd; 1420 struct pl08x_txd *txd;
1325 struct pl08x_sg *dsg; 1421 struct pl08x_sg *dsg;
1326 struct scatterlist *sg; 1422 struct scatterlist *sg;
1423 enum dma_slave_buswidth addr_width;
1327 dma_addr_t slave_addr; 1424 dma_addr_t slave_addr;
1328 int ret, tmp; 1425 int ret, tmp;
1426 u8 src_buses, dst_buses;
1427 u32 maxburst, cctl;
1329 1428
1330 dev_dbg(&pl08x->adev->dev, "%s prepare transaction of %d bytes from %s\n", 1429 dev_dbg(&pl08x->adev->dev, "%s prepare transaction of %d bytes from %s\n",
1331 __func__, sg_dma_len(sgl), plchan->name); 1430 __func__, sg_dma_len(sgl), plchan->name);
1332 1431
1333 txd = pl08x_get_txd(plchan, flags); 1432 txd = pl08x_get_txd(plchan);
1334 if (!txd) { 1433 if (!txd) {
1335 dev_err(&pl08x->adev->dev, "%s no txd\n", __func__); 1434 dev_err(&pl08x->adev->dev, "%s no txd\n", __func__);
1336 return NULL; 1435 return NULL;
1337 } 1436 }
1338 1437
1339 if (direction != plchan->runtime_direction)
1340 dev_err(&pl08x->adev->dev, "%s DMA setup does not match "
1341 "the direction configured for the PrimeCell\n",
1342 __func__);
1343
1344 /* 1438 /*
1345 * Set up addresses, the PrimeCell configured address 1439 * Set up addresses, the PrimeCell configured address
1346 * will take precedence since this may configure the 1440 * will take precedence since this may configure the
1347 * channel target address dynamically at runtime. 1441 * channel target address dynamically at runtime.
1348 */ 1442 */
1349 txd->direction = direction;
1350
1351 if (direction == DMA_MEM_TO_DEV) { 1443 if (direction == DMA_MEM_TO_DEV) {
1352 txd->cctl = plchan->dst_cctl; 1444 cctl = PL080_CONTROL_SRC_INCR;
1353 slave_addr = plchan->dst_addr; 1445 slave_addr = plchan->cfg.dst_addr;
1446 addr_width = plchan->cfg.dst_addr_width;
1447 maxburst = plchan->cfg.dst_maxburst;
1448 src_buses = pl08x->mem_buses;
1449 dst_buses = plchan->cd->periph_buses;
1354 } else if (direction == DMA_DEV_TO_MEM) { 1450 } else if (direction == DMA_DEV_TO_MEM) {
1355 txd->cctl = plchan->src_cctl; 1451 cctl = PL080_CONTROL_DST_INCR;
1356 slave_addr = plchan->src_addr; 1452 slave_addr = plchan->cfg.src_addr;
1453 addr_width = plchan->cfg.src_addr_width;
1454 maxburst = plchan->cfg.src_maxburst;
1455 src_buses = plchan->cd->periph_buses;
1456 dst_buses = pl08x->mem_buses;
1357 } else { 1457 } else {
1358 pl08x_free_txd(pl08x, txd); 1458 pl08x_free_txd(pl08x, txd);
1359 dev_err(&pl08x->adev->dev, 1459 dev_err(&pl08x->adev->dev,
@@ -1361,7 +1461,17 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
1361 return NULL; 1461 return NULL;
1362 } 1462 }
1363 1463
1364 if (plchan->device_fc) 1464 cctl |= pl08x_get_cctl(plchan, addr_width, maxburst);
1465 if (cctl == ~0) {
1466 pl08x_free_txd(pl08x, txd);
1467 dev_err(&pl08x->adev->dev,
1468 "DMA slave configuration botched?\n");
1469 return NULL;
1470 }
1471
1472 txd->cctl = cctl | pl08x_select_bus(src_buses, dst_buses);
1473
1474 if (plchan->cfg.device_fc)
1365 tmp = (direction == DMA_MEM_TO_DEV) ? PL080_FLOW_MEM2PER_PER : 1475 tmp = (direction == DMA_MEM_TO_DEV) ? PL080_FLOW_MEM2PER_PER :
1366 PL080_FLOW_PER2MEM_PER; 1476 PL080_FLOW_PER2MEM_PER;
1367 else 1477 else
@@ -1370,9 +1480,28 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
1370 1480
1371 txd->ccfg |= tmp << PL080_CONFIG_FLOW_CONTROL_SHIFT; 1481 txd->ccfg |= tmp << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1372 1482
1483 ret = pl08x_request_mux(plchan);
1484 if (ret < 0) {
1485 pl08x_free_txd(pl08x, txd);
1486 dev_dbg(&pl08x->adev->dev,
1487 "unable to mux for transfer on %s due to platform restrictions\n",
1488 plchan->name);
1489 return NULL;
1490 }
1491
1492 dev_dbg(&pl08x->adev->dev, "allocated DMA request signal %d for xfer on %s\n",
1493 plchan->signal, plchan->name);
1494
1495 /* Assign the flow control signal to this channel */
1496 if (direction == DMA_MEM_TO_DEV)
1497 txd->ccfg |= plchan->signal << PL080_CONFIG_DST_SEL_SHIFT;
1498 else
1499 txd->ccfg |= plchan->signal << PL080_CONFIG_SRC_SEL_SHIFT;
1500
1373 for_each_sg(sgl, sg, sg_len, tmp) { 1501 for_each_sg(sgl, sg, sg_len, tmp) {
1374 dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT); 1502 dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT);
1375 if (!dsg) { 1503 if (!dsg) {
1504 pl08x_release_mux(plchan);
1376 pl08x_free_txd(pl08x, txd); 1505 pl08x_free_txd(pl08x, txd);
1377 dev_err(&pl08x->adev->dev, "%s no mem for pl080 sg\n", 1506 dev_err(&pl08x->adev->dev, "%s no mem for pl080 sg\n",
1378 __func__); 1507 __func__);
@@ -1390,11 +1519,14 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
1390 } 1519 }
1391 } 1520 }
1392 1521
1393 ret = pl08x_prep_channel_resources(plchan, txd); 1522 ret = pl08x_fill_llis_for_desc(plchan->host, txd);
1394 if (ret) 1523 if (!ret) {
1524 pl08x_release_mux(plchan);
1525 pl08x_free_txd(pl08x, txd);
1395 return NULL; 1526 return NULL;
1527 }
1396 1528
1397 return &txd->tx; 1529 return vchan_tx_prep(&plchan->vc, &txd->vd, flags);
1398} 1530}
1399 1531
1400static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, 1532static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
@@ -1415,9 +1547,9 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1415 * Anything succeeds on channels with no physical allocation and 1547 * Anything succeeds on channels with no physical allocation and
1416 * no queued transfers. 1548 * no queued transfers.
1417 */ 1549 */
1418 spin_lock_irqsave(&plchan->lock, flags); 1550 spin_lock_irqsave(&plchan->vc.lock, flags);
1419 if (!plchan->phychan && !plchan->at) { 1551 if (!plchan->phychan && !plchan->at) {
1420 spin_unlock_irqrestore(&plchan->lock, flags); 1552 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1421 return 0; 1553 return 0;
1422 } 1554 }
1423 1555
@@ -1426,18 +1558,15 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1426 plchan->state = PL08X_CHAN_IDLE; 1558 plchan->state = PL08X_CHAN_IDLE;
1427 1559
1428 if (plchan->phychan) { 1560 if (plchan->phychan) {
1429 pl08x_terminate_phy_chan(pl08x, plchan->phychan);
1430
1431 /* 1561 /*
1432 * Mark physical channel as free and free any slave 1562 * Mark physical channel as free and free any slave
1433 * signal 1563 * signal
1434 */ 1564 */
1435 release_phy_channel(plchan); 1565 pl08x_phy_free(plchan);
1436 plchan->phychan_hold = 0;
1437 } 1566 }
1438 /* Dequeue jobs and free LLIs */ 1567 /* Dequeue jobs and free LLIs */
1439 if (plchan->at) { 1568 if (plchan->at) {
1440 pl08x_free_txd(pl08x, plchan->at); 1569 pl08x_desc_free(&plchan->at->vd);
1441 plchan->at = NULL; 1570 plchan->at = NULL;
1442 } 1571 }
1443 /* Dequeue jobs not yet fired as well */ 1572 /* Dequeue jobs not yet fired as well */
@@ -1457,7 +1586,7 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1457 break; 1586 break;
1458 } 1587 }
1459 1588
1460 spin_unlock_irqrestore(&plchan->lock, flags); 1589 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1461 1590
1462 return ret; 1591 return ret;
1463} 1592}
@@ -1494,123 +1623,6 @@ static void pl08x_ensure_on(struct pl08x_driver_data *pl08x)
1494 writel(PL080_CONFIG_ENABLE, pl08x->base + PL080_CONFIG); 1623 writel(PL080_CONFIG_ENABLE, pl08x->base + PL080_CONFIG);
1495} 1624}
1496 1625
1497static void pl08x_unmap_buffers(struct pl08x_txd *txd)
1498{
1499 struct device *dev = txd->tx.chan->device->dev;
1500 struct pl08x_sg *dsg;
1501
1502 if (!(txd->tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
1503 if (txd->tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
1504 list_for_each_entry(dsg, &txd->dsg_list, node)
1505 dma_unmap_single(dev, dsg->src_addr, dsg->len,
1506 DMA_TO_DEVICE);
1507 else {
1508 list_for_each_entry(dsg, &txd->dsg_list, node)
1509 dma_unmap_page(dev, dsg->src_addr, dsg->len,
1510 DMA_TO_DEVICE);
1511 }
1512 }
1513 if (!(txd->tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
1514 if (txd->tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
1515 list_for_each_entry(dsg, &txd->dsg_list, node)
1516 dma_unmap_single(dev, dsg->dst_addr, dsg->len,
1517 DMA_FROM_DEVICE);
1518 else
1519 list_for_each_entry(dsg, &txd->dsg_list, node)
1520 dma_unmap_page(dev, dsg->dst_addr, dsg->len,
1521 DMA_FROM_DEVICE);
1522 }
1523}
1524
1525static void pl08x_tasklet(unsigned long data)
1526{
1527 struct pl08x_dma_chan *plchan = (struct pl08x_dma_chan *) data;
1528 struct pl08x_driver_data *pl08x = plchan->host;
1529 struct pl08x_txd *txd;
1530 unsigned long flags;
1531
1532 spin_lock_irqsave(&plchan->lock, flags);
1533
1534 txd = plchan->at;
1535 plchan->at = NULL;
1536
1537 if (txd) {
1538 /* Update last completed */
1539 dma_cookie_complete(&txd->tx);
1540 }
1541
1542 /* If a new descriptor is queued, set it up plchan->at is NULL here */
1543 if (!list_empty(&plchan->pend_list)) {
1544 struct pl08x_txd *next;
1545
1546 next = list_first_entry(&plchan->pend_list,
1547 struct pl08x_txd,
1548 node);
1549 list_del(&next->node);
1550
1551 pl08x_start_txd(plchan, next);
1552 } else if (plchan->phychan_hold) {
1553 /*
1554 * This channel is still in use - we have a new txd being
1555 * prepared and will soon be queued. Don't give up the
1556 * physical channel.
1557 */
1558 } else {
1559 struct pl08x_dma_chan *waiting = NULL;
1560
1561 /*
1562 * No more jobs, so free up the physical channel
1563 * Free any allocated signal on slave transfers too
1564 */
1565 release_phy_channel(plchan);
1566 plchan->state = PL08X_CHAN_IDLE;
1567
1568 /*
1569 * And NOW before anyone else can grab that free:d up
1570 * physical channel, see if there is some memcpy pending
1571 * that seriously needs to start because of being stacked
1572 * up while we were choking the physical channels with data.
1573 */
1574 list_for_each_entry(waiting, &pl08x->memcpy.channels,
1575 chan.device_node) {
1576 if (waiting->state == PL08X_CHAN_WAITING &&
1577 waiting->waiting != NULL) {
1578 int ret;
1579
1580 /* This should REALLY not fail now */
1581 ret = prep_phy_channel(waiting,
1582 waiting->waiting);
1583 BUG_ON(ret);
1584 waiting->phychan_hold--;
1585 waiting->state = PL08X_CHAN_RUNNING;
1586 waiting->waiting = NULL;
1587 pl08x_issue_pending(&waiting->chan);
1588 break;
1589 }
1590 }
1591 }
1592
1593 spin_unlock_irqrestore(&plchan->lock, flags);
1594
1595 if (txd) {
1596 dma_async_tx_callback callback = txd->tx.callback;
1597 void *callback_param = txd->tx.callback_param;
1598
1599 /* Don't try to unmap buffers on slave channels */
1600 if (!plchan->slave)
1601 pl08x_unmap_buffers(txd);
1602
1603 /* Free the descriptor */
1604 spin_lock_irqsave(&plchan->lock, flags);
1605 pl08x_free_txd(pl08x, txd);
1606 spin_unlock_irqrestore(&plchan->lock, flags);
1607
1608 /* Callback to signal completion */
1609 if (callback)
1610 callback(callback_param);
1611 }
1612}
1613
1614static irqreturn_t pl08x_irq(int irq, void *dev) 1626static irqreturn_t pl08x_irq(int irq, void *dev)
1615{ 1627{
1616 struct pl08x_driver_data *pl08x = dev; 1628 struct pl08x_driver_data *pl08x = dev;
@@ -1635,6 +1647,7 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
1635 /* Locate physical channel */ 1647 /* Locate physical channel */
1636 struct pl08x_phy_chan *phychan = &pl08x->phy_chans[i]; 1648 struct pl08x_phy_chan *phychan = &pl08x->phy_chans[i];
1637 struct pl08x_dma_chan *plchan = phychan->serving; 1649 struct pl08x_dma_chan *plchan = phychan->serving;
1650 struct pl08x_txd *tx;
1638 1651
1639 if (!plchan) { 1652 if (!plchan) {
1640 dev_err(&pl08x->adev->dev, 1653 dev_err(&pl08x->adev->dev,
@@ -1643,8 +1656,29 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
1643 continue; 1656 continue;
1644 } 1657 }
1645 1658
1646 /* Schedule tasklet on this channel */ 1659 spin_lock(&plchan->vc.lock);
1647 tasklet_schedule(&plchan->tasklet); 1660 tx = plchan->at;
1661 if (tx) {
1662 plchan->at = NULL;
1663 /*
1664 * This descriptor is done, release its mux
1665 * reservation.
1666 */
1667 pl08x_release_mux(plchan);
1668 tx->done = true;
1669 vchan_cookie_complete(&tx->vd);
1670
1671 /*
1672 * And start the next descriptor (if any),
1673 * otherwise free this channel.
1674 */
1675 if (vchan_next_desc(&plchan->vc))
1676 pl08x_start_next_txd(plchan);
1677 else
1678 pl08x_phy_free(plchan);
1679 }
1680 spin_unlock(&plchan->vc.lock);
1681
1648 mask |= (1 << i); 1682 mask |= (1 << i);
1649 } 1683 }
1650 } 1684 }
@@ -1654,16 +1688,10 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
1654 1688
1655static void pl08x_dma_slave_init(struct pl08x_dma_chan *chan) 1689static void pl08x_dma_slave_init(struct pl08x_dma_chan *chan)
1656{ 1690{
1657 u32 cctl = pl08x_cctl(chan->cd->cctl);
1658
1659 chan->slave = true; 1691 chan->slave = true;
1660 chan->name = chan->cd->bus_id; 1692 chan->name = chan->cd->bus_id;
1661 chan->src_addr = chan->cd->addr; 1693 chan->cfg.src_addr = chan->cd->addr;
1662 chan->dst_addr = chan->cd->addr; 1694 chan->cfg.dst_addr = chan->cd->addr;
1663 chan->src_cctl = cctl | PL080_CONTROL_DST_INCR |
1664 pl08x_select_bus(chan->cd->periph_buses, chan->host->mem_buses);
1665 chan->dst_cctl = cctl | PL080_CONTROL_SRC_INCR |
1666 pl08x_select_bus(chan->host->mem_buses, chan->cd->periph_buses);
1667} 1695}
1668 1696
1669/* 1697/*
@@ -1693,6 +1721,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1693 1721
1694 chan->host = pl08x; 1722 chan->host = pl08x;
1695 chan->state = PL08X_CHAN_IDLE; 1723 chan->state = PL08X_CHAN_IDLE;
1724 chan->signal = -1;
1696 1725
1697 if (slave) { 1726 if (slave) {
1698 chan->cd = &pl08x->pd->slave_channels[i]; 1727 chan->cd = &pl08x->pd->slave_channels[i];
@@ -1705,26 +1734,12 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1705 return -ENOMEM; 1734 return -ENOMEM;
1706 } 1735 }
1707 } 1736 }
1708 if (chan->cd->circular_buffer) {
1709 dev_err(&pl08x->adev->dev,
1710 "channel %s: circular buffers not supported\n",
1711 chan->name);
1712 kfree(chan);
1713 continue;
1714 }
1715 dev_dbg(&pl08x->adev->dev, 1737 dev_dbg(&pl08x->adev->dev,
1716 "initialize virtual channel \"%s\"\n", 1738 "initialize virtual channel \"%s\"\n",
1717 chan->name); 1739 chan->name);
1718 1740
1719 chan->chan.device = dmadev; 1741 chan->vc.desc_free = pl08x_desc_free;
1720 dma_cookie_init(&chan->chan); 1742 vchan_init(&chan->vc, dmadev);
1721
1722 spin_lock_init(&chan->lock);
1723 INIT_LIST_HEAD(&chan->pend_list);
1724 tasklet_init(&chan->tasklet, pl08x_tasklet,
1725 (unsigned long) chan);
1726
1727 list_add_tail(&chan->chan.device_node, &dmadev->channels);
1728 } 1743 }
1729 dev_info(&pl08x->adev->dev, "initialized %d virtual %s channels\n", 1744 dev_info(&pl08x->adev->dev, "initialized %d virtual %s channels\n",
1730 i, slave ? "slave" : "memcpy"); 1745 i, slave ? "slave" : "memcpy");
@@ -1737,8 +1752,8 @@ static void pl08x_free_virtual_channels(struct dma_device *dmadev)
1737 struct pl08x_dma_chan *next; 1752 struct pl08x_dma_chan *next;
1738 1753
1739 list_for_each_entry_safe(chan, 1754 list_for_each_entry_safe(chan,
1740 next, &dmadev->channels, chan.device_node) { 1755 next, &dmadev->channels, vc.chan.device_node) {
1741 list_del(&chan->chan.device_node); 1756 list_del(&chan->vc.chan.device_node);
1742 kfree(chan); 1757 kfree(chan);
1743 } 1758 }
1744} 1759}
@@ -1791,7 +1806,7 @@ static int pl08x_debugfs_show(struct seq_file *s, void *data)
1791 seq_printf(s, "\nPL08x virtual memcpy channels:\n"); 1806 seq_printf(s, "\nPL08x virtual memcpy channels:\n");
1792 seq_printf(s, "CHANNEL:\tSTATE:\n"); 1807 seq_printf(s, "CHANNEL:\tSTATE:\n");
1793 seq_printf(s, "--------\t------\n"); 1808 seq_printf(s, "--------\t------\n");
1794 list_for_each_entry(chan, &pl08x->memcpy.channels, chan.device_node) { 1809 list_for_each_entry(chan, &pl08x->memcpy.channels, vc.chan.device_node) {
1795 seq_printf(s, "%s\t\t%s\n", chan->name, 1810 seq_printf(s, "%s\t\t%s\n", chan->name,
1796 pl08x_state_str(chan->state)); 1811 pl08x_state_str(chan->state));
1797 } 1812 }
@@ -1799,7 +1814,7 @@ static int pl08x_debugfs_show(struct seq_file *s, void *data)
1799 seq_printf(s, "\nPL08x virtual slave channels:\n"); 1814 seq_printf(s, "\nPL08x virtual slave channels:\n");
1800 seq_printf(s, "CHANNEL:\tSTATE:\n"); 1815 seq_printf(s, "CHANNEL:\tSTATE:\n");
1801 seq_printf(s, "--------\t------\n"); 1816 seq_printf(s, "--------\t------\n");
1802 list_for_each_entry(chan, &pl08x->slave.channels, chan.device_node) { 1817 list_for_each_entry(chan, &pl08x->slave.channels, vc.chan.device_node) {
1803 seq_printf(s, "%s\t\t%s\n", chan->name, 1818 seq_printf(s, "%s\t\t%s\n", chan->name,
1804 pl08x_state_str(chan->state)); 1819 pl08x_state_str(chan->state));
1805 } 1820 }
@@ -1851,9 +1866,6 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
1851 goto out_no_pl08x; 1866 goto out_no_pl08x;
1852 } 1867 }
1853 1868
1854 pm_runtime_set_active(&adev->dev);
1855 pm_runtime_enable(&adev->dev);
1856
1857 /* Initialize memcpy engine */ 1869 /* Initialize memcpy engine */
1858 dma_cap_set(DMA_MEMCPY, pl08x->memcpy.cap_mask); 1870 dma_cap_set(DMA_MEMCPY, pl08x->memcpy.cap_mask);
1859 pl08x->memcpy.dev = &adev->dev; 1871 pl08x->memcpy.dev = &adev->dev;
@@ -1903,8 +1915,6 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
1903 goto out_no_lli_pool; 1915 goto out_no_lli_pool;
1904 } 1916 }
1905 1917
1906 spin_lock_init(&pl08x->lock);
1907
1908 pl08x->base = ioremap(adev->res.start, resource_size(&adev->res)); 1918 pl08x->base = ioremap(adev->res.start, resource_size(&adev->res));
1909 if (!pl08x->base) { 1919 if (!pl08x->base) {
1910 ret = -ENOMEM; 1920 ret = -ENOMEM;
@@ -1942,7 +1952,6 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
1942 ch->id = i; 1952 ch->id = i;
1943 ch->base = pl08x->base + PL080_Cx_BASE(i); 1953 ch->base = pl08x->base + PL080_Cx_BASE(i);
1944 spin_lock_init(&ch->lock); 1954 spin_lock_init(&ch->lock);
1945 ch->signal = -1;
1946 1955
1947 /* 1956 /*
1948 * Nomadik variants can have channels that are locked 1957 * Nomadik variants can have channels that are locked
@@ -2007,7 +2016,6 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
2007 amba_part(adev), amba_rev(adev), 2016 amba_part(adev), amba_rev(adev),
2008 (unsigned long long)adev->res.start, adev->irq[0]); 2017 (unsigned long long)adev->res.start, adev->irq[0]);
2009 2018
2010 pm_runtime_put(&adev->dev);
2011 return 0; 2019 return 0;
2012 2020
2013out_no_slave_reg: 2021out_no_slave_reg:
@@ -2026,9 +2034,6 @@ out_no_ioremap:
2026 dma_pool_destroy(pl08x->pool); 2034 dma_pool_destroy(pl08x->pool);
2027out_no_lli_pool: 2035out_no_lli_pool:
2028out_no_platdata: 2036out_no_platdata:
2029 pm_runtime_put(&adev->dev);
2030 pm_runtime_disable(&adev->dev);
2031
2032 kfree(pl08x); 2037 kfree(pl08x);
2033out_no_pl08x: 2038out_no_pl08x:
2034 amba_release_regions(adev); 2039 amba_release_regions(adev);
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index 5f1d2e670837..f5a73606217e 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -78,6 +78,8 @@ struct sa11x0_dma_desc {
78 78
79 u32 ddar; 79 u32 ddar;
80 size_t size; 80 size_t size;
81 unsigned period;
82 bool cyclic;
81 83
82 unsigned sglen; 84 unsigned sglen;
83 struct sa11x0_dma_sg sg[0]; 85 struct sa11x0_dma_sg sg[0];
@@ -178,19 +180,24 @@ static void noinline sa11x0_dma_start_sg(struct sa11x0_dma_phy *p,
178 return; 180 return;
179 181
180 if (p->sg_load == txd->sglen) { 182 if (p->sg_load == txd->sglen) {
181 struct sa11x0_dma_desc *txn = sa11x0_dma_next_desc(c); 183 if (!txd->cyclic) {
184 struct sa11x0_dma_desc *txn = sa11x0_dma_next_desc(c);
182 185
183 /* 186 /*
184 * We have reached the end of the current descriptor. 187 * We have reached the end of the current descriptor.
185 * Peek at the next descriptor, and if compatible with 188 * Peek at the next descriptor, and if compatible with
186 * the current, start processing it. 189 * the current, start processing it.
187 */ 190 */
188 if (txn && txn->ddar == txd->ddar) { 191 if (txn && txn->ddar == txd->ddar) {
189 txd = txn; 192 txd = txn;
190 sa11x0_dma_start_desc(p, txn); 193 sa11x0_dma_start_desc(p, txn);
194 } else {
195 p->txd_load = NULL;
196 return;
197 }
191 } else { 198 } else {
192 p->txd_load = NULL; 199 /* Cyclic: reset back to beginning */
193 return; 200 p->sg_load = 0;
194 } 201 }
195 } 202 }
196 203
@@ -224,13 +231,21 @@ static void noinline sa11x0_dma_complete(struct sa11x0_dma_phy *p,
224 struct sa11x0_dma_desc *txd = p->txd_done; 231 struct sa11x0_dma_desc *txd = p->txd_done;
225 232
226 if (++p->sg_done == txd->sglen) { 233 if (++p->sg_done == txd->sglen) {
227 vchan_cookie_complete(&txd->vd); 234 if (!txd->cyclic) {
235 vchan_cookie_complete(&txd->vd);
228 236
229 p->sg_done = 0; 237 p->sg_done = 0;
230 p->txd_done = p->txd_load; 238 p->txd_done = p->txd_load;
231 239
232 if (!p->txd_done) 240 if (!p->txd_done)
233 tasklet_schedule(&p->dev->task); 241 tasklet_schedule(&p->dev->task);
242 } else {
243 if ((p->sg_done % txd->period) == 0)
244 vchan_cyclic_callback(&txd->vd);
245
246 /* Cyclic: reset back to beginning */
247 p->sg_done = 0;
248 }
234 } 249 }
235 250
236 sa11x0_dma_start_sg(p, c); 251 sa11x0_dma_start_sg(p, c);
@@ -416,27 +431,47 @@ static enum dma_status sa11x0_dma_tx_status(struct dma_chan *chan,
416 struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); 431 struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
417 struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); 432 struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
418 struct sa11x0_dma_phy *p; 433 struct sa11x0_dma_phy *p;
419 struct sa11x0_dma_desc *txd; 434 struct virt_dma_desc *vd;
420 unsigned long flags; 435 unsigned long flags;
421 enum dma_status ret; 436 enum dma_status ret;
422 size_t bytes = 0;
423 437
424 ret = dma_cookie_status(&c->vc.chan, cookie, state); 438 ret = dma_cookie_status(&c->vc.chan, cookie, state);
425 if (ret == DMA_SUCCESS) 439 if (ret == DMA_SUCCESS)
426 return ret; 440 return ret;
427 441
442 if (!state)
443 return c->status;
444
428 spin_lock_irqsave(&c->vc.lock, flags); 445 spin_lock_irqsave(&c->vc.lock, flags);
429 p = c->phy; 446 p = c->phy;
430 ret = c->status;
431 if (p) {
432 dma_addr_t addr = sa11x0_dma_pos(p);
433 447
434 dev_vdbg(d->slave.dev, "tx_status: addr:%x\n", addr); 448 /*
449 * If the cookie is on our issue queue, then the residue is
450 * its total size.
451 */
452 vd = vchan_find_desc(&c->vc, cookie);
453 if (vd) {
454 state->residue = container_of(vd, struct sa11x0_dma_desc, vd)->size;
455 } else if (!p) {
456 state->residue = 0;
457 } else {
458 struct sa11x0_dma_desc *txd;
459 size_t bytes = 0;
435 460
436 txd = p->txd_done; 461 if (p->txd_done && p->txd_done->vd.tx.cookie == cookie)
462 txd = p->txd_done;
463 else if (p->txd_load && p->txd_load->vd.tx.cookie == cookie)
464 txd = p->txd_load;
465 else
466 txd = NULL;
467
468 ret = c->status;
437 if (txd) { 469 if (txd) {
470 dma_addr_t addr = sa11x0_dma_pos(p);
438 unsigned i; 471 unsigned i;
439 472
473 dev_vdbg(d->slave.dev, "tx_status: addr:%x\n", addr);
474
440 for (i = 0; i < txd->sglen; i++) { 475 for (i = 0; i < txd->sglen; i++) {
441 dev_vdbg(d->slave.dev, "tx_status: [%u] %x+%x\n", 476 dev_vdbg(d->slave.dev, "tx_status: [%u] %x+%x\n",
442 i, txd->sg[i].addr, txd->sg[i].len); 477 i, txd->sg[i].addr, txd->sg[i].len);
@@ -459,18 +494,11 @@ static enum dma_status sa11x0_dma_tx_status(struct dma_chan *chan,
459 bytes += txd->sg[i].len; 494 bytes += txd->sg[i].len;
460 } 495 }
461 } 496 }
462 if (txd != p->txd_load && p->txd_load) 497 state->residue = bytes;
463 bytes += p->txd_load->size;
464 }
465 list_for_each_entry(txd, &c->vc.desc_issued, vd.node) {
466 bytes += txd->size;
467 } 498 }
468 spin_unlock_irqrestore(&c->vc.lock, flags); 499 spin_unlock_irqrestore(&c->vc.lock, flags);
469 500
470 if (state) 501 dev_vdbg(d->slave.dev, "tx_status: bytes 0x%zx\n", state->residue);
471 state->residue = bytes;
472
473 dev_vdbg(d->slave.dev, "tx_status: bytes 0x%zx\n", bytes);
474 502
475 return ret; 503 return ret;
476} 504}
@@ -584,6 +612,65 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg(
584 return vchan_tx_prep(&c->vc, &txd->vd, flags); 612 return vchan_tx_prep(&c->vc, &txd->vd, flags);
585} 613}
586 614
615static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic(
616 struct dma_chan *chan, dma_addr_t addr, size_t size, size_t period,
617 enum dma_transfer_direction dir, void *context)
618{
619 struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
620 struct sa11x0_dma_desc *txd;
621 unsigned i, j, k, sglen, sgperiod;
622
623 /* SA11x0 channels can only operate in their native direction */
624 if (dir != (c->ddar & DDAR_RW ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV)) {
625 dev_err(chan->device->dev, "vchan %p: bad DMA direction: DDAR:%08x dir:%u\n",
626 &c->vc, c->ddar, dir);
627 return NULL;
628 }
629
630 sgperiod = DIV_ROUND_UP(period, DMA_MAX_SIZE & ~DMA_ALIGN);
631 sglen = size * sgperiod / period;
632
633 /* Do not allow zero-sized txds */
634 if (sglen == 0)
635 return NULL;
636
637 txd = kzalloc(sizeof(*txd) + sglen * sizeof(txd->sg[0]), GFP_ATOMIC);
638 if (!txd) {
639 dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc);
640 return NULL;
641 }
642
643 for (i = k = 0; i < size / period; i++) {
644 size_t tlen, len = period;
645
646 for (j = 0; j < sgperiod; j++, k++) {
647 tlen = len;
648
649 if (tlen > DMA_MAX_SIZE) {
650 unsigned mult = DIV_ROUND_UP(tlen, DMA_MAX_SIZE & ~DMA_ALIGN);
651 tlen = (tlen / mult) & ~DMA_ALIGN;
652 }
653
654 txd->sg[k].addr = addr;
655 txd->sg[k].len = tlen;
656 addr += tlen;
657 len -= tlen;
658 }
659
660 WARN_ON(len != 0);
661 }
662
663 WARN_ON(k != sglen);
664
665 txd->ddar = c->ddar;
666 txd->size = size;
667 txd->sglen = sglen;
668 txd->cyclic = 1;
669 txd->period = sgperiod;
670
671 return vchan_tx_prep(&c->vc, &txd->vd, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
672}
673
587static int sa11x0_dma_slave_config(struct sa11x0_dma_chan *c, struct dma_slave_config *cfg) 674static int sa11x0_dma_slave_config(struct sa11x0_dma_chan *c, struct dma_slave_config *cfg)
588{ 675{
589 u32 ddar = c->ddar & ((0xf << 4) | DDAR_RW); 676 u32 ddar = c->ddar & ((0xf << 4) | DDAR_RW);
@@ -854,7 +941,9 @@ static int __devinit sa11x0_dma_probe(struct platform_device *pdev)
854 } 941 }
855 942
856 dma_cap_set(DMA_SLAVE, d->slave.cap_mask); 943 dma_cap_set(DMA_SLAVE, d->slave.cap_mask);
944 dma_cap_set(DMA_CYCLIC, d->slave.cap_mask);
857 d->slave.device_prep_slave_sg = sa11x0_dma_prep_slave_sg; 945 d->slave.device_prep_slave_sg = sa11x0_dma_prep_slave_sg;
946 d->slave.device_prep_dma_cyclic = sa11x0_dma_prep_dma_cyclic;
858 ret = sa11x0_dma_init_dmadev(&d->slave, &pdev->dev); 947 ret = sa11x0_dma_init_dmadev(&d->slave, &pdev->dev);
859 if (ret) { 948 if (ret) {
860 dev_warn(d->slave.dev, "failed to register slave async device: %d\n", 949 dev_warn(d->slave.dev, "failed to register slave async device: %d\n",
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
index 02549017212a..2a5f64a11b77 100644
--- a/include/linux/amba/pl08x.h
+++ b/include/linux/amba/pl08x.h
@@ -21,8 +21,9 @@
21#include <linux/dmaengine.h> 21#include <linux/dmaengine.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23 23
24struct pl08x_lli;
25struct pl08x_driver_data; 24struct pl08x_driver_data;
25struct pl08x_phy_chan;
26struct pl08x_txd;
26 27
27/* Bitmasks for selecting AHB ports for DMA transfers */ 28/* Bitmasks for selecting AHB ports for DMA transfers */
28enum { 29enum {
@@ -46,170 +47,29 @@ enum {
46 * devices with static assignments 47 * devices with static assignments
47 * @muxval: a number usually used to poke into some mux regiser to 48 * @muxval: a number usually used to poke into some mux regiser to
48 * mux in the signal to this channel 49 * mux in the signal to this channel
49 * @cctl_opt: default options for the channel control register 50 * @cctl_memcpy: options for the channel control register for memcpy
51 * *** not used for slave channels ***
50 * @addr: source/target address in physical memory for this DMA channel, 52 * @addr: source/target address in physical memory for this DMA channel,
51 * can be the address of a FIFO register for burst requests for example. 53 * can be the address of a FIFO register for burst requests for example.
52 * This can be left undefined if the PrimeCell API is used for configuring 54 * This can be left undefined if the PrimeCell API is used for configuring
53 * this. 55 * this.
54 * @circular_buffer: whether the buffer passed in is circular and
55 * shall simply be looped round round (like a record baby round
56 * round round round)
57 * @single: the device connected to this channel will request single DMA 56 * @single: the device connected to this channel will request single DMA
58 * transfers, not bursts. (Bursts are default.) 57 * transfers, not bursts. (Bursts are default.)
59 * @periph_buses: the device connected to this channel is accessible via 58 * @periph_buses: the device connected to this channel is accessible via
60 * these buses (use PL08X_AHB1 | PL08X_AHB2). 59 * these buses (use PL08X_AHB1 | PL08X_AHB2).
61 */ 60 */
62struct pl08x_channel_data { 61struct pl08x_channel_data {
63 char *bus_id; 62 const char *bus_id;
64 int min_signal; 63 int min_signal;
65 int max_signal; 64 int max_signal;
66 u32 muxval; 65 u32 muxval;
67 u32 cctl; 66 u32 cctl_memcpy;
68 dma_addr_t addr; 67 dma_addr_t addr;
69 bool circular_buffer;
70 bool single; 68 bool single;
71 u8 periph_buses; 69 u8 periph_buses;
72}; 70};
73 71
74/** 72/**
75 * Struct pl08x_bus_data - information of source or destination
76 * busses for a transfer
77 * @addr: current address
78 * @maxwidth: the maximum width of a transfer on this bus
79 * @buswidth: the width of this bus in bytes: 1, 2 or 4
80 */
81struct pl08x_bus_data {
82 dma_addr_t addr;
83 u8 maxwidth;
84 u8 buswidth;
85};
86
87/**
88 * struct pl08x_phy_chan - holder for the physical channels
89 * @id: physical index to this channel
90 * @lock: a lock to use when altering an instance of this struct
91 * @signal: the physical signal (aka channel) serving this physical channel
92 * right now
93 * @serving: the virtual channel currently being served by this physical
94 * channel
95 * @locked: channel unavailable for the system, e.g. dedicated to secure
96 * world
97 */
98struct pl08x_phy_chan {
99 unsigned int id;
100 void __iomem *base;
101 spinlock_t lock;
102 int signal;
103 struct pl08x_dma_chan *serving;
104 bool locked;
105};
106
107/**
108 * struct pl08x_sg - structure containing data per sg
109 * @src_addr: src address of sg
110 * @dst_addr: dst address of sg
111 * @len: transfer len in bytes
112 * @node: node for txd's dsg_list
113 */
114struct pl08x_sg {
115 dma_addr_t src_addr;
116 dma_addr_t dst_addr;
117 size_t len;
118 struct list_head node;
119};
120
121/**
122 * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
123 * @tx: async tx descriptor
124 * @node: node for txd list for channels
125 * @dsg_list: list of children sg's
126 * @direction: direction of transfer
127 * @llis_bus: DMA memory address (physical) start for the LLIs
128 * @llis_va: virtual memory address start for the LLIs
129 * @cctl: control reg values for current txd
130 * @ccfg: config reg values for current txd
131 */
132struct pl08x_txd {
133 struct dma_async_tx_descriptor tx;
134 struct list_head node;
135 struct list_head dsg_list;
136 enum dma_transfer_direction direction;
137 dma_addr_t llis_bus;
138 struct pl08x_lli *llis_va;
139 /* Default cctl value for LLIs */
140 u32 cctl;
141 /*
142 * Settings to be put into the physical channel when we
143 * trigger this txd. Other registers are in llis_va[0].
144 */
145 u32 ccfg;
146};
147
148/**
149 * struct pl08x_dma_chan_state - holds the PL08x specific virtual channel
150 * states
151 * @PL08X_CHAN_IDLE: the channel is idle
152 * @PL08X_CHAN_RUNNING: the channel has allocated a physical transport
153 * channel and is running a transfer on it
154 * @PL08X_CHAN_PAUSED: the channel has allocated a physical transport
155 * channel, but the transfer is currently paused
156 * @PL08X_CHAN_WAITING: the channel is waiting for a physical transport
157 * channel to become available (only pertains to memcpy channels)
158 */
159enum pl08x_dma_chan_state {
160 PL08X_CHAN_IDLE,
161 PL08X_CHAN_RUNNING,
162 PL08X_CHAN_PAUSED,
163 PL08X_CHAN_WAITING,
164};
165
166/**
167 * struct pl08x_dma_chan - this structure wraps a DMA ENGINE channel
168 * @chan: wrappped abstract channel
169 * @phychan: the physical channel utilized by this channel, if there is one
170 * @phychan_hold: if non-zero, hold on to the physical channel even if we
171 * have no pending entries
172 * @tasklet: tasklet scheduled by the IRQ to handle actual work etc
173 * @name: name of channel
174 * @cd: channel platform data
175 * @runtime_addr: address for RX/TX according to the runtime config
176 * @runtime_direction: current direction of this channel according to
177 * runtime config
178 * @pend_list: queued transactions pending on this channel
179 * @at: active transaction on this channel
180 * @lock: a lock for this channel data
181 * @host: a pointer to the host (internal use)
182 * @state: whether the channel is idle, paused, running etc
183 * @slave: whether this channel is a device (slave) or for memcpy
184 * @device_fc: Flow Controller Settings for ccfg register. Only valid for slave
185 * channels. Fill with 'true' if peripheral should be flow controller. Direction
186 * will be selected at Runtime.
187 * @waiting: a TX descriptor on this channel which is waiting for a physical
188 * channel to become available
189 */
190struct pl08x_dma_chan {
191 struct dma_chan chan;
192 struct pl08x_phy_chan *phychan;
193 int phychan_hold;
194 struct tasklet_struct tasklet;
195 char *name;
196 const struct pl08x_channel_data *cd;
197 dma_addr_t src_addr;
198 dma_addr_t dst_addr;
199 u32 src_cctl;
200 u32 dst_cctl;
201 enum dma_transfer_direction runtime_direction;
202 struct list_head pend_list;
203 struct pl08x_txd *at;
204 spinlock_t lock;
205 struct pl08x_driver_data *host;
206 enum pl08x_dma_chan_state state;
207 bool slave;
208 bool device_fc;
209 struct pl08x_txd *waiting;
210};
211
212/**
213 * struct pl08x_platform_data - the platform configuration for the PL08x 73 * struct pl08x_platform_data - the platform configuration for the PL08x
214 * PrimeCells. 74 * PrimeCells.
215 * @slave_channels: the channels defined for the different devices on the 75 * @slave_channels: the channels defined for the different devices on the
@@ -229,8 +89,8 @@ struct pl08x_platform_data {
229 const struct pl08x_channel_data *slave_channels; 89 const struct pl08x_channel_data *slave_channels;
230 unsigned int num_slave_channels; 90 unsigned int num_slave_channels;
231 struct pl08x_channel_data memcpy_channel; 91 struct pl08x_channel_data memcpy_channel;
232 int (*get_signal)(struct pl08x_dma_chan *); 92 int (*get_signal)(const struct pl08x_channel_data *);
233 void (*put_signal)(struct pl08x_dma_chan *); 93 void (*put_signal)(const struct pl08x_channel_data *, int);
234 u8 lli_buses; 94 u8 lli_buses;
235 u8 mem_buses; 95 u8 mem_buses;
236}; 96};