diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-07 14:11:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-07 14:11:43 -0400 |
commit | d2b4a646717153a1a180b64d4a8464054dbd700e (patch) | |
tree | a019907da37389f59ddb429c7d10de178514af1e /arch | |
parent | 8dce5f3dee21bf976193ddb06426b9727cf5d1a2 (diff) | |
parent | 67eacc1583909d0588c8d5d80c16298c899a6382 (diff) |
Merge branch 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma
Pull slave-dmaengine updates from Vinod Koul:
"Once you have some time from extended weekend celebrations please
consider pulling the following to get:
- Various fixes and PCI driver for dw_dmac by Andy
- DT binding for imx-dma by Markus & imx-sdma by Shawn
- DT fixes for dmaengine by Lars
- jz4740 dmac driver by Lars
- and various fixes across the drivers"
What "extended weekend celebrations"? I'm in the merge window, who has
time for extended celebrations..
* 'for-linus' of git://git.infradead.org/users/vkoul/slave-dma: (40 commits)
DMA: shdma: add DT support
DMA: shdma: shdma_chan_filter() has to be in shdma-base.h
DMA: shdma: (cosmetic) don't re-calculate a pointer
dmaengine: at_hdmac: prepare clk before calling enable
dmaengine/trivial: at_hdmac: add curly brackets to if/else expressions
dmaengine: at_hdmac: remove unsuded atc_cleanup_descriptors()
dmaengine: at_hdmac: add FIFO configuration parameter to DMA DT binding
ARM: at91: dt: add header to define at_hdmac configuration
MIPS: jz4740: Correct clock gate bit for DMA controller
MIPS: jz4740: Remove custom DMA API
MIPS: jz4740: Register jz4740 DMA device
dma: Add a jz4740 dmaengine driver
MIPS: jz4740: Acquire and enable DMA controller clock
dma: mmp_tdma: disable irq when disabling dma channel
dmaengine: PL08x: Avoid collisions with get_signal() macro
dmaengine: dw: select DW_DMAC_BIG_ENDIAN_IO automagically
dma: dw: add PCI part of the driver
dma: dw: split driver to library part and platform code
dma: move dw_dmac driver to an own directory
dw_dmac: don't check resource with devm_ioremap_resource
...
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-lpc32xx/phy3250.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-spear/spear3xx.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-spear/spear6xx.c | 4 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-jz4740/dma.h | 56 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-jz4740/platform.h | 1 | ||||
-rw-r--r-- | arch/mips/jz4740/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/jz4740/board-qi_lb60.c | 1 | ||||
-rw-r--r-- | arch/mips/jz4740/clock.c | 2 | ||||
-rw-r--r-- | arch/mips/jz4740/dma.c | 287 | ||||
-rw-r--r-- | arch/mips/jz4740/platform.c | 21 |
10 files changed, 31 insertions, 351 deletions
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index c1cd5a943ab1..e54f87ec2e4a 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c | |||
@@ -182,8 +182,8 @@ static void pl08x_put_signal(const struct pl08x_channel_data *cd, int ch) | |||
182 | static struct pl08x_platform_data pl08x_pd = { | 182 | static struct pl08x_platform_data pl08x_pd = { |
183 | .slave_channels = &pl08x_slave_channels[0], | 183 | .slave_channels = &pl08x_slave_channels[0], |
184 | .num_slave_channels = ARRAY_SIZE(pl08x_slave_channels), | 184 | .num_slave_channels = ARRAY_SIZE(pl08x_slave_channels), |
185 | .get_signal = pl08x_get_signal, | 185 | .get_xfer_signal = pl08x_get_signal, |
186 | .put_signal = pl08x_put_signal, | 186 | .put_xfer_signal = pl08x_put_signal, |
187 | .lli_buses = PL08X_AHB1, | 187 | .lli_buses = PL08X_AHB1, |
188 | .mem_buses = PL08X_AHB1, | 188 | .mem_buses = PL08X_AHB1, |
189 | }; | 189 | }; |
diff --git a/arch/arm/mach-spear/spear3xx.c b/arch/arm/mach-spear/spear3xx.c index 0227c97797cd..bf3b1fd8cb23 100644 --- a/arch/arm/mach-spear/spear3xx.c +++ b/arch/arm/mach-spear/spear3xx.c | |||
@@ -56,8 +56,8 @@ struct pl08x_platform_data pl080_plat_data = { | |||
56 | }, | 56 | }, |
57 | .lli_buses = PL08X_AHB1, | 57 | .lli_buses = PL08X_AHB1, |
58 | .mem_buses = PL08X_AHB1, | 58 | .mem_buses = PL08X_AHB1, |
59 | .get_signal = pl080_get_signal, | 59 | .get_xfer_signal = pl080_get_signal, |
60 | .put_signal = pl080_put_signal, | 60 | .put_xfer_signal = pl080_put_signal, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* | 63 | /* |
diff --git a/arch/arm/mach-spear/spear6xx.c b/arch/arm/mach-spear/spear6xx.c index 8b0295a41226..da26fa5b68d7 100644 --- a/arch/arm/mach-spear/spear6xx.c +++ b/arch/arm/mach-spear/spear6xx.c | |||
@@ -334,8 +334,8 @@ static struct pl08x_platform_data spear6xx_pl080_plat_data = { | |||
334 | }, | 334 | }, |
335 | .lli_buses = PL08X_AHB1, | 335 | .lli_buses = PL08X_AHB1, |
336 | .mem_buses = PL08X_AHB1, | 336 | .mem_buses = PL08X_AHB1, |
337 | .get_signal = pl080_get_signal, | 337 | .get_xfer_signal = pl080_get_signal, |
338 | .put_signal = pl080_put_signal, | 338 | .put_xfer_signal = pl080_put_signal, |
339 | .slave_channels = spear600_dma_info, | 339 | .slave_channels = spear600_dma_info, |
340 | .num_slave_channels = ARRAY_SIZE(spear600_dma_info), | 340 | .num_slave_channels = ARRAY_SIZE(spear600_dma_info), |
341 | }; | 341 | }; |
diff --git a/arch/mips/include/asm/mach-jz4740/dma.h b/arch/mips/include/asm/mach-jz4740/dma.h index 98b4e7c0dbae..509cd5828044 100644 --- a/arch/mips/include/asm/mach-jz4740/dma.h +++ b/arch/mips/include/asm/mach-jz4740/dma.h | |||
@@ -16,8 +16,6 @@ | |||
16 | #ifndef __ASM_MACH_JZ4740_DMA_H__ | 16 | #ifndef __ASM_MACH_JZ4740_DMA_H__ |
17 | #define __ASM_MACH_JZ4740_DMA_H__ | 17 | #define __ASM_MACH_JZ4740_DMA_H__ |
18 | 18 | ||
19 | struct jz4740_dma_chan; | ||
20 | |||
21 | enum jz4740_dma_request_type { | 19 | enum jz4740_dma_request_type { |
22 | JZ4740_DMA_TYPE_AUTO_REQUEST = 8, | 20 | JZ4740_DMA_TYPE_AUTO_REQUEST = 8, |
23 | JZ4740_DMA_TYPE_UART_TRANSMIT = 20, | 21 | JZ4740_DMA_TYPE_UART_TRANSMIT = 20, |
@@ -33,58 +31,4 @@ enum jz4740_dma_request_type { | |||
33 | JZ4740_DMA_TYPE_SLCD = 30, | 31 | JZ4740_DMA_TYPE_SLCD = 30, |
34 | }; | 32 | }; |
35 | 33 | ||
36 | enum jz4740_dma_width { | ||
37 | JZ4740_DMA_WIDTH_32BIT = 0, | ||
38 | JZ4740_DMA_WIDTH_8BIT = 1, | ||
39 | JZ4740_DMA_WIDTH_16BIT = 2, | ||
40 | }; | ||
41 | |||
42 | enum jz4740_dma_transfer_size { | ||
43 | JZ4740_DMA_TRANSFER_SIZE_4BYTE = 0, | ||
44 | JZ4740_DMA_TRANSFER_SIZE_1BYTE = 1, | ||
45 | JZ4740_DMA_TRANSFER_SIZE_2BYTE = 2, | ||
46 | JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3, | ||
47 | JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4, | ||
48 | }; | ||
49 | |||
50 | enum jz4740_dma_flags { | ||
51 | JZ4740_DMA_SRC_AUTOINC = 0x2, | ||
52 | JZ4740_DMA_DST_AUTOINC = 0x1, | ||
53 | }; | ||
54 | |||
55 | enum jz4740_dma_mode { | ||
56 | JZ4740_DMA_MODE_SINGLE = 0, | ||
57 | JZ4740_DMA_MODE_BLOCK = 1, | ||
58 | }; | ||
59 | |||
60 | struct jz4740_dma_config { | ||
61 | enum jz4740_dma_width src_width; | ||
62 | enum jz4740_dma_width dst_width; | ||
63 | enum jz4740_dma_transfer_size transfer_size; | ||
64 | enum jz4740_dma_request_type request_type; | ||
65 | enum jz4740_dma_flags flags; | ||
66 | enum jz4740_dma_mode mode; | ||
67 | }; | ||
68 | |||
69 | typedef void (*jz4740_dma_complete_callback_t)(struct jz4740_dma_chan *, int, void *); | ||
70 | |||
71 | struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name); | ||
72 | void jz4740_dma_free(struct jz4740_dma_chan *dma); | ||
73 | |||
74 | void jz4740_dma_configure(struct jz4740_dma_chan *dma, | ||
75 | const struct jz4740_dma_config *config); | ||
76 | |||
77 | |||
78 | void jz4740_dma_enable(struct jz4740_dma_chan *dma); | ||
79 | void jz4740_dma_disable(struct jz4740_dma_chan *dma); | ||
80 | |||
81 | void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src); | ||
82 | void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst); | ||
83 | void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count); | ||
84 | |||
85 | uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma); | ||
86 | |||
87 | void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma, | ||
88 | jz4740_dma_complete_callback_t cb); | ||
89 | |||
90 | #endif /* __ASM_JZ4740_DMA_H__ */ | 34 | #endif /* __ASM_JZ4740_DMA_H__ */ |
diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h index 72cfebdb5a47..05988c2d6565 100644 --- a/arch/mips/include/asm/mach-jz4740/platform.h +++ b/arch/mips/include/asm/mach-jz4740/platform.h | |||
@@ -32,6 +32,7 @@ extern struct platform_device jz4740_codec_device; | |||
32 | extern struct platform_device jz4740_adc_device; | 32 | extern struct platform_device jz4740_adc_device; |
33 | extern struct platform_device jz4740_wdt_device; | 33 | extern struct platform_device jz4740_wdt_device; |
34 | extern struct platform_device jz4740_pwm_device; | 34 | extern struct platform_device jz4740_pwm_device; |
35 | extern struct platform_device jz4740_dma_device; | ||
35 | 36 | ||
36 | void jz4740_serial_device_register(void); | 37 | void jz4740_serial_device_register(void); |
37 | 38 | ||
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile index 63bad0e491d0..28e5535dfa9e 100644 --- a/arch/mips/jz4740/Makefile +++ b/arch/mips/jz4740/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | # Object file lists. | 5 | # Object file lists. |
6 | 6 | ||
7 | obj-y += prom.o irq.o time.o reset.o setup.o dma.o \ | 7 | obj-y += prom.o irq.o time.o reset.o setup.o \ |
8 | gpio.o clock.o platform.o timer.o serial.o | 8 | gpio.o clock.o platform.o timer.o serial.o |
9 | 9 | ||
10 | obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o | 10 | obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o |
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index be2b3deeef1d..8a5ec0eedeb0 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
@@ -438,6 +438,7 @@ static struct platform_device *jz_platform_devices[] __initdata = { | |||
438 | &jz4740_rtc_device, | 438 | &jz4740_rtc_device, |
439 | &jz4740_adc_device, | 439 | &jz4740_adc_device, |
440 | &jz4740_pwm_device, | 440 | &jz4740_pwm_device, |
441 | &jz4740_dma_device, | ||
441 | &qi_lb60_gpio_keys, | 442 | &qi_lb60_gpio_keys, |
442 | &qi_lb60_pwm_beeper, | 443 | &qi_lb60_pwm_beeper, |
443 | &qi_lb60_charger_device, | 444 | &qi_lb60_charger_device, |
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c index 484d38a0864f..1b5f55426cad 100644 --- a/arch/mips/jz4740/clock.c +++ b/arch/mips/jz4740/clock.c | |||
@@ -687,7 +687,7 @@ static struct clk jz4740_clock_simple_clks[] = { | |||
687 | [3] = { | 687 | [3] = { |
688 | .name = "dma", | 688 | .name = "dma", |
689 | .parent = &jz_clk_high_speed_peripheral.clk, | 689 | .parent = &jz_clk_high_speed_peripheral.clk, |
690 | .gate_bit = JZ_CLOCK_GATE_UART0, | 690 | .gate_bit = JZ_CLOCK_GATE_DMAC, |
691 | .ops = &jz_clk_simple_ops, | 691 | .ops = &jz_clk_simple_ops, |
692 | }, | 692 | }, |
693 | [4] = { | 693 | [4] = { |
diff --git a/arch/mips/jz4740/dma.c b/arch/mips/jz4740/dma.c deleted file mode 100644 index 317ec6fffb12..000000000000 --- a/arch/mips/jz4740/dma.c +++ /dev/null | |||
@@ -1,287 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> | ||
3 | * JZ4740 SoC DMA support | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * You should have received a copy of the GNU General Public License along | ||
11 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
12 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | |||
21 | #include <linux/dma-mapping.h> | ||
22 | #include <asm/mach-jz4740/dma.h> | ||
23 | #include <asm/mach-jz4740/base.h> | ||
24 | |||
25 | #define JZ_REG_DMA_SRC_ADDR(x) (0x00 + (x) * 0x20) | ||
26 | #define JZ_REG_DMA_DST_ADDR(x) (0x04 + (x) * 0x20) | ||
27 | #define JZ_REG_DMA_TRANSFER_COUNT(x) (0x08 + (x) * 0x20) | ||
28 | #define JZ_REG_DMA_REQ_TYPE(x) (0x0C + (x) * 0x20) | ||
29 | #define JZ_REG_DMA_STATUS_CTRL(x) (0x10 + (x) * 0x20) | ||
30 | #define JZ_REG_DMA_CMD(x) (0x14 + (x) * 0x20) | ||
31 | #define JZ_REG_DMA_DESC_ADDR(x) (0x18 + (x) * 0x20) | ||
32 | |||
33 | #define JZ_REG_DMA_CTRL 0x300 | ||
34 | #define JZ_REG_DMA_IRQ 0x304 | ||
35 | #define JZ_REG_DMA_DOORBELL 0x308 | ||
36 | #define JZ_REG_DMA_DOORBELL_SET 0x30C | ||
37 | |||
38 | #define JZ_DMA_STATUS_CTRL_NO_DESC BIT(31) | ||
39 | #define JZ_DMA_STATUS_CTRL_DESC_INV BIT(6) | ||
40 | #define JZ_DMA_STATUS_CTRL_ADDR_ERR BIT(4) | ||
41 | #define JZ_DMA_STATUS_CTRL_TRANSFER_DONE BIT(3) | ||
42 | #define JZ_DMA_STATUS_CTRL_HALT BIT(2) | ||
43 | #define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE BIT(1) | ||
44 | #define JZ_DMA_STATUS_CTRL_ENABLE BIT(0) | ||
45 | |||
46 | #define JZ_DMA_CMD_SRC_INC BIT(23) | ||
47 | #define JZ_DMA_CMD_DST_INC BIT(22) | ||
48 | #define JZ_DMA_CMD_RDIL_MASK (0xf << 16) | ||
49 | #define JZ_DMA_CMD_SRC_WIDTH_MASK (0x3 << 14) | ||
50 | #define JZ_DMA_CMD_DST_WIDTH_MASK (0x3 << 12) | ||
51 | #define JZ_DMA_CMD_INTERVAL_LENGTH_MASK (0x7 << 8) | ||
52 | #define JZ_DMA_CMD_BLOCK_MODE BIT(7) | ||
53 | #define JZ_DMA_CMD_DESC_VALID BIT(4) | ||
54 | #define JZ_DMA_CMD_DESC_VALID_MODE BIT(3) | ||
55 | #define JZ_DMA_CMD_VALID_IRQ_ENABLE BIT(2) | ||
56 | #define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE BIT(1) | ||
57 | #define JZ_DMA_CMD_LINK_ENABLE BIT(0) | ||
58 | |||
59 | #define JZ_DMA_CMD_FLAGS_OFFSET 22 | ||
60 | #define JZ_DMA_CMD_RDIL_OFFSET 16 | ||
61 | #define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14 | ||
62 | #define JZ_DMA_CMD_DST_WIDTH_OFFSET 12 | ||
63 | #define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8 | ||
64 | #define JZ_DMA_CMD_MODE_OFFSET 7 | ||
65 | |||
66 | #define JZ_DMA_CTRL_PRIORITY_MASK (0x3 << 8) | ||
67 | #define JZ_DMA_CTRL_HALT BIT(3) | ||
68 | #define JZ_DMA_CTRL_ADDRESS_ERROR BIT(2) | ||
69 | #define JZ_DMA_CTRL_ENABLE BIT(0) | ||
70 | |||
71 | |||
72 | static void __iomem *jz4740_dma_base; | ||
73 | static spinlock_t jz4740_dma_lock; | ||
74 | |||
75 | static inline uint32_t jz4740_dma_read(size_t reg) | ||
76 | { | ||
77 | return readl(jz4740_dma_base + reg); | ||
78 | } | ||
79 | |||
80 | static inline void jz4740_dma_write(size_t reg, uint32_t val) | ||
81 | { | ||
82 | writel(val, jz4740_dma_base + reg); | ||
83 | } | ||
84 | |||
85 | static inline void jz4740_dma_write_mask(size_t reg, uint32_t val, uint32_t mask) | ||
86 | { | ||
87 | uint32_t val2; | ||
88 | val2 = jz4740_dma_read(reg); | ||
89 | val2 &= ~mask; | ||
90 | val2 |= val; | ||
91 | jz4740_dma_write(reg, val2); | ||
92 | } | ||
93 | |||
94 | struct jz4740_dma_chan { | ||
95 | unsigned int id; | ||
96 | void *dev; | ||
97 | const char *name; | ||
98 | |||
99 | enum jz4740_dma_flags flags; | ||
100 | uint32_t transfer_shift; | ||
101 | |||
102 | jz4740_dma_complete_callback_t complete_cb; | ||
103 | |||
104 | unsigned used:1; | ||
105 | }; | ||
106 | |||
107 | #define JZ4740_DMA_CHANNEL(_id) { .id = _id } | ||
108 | |||
109 | struct jz4740_dma_chan jz4740_dma_channels[] = { | ||
110 | JZ4740_DMA_CHANNEL(0), | ||
111 | JZ4740_DMA_CHANNEL(1), | ||
112 | JZ4740_DMA_CHANNEL(2), | ||
113 | JZ4740_DMA_CHANNEL(3), | ||
114 | JZ4740_DMA_CHANNEL(4), | ||
115 | JZ4740_DMA_CHANNEL(5), | ||
116 | }; | ||
117 | |||
118 | struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name) | ||
119 | { | ||
120 | unsigned int i; | ||
121 | struct jz4740_dma_chan *dma = NULL; | ||
122 | |||
123 | spin_lock(&jz4740_dma_lock); | ||
124 | |||
125 | for (i = 0; i < ARRAY_SIZE(jz4740_dma_channels); ++i) { | ||
126 | if (!jz4740_dma_channels[i].used) { | ||
127 | dma = &jz4740_dma_channels[i]; | ||
128 | dma->used = 1; | ||
129 | break; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | spin_unlock(&jz4740_dma_lock); | ||
134 | |||
135 | if (!dma) | ||
136 | return NULL; | ||
137 | |||
138 | dma->dev = dev; | ||
139 | dma->name = name; | ||
140 | |||
141 | return dma; | ||
142 | } | ||
143 | EXPORT_SYMBOL_GPL(jz4740_dma_request); | ||
144 | |||
145 | void jz4740_dma_configure(struct jz4740_dma_chan *dma, | ||
146 | const struct jz4740_dma_config *config) | ||
147 | { | ||
148 | uint32_t cmd; | ||
149 | |||
150 | switch (config->transfer_size) { | ||
151 | case JZ4740_DMA_TRANSFER_SIZE_2BYTE: | ||
152 | dma->transfer_shift = 1; | ||
153 | break; | ||
154 | case JZ4740_DMA_TRANSFER_SIZE_4BYTE: | ||
155 | dma->transfer_shift = 2; | ||
156 | break; | ||
157 | case JZ4740_DMA_TRANSFER_SIZE_16BYTE: | ||
158 | dma->transfer_shift = 4; | ||
159 | break; | ||
160 | case JZ4740_DMA_TRANSFER_SIZE_32BYTE: | ||
161 | dma->transfer_shift = 5; | ||
162 | break; | ||
163 | default: | ||
164 | dma->transfer_shift = 0; | ||
165 | break; | ||
166 | } | ||
167 | |||
168 | cmd = config->flags << JZ_DMA_CMD_FLAGS_OFFSET; | ||
169 | cmd |= config->src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET; | ||
170 | cmd |= config->dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET; | ||
171 | cmd |= config->transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET; | ||
172 | cmd |= config->mode << JZ_DMA_CMD_MODE_OFFSET; | ||
173 | cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE; | ||
174 | |||
175 | jz4740_dma_write(JZ_REG_DMA_CMD(dma->id), cmd); | ||
176 | jz4740_dma_write(JZ_REG_DMA_STATUS_CTRL(dma->id), 0); | ||
177 | jz4740_dma_write(JZ_REG_DMA_REQ_TYPE(dma->id), config->request_type); | ||
178 | } | ||
179 | EXPORT_SYMBOL_GPL(jz4740_dma_configure); | ||
180 | |||
181 | void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src) | ||
182 | { | ||
183 | jz4740_dma_write(JZ_REG_DMA_SRC_ADDR(dma->id), src); | ||
184 | } | ||
185 | EXPORT_SYMBOL_GPL(jz4740_dma_set_src_addr); | ||
186 | |||
187 | void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst) | ||
188 | { | ||
189 | jz4740_dma_write(JZ_REG_DMA_DST_ADDR(dma->id), dst); | ||
190 | } | ||
191 | EXPORT_SYMBOL_GPL(jz4740_dma_set_dst_addr); | ||
192 | |||
193 | void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count) | ||
194 | { | ||
195 | count >>= dma->transfer_shift; | ||
196 | jz4740_dma_write(JZ_REG_DMA_TRANSFER_COUNT(dma->id), count); | ||
197 | } | ||
198 | EXPORT_SYMBOL_GPL(jz4740_dma_set_transfer_count); | ||
199 | |||
200 | void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma, | ||
201 | jz4740_dma_complete_callback_t cb) | ||
202 | { | ||
203 | dma->complete_cb = cb; | ||
204 | } | ||
205 | EXPORT_SYMBOL_GPL(jz4740_dma_set_complete_cb); | ||
206 | |||
207 | void jz4740_dma_free(struct jz4740_dma_chan *dma) | ||
208 | { | ||
209 | dma->dev = NULL; | ||
210 | dma->complete_cb = NULL; | ||
211 | dma->used = 0; | ||
212 | } | ||
213 | EXPORT_SYMBOL_GPL(jz4740_dma_free); | ||
214 | |||
215 | void jz4740_dma_enable(struct jz4740_dma_chan *dma) | ||
216 | { | ||
217 | jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), | ||
218 | JZ_DMA_STATUS_CTRL_NO_DESC | JZ_DMA_STATUS_CTRL_ENABLE, | ||
219 | JZ_DMA_STATUS_CTRL_HALT | JZ_DMA_STATUS_CTRL_NO_DESC | | ||
220 | JZ_DMA_STATUS_CTRL_ENABLE); | ||
221 | |||
222 | jz4740_dma_write_mask(JZ_REG_DMA_CTRL, | ||
223 | JZ_DMA_CTRL_ENABLE, | ||
224 | JZ_DMA_CTRL_HALT | JZ_DMA_CTRL_ENABLE); | ||
225 | } | ||
226 | EXPORT_SYMBOL_GPL(jz4740_dma_enable); | ||
227 | |||
228 | void jz4740_dma_disable(struct jz4740_dma_chan *dma) | ||
229 | { | ||
230 | jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0, | ||
231 | JZ_DMA_STATUS_CTRL_ENABLE); | ||
232 | } | ||
233 | EXPORT_SYMBOL_GPL(jz4740_dma_disable); | ||
234 | |||
235 | uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma) | ||
236 | { | ||
237 | uint32_t residue; | ||
238 | residue = jz4740_dma_read(JZ_REG_DMA_TRANSFER_COUNT(dma->id)); | ||
239 | return residue << dma->transfer_shift; | ||
240 | } | ||
241 | EXPORT_SYMBOL_GPL(jz4740_dma_get_residue); | ||
242 | |||
243 | static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma) | ||
244 | { | ||
245 | (void) jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id)); | ||
246 | |||
247 | jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0, | ||
248 | JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE); | ||
249 | |||
250 | if (dma->complete_cb) | ||
251 | dma->complete_cb(dma, 0, dma->dev); | ||
252 | } | ||
253 | |||
254 | static irqreturn_t jz4740_dma_irq(int irq, void *dev_id) | ||
255 | { | ||
256 | uint32_t irq_status; | ||
257 | unsigned int i; | ||
258 | |||
259 | irq_status = readl(jz4740_dma_base + JZ_REG_DMA_IRQ); | ||
260 | |||
261 | for (i = 0; i < 6; ++i) { | ||
262 | if (irq_status & (1 << i)) | ||
263 | jz4740_dma_chan_irq(&jz4740_dma_channels[i]); | ||
264 | } | ||
265 | |||
266 | return IRQ_HANDLED; | ||
267 | } | ||
268 | |||
269 | static int jz4740_dma_init(void) | ||
270 | { | ||
271 | unsigned int ret; | ||
272 | |||
273 | jz4740_dma_base = ioremap(JZ4740_DMAC_BASE_ADDR, 0x400); | ||
274 | |||
275 | if (!jz4740_dma_base) | ||
276 | return -EBUSY; | ||
277 | |||
278 | spin_lock_init(&jz4740_dma_lock); | ||
279 | |||
280 | ret = request_irq(JZ4740_IRQ_DMAC, jz4740_dma_irq, 0, "DMA", NULL); | ||
281 | |||
282 | if (ret) | ||
283 | printk(KERN_ERR "JZ4740 DMA: Failed to request irq: %d\n", ret); | ||
284 | |||
285 | return ret; | ||
286 | } | ||
287 | arch_initcall(jz4740_dma_init); | ||
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index e9348fd26a35..df65677f3d0b 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c | |||
@@ -329,3 +329,24 @@ struct platform_device jz4740_pwm_device = { | |||
329 | .name = "jz4740-pwm", | 329 | .name = "jz4740-pwm", |
330 | .id = -1, | 330 | .id = -1, |
331 | }; | 331 | }; |
332 | |||
333 | /* DMA */ | ||
334 | static struct resource jz4740_dma_resources[] = { | ||
335 | { | ||
336 | .start = JZ4740_DMAC_BASE_ADDR, | ||
337 | .end = JZ4740_DMAC_BASE_ADDR + 0x400 - 1, | ||
338 | .flags = IORESOURCE_MEM, | ||
339 | }, | ||
340 | { | ||
341 | .start = JZ4740_IRQ_DMAC, | ||
342 | .end = JZ4740_IRQ_DMAC, | ||
343 | .flags = IORESOURCE_IRQ, | ||
344 | }, | ||
345 | }; | ||
346 | |||
347 | struct platform_device jz4740_dma_device = { | ||
348 | .name = "jz4740-dma", | ||
349 | .id = -1, | ||
350 | .num_resources = ARRAY_SIZE(jz4740_dma_resources), | ||
351 | .resource = jz4740_dma_resources, | ||
352 | }; | ||