diff options
author | Dan Williams <dan.j.williams@intel.com> | 2007-01-02 15:52:31 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2007-07-13 11:06:18 -0400 |
commit | 39a8d7d13c113e4a98bfdfc45c7233188e4d715f (patch) | |
tree | 7595e6b48de6a11d98ad206f4aaa1d976c349e4f | |
parent | c211092313b90f898dec61f35207fc282d1eadc3 (diff) |
iop13xx: surface the iop13xx adma units to the iop-adma driver
Adds the platform device definitions and the architecture specific
support routines (i.e. register initialization and descriptor formats) for the
iop-adma driver.
Changelog:
* added 'descriptor pool size' to the platform data
* add base support for buffer sizes larger than 16MB (hw max)
* build error fix from Kirill A. Shutemov
* rebase for async_tx changes
* add interrupt support
* do not call platform register macros in driver code
* remove unnecessary ARM assembly statement
* checkpatch.pl fixes
* gpl v2 only correction
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r-- | arch/arm/mach-iop13xx/setup.c | 217 | ||||
-rw-r--r-- | include/asm-arm/arch-iop13xx/adma.h | 544 | ||||
-rw-r--r-- | include/asm-arm/arch-iop13xx/iop13xx.h | 38 |
3 files changed, 774 insertions, 25 deletions
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c index bc4871553f6a..bfe0c87e3397 100644 --- a/arch/arm/mach-iop13xx/setup.c +++ b/arch/arm/mach-iop13xx/setup.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/hardware.h> | 25 | #include <asm/hardware.h> |
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | #include <asm/io.h> | 27 | #include <asm/io.h> |
28 | #include <asm/hardware/iop_adma.h> | ||
28 | 29 | ||
29 | #define IOP13XX_UART_XTAL 33334000 | 30 | #define IOP13XX_UART_XTAL 33334000 |
30 | #define IOP13XX_SETUP_DEBUG 0 | 31 | #define IOP13XX_SETUP_DEBUG 0 |
@@ -236,19 +237,143 @@ static unsigned long iq8134x_probe_flash_size(void) | |||
236 | } | 237 | } |
237 | #endif | 238 | #endif |
238 | 239 | ||
240 | /* ADMA Channels */ | ||
241 | static struct resource iop13xx_adma_0_resources[] = { | ||
242 | [0] = { | ||
243 | .start = IOP13XX_ADMA_PHYS_BASE(0), | ||
244 | .end = IOP13XX_ADMA_UPPER_PA(0), | ||
245 | .flags = IORESOURCE_MEM, | ||
246 | }, | ||
247 | [1] = { | ||
248 | .start = IRQ_IOP13XX_ADMA0_EOT, | ||
249 | .end = IRQ_IOP13XX_ADMA0_EOT, | ||
250 | .flags = IORESOURCE_IRQ | ||
251 | }, | ||
252 | [2] = { | ||
253 | .start = IRQ_IOP13XX_ADMA0_EOC, | ||
254 | .end = IRQ_IOP13XX_ADMA0_EOC, | ||
255 | .flags = IORESOURCE_IRQ | ||
256 | }, | ||
257 | [3] = { | ||
258 | .start = IRQ_IOP13XX_ADMA0_ERR, | ||
259 | .end = IRQ_IOP13XX_ADMA0_ERR, | ||
260 | .flags = IORESOURCE_IRQ | ||
261 | } | ||
262 | }; | ||
263 | |||
264 | static struct resource iop13xx_adma_1_resources[] = { | ||
265 | [0] = { | ||
266 | .start = IOP13XX_ADMA_PHYS_BASE(1), | ||
267 | .end = IOP13XX_ADMA_UPPER_PA(1), | ||
268 | .flags = IORESOURCE_MEM, | ||
269 | }, | ||
270 | [1] = { | ||
271 | .start = IRQ_IOP13XX_ADMA1_EOT, | ||
272 | .end = IRQ_IOP13XX_ADMA1_EOT, | ||
273 | .flags = IORESOURCE_IRQ | ||
274 | }, | ||
275 | [2] = { | ||
276 | .start = IRQ_IOP13XX_ADMA1_EOC, | ||
277 | .end = IRQ_IOP13XX_ADMA1_EOC, | ||
278 | .flags = IORESOURCE_IRQ | ||
279 | }, | ||
280 | [3] = { | ||
281 | .start = IRQ_IOP13XX_ADMA1_ERR, | ||
282 | .end = IRQ_IOP13XX_ADMA1_ERR, | ||
283 | .flags = IORESOURCE_IRQ | ||
284 | } | ||
285 | }; | ||
286 | |||
287 | static struct resource iop13xx_adma_2_resources[] = { | ||
288 | [0] = { | ||
289 | .start = IOP13XX_ADMA_PHYS_BASE(2), | ||
290 | .end = IOP13XX_ADMA_UPPER_PA(2), | ||
291 | .flags = IORESOURCE_MEM, | ||
292 | }, | ||
293 | [1] = { | ||
294 | .start = IRQ_IOP13XX_ADMA2_EOT, | ||
295 | .end = IRQ_IOP13XX_ADMA2_EOT, | ||
296 | .flags = IORESOURCE_IRQ | ||
297 | }, | ||
298 | [2] = { | ||
299 | .start = IRQ_IOP13XX_ADMA2_EOC, | ||
300 | .end = IRQ_IOP13XX_ADMA2_EOC, | ||
301 | .flags = IORESOURCE_IRQ | ||
302 | }, | ||
303 | [3] = { | ||
304 | .start = IRQ_IOP13XX_ADMA2_ERR, | ||
305 | .end = IRQ_IOP13XX_ADMA2_ERR, | ||
306 | .flags = IORESOURCE_IRQ | ||
307 | } | ||
308 | }; | ||
309 | |||
310 | static u64 iop13xx_adma_dmamask = DMA_64BIT_MASK; | ||
311 | static struct iop_adma_platform_data iop13xx_adma_0_data = { | ||
312 | .hw_id = 0, | ||
313 | .pool_size = PAGE_SIZE, | ||
314 | }; | ||
315 | |||
316 | static struct iop_adma_platform_data iop13xx_adma_1_data = { | ||
317 | .hw_id = 1, | ||
318 | .pool_size = PAGE_SIZE, | ||
319 | }; | ||
320 | |||
321 | static struct iop_adma_platform_data iop13xx_adma_2_data = { | ||
322 | .hw_id = 2, | ||
323 | .pool_size = PAGE_SIZE, | ||
324 | }; | ||
325 | |||
326 | /* The ids are fixed up later in iop13xx_platform_init */ | ||
327 | static struct platform_device iop13xx_adma_0_channel = { | ||
328 | .name = "iop-adma", | ||
329 | .id = 0, | ||
330 | .num_resources = 4, | ||
331 | .resource = iop13xx_adma_0_resources, | ||
332 | .dev = { | ||
333 | .dma_mask = &iop13xx_adma_dmamask, | ||
334 | .coherent_dma_mask = DMA_64BIT_MASK, | ||
335 | .platform_data = (void *) &iop13xx_adma_0_data, | ||
336 | }, | ||
337 | }; | ||
338 | |||
339 | static struct platform_device iop13xx_adma_1_channel = { | ||
340 | .name = "iop-adma", | ||
341 | .id = 0, | ||
342 | .num_resources = 4, | ||
343 | .resource = iop13xx_adma_1_resources, | ||
344 | .dev = { | ||
345 | .dma_mask = &iop13xx_adma_dmamask, | ||
346 | .coherent_dma_mask = DMA_64BIT_MASK, | ||
347 | .platform_data = (void *) &iop13xx_adma_1_data, | ||
348 | }, | ||
349 | }; | ||
350 | |||
351 | static struct platform_device iop13xx_adma_2_channel = { | ||
352 | .name = "iop-adma", | ||
353 | .id = 0, | ||
354 | .num_resources = 4, | ||
355 | .resource = iop13xx_adma_2_resources, | ||
356 | .dev = { | ||
357 | .dma_mask = &iop13xx_adma_dmamask, | ||
358 | .coherent_dma_mask = DMA_64BIT_MASK, | ||
359 | .platform_data = (void *) &iop13xx_adma_2_data, | ||
360 | }, | ||
361 | }; | ||
362 | |||
239 | void __init iop13xx_map_io(void) | 363 | void __init iop13xx_map_io(void) |
240 | { | 364 | { |
241 | /* Initialize the Static Page Table maps */ | 365 | /* Initialize the Static Page Table maps */ |
242 | iotable_init(iop13xx_std_desc, ARRAY_SIZE(iop13xx_std_desc)); | 366 | iotable_init(iop13xx_std_desc, ARRAY_SIZE(iop13xx_std_desc)); |
243 | } | 367 | } |
244 | 368 | ||
245 | static int init_uart = 0; | 369 | static int init_uart; |
246 | static int init_i2c = 0; | 370 | static int init_i2c; |
371 | static int init_adma; | ||
247 | 372 | ||
248 | void __init iop13xx_platform_init(void) | 373 | void __init iop13xx_platform_init(void) |
249 | { | 374 | { |
250 | int i; | 375 | int i; |
251 | u32 uart_idx, i2c_idx, plat_idx; | 376 | u32 uart_idx, i2c_idx, adma_idx, plat_idx; |
252 | struct platform_device *iop13xx_devices[IQ81340_MAX_PLAT_DEVICES]; | 377 | struct platform_device *iop13xx_devices[IQ81340_MAX_PLAT_DEVICES]; |
253 | 378 | ||
254 | /* set the bases so we can read the device id */ | 379 | /* set the bases so we can read the device id */ |
@@ -294,6 +419,12 @@ void __init iop13xx_platform_init(void) | |||
294 | } | 419 | } |
295 | } | 420 | } |
296 | 421 | ||
422 | if (init_adma == IOP13XX_INIT_ADMA_DEFAULT) { | ||
423 | init_adma |= IOP13XX_INIT_ADMA_0; | ||
424 | init_adma |= IOP13XX_INIT_ADMA_1; | ||
425 | init_adma |= IOP13XX_INIT_ADMA_2; | ||
426 | } | ||
427 | |||
297 | plat_idx = 0; | 428 | plat_idx = 0; |
298 | uart_idx = 0; | 429 | uart_idx = 0; |
299 | i2c_idx = 0; | 430 | i2c_idx = 0; |
@@ -332,6 +463,56 @@ void __init iop13xx_platform_init(void) | |||
332 | } | 463 | } |
333 | } | 464 | } |
334 | 465 | ||
466 | /* initialize adma channel ids and capabilities */ | ||
467 | adma_idx = 0; | ||
468 | for (i = 0; i < IQ81340_NUM_ADMA; i++) { | ||
469 | struct iop_adma_platform_data *plat_data; | ||
470 | if ((init_adma & (1 << i)) && IOP13XX_SETUP_DEBUG) | ||
471 | printk(KERN_INFO | ||
472 | "Adding adma%d to platform device list\n", i); | ||
473 | switch (init_adma & (1 << i)) { | ||
474 | case IOP13XX_INIT_ADMA_0: | ||
475 | iop13xx_adma_0_channel.id = adma_idx++; | ||
476 | iop13xx_devices[plat_idx++] = &iop13xx_adma_0_channel; | ||
477 | plat_data = &iop13xx_adma_0_data; | ||
478 | dma_cap_set(DMA_MEMCPY, plat_data->cap_mask); | ||
479 | dma_cap_set(DMA_XOR, plat_data->cap_mask); | ||
480 | dma_cap_set(DMA_DUAL_XOR, plat_data->cap_mask); | ||
481 | dma_cap_set(DMA_ZERO_SUM, plat_data->cap_mask); | ||
482 | dma_cap_set(DMA_MEMSET, plat_data->cap_mask); | ||
483 | dma_cap_set(DMA_MEMCPY_CRC32C, plat_data->cap_mask); | ||
484 | dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask); | ||
485 | break; | ||
486 | case IOP13XX_INIT_ADMA_1: | ||
487 | iop13xx_adma_1_channel.id = adma_idx++; | ||
488 | iop13xx_devices[plat_idx++] = &iop13xx_adma_1_channel; | ||
489 | plat_data = &iop13xx_adma_1_data; | ||
490 | dma_cap_set(DMA_MEMCPY, plat_data->cap_mask); | ||
491 | dma_cap_set(DMA_XOR, plat_data->cap_mask); | ||
492 | dma_cap_set(DMA_DUAL_XOR, plat_data->cap_mask); | ||
493 | dma_cap_set(DMA_ZERO_SUM, plat_data->cap_mask); | ||
494 | dma_cap_set(DMA_MEMSET, plat_data->cap_mask); | ||
495 | dma_cap_set(DMA_MEMCPY_CRC32C, plat_data->cap_mask); | ||
496 | dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask); | ||
497 | break; | ||
498 | case IOP13XX_INIT_ADMA_2: | ||
499 | iop13xx_adma_2_channel.id = adma_idx++; | ||
500 | iop13xx_devices[plat_idx++] = &iop13xx_adma_2_channel; | ||
501 | plat_data = &iop13xx_adma_2_data; | ||
502 | dma_cap_set(DMA_MEMCPY, plat_data->cap_mask); | ||
503 | dma_cap_set(DMA_XOR, plat_data->cap_mask); | ||
504 | dma_cap_set(DMA_DUAL_XOR, plat_data->cap_mask); | ||
505 | dma_cap_set(DMA_ZERO_SUM, plat_data->cap_mask); | ||
506 | dma_cap_set(DMA_MEMSET, plat_data->cap_mask); | ||
507 | dma_cap_set(DMA_MEMCPY_CRC32C, plat_data->cap_mask); | ||
508 | dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask); | ||
509 | dma_cap_set(DMA_PQ_XOR, plat_data->cap_mask); | ||
510 | dma_cap_set(DMA_PQ_UPDATE, plat_data->cap_mask); | ||
511 | dma_cap_set(DMA_PQ_ZERO_SUM, plat_data->cap_mask); | ||
512 | break; | ||
513 | } | ||
514 | } | ||
515 | |||
335 | #ifdef CONFIG_MTD_PHYSMAP | 516 | #ifdef CONFIG_MTD_PHYSMAP |
336 | iq8134x_flash_resource.end = iq8134x_flash_resource.start + | 517 | iq8134x_flash_resource.end = iq8134x_flash_resource.start + |
337 | iq8134x_probe_flash_size() - 1; | 518 | iq8134x_probe_flash_size() - 1; |
@@ -399,5 +580,35 @@ static int __init iop13xx_init_i2c_setup(char *str) | |||
399 | return 1; | 580 | return 1; |
400 | } | 581 | } |
401 | 582 | ||
583 | static int __init iop13xx_init_adma_setup(char *str) | ||
584 | { | ||
585 | if (str) { | ||
586 | while (*str != '\0') { | ||
587 | switch (*str) { | ||
588 | case '0': | ||
589 | init_adma |= IOP13XX_INIT_ADMA_0; | ||
590 | break; | ||
591 | case '1': | ||
592 | init_adma |= IOP13XX_INIT_ADMA_1; | ||
593 | break; | ||
594 | case '2': | ||
595 | init_adma |= IOP13XX_INIT_ADMA_2; | ||
596 | break; | ||
597 | case ',': | ||
598 | case '=': | ||
599 | break; | ||
600 | default: | ||
601 | PRINTK("\"iop13xx_init_adma\" malformed" | ||
602 | " at character: \'%c\'", *str); | ||
603 | *(str + 1) = '\0'; | ||
604 | init_adma = IOP13XX_INIT_ADMA_DEFAULT; | ||
605 | } | ||
606 | str++; | ||
607 | } | ||
608 | } | ||
609 | return 1; | ||
610 | } | ||
611 | |||
612 | __setup("iop13xx_init_adma", iop13xx_init_adma_setup); | ||
402 | __setup("iop13xx_init_uart", iop13xx_init_uart_setup); | 613 | __setup("iop13xx_init_uart", iop13xx_init_uart_setup); |
403 | __setup("iop13xx_init_i2c", iop13xx_init_i2c_setup); | 614 | __setup("iop13xx_init_i2c", iop13xx_init_i2c_setup); |
diff --git a/include/asm-arm/arch-iop13xx/adma.h b/include/asm-arm/arch-iop13xx/adma.h new file mode 100644 index 000000000000..04006c1c5fd7 --- /dev/null +++ b/include/asm-arm/arch-iop13xx/adma.h | |||
@@ -0,0 +1,544 @@ | |||
1 | /* | ||
2 | * Copyright(c) 2006, Intel Corporation. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along with | ||
14 | * this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
16 | * | ||
17 | */ | ||
18 | #ifndef _ADMA_H | ||
19 | #define _ADMA_H | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <asm/hardware.h> | ||
23 | #include <asm/hardware/iop_adma.h> | ||
24 | |||
25 | #define ADMA_ACCR(chan) (chan->mmr_base + 0x0) | ||
26 | #define ADMA_ACSR(chan) (chan->mmr_base + 0x4) | ||
27 | #define ADMA_ADAR(chan) (chan->mmr_base + 0x8) | ||
28 | #define ADMA_IIPCR(chan) (chan->mmr_base + 0x18) | ||
29 | #define ADMA_IIPAR(chan) (chan->mmr_base + 0x1c) | ||
30 | #define ADMA_IIPUAR(chan) (chan->mmr_base + 0x20) | ||
31 | #define ADMA_ANDAR(chan) (chan->mmr_base + 0x24) | ||
32 | #define ADMA_ADCR(chan) (chan->mmr_base + 0x28) | ||
33 | #define ADMA_CARMD(chan) (chan->mmr_base + 0x2c) | ||
34 | #define ADMA_ABCR(chan) (chan->mmr_base + 0x30) | ||
35 | #define ADMA_DLADR(chan) (chan->mmr_base + 0x34) | ||
36 | #define ADMA_DUADR(chan) (chan->mmr_base + 0x38) | ||
37 | #define ADMA_SLAR(src, chan) (chan->mmr_base + (0x3c + (src << 3))) | ||
38 | #define ADMA_SUAR(src, chan) (chan->mmr_base + (0x40 + (src << 3))) | ||
39 | |||
40 | struct iop13xx_adma_src { | ||
41 | u32 src_addr; | ||
42 | union { | ||
43 | u32 upper_src_addr; | ||
44 | struct { | ||
45 | unsigned int pq_upper_src_addr:24; | ||
46 | unsigned int pq_dmlt:8; | ||
47 | }; | ||
48 | }; | ||
49 | }; | ||
50 | |||
51 | struct iop13xx_adma_desc_ctrl { | ||
52 | unsigned int int_en:1; | ||
53 | unsigned int xfer_dir:2; | ||
54 | unsigned int src_select:4; | ||
55 | unsigned int zero_result:1; | ||
56 | unsigned int block_fill_en:1; | ||
57 | unsigned int crc_gen_en:1; | ||
58 | unsigned int crc_xfer_dis:1; | ||
59 | unsigned int crc_seed_fetch_dis:1; | ||
60 | unsigned int status_write_back_en:1; | ||
61 | unsigned int endian_swap_en:1; | ||
62 | unsigned int reserved0:2; | ||
63 | unsigned int pq_update_xfer_en:1; | ||
64 | unsigned int dual_xor_en:1; | ||
65 | unsigned int pq_xfer_en:1; | ||
66 | unsigned int p_xfer_dis:1; | ||
67 | unsigned int reserved1:10; | ||
68 | unsigned int relax_order_en:1; | ||
69 | unsigned int no_snoop_en:1; | ||
70 | }; | ||
71 | |||
72 | struct iop13xx_adma_byte_count { | ||
73 | unsigned int byte_count:24; | ||
74 | unsigned int host_if:3; | ||
75 | unsigned int reserved:2; | ||
76 | unsigned int zero_result_err_q:1; | ||
77 | unsigned int zero_result_err:1; | ||
78 | unsigned int tx_complete:1; | ||
79 | }; | ||
80 | |||
81 | struct iop13xx_adma_desc_hw { | ||
82 | u32 next_desc; | ||
83 | union { | ||
84 | u32 desc_ctrl; | ||
85 | struct iop13xx_adma_desc_ctrl desc_ctrl_field; | ||
86 | }; | ||
87 | union { | ||
88 | u32 crc_addr; | ||
89 | u32 block_fill_data; | ||
90 | u32 q_dest_addr; | ||
91 | }; | ||
92 | union { | ||
93 | u32 byte_count; | ||
94 | struct iop13xx_adma_byte_count byte_count_field; | ||
95 | }; | ||
96 | union { | ||
97 | u32 dest_addr; | ||
98 | u32 p_dest_addr; | ||
99 | }; | ||
100 | union { | ||
101 | u32 upper_dest_addr; | ||
102 | u32 pq_upper_dest_addr; | ||
103 | }; | ||
104 | struct iop13xx_adma_src src[1]; | ||
105 | }; | ||
106 | |||
107 | struct iop13xx_adma_desc_dual_xor { | ||
108 | u32 next_desc; | ||
109 | u32 desc_ctrl; | ||
110 | u32 reserved; | ||
111 | u32 byte_count; | ||
112 | u32 h_dest_addr; | ||
113 | u32 h_upper_dest_addr; | ||
114 | u32 src0_addr; | ||
115 | u32 upper_src0_addr; | ||
116 | u32 src1_addr; | ||
117 | u32 upper_src1_addr; | ||
118 | u32 h_src_addr; | ||
119 | u32 h_upper_src_addr; | ||
120 | u32 d_src_addr; | ||
121 | u32 d_upper_src_addr; | ||
122 | u32 d_dest_addr; | ||
123 | u32 d_upper_dest_addr; | ||
124 | }; | ||
125 | |||
126 | struct iop13xx_adma_desc_pq_update { | ||
127 | u32 next_desc; | ||
128 | u32 desc_ctrl; | ||
129 | u32 reserved; | ||
130 | u32 byte_count; | ||
131 | u32 p_dest_addr; | ||
132 | u32 p_upper_dest_addr; | ||
133 | u32 src0_addr; | ||
134 | u32 upper_src0_addr; | ||
135 | u32 src1_addr; | ||
136 | u32 upper_src1_addr; | ||
137 | u32 p_src_addr; | ||
138 | u32 p_upper_src_addr; | ||
139 | u32 q_src_addr; | ||
140 | struct { | ||
141 | unsigned int q_upper_src_addr:24; | ||
142 | unsigned int q_dmlt:8; | ||
143 | }; | ||
144 | u32 q_dest_addr; | ||
145 | u32 q_upper_dest_addr; | ||
146 | }; | ||
147 | |||
148 | static inline int iop_adma_get_max_xor(void) | ||
149 | { | ||
150 | return 16; | ||
151 | } | ||
152 | |||
153 | static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan) | ||
154 | { | ||
155 | return __raw_readl(ADMA_ADAR(chan)); | ||
156 | } | ||
157 | |||
158 | static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan, | ||
159 | u32 next_desc_addr) | ||
160 | { | ||
161 | __raw_writel(next_desc_addr, ADMA_ANDAR(chan)); | ||
162 | } | ||
163 | |||
164 | #define ADMA_STATUS_BUSY (1 << 13) | ||
165 | |||
166 | static inline char iop_chan_is_busy(struct iop_adma_chan *chan) | ||
167 | { | ||
168 | if (__raw_readl(ADMA_ACSR(chan)) & | ||
169 | ADMA_STATUS_BUSY) | ||
170 | return 1; | ||
171 | else | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static inline int | ||
176 | iop_chan_get_desc_align(struct iop_adma_chan *chan, int num_slots) | ||
177 | { | ||
178 | return 1; | ||
179 | } | ||
180 | #define iop_desc_is_aligned(x, y) 1 | ||
181 | |||
182 | static inline int | ||
183 | iop_chan_memcpy_slot_count(size_t len, int *slots_per_op) | ||
184 | { | ||
185 | *slots_per_op = 1; | ||
186 | return 1; | ||
187 | } | ||
188 | |||
189 | #define iop_chan_interrupt_slot_count(s, c) iop_chan_memcpy_slot_count(0, s) | ||
190 | |||
191 | static inline int | ||
192 | iop_chan_memset_slot_count(size_t len, int *slots_per_op) | ||
193 | { | ||
194 | *slots_per_op = 1; | ||
195 | return 1; | ||
196 | } | ||
197 | |||
198 | static inline int | ||
199 | iop_chan_xor_slot_count(size_t len, int src_cnt, int *slots_per_op) | ||
200 | { | ||
201 | int num_slots; | ||
202 | /* slots_to_find = 1 for basic descriptor + 1 per 4 sources above 1 | ||
203 | * (1 source => 8 bytes) (1 slot => 32 bytes) | ||
204 | */ | ||
205 | num_slots = 1 + (((src_cnt - 1) << 3) >> 5); | ||
206 | if (((src_cnt - 1) << 3) & 0x1f) | ||
207 | num_slots++; | ||
208 | |||
209 | *slots_per_op = num_slots; | ||
210 | |||
211 | return num_slots; | ||
212 | } | ||
213 | |||
214 | #define ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024) | ||
215 | #define IOP_ADMA_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT | ||
216 | #define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT | ||
217 | #define IOP_ADMA_XOR_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT | ||
218 | #define iop_chan_zero_sum_slot_count(l, s, o) iop_chan_xor_slot_count(l, s, o) | ||
219 | |||
220 | static inline u32 iop_desc_get_dest_addr(struct iop_adma_desc_slot *desc, | ||
221 | struct iop_adma_chan *chan) | ||
222 | { | ||
223 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
224 | return hw_desc->dest_addr; | ||
225 | } | ||
226 | |||
227 | static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc, | ||
228 | struct iop_adma_chan *chan) | ||
229 | { | ||
230 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
231 | return hw_desc->byte_count_field.byte_count; | ||
232 | } | ||
233 | |||
234 | static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc, | ||
235 | struct iop_adma_chan *chan, | ||
236 | int src_idx) | ||
237 | { | ||
238 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
239 | return hw_desc->src[src_idx].src_addr; | ||
240 | } | ||
241 | |||
242 | static inline u32 iop_desc_get_src_count(struct iop_adma_desc_slot *desc, | ||
243 | struct iop_adma_chan *chan) | ||
244 | { | ||
245 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
246 | return hw_desc->desc_ctrl_field.src_select + 1; | ||
247 | } | ||
248 | |||
249 | static inline void | ||
250 | iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, int int_en) | ||
251 | { | ||
252 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
253 | union { | ||
254 | u32 value; | ||
255 | struct iop13xx_adma_desc_ctrl field; | ||
256 | } u_desc_ctrl; | ||
257 | |||
258 | u_desc_ctrl.value = 0; | ||
259 | u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ | ||
260 | u_desc_ctrl.field.int_en = int_en; | ||
261 | hw_desc->desc_ctrl = u_desc_ctrl.value; | ||
262 | hw_desc->crc_addr = 0; | ||
263 | } | ||
264 | |||
265 | static inline void | ||
266 | iop_desc_init_memset(struct iop_adma_desc_slot *desc, int int_en) | ||
267 | { | ||
268 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
269 | union { | ||
270 | u32 value; | ||
271 | struct iop13xx_adma_desc_ctrl field; | ||
272 | } u_desc_ctrl; | ||
273 | |||
274 | u_desc_ctrl.value = 0; | ||
275 | u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ | ||
276 | u_desc_ctrl.field.block_fill_en = 1; | ||
277 | u_desc_ctrl.field.int_en = int_en; | ||
278 | hw_desc->desc_ctrl = u_desc_ctrl.value; | ||
279 | hw_desc->crc_addr = 0; | ||
280 | } | ||
281 | |||
282 | /* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */ | ||
283 | static inline void | ||
284 | iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt, int int_en) | ||
285 | { | ||
286 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
287 | union { | ||
288 | u32 value; | ||
289 | struct iop13xx_adma_desc_ctrl field; | ||
290 | } u_desc_ctrl; | ||
291 | |||
292 | u_desc_ctrl.value = 0; | ||
293 | u_desc_ctrl.field.src_select = src_cnt - 1; | ||
294 | u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ | ||
295 | u_desc_ctrl.field.int_en = int_en; | ||
296 | hw_desc->desc_ctrl = u_desc_ctrl.value; | ||
297 | hw_desc->crc_addr = 0; | ||
298 | |||
299 | } | ||
300 | #define iop_desc_init_null_xor(d, s, i) iop_desc_init_xor(d, s, i) | ||
301 | |||
302 | /* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */ | ||
303 | static inline int | ||
304 | iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt, int int_en) | ||
305 | { | ||
306 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
307 | union { | ||
308 | u32 value; | ||
309 | struct iop13xx_adma_desc_ctrl field; | ||
310 | } u_desc_ctrl; | ||
311 | |||
312 | u_desc_ctrl.value = 0; | ||
313 | u_desc_ctrl.field.src_select = src_cnt - 1; | ||
314 | u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */ | ||
315 | u_desc_ctrl.field.zero_result = 1; | ||
316 | u_desc_ctrl.field.status_write_back_en = 1; | ||
317 | u_desc_ctrl.field.int_en = int_en; | ||
318 | hw_desc->desc_ctrl = u_desc_ctrl.value; | ||
319 | hw_desc->crc_addr = 0; | ||
320 | |||
321 | return 1; | ||
322 | } | ||
323 | |||
324 | static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc, | ||
325 | struct iop_adma_chan *chan, | ||
326 | u32 byte_count) | ||
327 | { | ||
328 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
329 | hw_desc->byte_count = byte_count; | ||
330 | } | ||
331 | |||
332 | static inline void | ||
333 | iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len) | ||
334 | { | ||
335 | int slots_per_op = desc->slots_per_op; | ||
336 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter; | ||
337 | int i = 0; | ||
338 | |||
339 | if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) { | ||
340 | hw_desc->byte_count = len; | ||
341 | } else { | ||
342 | do { | ||
343 | iter = iop_hw_desc_slot_idx(hw_desc, i); | ||
344 | iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; | ||
345 | len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; | ||
346 | i += slots_per_op; | ||
347 | } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT); | ||
348 | |||
349 | if (len) { | ||
350 | iter = iop_hw_desc_slot_idx(hw_desc, i); | ||
351 | iter->byte_count = len; | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | |||
356 | |||
357 | static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc, | ||
358 | struct iop_adma_chan *chan, | ||
359 | dma_addr_t addr) | ||
360 | { | ||
361 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
362 | hw_desc->dest_addr = addr; | ||
363 | hw_desc->upper_dest_addr = 0; | ||
364 | } | ||
365 | |||
366 | static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc, | ||
367 | dma_addr_t addr) | ||
368 | { | ||
369 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
370 | hw_desc->src[0].src_addr = addr; | ||
371 | hw_desc->src[0].upper_src_addr = 0; | ||
372 | } | ||
373 | |||
374 | static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc, | ||
375 | int src_idx, dma_addr_t addr) | ||
376 | { | ||
377 | int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op; | ||
378 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter; | ||
379 | int i = 0; | ||
380 | |||
381 | do { | ||
382 | iter = iop_hw_desc_slot_idx(hw_desc, i); | ||
383 | iter->src[src_idx].src_addr = addr; | ||
384 | iter->src[src_idx].upper_src_addr = 0; | ||
385 | slot_cnt -= slots_per_op; | ||
386 | if (slot_cnt) { | ||
387 | i += slots_per_op; | ||
388 | addr += IOP_ADMA_XOR_MAX_BYTE_COUNT; | ||
389 | } | ||
390 | } while (slot_cnt); | ||
391 | } | ||
392 | |||
393 | static inline void | ||
394 | iop_desc_init_interrupt(struct iop_adma_desc_slot *desc, | ||
395 | struct iop_adma_chan *chan) | ||
396 | { | ||
397 | iop_desc_init_memcpy(desc, 1); | ||
398 | iop_desc_set_byte_count(desc, chan, 0); | ||
399 | iop_desc_set_dest_addr(desc, chan, 0); | ||
400 | iop_desc_set_memcpy_src_addr(desc, 0); | ||
401 | } | ||
402 | |||
403 | #define iop_desc_set_zero_sum_src_addr iop_desc_set_xor_src_addr | ||
404 | |||
405 | static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc, | ||
406 | u32 next_desc_addr) | ||
407 | { | ||
408 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
409 | BUG_ON(hw_desc->next_desc); | ||
410 | hw_desc->next_desc = next_desc_addr; | ||
411 | } | ||
412 | |||
413 | static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc) | ||
414 | { | ||
415 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
416 | return hw_desc->next_desc; | ||
417 | } | ||
418 | |||
419 | static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc) | ||
420 | { | ||
421 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
422 | hw_desc->next_desc = 0; | ||
423 | } | ||
424 | |||
425 | static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc, | ||
426 | u32 val) | ||
427 | { | ||
428 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
429 | hw_desc->block_fill_data = val; | ||
430 | } | ||
431 | |||
432 | static inline int iop_desc_get_zero_result(struct iop_adma_desc_slot *desc) | ||
433 | { | ||
434 | struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; | ||
435 | struct iop13xx_adma_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field; | ||
436 | struct iop13xx_adma_byte_count byte_count = hw_desc->byte_count_field; | ||
437 | |||
438 | BUG_ON(!(byte_count.tx_complete && desc_ctrl.zero_result)); | ||
439 | |||
440 | if (desc_ctrl.pq_xfer_en) | ||
441 | return byte_count.zero_result_err_q; | ||
442 | else | ||
443 | return byte_count.zero_result_err; | ||
444 | } | ||
445 | |||
446 | static inline void iop_chan_append(struct iop_adma_chan *chan) | ||
447 | { | ||
448 | u32 adma_accr; | ||
449 | |||
450 | adma_accr = __raw_readl(ADMA_ACCR(chan)); | ||
451 | adma_accr |= 0x2; | ||
452 | __raw_writel(adma_accr, ADMA_ACCR(chan)); | ||
453 | } | ||
454 | |||
455 | static inline void iop_chan_idle(int busy, struct iop_adma_chan *chan) | ||
456 | { | ||
457 | do { } while (0); | ||
458 | } | ||
459 | |||
460 | static inline u32 iop_chan_get_status(struct iop_adma_chan *chan) | ||
461 | { | ||
462 | return __raw_readl(ADMA_ACSR(chan)); | ||
463 | } | ||
464 | |||
465 | static inline void iop_chan_disable(struct iop_adma_chan *chan) | ||
466 | { | ||
467 | u32 adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan)); | ||
468 | adma_chan_ctrl &= ~0x1; | ||
469 | __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan)); | ||
470 | } | ||
471 | |||
472 | static inline void iop_chan_enable(struct iop_adma_chan *chan) | ||
473 | { | ||
474 | u32 adma_chan_ctrl; | ||
475 | |||
476 | adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan)); | ||
477 | adma_chan_ctrl |= 0x1; | ||
478 | __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan)); | ||
479 | } | ||
480 | |||
481 | static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan) | ||
482 | { | ||
483 | u32 status = __raw_readl(ADMA_ACSR(chan)); | ||
484 | status &= (1 << 12); | ||
485 | __raw_writel(status, ADMA_ACSR(chan)); | ||
486 | } | ||
487 | |||
488 | static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan) | ||
489 | { | ||
490 | u32 status = __raw_readl(ADMA_ACSR(chan)); | ||
491 | status &= (1 << 11); | ||
492 | __raw_writel(status, ADMA_ACSR(chan)); | ||
493 | } | ||
494 | |||
495 | static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan) | ||
496 | { | ||
497 | u32 status = __raw_readl(ADMA_ACSR(chan)); | ||
498 | status &= (1 << 9) | (1 << 5) | (1 << 4) | (1 << 3); | ||
499 | __raw_writel(status, ADMA_ACSR(chan)); | ||
500 | } | ||
501 | |||
502 | static inline int | ||
503 | iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan) | ||
504 | { | ||
505 | return test_bit(9, &status); | ||
506 | } | ||
507 | |||
508 | static inline int | ||
509 | iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan) | ||
510 | { | ||
511 | return test_bit(5, &status); | ||
512 | } | ||
513 | |||
514 | static inline int | ||
515 | iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan) | ||
516 | { | ||
517 | return test_bit(4, &status); | ||
518 | } | ||
519 | |||
520 | static inline int | ||
521 | iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan) | ||
522 | { | ||
523 | return test_bit(3, &status); | ||
524 | } | ||
525 | |||
526 | static inline int | ||
527 | iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan) | ||
528 | { | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static inline int | ||
533 | iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan) | ||
534 | { | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static inline int | ||
539 | iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan) | ||
540 | { | ||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | #endif /* _ADMA_H */ | ||
diff --git a/include/asm-arm/arch-iop13xx/iop13xx.h b/include/asm-arm/arch-iop13xx/iop13xx.h index e6736c3d1f7f..d4e4f828577c 100644 --- a/include/asm-arm/arch-iop13xx/iop13xx.h +++ b/include/asm-arm/arch-iop13xx/iop13xx.h | |||
@@ -166,12 +166,22 @@ static inline int iop13xx_cpu_id(void) | |||
166 | #define IOP13XX_INIT_I2C_1 (1 << 1) | 166 | #define IOP13XX_INIT_I2C_1 (1 << 1) |
167 | #define IOP13XX_INIT_I2C_2 (1 << 2) | 167 | #define IOP13XX_INIT_I2C_2 (1 << 2) |
168 | 168 | ||
169 | #define IQ81340_NUM_UART 2 | 169 | /* ADMA selection flags */ |
170 | #define IQ81340_NUM_I2C 3 | 170 | /* INIT_ADMA_DEFAULT = Rely on CONFIG_IOP13XX_ADMA* */ |
171 | #define IQ81340_NUM_PHYS_MAP_FLASH 1 | 171 | #define IOP13XX_INIT_ADMA_DEFAULT (0) |
172 | #define IQ81340_MAX_PLAT_DEVICES (IQ81340_NUM_UART +\ | 172 | #define IOP13XX_INIT_ADMA_0 (1 << 0) |
173 | IQ81340_NUM_I2C +\ | 173 | #define IOP13XX_INIT_ADMA_1 (1 << 1) |
174 | IQ81340_NUM_PHYS_MAP_FLASH) | 174 | #define IOP13XX_INIT_ADMA_2 (1 << 2) |
175 | |||
176 | /* Platform devices */ | ||
177 | #define IQ81340_NUM_UART 2 | ||
178 | #define IQ81340_NUM_I2C 3 | ||
179 | #define IQ81340_NUM_PHYS_MAP_FLASH 1 | ||
180 | #define IQ81340_NUM_ADMA 3 | ||
181 | #define IQ81340_MAX_PLAT_DEVICES (IQ81340_NUM_UART + \ | ||
182 | IQ81340_NUM_I2C + \ | ||
183 | IQ81340_NUM_PHYS_MAP_FLASH + \ | ||
184 | IQ81340_NUM_ADMA) | ||
175 | 185 | ||
176 | /*========================== PMMR offsets for key registers ============*/ | 186 | /*========================== PMMR offsets for key registers ============*/ |
177 | #define IOP13XX_ATU0_PMMR_OFFSET 0x00048000 | 187 | #define IOP13XX_ATU0_PMMR_OFFSET 0x00048000 |
@@ -444,22 +454,6 @@ static inline int iop13xx_cpu_id(void) | |||
444 | /*==============================ADMA UNITS===============================*/ | 454 | /*==============================ADMA UNITS===============================*/ |
445 | #define IOP13XX_ADMA_PHYS_BASE(chan) IOP13XX_REG_ADDR32_PHYS((chan << 9)) | 455 | #define IOP13XX_ADMA_PHYS_BASE(chan) IOP13XX_REG_ADDR32_PHYS((chan << 9)) |
446 | #define IOP13XX_ADMA_UPPER_PA(chan) (IOP13XX_ADMA_PHYS_BASE(chan) + 0xc0) | 456 | #define IOP13XX_ADMA_UPPER_PA(chan) (IOP13XX_ADMA_PHYS_BASE(chan) + 0xc0) |
447 | #define IOP13XX_ADMA_OFFSET(chan, ofs) IOP13XX_REG_ADDR32((chan << 9) + (ofs)) | ||
448 | |||
449 | #define IOP13XX_ADMA_ACCR(chan) IOP13XX_ADMA_OFFSET(chan, 0x0) | ||
450 | #define IOP13XX_ADMA_ACSR(chan) IOP13XX_ADMA_OFFSET(chan, 0x4) | ||
451 | #define IOP13XX_ADMA_ADAR(chan) IOP13XX_ADMA_OFFSET(chan, 0x8) | ||
452 | #define IOP13XX_ADMA_IIPCR(chan) IOP13XX_ADMA_OFFSET(chan, 0x18) | ||
453 | #define IOP13XX_ADMA_IIPAR(chan) IOP13XX_ADMA_OFFSET(chan, 0x1c) | ||
454 | #define IOP13XX_ADMA_IIPUAR(chan) IOP13XX_ADMA_OFFSET(chan, 0x20) | ||
455 | #define IOP13XX_ADMA_ANDAR(chan) IOP13XX_ADMA_OFFSET(chan, 0x24) | ||
456 | #define IOP13XX_ADMA_ADCR(chan) IOP13XX_ADMA_OFFSET(chan, 0x28) | ||
457 | #define IOP13XX_ADMA_CARMD(chan) IOP13XX_ADMA_OFFSET(chan, 0x2c) | ||
458 | #define IOP13XX_ADMA_ABCR(chan) IOP13XX_ADMA_OFFSET(chan, 0x30) | ||
459 | #define IOP13XX_ADMA_DLADR(chan) IOP13XX_ADMA_OFFSET(chan, 0x34) | ||
460 | #define IOP13XX_ADMA_DUADR(chan) IOP13XX_ADMA_OFFSET(chan, 0x38) | ||
461 | #define IOP13XX_ADMA_SLAR(src, chan) IOP13XX_ADMA_OFFSET(chan, 0x3c + (src <<3)) | ||
462 | #define IOP13XX_ADMA_SUAR(src, chan) IOP13XX_ADMA_OFFSET(chan, 0x40 + (src <<3)) | ||
463 | 457 | ||
464 | /*==============================XSI BRIDGE===============================*/ | 458 | /*==============================XSI BRIDGE===============================*/ |
465 | #define IOP13XX_XBG_BECSR IOP13XX_REG_ADDR32(0x178c) | 459 | #define IOP13XX_XBG_BECSR IOP13XX_REG_ADDR32(0x178c) |