2 * Copyright (C) Marvell International Ltd. and its affiliates
4 * SPDX-License-Identifier: GPL-2.0
11 #include <asm/arch/cpu.h>
12 #include <asm/arch/soc.h>
14 #include "ddr3_init.h"
24 static u32 ui_xor_regs_ctrl_backup;
25 static u32 ui_xor_regs_base_backup[MAX_CS];
26 static u32 ui_xor_regs_mask_backup[MAX_CS];
28 void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, u32 cs_size, u32 base_delta)
30 u32 reg, ui, base, cs_count;
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));
41 for (ui = 0; ui < (num_of_cs); ui++) {
42 /* Enable Window x for each CS */
44 /* Enable Window x for each CS */
45 reg |= (0x3 << ((ui * 2) + 16));
48 reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);
51 for (ui = 0; ui < num_of_cs; ui++) {
52 if (cs_ena & (1 << ui)) {
54 * window x - Base - 0x00000000,
55 * Attribute 0x0e - DRAM
57 base = cs_size * ui + base_delta;
73 reg_write(XOR_BASE_ADDR_REG(0, cs_count), base);
76 reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x7fff0000);
86 void mv_sys_xor_finish(void)
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]);
98 reg_write(XOR_ADDR_OVRD_REG(0, 0), 0);
102 * mv_xor_hal_init - Initialize XOR engine
105 * This function initialize XOR unit.
113 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
115 void mv_xor_hal_init(u32 xor_chan_num)
119 /* Abort any XOR activity & set default configuration */
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));
129 * mv_xor_ctrl_set - Set XOR channel control registers
139 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
141 * This function does not modify the Operation_mode field of control register.
143 int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
147 /* update the XOR Engine [0..1] Configuration Registers (XEx_c_r) */
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);
157 int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size,
158 u32 init_val_high, u32 init_val_low)
162 /* Parameter checking */
163 if (chan >= MV_XOR_MAX_CHAN)
166 if (MV_ACTIVE == mv_xor_state_get(chan))
169 if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) ||
170 (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE))
173 /* set the operation mode to Memory Init */
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);
180 * update the start_ptr field in XOR Engine [0..1] Destination Pointer
183 reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr);
186 * update the Block_size field in the XOR Engine[0..1] Block Size
189 reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
193 * update the field Init_val_l in the XOR Engine Initial Value Register
196 reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low);
199 * update the field Init_val_h in the XOR Engine Initial Value Register
202 reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high);
205 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
206 XEXACTR_XESTART_MASK);
212 * mv_xor_state_get - Get XOR channel state.
215 * XOR channel activity state can be active, idle, paused.
216 * This function retrunes the channel activity state.
219 * chan - the channel number
225 * XOR_CHANNEL_IDLE - If the engine is idle.
226 * XOR_CHANNEL_ACTIVE - If the engine is busy.
227 * XOR_CHANNEL_PAUSED - If the engine is paused.
228 * MV_UNDEFINED_STATE - If the engine state is undefind or there is no
231 enum mv_state mv_xor_state_get(u32 chan)
235 /* Parameter checking */
236 if (chan >= MV_XOR_MAX_CHAN) {
237 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
238 return MV_UNDEFINED_STATE;
241 /* read the current state */
242 state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
243 state &= XEXACTR_XESTATUS_MASK;
245 /* return the state */
247 case XEXACTR_XESTATUS_IDLE:
249 case XEXACTR_XESTATUS_ACTIVE:
251 case XEXACTR_XESTATUS_PAUSED:
255 return MV_UNDEFINED_STATE;
259 * mv_xor_command_set - Set command of XOR channel
262 * XOR channel can be started, idle, paused and restarted.
263 * Paused can be set only if channel is active.
264 * Start can be set only if channel is idle or paused.
265 * Restart can be set only if channel is paused.
266 * Stop can be set only if channel is active.
269 * chan - The channel number
270 * command - The command type (start, stop, restart, pause)
276 * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on
277 * undefind XOR engine mode
279 int mv_xor_command_set(u32 chan, enum mv_command command)
283 /* Parameter checking */
284 if (chan >= MV_XOR_MAX_CHAN) {
285 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
289 /* get the current state */
290 state = mv_xor_state_get(chan);
292 if ((command == MV_START) && (state == MV_IDLE)) {
293 /* command is start and current state is idle */
294 reg_bit_set(XOR_ACTIVATION_REG
295 (XOR_UNIT(chan), XOR_CHAN(chan)),
296 XEXACTR_XESTART_MASK);
298 } else if ((command == MV_STOP) && (state == MV_ACTIVE)) {
299 /* command is stop and current state is active */
300 reg_bit_set(XOR_ACTIVATION_REG
301 (XOR_UNIT(chan), XOR_CHAN(chan)),
302 XEXACTR_XESTOP_MASK);
304 } else if (((enum mv_state)command == MV_PAUSED) &&
305 (state == MV_ACTIVE)) {
306 /* command is paused and current state is active */
307 reg_bit_set(XOR_ACTIVATION_REG
308 (XOR_UNIT(chan), XOR_CHAN(chan)),
309 XEXACTR_XEPAUSE_MASK);
311 } else if ((command == MV_RESTART) && (state == MV_PAUSED)) {
312 /* command is restart and current state is paused */
313 reg_bit_set(XOR_ACTIVATION_REG
314 (XOR_UNIT(chan), XOR_CHAN(chan)),
315 XEXACTR_XERESTART_MASK);
317 } else if ((command == MV_STOP) && (state == MV_IDLE)) {
318 /* command is stop and current state is active */
322 /* illegal command */
323 DB(printf("%s: ERR. Illegal command\n", __func__));
328 void ddr3_new_tip_ecc_scrub(void)
333 printf("DDR3 Training Sequence - Start scrubbing\n");
335 max_cs = hws_ddr3_tip_max_cs_get();
336 for (cs_c = 0; cs_c < max_cs; cs_c++)
339 mv_sys_xor_init(max_cs, cs_ena, 0x80000000, 0);
341 mv_xor_mem_init(0, 0x00000000, 0x80000000, 0xdeadbeef, 0xdeadbeef);
342 /* wait for previous transfer completion */
343 while (mv_xor_state_get(0) != MV_IDLE)
346 mv_xor_mem_init(0, 0x80000000, 0x40000000, 0xdeadbeef, 0xdeadbeef);
348 /* wait for previous transfer completion */
349 while (mv_xor_state_get(0) != MV_IDLE)
352 /* Return XOR State */
355 printf("DDR3 Training Sequence - End scrubbing\n");