• 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/arch/cris/arch-v32/mach-a3/
1/* Wrapper for DMA channel allocator that starts clocks etc */
2
3#include <linux/kernel.h>
4#include <linux/spinlock.h>
5#include <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
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, 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
180void crisv32_free_dma(unsigned int dmanr)
181{
182	spin_lock(&dma_lock);
183	used_dma_channels[dmanr] = 0;
184	spin_unlock(&dma_lock);
185}
186