• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 
crisv32_request_dma(unsigned int dmanr,const char * device_id,unsigned options,unsigned int bandwidth,enum dma_owner owner)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 
crisv32_free_dma(unsigned int dmanr)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 }
186