CRIS v32: Add new machine dependent files for Etrax-FS and Artpec-3.
[linux-2.6.git] / arch / cris / arch-v32 / mach-a3 / 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/arch/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
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_bandwith(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
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 }