1
2
3
4
5
6#include <common.h>
7#include <i2c.h>
8#include <spl.h>
9#include <asm/io.h>
10#include <asm/arch/cpu.h>
11#include <asm/arch/soc.h>
12
13#include "xor.h"
14#include "xor_regs.h"
15
16static u32 xor_regs_ctrl_backup;
17static u32 xor_regs_base_backup[MAX_CS];
18static u32 xor_regs_mask_backup[MAX_CS];
19
20static int mv_xor_cmd_set(u32 chan, int command);
21static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl);
22
23void mv_sys_xor_init(MV_DRAM_INFO *dram_info)
24{
25 u32 reg, ui, base, cs_count;
26
27 xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0));
28 for (ui = 0; ui < MAX_CS; ui++)
29 xor_regs_base_backup[ui] = reg_read(XOR_BASE_ADDR_REG(0, ui));
30 for (ui = 0; ui < MAX_CS; ui++)
31 xor_regs_mask_backup[ui] = reg_read(XOR_SIZE_MASK_REG(0, ui));
32
33 reg = 0;
34 for (ui = 0; ui < (dram_info->num_cs + 1); ui++) {
35
36 reg |= (0x1 << (ui));
37
38 reg |= (0x3 << ((ui * 2) + 16));
39 }
40
41 reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);
42
43
44 base = (SRAM_BASE & 0xFFFF0000) | 0x1E00;
45 reg_write(XOR_BASE_ADDR_REG(0, dram_info->num_cs), base);
46
47 reg_write(XOR_SIZE_MASK_REG(0, dram_info->num_cs), 0x03FF0000);
48
49 cs_count = 0;
50 for (ui = 0; ui < MAX_CS; ui++) {
51 if (dram_info->cs_ena & (1 << ui)) {
52
53
54
55 base = 0;
56 switch (ui) {
57 case 0:
58 base |= 0xE00;
59 break;
60 case 1:
61 base |= 0xD00;
62 break;
63 case 2:
64 base |= 0xB00;
65 break;
66 case 3:
67 base |= 0x700;
68 break;
69 }
70
71 reg_write(XOR_BASE_ADDR_REG(0, cs_count), base);
72
73
74 reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x0FFF0000);
75 cs_count++;
76 }
77 }
78
79 mv_xor_hal_init(1);
80
81 return;
82}
83
84void mv_sys_xor_finish(void)
85{
86 u32 ui;
87
88 reg_write(XOR_WINDOW_CTRL_REG(0, 0), xor_regs_ctrl_backup);
89 for (ui = 0; ui < MAX_CS; ui++)
90 reg_write(XOR_BASE_ADDR_REG(0, ui), xor_regs_base_backup[ui]);
91 for (ui = 0; ui < MAX_CS; ui++)
92 reg_write(XOR_SIZE_MASK_REG(0, ui), xor_regs_mask_backup[ui]);
93
94 reg_write(XOR_ADDR_OVRD_REG(0, 0), 0);
95}
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111void mv_xor_hal_init(u32 chan_num)
112{
113 u32 i;
114
115
116 for (i = 0; i < chan_num; i++) {
117 mv_xor_cmd_set(i, MV_STOP);
118 mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) |
119 (4 << XEXCR_DST_BURST_LIMIT_OFFS) |
120 (4 << XEXCR_SRC_BURST_LIMIT_OFFS));
121 }
122}
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
141{
142 u32 val;
143
144
145 val = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)))
146 & XEXCR_OPERATION_MODE_MASK;
147 xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK;
148 xor_ctrl |= val;
149 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl);
150
151 return MV_OK;
152}
153
154int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size, u32 init_val_high,
155 u32 init_val_low)
156{
157 u32 tmp;
158
159
160 if (chan >= MV_XOR_MAX_CHAN)
161 return MV_BAD_PARAM;
162
163 if (MV_ACTIVE == mv_xor_state_get(chan))
164 return MV_BUSY;
165
166 if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) ||
167 (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE))
168 return MV_BAD_PARAM;
169
170
171 tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
172 tmp &= ~XEXCR_OPERATION_MODE_MASK;
173 tmp |= XEXCR_OPERATION_MODE_MEM_INIT;
174 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp);
175
176
177
178
179
180 reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr);
181
182
183
184
185
186 reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
187 block_size);
188
189
190
191
192
193 reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low);
194
195
196
197
198
199 reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high);
200
201
202 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
203 XEXACTR_XESTART_MASK);
204
205 return MV_OK;
206}
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240int mv_xor_transfer(u32 chan, int xor_type, u32 xor_chain_ptr)
241{
242 u32 tmp;
243
244
245 if (chan >= MV_XOR_MAX_CHAN) {
246 debug("%s: ERR. Invalid chan num %d\n", __func__, chan);
247 return MV_BAD_PARAM;
248 }
249
250 if (MV_ACTIVE == mv_xor_state_get(chan)) {
251 debug("%s: ERR. Channel is already active\n", __func__);
252 return MV_BUSY;
253 }
254
255 if (0x0 == xor_chain_ptr) {
256 debug("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__);
257 return MV_BAD_PARAM;
258 }
259
260
261 tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
262 tmp &= ~XEXCR_OPERATION_MODE_MASK;
263
264 switch (xor_type) {
265 case MV_XOR:
266 if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_XOR_MASK)) {
267 debug("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n",
268 __func__);
269 return MV_BAD_PARAM;
270 }
271
272
273 tmp |= XEXCR_OPERATION_MODE_XOR;
274 break;
275
276 case MV_DMA:
277 if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_DMA_MASK)) {
278 debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
279 __func__);
280 return MV_BAD_PARAM;
281 }
282
283
284 tmp |= XEXCR_OPERATION_MODE_DMA;
285 break;
286
287 case MV_CRC32:
288 if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_CRC_MASK)) {
289 debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
290 __func__);
291 return MV_BAD_PARAM;
292 }
293
294
295 tmp |= XEXCR_OPERATION_MODE_CRC;
296 break;
297
298 default:
299 return MV_BAD_PARAM;
300 }
301
302
303 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp);
304
305
306
307
308
309 reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
310 xor_chain_ptr);
311
312
313 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
314 XEXACTR_XESTART_MASK);
315
316 return MV_OK;
317}
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340int mv_xor_state_get(u32 chan)
341{
342 u32 state;
343
344
345 if (chan >= MV_XOR_MAX_CHAN) {
346 debug("%s: ERR. Invalid chan num %d\n", __func__, chan);
347 return MV_UNDEFINED_STATE;
348 }
349
350
351 state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
352 state &= XEXACTR_XESTATUS_MASK;
353
354
355 switch (state) {
356 case XEXACTR_XESTATUS_IDLE:
357 return MV_IDLE;
358 case XEXACTR_XESTATUS_ACTIVE:
359 return MV_ACTIVE;
360 case XEXACTR_XESTATUS_PAUSED:
361 return MV_PAUSED;
362 }
363
364 return MV_UNDEFINED_STATE;
365}
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389static int mv_xor_cmd_set(u32 chan, int command)
390{
391 int state;
392
393
394 if (chan >= MV_XOR_MAX_CHAN) {
395 debug("%s: ERR. Invalid chan num %d\n", __func__, chan);
396 return MV_BAD_PARAM;
397 }
398
399
400 state = mv_xor_state_get(chan);
401
402
403 if ((command == MV_START) && (state == MV_IDLE)) {
404 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
405 XEXACTR_XESTART_MASK);
406 return MV_OK;
407 }
408
409 else if ((command == MV_STOP) && (state == MV_ACTIVE)) {
410 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
411 XEXACTR_XESTOP_MASK);
412 return MV_OK;
413 }
414
415 else if ((command == MV_PAUSED) && (state == MV_ACTIVE)) {
416 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
417 XEXACTR_XEPAUSE_MASK);
418 return MV_OK;
419 }
420
421 else if ((command == MV_RESTART) && (state == MV_PAUSED)) {
422 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
423 XEXACTR_XERESTART_MASK);
424 return MV_OK;
425 }
426
427 else if ((command == MV_STOP) && (state == MV_IDLE))
428 return MV_OK;
429
430
431 debug("%s: ERR. Illegal command\n", __func__);
432
433 return MV_BAD_PARAM;
434}
435