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