1 /* 2 * Copyright (C) Marvell International Ltd. and its affiliates 3 * 4 * SPDX-License-Identifier: GPL-2.0 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 /* defines */ 18 #ifdef MV_DEBUG 19 #define DB(x) x 20 #else 21 #define DB(x) 22 #endif 23 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]; 27 28 void 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 /* Enable Window x for each CS */ 43 reg |= (0x1 << (ui)); 44 /* Enable Window x for each CS */ 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 * window x - Base - 0x00000000, 55 * Attribute 0x0e - DRAM 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 /* window x - Size */ 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 86 void 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 * mv_xor_hal_init - Initialize XOR engine 103 * 104 * DESCRIPTION: 105 * This function initialize XOR unit. 106 * INPUT: 107 * None. 108 * 109 * OUTPUT: 110 * None. 111 * 112 * RETURN: 113 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. 114 */ 115 void mv_xor_hal_init(u32 xor_chan_num) 116 { 117 u32 i; 118 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)); 125 } 126 } 127 128 /* 129 * mv_xor_ctrl_set - Set XOR channel control registers 130 * 131 * DESCRIPTION: 132 * 133 * INPUT: 134 * 135 * OUTPUT: 136 * None. 137 * 138 * RETURN: 139 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. 140 * NOTE: 141 * This function does not modify the Operation_mode field of control register. 142 */ 143 int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl) 144 { 145 u32 old_value; 146 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); 153 154 return MV_OK; 155 } 156 157 int 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 /* Parameter checking */ 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 /* 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); 178 179 /* 180 * update the start_ptr field in XOR Engine [0..1] Destination Pointer 181 * Register 182 */ 183 reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr); 184 185 /* 186 * update the Block_size field in the XOR Engine[0..1] Block Size 187 * Registers 188 */ 189 reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 190 block_size); 191 192 /* 193 * update the field Init_val_l in the XOR Engine Initial Value Register 194 * Low (XEIVRL) 195 */ 196 reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low); 197 198 /* 199 * update the field Init_val_h in the XOR Engine Initial Value Register 200 * High (XEIVRH) 201 */ 202 reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high); 203 204 /* start transfer */ 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 * mv_xor_state_get - Get XOR channel state. 213 * 214 * DESCRIPTION: 215 * XOR channel activity state can be active, idle, paused. 216 * This function retrunes the channel activity state. 217 * 218 * INPUT: 219 * chan - the channel number 220 * 221 * OUTPUT: 222 * None. 223 * 224 * RETURN: 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 229 * such engine 230 */ 231 enum mv_state mv_xor_state_get(u32 chan) 232 { 233 u32 state; 234 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; 239 } 240 241 /* read the current state */ 242 state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan))); 243 state &= XEXACTR_XESTATUS_MASK; 244 245 /* return the state */ 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 * mv_xor_command_set - Set command of XOR channel 260 * 261 * DESCRIPTION: 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. 267 * 268 * INPUT: 269 * chan - The channel number 270 * command - The command type (start, stop, restart, pause) 271 * 272 * OUTPUT: 273 * None. 274 * 275 * RETURN: 276 * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on 277 * undefind XOR engine mode 278 */ 279 int mv_xor_command_set(u32 chan, enum mv_command command) 280 { 281 enum mv_state state; 282 283 /* Parameter checking */ 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 /* get the current state */ 290 state = mv_xor_state_get(chan); 291 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); 297 return MV_OK; 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); 303 return MV_OK; 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); 310 return MV_OK; 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); 316 return MV_OK; 317 } else if ((command == MV_STOP) && (state == MV_IDLE)) { 318 /* command is stop and current state is active */ 319 return MV_OK; 320 } 321 322 /* illegal command */ 323 DB(printf("%s: ERR. Illegal command\n", __func__)); 324 325 return MV_BAD_PARAM; 326 } 327 328 void 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 /* wait for previous transfer completion */ 343 while (mv_xor_state_get(0) != MV_IDLE) 344 ; 345 346 mv_xor_mem_init(0, 0x80000000, 0x40000000, 0xdeadbeef, 0xdeadbeef); 347 348 /* wait for previous transfer completion */ 349 while (mv_xor_state_get(0) != MV_IDLE) 350 ; 351 352 /* Return XOR State */ 353 mv_sys_xor_finish(); 354 355 printf("DDR3 Training Sequence - End scrubbing\n"); 356 } 357