]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - arch/cris/arch-v32/mach-fs/dma.c
Merge branch 'drm-armada-fixes' of git://git.armlinux.org.uk/~rmk/linux-arm into...
[mirror_ubuntu-focal-kernel.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 }