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