diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 13:01:28 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 13:01:28 -0500 |
commit | 0cf975e16927fd70f34cee20d3856246c13bb4c8 (patch) | |
tree | bb955d50f28e5d98c198701798c8341d9763299a /arch/cris/arch-v32/mach-a3/dma.c | |
parent | 03054de1e0b90b33e9974107d84dabd2509f5898 (diff) | |
parent | bc10ac3f2fe44e65f787d6197fd5d17304bf7d83 (diff) |
Merge branch 'cris' of git://www.jni.nu/cris
* 'cris' of git://www.jni.nu/cris: (158 commits)
CRIS v32: Remove hwregs/timer_defs.h, it is now architecture specific.
CRIS v32: Change drivers/i2c.c locking.
CRIS v32: Rewrite ARTPEC-3 gpio driver to avoid volatiles and general cleanup.
CRIS: Add new timerfd syscall entries.
MAINTAINERS: Add my information for the CRIS port.
CRIS v32: Correct spelling of bandwidth in function name.
CRIS v32: Clean up nandflash.c for ARTPEC-3 and ETRAX FS.
CRIS v10: Cleanup of drivers/gpio.c
CRIS v10: drivers/net/cris/eth_v10.c rename LED defines to CRIS_LED to avoid name clash.
CRIS: Make io_pwm_set_period members unsigned in etraxgpio.h
CRIS: Move ETRAX_AXISFLASHMAP to common Kconfig file.
CRIS: Drop regs parameter from call to profile_tick in kernel/time.c
CRIS v32: Fix minor formatting issue in mach-a3/io.c
CRIS v32: Initialize GIO even if we're rambooting in kernel/head.S
CRIS v32: Remove kernel/arbiter.c, it now exists in machine dependent directory.
CRIS v32: Minor changes to avoid errors in asm-cris/arch-v32/hwregs/reg_rdwr.h
CRIS v32: arch-v32/hwregs/intr_vect_defs.h moved to machine dependent directory.
CRIS v32: Correct offset for TASK_pid in asm-cris/arch-v32/offset.h
CRIS v32: Move register map header to machine dependent directory.
CRIS v32: Let compiler know that memory is clobbered after a break op.
...
Diffstat (limited to 'arch/cris/arch-v32/mach-a3/dma.c')
-rw-r--r-- | arch/cris/arch-v32/mach-a3/dma.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/arch/cris/arch-v32/mach-a3/dma.c b/arch/cris/arch-v32/mach-a3/dma.c new file mode 100644 index 000000000000..25f236ef0b81 --- /dev/null +++ b/arch/cris/arch-v32/mach-a3/dma.c | |||
@@ -0,0 +1,185 @@ | |||
1 | /* Wrapper for DMA channel allocator that starts clocks etc */ | ||
2 | |||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/spinlock.h> | ||
5 | #include <asm/arch/mach/dma.h> | ||
6 | #include <hwregs/reg_map.h> | ||
7 | #include <hwregs/reg_rdwr.h> | ||
8 | #include <hwregs/marb_defs.h> | ||
9 | #include <hwregs/clkgen_defs.h> | ||
10 | #include <hwregs/strmux_defs.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <asm/system.h> | ||
13 | #include <arbiter.h> | ||
14 | |||
15 | static char used_dma_channels[MAX_DMA_CHANNELS]; | ||
16 | static const char *used_dma_channels_users[MAX_DMA_CHANNELS]; | ||
17 | |||
18 | static DEFINE_SPINLOCK(dma_lock); | ||
19 | |||
20 | int crisv32_request_dma(unsigned int dmanr, const char *device_id, | ||
21 | unsigned options, unsigned int bandwidth, enum dma_owner owner) | ||
22 | { | ||
23 | unsigned long flags; | ||
24 | reg_clkgen_rw_clk_ctrl clk_ctrl; | ||
25 | reg_strmux_rw_cfg strmux_cfg; | ||
26 | |||
27 | if (crisv32_arbiter_allocate_bandwidth(dmanr, | ||
28 | options & DMA_INT_MEM ? INT_REGION : EXT_REGION, | ||
29 | bandwidth)) | ||
30 | return -ENOMEM; | ||
31 | |||
32 | spin_lock_irqsave(&dma_lock, flags); | ||
33 | |||
34 | if (used_dma_channels[dmanr]) { | ||
35 | spin_unlock_irqrestore(&dma_lock, flags); | ||
36 | if (options & DMA_VERBOSE_ON_ERROR) | ||
37 | printk(KERN_ERR "Failed to request DMA %i for %s, " | ||
38 | "already allocated by %s\n", | ||
39 | dmanr, | ||
40 | device_id, | ||
41 | used_dma_channels_users[dmanr]); | ||
42 | |||
43 | if (options & DMA_PANIC_ON_ERROR) | ||
44 | panic("request_dma error!"); | ||
45 | spin_unlock_irqrestore(&dma_lock, flags); | ||
46 | return -EBUSY; | ||
47 | } | ||
48 | clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl); | ||
49 | strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg); | ||
50 | |||
51 | switch (dmanr) { | ||
52 | case 0: | ||
53 | case 1: | ||
54 | clk_ctrl.dma0_1_eth = 1; | ||
55 | break; | ||
56 | case 2: | ||
57 | case 3: | ||
58 | clk_ctrl.dma2_3_strcop = 1; | ||
59 | break; | ||
60 | case 4: | ||
61 | case 5: | ||
62 | clk_ctrl.dma4_5_iop = 1; | ||
63 | break; | ||
64 | case 6: | ||
65 | case 7: | ||
66 | clk_ctrl.sser_ser_dma6_7 = 1; | ||
67 | break; | ||
68 | case 9: | ||
69 | case 11: | ||
70 | clk_ctrl.dma9_11 = 1; | ||
71 | break; | ||
72 | #if MAX_DMA_CHANNELS-1 != 11 | ||
73 | #error Check dma.c | ||
74 | #endif | ||
75 | default: | ||
76 | spin_unlock_irqrestore(&dma_lock, flags); | ||
77 | if (options & DMA_VERBOSE_ON_ERROR) | ||
78 | printk(KERN_ERR "Failed to request DMA %i for %s, " | ||
79 | "only 0-%i valid)\n", | ||
80 | dmanr, device_id, MAX_DMA_CHANNELS-1); | ||
81 | |||
82 | if (options & DMA_PANIC_ON_ERROR) | ||
83 | panic("request_dma error!"); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | switch (owner) { | ||
88 | case dma_eth: | ||
89 | if (dmanr == 0) | ||
90 | strmux_cfg.dma0 = regk_strmux_eth; | ||
91 | else if (dmanr == 1) | ||
92 | strmux_cfg.dma1 = regk_strmux_eth; | ||
93 | else | ||
94 | panic("Invalid DMA channel for eth\n"); | ||
95 | break; | ||
96 | case dma_ser0: | ||
97 | if (dmanr == 0) | ||
98 | strmux_cfg.dma0 = regk_strmux_ser0; | ||
99 | else if (dmanr == 1) | ||
100 | strmux_cfg.dma1 = regk_strmux_ser0; | ||
101 | else | ||
102 | panic("Invalid DMA channel for ser0\n"); | ||
103 | break; | ||
104 | case dma_ser3: | ||
105 | if (dmanr == 2) | ||
106 | strmux_cfg.dma2 = regk_strmux_ser3; | ||
107 | else if (dmanr == 3) | ||
108 | strmux_cfg.dma3 = regk_strmux_ser3; | ||
109 | else | ||
110 | panic("Invalid DMA channel for ser3\n"); | ||
111 | break; | ||
112 | case dma_strp: | ||
113 | if (dmanr == 2) | ||
114 | strmux_cfg.dma2 = regk_strmux_strcop; | ||
115 | else if (dmanr == 3) | ||
116 | strmux_cfg.dma3 = regk_strmux_strcop; | ||
117 | else | ||
118 | panic("Invalid DMA channel for strp\n"); | ||
119 | break; | ||
120 | case dma_ser1: | ||
121 | if (dmanr == 4) | ||
122 | strmux_cfg.dma4 = regk_strmux_ser1; | ||
123 | else if (dmanr == 5) | ||
124 | strmux_cfg.dma5 = regk_strmux_ser1; | ||
125 | else | ||
126 | panic("Invalid DMA channel for ser1\n"); | ||
127 | break; | ||
128 | case dma_iop: | ||
129 | if (dmanr == 4) | ||
130 | strmux_cfg.dma4 = regk_strmux_iop; | ||
131 | else if (dmanr == 5) | ||
132 | strmux_cfg.dma5 = regk_strmux_iop; | ||
133 | else | ||
134 | panic("Invalid DMA channel for iop\n"); | ||
135 | break; | ||
136 | case dma_ser2: | ||
137 | if (dmanr == 6) | ||
138 | strmux_cfg.dma6 = regk_strmux_ser2; | ||
139 | else if (dmanr == 7) | ||
140 | strmux_cfg.dma7 = regk_strmux_ser2; | ||
141 | else | ||
142 | panic("Invalid DMA channel for ser2\n"); | ||
143 | break; | ||
144 | case dma_sser: | ||
145 | if (dmanr == 6) | ||
146 | strmux_cfg.dma6 = regk_strmux_sser; | ||
147 | else if (dmanr == 7) | ||
148 | strmux_cfg.dma7 = regk_strmux_sser; | ||
149 | else | ||
150 | panic("Invalid DMA channel for sser\n"); | ||
151 | break; | ||
152 | case dma_ser4: | ||
153 | if (dmanr == 9) | ||
154 | strmux_cfg.dma9 = regk_strmux_ser4; | ||
155 | else | ||
156 | panic("Invalid DMA channel for ser4\n"); | ||
157 | break; | ||
158 | case dma_jpeg: | ||
159 | if (dmanr == 9) | ||
160 | strmux_cfg.dma9 = regk_strmux_jpeg; | ||
161 | else | ||
162 | panic("Invalid DMA channel for JPEG\n"); | ||
163 | break; | ||
164 | case dma_h264: | ||
165 | if (dmanr == 11) | ||
166 | strmux_cfg.dma11 = regk_strmux_h264; | ||
167 | else | ||
168 | panic("Invalid DMA channel for H264\n"); | ||
169 | break; | ||
170 | } | ||
171 | |||
172 | used_dma_channels[dmanr] = 1; | ||
173 | used_dma_channels_users[dmanr] = device_id; | ||
174 | REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl); | ||
175 | REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg); | ||
176 | spin_unlock_irqrestore(&dma_lock, flags); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | void crisv32_free_dma(unsigned int dmanr) | ||
181 | { | ||
182 | spin_lock(&dma_lock); | ||
183 | used_dma_channels[dmanr] = 0; | ||
184 | spin_unlock(&dma_lock); | ||
185 | } | ||