This source file includes following definitions.
- buffer_icap_get_status
- buffer_icap_get_bram
- buffer_icap_busy
- buffer_icap_set_size
- buffer_icap_set_offset
- buffer_icap_set_rnc
- buffer_icap_set_bram
- buffer_icap_device_read
- buffer_icap_device_write
- buffer_icap_reset
- buffer_icap_set_configuration
- buffer_icap_get_configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include "buffer_icap.h"
34
35
36 #define XHI_MAX_BUFFER_BYTES 2048
37 #define XHI_MAX_BUFFER_INTS (XHI_MAX_BUFFER_BYTES >> 2)
38
39
40 #define XHI_DEVICE_READ_ERROR -1
41 #define XHI_DEVICE_WRITE_ERROR -2
42 #define XHI_BUFFER_OVERFLOW_ERROR -3
43
44 #define XHI_DEVICE_READ 0x1
45 #define XHI_DEVICE_WRITE 0x0
46
47
48 #define XHI_CYCLE_DONE 0
49 #define XHI_CYCLE_EXECUTING 1
50
51
52
53
54 #define XHI_SIZE_REG_OFFSET 0x800L
55
56 #define XHI_BRAM_OFFSET_REG_OFFSET 0x804L
57
58 #define XHI_RNC_REG_OFFSET 0x808L
59
60 #define XHI_STATUS_REG_OFFSET 0x80CL
61
62
63 #define XHI_CONFIGURE 0x0UL
64 #define XHI_READBACK 0x1UL
65
66
67 #define XHI_NOT_FINISHED 0x0UL
68 #define XHI_FINISHED 0x1UL
69
70 #define XHI_BUFFER_START 0
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 u32 buffer_icap_get_status(struct hwicap_drvdata *drvdata)
89 {
90 return in_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET);
91 }
92
93
94
95
96
97
98
99
100
101 static inline u32 buffer_icap_get_bram(void __iomem *base_address,
102 u32 offset)
103 {
104 return in_be32(base_address + (offset << 2));
105 }
106
107
108
109
110
111
112
113
114
115 static inline bool buffer_icap_busy(void __iomem *base_address)
116 {
117 u32 status = in_be32(base_address + XHI_STATUS_REG_OFFSET);
118 return (status & 1) == XHI_NOT_FINISHED;
119 }
120
121
122
123
124
125
126
127
128
129 static inline void buffer_icap_set_size(void __iomem *base_address,
130 u32 data)
131 {
132 out_be32(base_address + XHI_SIZE_REG_OFFSET, data);
133 }
134
135
136
137
138
139
140
141
142
143 static inline void buffer_icap_set_offset(void __iomem *base_address,
144 u32 data)
145 {
146 out_be32(base_address + XHI_BRAM_OFFSET_REG_OFFSET, data);
147 }
148
149
150
151
152
153
154
155
156
157
158
159 static inline void buffer_icap_set_rnc(void __iomem *base_address,
160 u32 data)
161 {
162 out_be32(base_address + XHI_RNC_REG_OFFSET, data);
163 }
164
165
166
167
168
169
170
171
172
173
174 static inline void buffer_icap_set_bram(void __iomem *base_address,
175 u32 offset, u32 data)
176 {
177 out_be32(base_address + (offset << 2), data);
178 }
179
180
181
182
183
184
185
186
187 static int buffer_icap_device_read(struct hwicap_drvdata *drvdata,
188 u32 offset, u32 count)
189 {
190
191 s32 retries = 0;
192 void __iomem *base_address = drvdata->base_address;
193
194 if (buffer_icap_busy(base_address))
195 return -EBUSY;
196
197 if ((offset + count) > XHI_MAX_BUFFER_INTS)
198 return -EINVAL;
199
200
201 buffer_icap_set_size(base_address, (count << 2));
202 buffer_icap_set_offset(base_address, offset);
203 buffer_icap_set_rnc(base_address, XHI_READBACK);
204
205 while (buffer_icap_busy(base_address)) {
206 retries++;
207 if (retries > XHI_MAX_RETRIES)
208 return -EBUSY;
209 }
210 return 0;
211
212 };
213
214
215
216
217
218
219
220
221 static int buffer_icap_device_write(struct hwicap_drvdata *drvdata,
222 u32 offset, u32 count)
223 {
224
225 s32 retries = 0;
226 void __iomem *base_address = drvdata->base_address;
227
228 if (buffer_icap_busy(base_address))
229 return -EBUSY;
230
231 if ((offset + count) > XHI_MAX_BUFFER_INTS)
232 return -EINVAL;
233
234
235 buffer_icap_set_size(base_address, count << 2);
236 buffer_icap_set_offset(base_address, offset);
237 buffer_icap_set_rnc(base_address, XHI_CONFIGURE);
238
239 while (buffer_icap_busy(base_address)) {
240 retries++;
241 if (retries > XHI_MAX_RETRIES)
242 return -EBUSY;
243 }
244 return 0;
245
246 };
247
248
249
250
251
252
253
254
255
256 void buffer_icap_reset(struct hwicap_drvdata *drvdata)
257 {
258 out_be32(drvdata->base_address + XHI_STATUS_REG_OFFSET, 0xFEFE);
259 }
260
261
262
263
264
265
266
267 int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
268 u32 size)
269 {
270 int status;
271 s32 buffer_count = 0;
272 bool dirty = false;
273 u32 i;
274 void __iomem *base_address = drvdata->base_address;
275
276
277 for (i = 0, buffer_count = 0; i < size; i++) {
278
279
280 buffer_icap_set_bram(base_address, buffer_count, data[i]);
281 dirty = true;
282
283 if (buffer_count < XHI_MAX_BUFFER_INTS - 1) {
284 buffer_count++;
285 continue;
286 }
287
288
289 status = buffer_icap_device_write(
290 drvdata,
291 XHI_BUFFER_START,
292 XHI_MAX_BUFFER_INTS);
293 if (status != 0) {
294
295 buffer_icap_reset(drvdata);
296 return status;
297 }
298
299 buffer_count = 0;
300 dirty = false;
301 }
302
303
304 if (dirty) {
305
306 status = buffer_icap_device_write(drvdata, XHI_BUFFER_START,
307 buffer_count);
308 if (status != 0) {
309
310 buffer_icap_reset(drvdata);
311 }
312 return status;
313 }
314
315 return 0;
316 };
317
318
319
320
321
322
323
324 int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data,
325 u32 size)
326 {
327 int status;
328 s32 buffer_count = 0;
329 u32 i;
330 void __iomem *base_address = drvdata->base_address;
331
332
333 for (i = 0, buffer_count = XHI_MAX_BUFFER_INTS; i < size; i++) {
334 if (buffer_count == XHI_MAX_BUFFER_INTS) {
335 u32 words_remaining = size - i;
336 u32 words_to_read =
337 words_remaining <
338 XHI_MAX_BUFFER_INTS ? words_remaining :
339 XHI_MAX_BUFFER_INTS;
340
341
342 status = buffer_icap_device_read(
343 drvdata,
344 XHI_BUFFER_START,
345 words_to_read);
346 if (status != 0) {
347
348 buffer_icap_reset(drvdata);
349 return status;
350 }
351
352 buffer_count = 0;
353 }
354
355
356 data[i] = buffer_icap_get_bram(base_address, buffer_count);
357 buffer_count++;
358 }
359
360 return 0;
361 };