blob: e53834f54a94b7bb65c694a006d7fec4545e2712 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Stefan Roese5ffceb82015-03-26 15:36:56 +01002/*
3 * Copyright (C) Marvell International Ltd. and its affiliates
Stefan Roese5ffceb82015-03-26 15:36:56 +01004 */
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 "ddr3_init.h"
14#include "xor_regs.h"
15
16/* defines */
17#ifdef MV_DEBUG
18#define DB(x) x
19#else
20#define DB(x)
21#endif
22
23static u32 ui_xor_regs_ctrl_backup;
24static u32 ui_xor_regs_base_backup[MAX_CS];
25static u32 ui_xor_regs_mask_backup[MAX_CS];
26
27void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, u32 cs_size, u32 base_delta)
28{
29 u32 reg, ui, base, cs_count;
30
31 ui_xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0));
32 for (ui = 0; ui < MAX_CS; ui++)
33 ui_xor_regs_base_backup[ui] =
34 reg_read(XOR_BASE_ADDR_REG(0, ui));
35 for (ui = 0; ui < MAX_CS; ui++)
36 ui_xor_regs_mask_backup[ui] =
37 reg_read(XOR_SIZE_MASK_REG(0, ui));
38
39 reg = 0;
40 for (ui = 0; ui < (num_of_cs); ui++) {
41 /* Enable Window x for each CS */
42 reg |= (0x1 << (ui));
43 /* Enable Window x for each CS */
44 reg |= (0x3 << ((ui * 2) + 16));
45 }
46
47 reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);
48
49 cs_count = 0;
50 for (ui = 0; ui < num_of_cs; ui++) {
51 if (cs_ena & (1 << ui)) {
52 /*
53 * window x - Base - 0x00000000,
54 * Attribute 0x0e - DRAM
55 */
56 base = cs_size * ui + base_delta;
57 switch (ui) {
58 case 0:
59 base |= 0xe00;
60 break;
61 case 1:
62 base |= 0xd00;
63 break;
64 case 2:
65 base |= 0xb00;
66 break;
67 case 3:
68 base |= 0x700;
69 break;
70 }
71
72 reg_write(XOR_BASE_ADDR_REG(0, cs_count), base);
73
74 /* window x - Size */
75 reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x7fff0000);
76 cs_count++;
77 }
78 }
79
80 mv_xor_hal_init(1);
81
82 return;
83}
84
85void mv_sys_xor_finish(void)
86{
87 u32 ui;
88
89 reg_write(XOR_WINDOW_CTRL_REG(0, 0), ui_xor_regs_ctrl_backup);
90 for (ui = 0; ui < MAX_CS; ui++)
91 reg_write(XOR_BASE_ADDR_REG(0, ui),
92 ui_xor_regs_base_backup[ui]);
93 for (ui = 0; ui < MAX_CS; ui++)
94 reg_write(XOR_SIZE_MASK_REG(0, ui),
95 ui_xor_regs_mask_backup[ui]);
96
97 reg_write(XOR_ADDR_OVRD_REG(0, 0), 0);
98}
99
100/*
101 * mv_xor_hal_init - Initialize XOR engine
102 *
103 * DESCRIPTION:
104 * This function initialize XOR unit.
105 * INPUT:
106 * None.
107 *
108 * OUTPUT:
109 * None.
110 *
111 * RETURN:
112 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
113 */
114void mv_xor_hal_init(u32 xor_chan_num)
115{
116 u32 i;
117
118 /* Abort any XOR activity & set default configuration */
119 for (i = 0; i < xor_chan_num; i++) {
120 mv_xor_command_set(i, MV_STOP);
121 mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) |
122 (4 << XEXCR_DST_BURST_LIMIT_OFFS) |
123 (4 << XEXCR_SRC_BURST_LIMIT_OFFS));
124 }
125}
126
127/*
128 * mv_xor_ctrl_set - Set XOR channel control registers
129 *
130 * DESCRIPTION:
131 *
132 * INPUT:
133 *
134 * OUTPUT:
135 * None.
136 *
137 * RETURN:
138 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
139 * NOTE:
140 * This function does not modify the Operation_mode field of control register.
141 */
142int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
143{
144 u32 old_value;
145
146 /* update the XOR Engine [0..1] Configuration Registers (XEx_c_r) */
147 old_value = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))) &
148 XEXCR_OPERATION_MODE_MASK;
149 xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK;
150 xor_ctrl |= old_value;
151 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl);
152
153 return MV_OK;
154}
155
156int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size,
157 u32 init_val_high, u32 init_val_low)
158{
159 u32 temp;
160
161 /* Parameter checking */
162 if (chan >= MV_XOR_MAX_CHAN)
163 return MV_BAD_PARAM;
164
165 if (MV_ACTIVE == mv_xor_state_get(chan))
166 return MV_BUSY;
167
168 if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) ||
169 (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE))
170 return MV_BAD_PARAM;
171
172 /* set the operation mode to Memory Init */
173 temp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
174 temp &= ~XEXCR_OPERATION_MODE_MASK;
175 temp |= XEXCR_OPERATION_MODE_MEM_INIT;
176 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);
177
178 /*
179 * update the start_ptr field in XOR Engine [0..1] Destination Pointer
180 * Register
181 */
182 reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr);
183
184 /*
185 * update the Block_size field in the XOR Engine[0..1] Block Size
186 * Registers
187 */
188 reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
189 block_size);
190
191 /*
192 * update the field Init_val_l in the XOR Engine Initial Value Register
193 * Low (XEIVRL)
194 */
195 reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low);
196
197 /*
198 * update the field Init_val_h in the XOR Engine Initial Value Register
199 * High (XEIVRH)
200 */
201 reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high);
202
203 /* start transfer */
204 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
205 XEXACTR_XESTART_MASK);
206
207 return MV_OK;
208}
209
210/*
211 * mv_xor_state_get - Get XOR channel state.
212 *
213 * DESCRIPTION:
214 * XOR channel activity state can be active, idle, paused.
215 * This function retrunes the channel activity state.
216 *
217 * INPUT:
218 * chan - the channel number
219 *
220 * OUTPUT:
221 * None.
222 *
223 * RETURN:
224 * XOR_CHANNEL_IDLE - If the engine is idle.
225 * XOR_CHANNEL_ACTIVE - If the engine is busy.
226 * XOR_CHANNEL_PAUSED - If the engine is paused.
227 * MV_UNDEFINED_STATE - If the engine state is undefind or there is no
228 * such engine
229 */
230enum mv_state mv_xor_state_get(u32 chan)
231{
232 u32 state;
233
234 /* Parameter checking */
235 if (chan >= MV_XOR_MAX_CHAN) {
236 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
237 return MV_UNDEFINED_STATE;
238 }
239
240 /* read the current state */
241 state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
242 state &= XEXACTR_XESTATUS_MASK;
243
244 /* return the state */
245 switch (state) {
246 case XEXACTR_XESTATUS_IDLE:
247 return MV_IDLE;
248 case XEXACTR_XESTATUS_ACTIVE:
249 return MV_ACTIVE;
250 case XEXACTR_XESTATUS_PAUSED:
251 return MV_PAUSED;
252 }
253
254 return MV_UNDEFINED_STATE;
255}
256
257/*
258 * mv_xor_command_set - Set command of XOR channel
259 *
260 * DESCRIPTION:
261 * XOR channel can be started, idle, paused and restarted.
262 * Paused can be set only if channel is active.
263 * Start can be set only if channel is idle or paused.
264 * Restart can be set only if channel is paused.
265 * Stop can be set only if channel is active.
266 *
267 * INPUT:
268 * chan - The channel number
269 * command - The command type (start, stop, restart, pause)
270 *
271 * OUTPUT:
272 * None.
273 *
274 * RETURN:
275 * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on
276 * undefind XOR engine mode
277 */
278int mv_xor_command_set(u32 chan, enum mv_command command)
279{
280 enum mv_state state;
281
282 /* Parameter checking */
283 if (chan >= MV_XOR_MAX_CHAN) {
284 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
285 return MV_BAD_PARAM;
286 }
287
288 /* get the current state */
289 state = mv_xor_state_get(chan);
290
291 if ((command == MV_START) && (state == MV_IDLE)) {
292 /* command is start and current state is idle */
293 reg_bit_set(XOR_ACTIVATION_REG
294 (XOR_UNIT(chan), XOR_CHAN(chan)),
295 XEXACTR_XESTART_MASK);
296 return MV_OK;
297 } else if ((command == MV_STOP) && (state == MV_ACTIVE)) {
298 /* command is stop and current state is active */
299 reg_bit_set(XOR_ACTIVATION_REG
300 (XOR_UNIT(chan), XOR_CHAN(chan)),
301 XEXACTR_XESTOP_MASK);
302 return MV_OK;
303 } else if (((enum mv_state)command == MV_PAUSED) &&
304 (state == MV_ACTIVE)) {
305 /* command is paused and current state is active */
306 reg_bit_set(XOR_ACTIVATION_REG
307 (XOR_UNIT(chan), XOR_CHAN(chan)),
308 XEXACTR_XEPAUSE_MASK);
309 return MV_OK;
310 } else if ((command == MV_RESTART) && (state == MV_PAUSED)) {
311 /* command is restart and current state is paused */
312 reg_bit_set(XOR_ACTIVATION_REG
313 (XOR_UNIT(chan), XOR_CHAN(chan)),
314 XEXACTR_XERESTART_MASK);
315 return MV_OK;
316 } else if ((command == MV_STOP) && (state == MV_IDLE)) {
317 /* command is stop and current state is active */
318 return MV_OK;
319 }
320
321 /* illegal command */
322 DB(printf("%s: ERR. Illegal command\n", __func__));
323
324 return MV_BAD_PARAM;
325}
326
327void ddr3_new_tip_ecc_scrub(void)
328{
329 u32 cs_c, max_cs;
330 u32 cs_ena = 0;
331
332 printf("DDR3 Training Sequence - Start scrubbing\n");
333
334 max_cs = hws_ddr3_tip_max_cs_get();
335 for (cs_c = 0; cs_c < max_cs; cs_c++)
336 cs_ena |= 1 << cs_c;
337
338 mv_sys_xor_init(max_cs, cs_ena, 0x80000000, 0);
339
340 mv_xor_mem_init(0, 0x00000000, 0x80000000, 0xdeadbeef, 0xdeadbeef);
341 /* wait for previous transfer completion */
342 while (mv_xor_state_get(0) != MV_IDLE)
343 ;
344
345 mv_xor_mem_init(0, 0x80000000, 0x40000000, 0xdeadbeef, 0xdeadbeef);
346
347 /* wait for previous transfer completion */
348 while (mv_xor_state_get(0) != MV_IDLE)
349 ;
350
351 /* Return XOR State */
352 mv_sys_xor_finish();
353
354 printf("DDR3 Training Sequence - End scrubbing\n");
355}