Merge tag 'cris-for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jesper...
[cascardo/linux.git] / arch / cris / arch-v32 / mach-fs / dma.c
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
27         if (crisv32_arbiter_allocate_bandwidth(dmanr,
28                                                options & DMA_INT_MEM ?
29                                                INT_REGION : EXT_REGION,
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                 return -EBUSY;
47         }
48         clk_ctrl = REG_RD(config, regi_config, 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.dma01_eth0 = 1;
55                 break;
56         case 2:
57         case 3:
58                 clk_ctrl.dma23 = 1;
59                 break;
60         case 4:
61         case 5:
62                 clk_ctrl.dma45 = 1;
63                 break;
64         case 6:
65         case 7:
66                 clk_ctrl.dma67 = 1;
67                 break;
68         case 8:
69         case 9:
70                 clk_ctrl.dma89_strcop = 1;
71                 break;
72 #if MAX_DMA_CHANNELS-1 != 9
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
83                 if (options & DMA_PANIC_ON_ERROR)
84                         panic("request_dma error!");
85                 return -EINVAL;
86         }
87
88         switch (owner) {
89         case dma_eth0:
90                 if (dmanr == 0)
91                         strmux_cfg.dma0 = regk_strmux_eth0;
92                 else if (dmanr == 1)
93                         strmux_cfg.dma1 = regk_strmux_eth0;
94                 else
95                         panic("Invalid DMA channel for eth0\n");
96                 break;
97         case dma_eth1:
98                 if (dmanr == 6)
99                         strmux_cfg.dma6 = regk_strmux_eth1;
100                 else if (dmanr == 7)
101                         strmux_cfg.dma7 = regk_strmux_eth1;
102                 else
103                         panic("Invalid DMA channel for eth1\n");
104                 break;
105         case dma_iop0:
106                 if (dmanr == 2)
107                         strmux_cfg.dma2 = regk_strmux_iop0;
108                 else if (dmanr == 3)
109                         strmux_cfg.dma3 = regk_strmux_iop0;
110                 else
111                         panic("Invalid DMA channel for iop0\n");
112                 break;
113         case dma_iop1:
114                 if (dmanr == 4)
115                         strmux_cfg.dma4 = regk_strmux_iop1;
116                 else if (dmanr == 5)
117                         strmux_cfg.dma5 = regk_strmux_iop1;
118                 else
119                         panic("Invalid DMA channel for iop1\n");
120                 break;
121         case dma_ser0:
122                 if (dmanr == 6)
123                         strmux_cfg.dma6 = regk_strmux_ser0;
124                 else if (dmanr == 7)
125                         strmux_cfg.dma7 = regk_strmux_ser0;
126                 else
127                         panic("Invalid DMA channel for ser0\n");
128                 break;
129         case dma_ser1:
130                 if (dmanr == 4)
131                         strmux_cfg.dma4 = regk_strmux_ser1;
132                 else if (dmanr == 5)
133                         strmux_cfg.dma5 = regk_strmux_ser1;
134                 else
135                         panic("Invalid DMA channel for ser1\n");
136                 break;
137         case dma_ser2:
138                 if (dmanr == 2)
139                         strmux_cfg.dma2 = regk_strmux_ser2;
140                 else if (dmanr == 3)
141                         strmux_cfg.dma3 = regk_strmux_ser2;
142                 else
143                         panic("Invalid DMA channel for ser2\n");
144                 break;
145         case dma_ser3:
146                 if (dmanr == 8)
147                         strmux_cfg.dma8 = regk_strmux_ser3;
148                 else if (dmanr == 9)
149                         strmux_cfg.dma9 = regk_strmux_ser3;
150                 else
151                         panic("Invalid DMA channel for ser3\n");
152                 break;
153         case dma_sser0:
154                 if (dmanr == 4)
155                         strmux_cfg.dma4 = regk_strmux_sser0;
156                 else if (dmanr == 5)
157                         strmux_cfg.dma5 = regk_strmux_sser0;
158                 else
159                         panic("Invalid DMA channel for sser0\n");
160                 break;
161         case dma_sser1:
162                 if (dmanr == 6)
163                         strmux_cfg.dma6 = regk_strmux_sser1;
164                 else if (dmanr == 7)
165                         strmux_cfg.dma7 = regk_strmux_sser1;
166                 else
167                         panic("Invalid DMA channel for sser1\n");
168                 break;
169         case dma_ata:
170                 if (dmanr == 2)
171                         strmux_cfg.dma2 = regk_strmux_ata;
172                 else if (dmanr == 3)
173                         strmux_cfg.dma3 = regk_strmux_ata;
174                 else
175                         panic("Invalid DMA channel for ata\n");
176                 break;
177         case dma_strp:
178                 if (dmanr == 8)
179                         strmux_cfg.dma8 = regk_strmux_strcop;
180                 else if (dmanr == 9)
181                         strmux_cfg.dma9 = regk_strmux_strcop;
182                 else
183                         panic("Invalid DMA channel for strp\n");
184                 break;
185         case dma_ext0:
186                 if (dmanr == 6)
187                         strmux_cfg.dma6 = regk_strmux_ext0;
188                 else
189                         panic("Invalid DMA channel for ext0\n");
190                 break;
191         case dma_ext1:
192                 if (dmanr == 7)
193                         strmux_cfg.dma7 = regk_strmux_ext1;
194                 else
195                         panic("Invalid DMA channel for ext1\n");
196                 break;
197         case dma_ext2:
198                 if (dmanr == 2)
199                         strmux_cfg.dma2 = regk_strmux_ext2;
200                 else if (dmanr == 8)
201                         strmux_cfg.dma8 = regk_strmux_ext2;
202                 else
203                         panic("Invalid DMA channel for ext2\n");
204                 break;
205         case dma_ext3:
206                 if (dmanr == 3)
207                         strmux_cfg.dma3 = regk_strmux_ext3;
208                 else if (dmanr == 9)
209                         strmux_cfg.dma9 = regk_strmux_ext2;
210                 else
211                         panic("Invalid DMA channel for ext2\n");
212                 break;
213         }
214
215         used_dma_channels[dmanr] = 1;
216         used_dma_channels_users[dmanr] = device_id;
217         REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
218         REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
219         spin_unlock_irqrestore(&dma_lock, flags);
220         return 0;
221 }
222
223 void crisv32_free_dma(unsigned int dmanr)
224 {
225         spin_lock(&dma_lock);
226         used_dma_channels[dmanr] = 0;
227         spin_unlock(&dma_lock);
228 }