1
2
3
4
5
6
7#include <common.h>
8#include <i2c.h>
9#include <spl.h>
10#include <asm/io.h>
11#include <asm/arch/cpu.h>
12#include <asm/arch/soc.h>
13
14#include "ddr3_init.h"
15#include "xor_regs.h"
16
17
18#ifdef MV_DEBUG
19#define DB(x) x
20#else
21#define DB(x)
22#endif
23
24static u32 ui_xor_regs_ctrl_backup;
25static u32 ui_xor_regs_base_backup[MAX_CS];
26static u32 ui_xor_regs_mask_backup[MAX_CS];
27
28void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, u32 cs_size, u32 base_delta)
29{
30 u32 reg, ui, base, cs_count;
31
32 ui_xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0));
33 for (ui = 0; ui < MAX_CS; ui++)
34 ui_xor_regs_base_backup[ui] =
35 reg_read(XOR_BASE_ADDR_REG(0, ui));
36 for (ui = 0; ui < MAX_CS; ui++)
37 ui_xor_regs_mask_backup[ui] =
38 reg_read(XOR_SIZE_MASK_REG(0, ui));
39
40 reg = 0;
41 for (ui = 0; ui < (num_of_cs); ui++) {
42
43 reg |= (0x1 << (ui));
44
45 reg |= (0x3 << ((ui * 2) + 16));
46 }
47
48 reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);
49
50 cs_count = 0;
51 for (ui = 0; ui < num_of_cs; ui++) {
52 if (cs_ena & (1 << ui)) {
53
54
55
56
57 base = cs_size * ui + base_delta;
58 switch (ui) {
59 case 0:
60 base |= 0xe00;
61 break;
62 case 1:
63 base |= 0xd00;
64 break;
65 case 2:
66 base |= 0xb00;
67 break;
68 case 3:
69 base |= 0x700;
70 break;
71 }
72
73 reg_write(XOR_BASE_ADDR_REG(0, cs_count), base);
74
75
76 reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x7fff0000);
77 cs_count++;
78 }
79 }
80
81 mv_xor_hal_init(1);
82
83 return;
84}
85
86void mv_sys_xor_finish(void)
87{
88 u32 ui;
89
90 reg_write(XOR_WINDOW_CTRL_REG(0, 0), ui_xor_regs_ctrl_backup);
91 for (ui = 0; ui < MAX_CS; ui++)
92 reg_write(XOR_BASE_ADDR_REG(0, ui),
93 ui_xor_regs_base_backup[ui]);
94 for (ui = 0; ui < MAX_CS; ui++)
95 reg_write(XOR_SIZE_MASK_REG(0, ui),
96 ui_xor_regs_mask_backup[ui]);
97
98 reg_write(XOR_ADDR_OVRD_REG(0, 0), 0);
99}
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115void mv_xor_hal_init(u32 xor_chan_num)
116{
117 u32 i;
118
119
120 for (i = 0; i < xor_chan_num; i++) {
121 mv_xor_command_set(i, MV_STOP);
122 mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) |
123 (4 << XEXCR_DST_BURST_LIMIT_OFFS) |
124 (4 << XEXCR_SRC_BURST_LIMIT_OFFS));
125 }
126}
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
144{
145 u32 old_value;
146
147
148 old_value = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))) &
149 XEXCR_OPERATION_MODE_MASK;
150 xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK;
151 xor_ctrl |= old_value;
152 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl);
153
154 return MV_OK;
155}
156
157int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size,
158 u32 init_val_high, u32 init_val_low)
159{
160 u32 temp;
161
162
163 if (chan >= MV_XOR_MAX_CHAN)
164 return MV_BAD_PARAM;
165
166 if (MV_ACTIVE == mv_xor_state_get(chan))
167 return MV_BUSY;
168
169 if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) ||
170 (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE))
171 return MV_BAD_PARAM;
172
173
174 temp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
175 temp &= ~XEXCR_OPERATION_MODE_MASK;
176 temp |= XEXCR_OPERATION_MODE_MEM_INIT;
177 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);
178
179
180
181
182
183 reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr);
184
185
186
187
188
189 reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
190 block_size);
191
192
193
194
195
196 reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low);
197
198
199
200
201
202 reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high);
203
204
205 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
206 XEXACTR_XESTART_MASK);
207
208 return MV_OK;
209}
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231enum mv_state mv_xor_state_get(u32 chan)
232{
233 u32 state;
234
235
236 if (chan >= MV_XOR_MAX_CHAN) {
237 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
238 return MV_UNDEFINED_STATE;
239 }
240
241
242 state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
243 state &= XEXACTR_XESTATUS_MASK;
244
245
246 switch (state) {
247 case XEXACTR_XESTATUS_IDLE:
248 return MV_IDLE;
249 case XEXACTR_XESTATUS_ACTIVE:
250 return MV_ACTIVE;
251 case XEXACTR_XESTATUS_PAUSED:
252 return MV_PAUSED;
253 }
254
255 return MV_UNDEFINED_STATE;
256}
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279int mv_xor_command_set(u32 chan, enum mv_command command)
280{
281 enum mv_state state;
282
283
284 if (chan >= MV_XOR_MAX_CHAN) {
285 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
286 return MV_BAD_PARAM;
287 }
288
289
290 state = mv_xor_state_get(chan);
291
292 if ((command == MV_START) && (state == MV_IDLE)) {
293
294 reg_bit_set(XOR_ACTIVATION_REG
295 (XOR_UNIT(chan), XOR_CHAN(chan)),
296 XEXACTR_XESTART_MASK);
297 return MV_OK;
298 } else if ((command == MV_STOP) && (state == MV_ACTIVE)) {
299
300 reg_bit_set(XOR_ACTIVATION_REG
301 (XOR_UNIT(chan), XOR_CHAN(chan)),
302 XEXACTR_XESTOP_MASK);
303 return MV_OK;
304 } else if (((enum mv_state)command == MV_PAUSED) &&
305 (state == MV_ACTIVE)) {
306
307 reg_bit_set(XOR_ACTIVATION_REG
308 (XOR_UNIT(chan), XOR_CHAN(chan)),
309 XEXACTR_XEPAUSE_MASK);
310 return MV_OK;
311 } else if ((command == MV_RESTART) && (state == MV_PAUSED)) {
312
313 reg_bit_set(XOR_ACTIVATION_REG
314 (XOR_UNIT(chan), XOR_CHAN(chan)),
315 XEXACTR_XERESTART_MASK);
316 return MV_OK;
317 } else if ((command == MV_STOP) && (state == MV_IDLE)) {
318
319 return MV_OK;
320 }
321
322
323 DB(printf("%s: ERR. Illegal command\n", __func__));
324
325 return MV_BAD_PARAM;
326}
327
328void ddr3_new_tip_ecc_scrub(void)
329{
330 u32 cs_c, max_cs;
331 u32 cs_ena = 0;
332
333 printf("DDR3 Training Sequence - Start scrubbing\n");
334
335 max_cs = hws_ddr3_tip_max_cs_get();
336 for (cs_c = 0; cs_c < max_cs; cs_c++)
337 cs_ena |= 1 << cs_c;
338
339 mv_sys_xor_init(max_cs, cs_ena, 0x80000000, 0);
340
341 mv_xor_mem_init(0, 0x00000000, 0x80000000, 0xdeadbeef, 0xdeadbeef);
342
343 while (mv_xor_state_get(0) != MV_IDLE)
344 ;
345
346 mv_xor_mem_init(0, 0x80000000, 0x40000000, 0xdeadbeef, 0xdeadbeef);
347
348
349 while (mv_xor_state_get(0) != MV_IDLE)
350 ;
351
352
353 mv_sys_xor_finish();
354
355 printf("DDR3 Training Sequence - End scrubbing\n");
356}
357