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