Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/cris/arch-v32/mach-a3/dma.c
15125 views
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 <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_bandwidth(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
}
186
187