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