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 <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 <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, enum dma_owner owner)
21 {
22  unsigned long flags;
23  reg_clkgen_rw_clk_ctrl clk_ctrl;
24  reg_strmux_rw_cfg strmux_cfg;
25 
27  options & DMA_INT_MEM ? INT_REGION : EXT_REGION,
28  bandwidth))
29  return -ENOMEM;
30 
31  spin_lock_irqsave(&dma_lock, flags);
32 
33  if (used_dma_channels[dmanr]) {
34  spin_unlock_irqrestore(&dma_lock, flags);
35  if (options & DMA_VERBOSE_ON_ERROR)
36  printk(KERN_ERR "Failed to request DMA %i for %s, "
37  "already allocated by %s\n",
38  dmanr,
39  device_id,
40  used_dma_channels_users[dmanr]);
41 
42  if (options & DMA_PANIC_ON_ERROR)
43  panic("request_dma error!");
44  spin_unlock_irqrestore(&dma_lock, flags);
45  return -EBUSY;
46  }
47  clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
48  strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
49 
50  switch (dmanr) {
51  case 0:
52  case 1:
53  clk_ctrl.dma0_1_eth = 1;
54  break;
55  case 2:
56  case 3:
57  clk_ctrl.dma2_3_strcop = 1;
58  break;
59  case 4:
60  case 5:
61  clk_ctrl.dma4_5_iop = 1;
62  break;
63  case 6:
64  case 7:
65  clk_ctrl.sser_ser_dma6_7 = 1;
66  break;
67  case 9:
68  case 11:
69  clk_ctrl.dma9_11 = 1;
70  break;
71 #if MAX_DMA_CHANNELS-1 != 11
72 #error Check dma.c
73 #endif
74  default:
75  spin_unlock_irqrestore(&dma_lock, flags);
76  if (options & DMA_VERBOSE_ON_ERROR)
77  printk(KERN_ERR "Failed to request DMA %i for %s, "
78  "only 0-%i valid)\n",
79  dmanr, device_id, MAX_DMA_CHANNELS-1);
80 
81  if (options & DMA_PANIC_ON_ERROR)
82  panic("request_dma error!");
83  return -EINVAL;
84  }
85 
86  switch (owner) {
87  case dma_eth:
88  if (dmanr == 0)
89  strmux_cfg.dma0 = regk_strmux_eth;
90  else if (dmanr == 1)
91  strmux_cfg.dma1 = regk_strmux_eth;
92  else
93  panic("Invalid DMA channel for eth\n");
94  break;
95  case dma_ser0:
96  if (dmanr == 0)
97  strmux_cfg.dma0 = regk_strmux_ser0;
98  else if (dmanr == 1)
99  strmux_cfg.dma1 = regk_strmux_ser0;
100  else
101  panic("Invalid DMA channel for ser0\n");
102  break;
103  case dma_ser3:
104  if (dmanr == 2)
105  strmux_cfg.dma2 = regk_strmux_ser3;
106  else if (dmanr == 3)
107  strmux_cfg.dma3 = regk_strmux_ser3;
108  else
109  panic("Invalid DMA channel for ser3\n");
110  break;
111  case dma_strp:
112  if (dmanr == 2)
113  strmux_cfg.dma2 = regk_strmux_strcop;
114  else if (dmanr == 3)
115  strmux_cfg.dma3 = regk_strmux_strcop;
116  else
117  panic("Invalid DMA channel for strp\n");
118  break;
119  case dma_ser1:
120  if (dmanr == 4)
121  strmux_cfg.dma4 = regk_strmux_ser1;
122  else if (dmanr == 5)
123  strmux_cfg.dma5 = regk_strmux_ser1;
124  else
125  panic("Invalid DMA channel for ser1\n");
126  break;
127  case dma_iop:
128  if (dmanr == 4)
129  strmux_cfg.dma4 = regk_strmux_iop;
130  else if (dmanr == 5)
131  strmux_cfg.dma5 = regk_strmux_iop;
132  else
133  panic("Invalid DMA channel for iop\n");
134  break;
135  case dma_ser2:
136  if (dmanr == 6)
137  strmux_cfg.dma6 = regk_strmux_ser2;
138  else if (dmanr == 7)
139  strmux_cfg.dma7 = regk_strmux_ser2;
140  else
141  panic("Invalid DMA channel for ser2\n");
142  break;
143  case dma_sser:
144  if (dmanr == 6)
145  strmux_cfg.dma6 = regk_strmux_sser;
146  else if (dmanr == 7)
147  strmux_cfg.dma7 = regk_strmux_sser;
148  else
149  panic("Invalid DMA channel for sser\n");
150  break;
151  case dma_ser4:
152  if (dmanr == 9)
153  strmux_cfg.dma9 = regk_strmux_ser4;
154  else
155  panic("Invalid DMA channel for ser4\n");
156  break;
157  case dma_jpeg:
158  if (dmanr == 9)
159  strmux_cfg.dma9 = regk_strmux_jpeg;
160  else
161  panic("Invalid DMA channel for JPEG\n");
162  break;
163  case dma_h264:
164  if (dmanr == 11)
165  strmux_cfg.dma11 = regk_strmux_h264;
166  else
167  panic("Invalid DMA channel for H264\n");
168  break;
169  }
170 
171  used_dma_channels[dmanr] = 1;
172  used_dma_channels_users[dmanr] = device_id;
173  REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
174  REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
175  spin_unlock_irqrestore(&dma_lock, flags);
176  return 0;
177 }
178 
179 void crisv32_free_dma(unsigned int dmanr)
180 {
181  spin_lock(&dma_lock);
182  used_dma_channels[dmanr] = 0;
183  spin_unlock(&dma_lock);
184 }