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