1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) Marvell International Ltd. and its affiliates 4 */ 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 23 static u32 ui_xor_regs_ctrl_backup; 24 static u32 ui_xor_regs_base_backup[MAX_CS]; 25 static u32 ui_xor_regs_mask_backup[MAX_CS]; 26 27 void 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 85 void 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 */ 114 void 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 */ 142 int 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 156 int 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 */ 230 enum 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 */ 278 int 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 327 void 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 } 356