• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/cris/arch-v32/mach-fs/
1/* Wrapper for DMA channel allocator that starts clocks etc */
2
3#include <linux/kernel.h>
4#include <linux/spinlock.h>
5#include <asm/dma.h>
6#include <hwregs/reg_map.h>
7#include <hwregs/reg_rdwr.h>
8#include <hwregs/marb_defs.h>
9#include <hwregs/config_defs.h>
10#include <hwregs/strmux_defs.h>
11#include <linux/errno.h>
12#include <asm/system.h>
13#include <mach/arbiter.h>
14
15static char used_dma_channels[MAX_DMA_CHANNELS];
16static const char *used_dma_channels_users[MAX_DMA_CHANNELS];
17
18static DEFINE_SPINLOCK(dma_lock);
19
20int crisv32_request_dma(unsigned int dmanr, const char *device_id,
21			unsigned options, unsigned int bandwidth,
22			enum dma_owner owner)
23{
24	unsigned long flags;
25	reg_config_rw_clk_ctrl clk_ctrl;
26	reg_strmux_rw_cfg strmux_cfg;
27
28	if (crisv32_arbiter_allocate_bandwidth(dmanr,
29					       options & DMA_INT_MEM ?
30					       INT_REGION : EXT_REGION,
31					       bandwidth))
32		return -ENOMEM;
33
34	spin_lock_irqsave(&dma_lock, flags);
35
36	if (used_dma_channels[dmanr]) {
37		spin_unlock_irqrestore(&dma_lock, flags);
38		if (options & DMA_VERBOSE_ON_ERROR) {
39			printk(KERN_ERR "Failed to request DMA %i for %s, "
40				"already allocated by %s\n",
41				dmanr,
42				device_id,
43				used_dma_channels_users[dmanr]);
44		}
45		if (options & DMA_PANIC_ON_ERROR)
46			panic("request_dma error!");
47		spin_unlock_irqrestore(&dma_lock, flags);
48		return -EBUSY;
49	}
50	clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
51	strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
52
53	switch (dmanr) {
54	case 0:
55	case 1:
56		clk_ctrl.dma01_eth0 = 1;
57		break;
58	case 2:
59	case 3:
60		clk_ctrl.dma23 = 1;
61		break;
62	case 4:
63	case 5:
64		clk_ctrl.dma45 = 1;
65		break;
66	case 6:
67	case 7:
68		clk_ctrl.dma67 = 1;
69		break;
70	case 8:
71	case 9:
72		clk_ctrl.dma89_strcop = 1;
73		break;
74#if MAX_DMA_CHANNELS-1 != 9
75#error Check dma.c
76#endif
77	default:
78		spin_unlock_irqrestore(&dma_lock, flags);
79		if (options & DMA_VERBOSE_ON_ERROR) {
80			printk(KERN_ERR "Failed to request DMA %i for %s, "
81				"only 0-%i valid)\n",
82				dmanr, device_id, MAX_DMA_CHANNELS - 1);
83		}
84
85		if (options & DMA_PANIC_ON_ERROR)
86			panic("request_dma error!");
87		return -EINVAL;
88	}
89
90	switch (owner) {
91	case dma_eth0:
92		if (dmanr == 0)
93			strmux_cfg.dma0 = regk_strmux_eth0;
94		else if (dmanr == 1)
95			strmux_cfg.dma1 = regk_strmux_eth0;
96		else
97			panic("Invalid DMA channel for eth0\n");
98		break;
99	case dma_eth1:
100		if (dmanr == 6)
101			strmux_cfg.dma6 = regk_strmux_eth1;
102		else if (dmanr == 7)
103			strmux_cfg.dma7 = regk_strmux_eth1;
104		else
105			panic("Invalid DMA channel for eth1\n");
106		break;
107	case dma_iop0:
108		if (dmanr == 2)
109			strmux_cfg.dma2 = regk_strmux_iop0;
110		else if (dmanr == 3)
111			strmux_cfg.dma3 = regk_strmux_iop0;
112		else
113			panic("Invalid DMA channel for iop0\n");
114		break;
115	case dma_iop1:
116		if (dmanr == 4)
117			strmux_cfg.dma4 = regk_strmux_iop1;
118		else if (dmanr == 5)
119			strmux_cfg.dma5 = regk_strmux_iop1;
120		else
121			panic("Invalid DMA channel for iop1\n");
122		break;
123	case dma_ser0:
124		if (dmanr == 6)
125			strmux_cfg.dma6 = regk_strmux_ser0;
126		else if (dmanr == 7)
127			strmux_cfg.dma7 = regk_strmux_ser0;
128		else
129			panic("Invalid DMA channel for ser0\n");
130		break;
131	case dma_ser1:
132		if (dmanr == 4)
133			strmux_cfg.dma4 = regk_strmux_ser1;
134		else if (dmanr == 5)
135			strmux_cfg.dma5 = regk_strmux_ser1;
136		else
137			panic("Invalid DMA channel for ser1\n");
138		break;
139	case dma_ser2:
140		if (dmanr == 2)
141			strmux_cfg.dma2 = regk_strmux_ser2;
142		else if (dmanr == 3)
143			strmux_cfg.dma3 = regk_strmux_ser2;
144		else
145			panic("Invalid DMA channel for ser2\n");
146		break;
147	case dma_ser3:
148		if (dmanr == 8)
149			strmux_cfg.dma8 = regk_strmux_ser3;
150		else if (dmanr == 9)
151			strmux_cfg.dma9 = regk_strmux_ser3;
152		else
153			panic("Invalid DMA channel for ser3\n");
154		break;
155	case dma_sser0:
156		if (dmanr == 4)
157			strmux_cfg.dma4 = regk_strmux_sser0;
158		else if (dmanr == 5)
159			strmux_cfg.dma5 = regk_strmux_sser0;
160		else
161			panic("Invalid DMA channel for sser0\n");
162		break;
163	case dma_sser1:
164		if (dmanr == 6)
165			strmux_cfg.dma6 = regk_strmux_sser1;
166		else if (dmanr == 7)
167			strmux_cfg.dma7 = regk_strmux_sser1;
168		else
169			panic("Invalid DMA channel for sser1\n");
170		break;
171	case dma_ata:
172		if (dmanr == 2)
173			strmux_cfg.dma2 = regk_strmux_ata;
174		else if (dmanr == 3)
175			strmux_cfg.dma3 = regk_strmux_ata;
176		else
177			panic("Invalid DMA channel for ata\n");
178		break;
179	case dma_strp:
180		if (dmanr == 8)
181			strmux_cfg.dma8 = regk_strmux_strcop;
182		else if (dmanr == 9)
183			strmux_cfg.dma9 = regk_strmux_strcop;
184		else
185			panic("Invalid DMA channel for strp\n");
186		break;
187	case dma_ext0:
188		if (dmanr == 6)
189			strmux_cfg.dma6 = regk_strmux_ext0;
190		else
191			panic("Invalid DMA channel for ext0\n");
192		break;
193	case dma_ext1:
194		if (dmanr == 7)
195			strmux_cfg.dma7 = regk_strmux_ext1;
196		else
197			panic("Invalid DMA channel for ext1\n");
198		break;
199	case dma_ext2:
200		if (dmanr == 2)
201			strmux_cfg.dma2 = regk_strmux_ext2;
202		else if (dmanr == 8)
203			strmux_cfg.dma8 = regk_strmux_ext2;
204		else
205			panic("Invalid DMA channel for ext2\n");
206		break;
207	case dma_ext3:
208		if (dmanr == 3)
209			strmux_cfg.dma3 = regk_strmux_ext3;
210		else if (dmanr == 9)
211			strmux_cfg.dma9 = regk_strmux_ext2;
212		else
213			panic("Invalid DMA channel for ext2\n");
214		break;
215	}
216
217	used_dma_channels[dmanr] = 1;
218	used_dma_channels_users[dmanr] = device_id;
219	REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
220	REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
221	spin_unlock_irqrestore(&dma_lock, flags);
222	return 0;
223}
224
225void crisv32_free_dma(unsigned int dmanr)
226{
227	spin_lock(&dma_lock);
228	used_dma_channels[dmanr] = 0;
229	spin_unlock(&dma_lock);
230}
231