1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) Marvell International Ltd. and its affiliates 4 */ 5 6 #include "ddr3_init.h" 7 #include "xor_regs.h" 8 9 /* defines */ 10 #ifdef MV_DEBUG 11 #define DB(x) x 12 #else 13 #define DB(x) 14 #endif 15 16 static u32 ui_xor_regs_ctrl_backup; 17 static u32 ui_xor_regs_base_backup[MAX_CS_NUM + 1]; 18 static u32 ui_xor_regs_mask_backup[MAX_CS_NUM + 1]; 19 20 void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, uint64_t cs_size, u32 base_delta) 21 { 22 u32 reg, ui, cs_count; 23 uint64_t base, size_mask; 24 25 ui_xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0)); 26 for (ui = 0; ui < MAX_CS_NUM + 1; ui++) 27 ui_xor_regs_base_backup[ui] = 28 reg_read(XOR_BASE_ADDR_REG(0, ui)); 29 for (ui = 0; ui < MAX_CS_NUM + 1; ui++) 30 ui_xor_regs_mask_backup[ui] = 31 reg_read(XOR_SIZE_MASK_REG(0, ui)); 32 33 reg = 0; 34 for (ui = 0, cs_count = 0; 35 (cs_count < num_of_cs) && (ui < 8); 36 ui++, cs_count++) { 37 if (cs_ena & (1 << ui)) { 38 /* Enable Window x for each CS */ 39 reg |= (0x1 << (ui)); 40 /* Enable Window x for each CS */ 41 reg |= (0x3 << ((ui * 2) + 16)); 42 } 43 } 44 45 reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg); 46 47 cs_count = 0; 48 for (ui = 0, cs_count = 0; 49 (cs_count < num_of_cs) && (ui < 8); 50 ui++, cs_count++) { 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 /* fixed size 2GB for each CS */ 58 size_mask = 0x7FFF0000; 59 switch (ui) { 60 case 0: 61 base |= 0xe00; 62 break; 63 case 1: 64 base |= 0xd00; 65 break; 66 case 2: 67 base |= 0xb00; 68 break; 69 case 3: 70 base |= 0x700; 71 break; 72 case 4: /* SRAM */ 73 base = 0x40000000; 74 /* configure as shared transaction */ 75 base |= 0x1F00; 76 size_mask = 0xF0000; 77 break; 78 } 79 80 reg_write(XOR_BASE_ADDR_REG(0, ui), (u32)base); 81 size_mask = (cs_size / _64K) - 1; 82 size_mask = (size_mask << XESMRX_SIZE_MASK_OFFS) & XESMRX_SIZE_MASK_MASK; 83 /* window x - Size */ 84 reg_write(XOR_SIZE_MASK_REG(0, ui), (u32)size_mask); 85 } 86 } 87 88 mv_xor_hal_init(1); 89 90 return; 91 } 92 93 void mv_sys_xor_finish(void) 94 { 95 u32 ui; 96 97 reg_write(XOR_WINDOW_CTRL_REG(0, 0), ui_xor_regs_ctrl_backup); 98 for (ui = 0; ui < MAX_CS_NUM + 1; ui++) 99 reg_write(XOR_BASE_ADDR_REG(0, ui), 100 ui_xor_regs_base_backup[ui]); 101 for (ui = 0; ui < MAX_CS_NUM + 1; ui++) 102 reg_write(XOR_SIZE_MASK_REG(0, ui), 103 ui_xor_regs_mask_backup[ui]); 104 105 reg_write(XOR_ADDR_OVRD_REG(0, 0), 0); 106 } 107 108 /* 109 * mv_xor_hal_init - Initialize XOR engine 110 * 111 * DESCRIPTION: 112 * This function initialize XOR unit. 113 * INPUT: 114 * None. 115 * 116 * OUTPUT: 117 * None. 118 * 119 * RETURN: 120 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. 121 */ 122 void mv_xor_hal_init(u32 xor_chan_num) 123 { 124 u32 i; 125 126 /* Abort any XOR activity & set default configuration */ 127 for (i = 0; i < xor_chan_num; i++) { 128 mv_xor_command_set(i, MV_STOP); 129 mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) | 130 (4 << XEXCR_DST_BURST_LIMIT_OFFS) | 131 (4 << XEXCR_SRC_BURST_LIMIT_OFFS)); 132 } 133 } 134 135 /* 136 * mv_xor_ctrl_set - Set XOR channel control registers 137 * 138 * DESCRIPTION: 139 * 140 * INPUT: 141 * 142 * OUTPUT: 143 * None. 144 * 145 * RETURN: 146 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. 147 * NOTE: 148 * This function does not modify the Operation_mode field of control register. 149 */ 150 int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl) 151 { 152 u32 old_value; 153 154 /* update the XOR Engine [0..1] Configuration Registers (XEx_c_r) */ 155 old_value = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))) & 156 XEXCR_OPERATION_MODE_MASK; 157 xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK; 158 xor_ctrl |= old_value; 159 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl); 160 161 return MV_OK; 162 } 163 164 int mv_xor_mem_init(u32 chan, u32 start_ptr, unsigned long long block_size, 165 u32 init_val_high, u32 init_val_low) 166 { 167 u32 temp; 168 169 if (block_size == _4G) 170 block_size -= 1; 171 172 /* Parameter checking */ 173 if (chan >= MV_XOR_MAX_CHAN) 174 return MV_BAD_PARAM; 175 176 if (MV_ACTIVE == mv_xor_state_get(chan)) 177 return MV_BUSY; 178 179 if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) || 180 (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE)) 181 return MV_BAD_PARAM; 182 183 /* set the operation mode to Memory Init */ 184 temp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); 185 temp &= ~XEXCR_OPERATION_MODE_MASK; 186 temp |= XEXCR_OPERATION_MODE_MEM_INIT; 187 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp); 188 189 /* 190 * update the start_ptr field in XOR Engine [0..1] Destination Pointer 191 * Register 192 */ 193 reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr); 194 195 /* 196 * update the Block_size field in the XOR Engine[0..1] Block Size 197 * Registers 198 */ 199 reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 200 block_size); 201 202 /* 203 * update the field Init_val_l in the XOR Engine Initial Value Register 204 * Low (XEIVRL) 205 */ 206 reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low); 207 208 /* 209 * update the field Init_val_h in the XOR Engine Initial Value Register 210 * High (XEIVRH) 211 */ 212 reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high); 213 214 /* start transfer */ 215 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 216 XEXACTR_XESTART_MASK); 217 218 return MV_OK; 219 } 220 221 /* 222 * mv_xor_state_get - Get XOR channel state. 223 * 224 * DESCRIPTION: 225 * XOR channel activity state can be active, idle, paused. 226 * This function retrunes the channel activity state. 227 * 228 * INPUT: 229 * chan - the channel number 230 * 231 * OUTPUT: 232 * None. 233 * 234 * RETURN: 235 * XOR_CHANNEL_IDLE - If the engine is idle. 236 * XOR_CHANNEL_ACTIVE - If the engine is busy. 237 * XOR_CHANNEL_PAUSED - If the engine is paused. 238 * MV_UNDEFINED_STATE - If the engine state is undefind or there is no 239 * such engine 240 */ 241 enum mv_state mv_xor_state_get(u32 chan) 242 { 243 u32 state; 244 245 /* Parameter checking */ 246 if (chan >= MV_XOR_MAX_CHAN) { 247 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan)); 248 return MV_UNDEFINED_STATE; 249 } 250 251 /* read the current state */ 252 state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan))); 253 state &= XEXACTR_XESTATUS_MASK; 254 255 /* return the state */ 256 switch (state) { 257 case XEXACTR_XESTATUS_IDLE: 258 return MV_IDLE; 259 case XEXACTR_XESTATUS_ACTIVE: 260 return MV_ACTIVE; 261 case XEXACTR_XESTATUS_PAUSED: 262 return MV_PAUSED; 263 } 264 265 return MV_UNDEFINED_STATE; 266 } 267 268 /* 269 * mv_xor_command_set - Set command of XOR channel 270 * 271 * DESCRIPTION: 272 * XOR channel can be started, idle, paused and restarted. 273 * Paused can be set only if channel is active. 274 * Start can be set only if channel is idle or paused. 275 * Restart can be set only if channel is paused. 276 * Stop can be set only if channel is active. 277 * 278 * INPUT: 279 * chan - The channel number 280 * command - The command type (start, stop, restart, pause) 281 * 282 * OUTPUT: 283 * None. 284 * 285 * RETURN: 286 * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on 287 * undefind XOR engine mode 288 */ 289 int mv_xor_command_set(u32 chan, enum mv_command command) 290 { 291 enum mv_state state; 292 293 /* Parameter checking */ 294 if (chan >= MV_XOR_MAX_CHAN) { 295 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan)); 296 return MV_BAD_PARAM; 297 } 298 299 /* get the current state */ 300 state = mv_xor_state_get(chan); 301 302 if ((command == MV_START) && (state == MV_IDLE)) { 303 /* command is start and current state is idle */ 304 reg_bit_set(XOR_ACTIVATION_REG 305 (XOR_UNIT(chan), XOR_CHAN(chan)), 306 XEXACTR_XESTART_MASK); 307 return MV_OK; 308 } else if ((command == MV_STOP) && (state == MV_ACTIVE)) { 309 /* command is stop and current state is active */ 310 reg_bit_set(XOR_ACTIVATION_REG 311 (XOR_UNIT(chan), XOR_CHAN(chan)), 312 XEXACTR_XESTOP_MASK); 313 return MV_OK; 314 } else if (((enum mv_state)command == MV_PAUSED) && 315 (state == MV_ACTIVE)) { 316 /* command is paused and current state is active */ 317 reg_bit_set(XOR_ACTIVATION_REG 318 (XOR_UNIT(chan), XOR_CHAN(chan)), 319 XEXACTR_XEPAUSE_MASK); 320 return MV_OK; 321 } else if ((command == MV_RESTART) && (state == MV_PAUSED)) { 322 /* command is restart and current state is paused */ 323 reg_bit_set(XOR_ACTIVATION_REG 324 (XOR_UNIT(chan), XOR_CHAN(chan)), 325 XEXACTR_XERESTART_MASK); 326 return MV_OK; 327 } else if ((command == MV_STOP) && (state == MV_IDLE)) { 328 /* command is stop and current state is active */ 329 return MV_OK; 330 } 331 332 /* illegal command */ 333 DB(printf("%s: ERR. Illegal command\n", __func__)); 334 335 return MV_BAD_PARAM; 336 } 337 338 void ddr3_new_tip_ecc_scrub(void) 339 { 340 u32 cs_c, max_cs; 341 u32 cs_ena = 0; 342 u32 dev_num = 0; 343 uint64_t total_mem_size, cs_mem_size = 0; 344 345 printf("DDR Training Sequence - Start scrubbing\n"); 346 max_cs = ddr3_tip_max_cs_get(dev_num); 347 for (cs_c = 0; cs_c < max_cs; cs_c++) 348 cs_ena |= 1 << cs_c; 349 350 /* assume that all CS have same size */ 351 ddr3_calc_mem_cs_size(0, &cs_mem_size); 352 353 mv_sys_xor_init(max_cs, cs_ena, cs_mem_size, 0); 354 total_mem_size = max_cs * cs_mem_size; 355 mv_xor_mem_init(0, 0, total_mem_size, 0xdeadbeef, 0xdeadbeef); 356 /* wait for previous transfer completion */ 357 while (mv_xor_state_get(0) != MV_IDLE) 358 ; 359 /* Return XOR State */ 360 mv_sys_xor_finish(); 361 362 printf("DDR3 Training Sequence - End scrubbing\n"); 363 } 364 365 /* 366 * mv_xor_transfer - Transfer data from source to destination in one of 367 * three modes: XOR, CRC32 or DMA 368 * 369 * DESCRIPTION: 370 * This function initiates XOR channel, according to function parameters, 371 * in order to perform XOR, CRC32 or DMA transaction. 372 * To gain maximum performance the user is asked to keep the following 373 * restrictions: 374 * 1) Selected engine is available (not busy). 375 * 2) This module does not take into consideration CPU MMU issues. 376 * In order for the XOR engine to access the appropriate source 377 * and destination, address parameters must be given in system 378 * physical mode. 379 * 3) This API does not take care of cache coherency issues. The source, 380 * destination and, in case of chain, the descriptor list are assumed 381 * to be cache coherent. 382 * 4) Parameters validity. 383 * 384 * INPUT: 385 * chan - XOR channel number. 386 * type - One of three: XOR, CRC32 and DMA operations. 387 * xor_chain_ptr - address of chain pointer 388 * 389 * OUTPUT: 390 * None. 391 * 392 * RETURN: 393 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. 394 * 395 *******************************************************************************/ 396 int mv_xor_transfer(u32 chan, enum xor_type type, u32 xor_chain_ptr) 397 { 398 u32 temp; 399 400 /* Parameter checking */ 401 if (chan >= MV_XOR_MAX_CHAN) { 402 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan)); 403 return MV_BAD_PARAM; 404 } 405 if (mv_xor_state_get(chan) == MV_ACTIVE) { 406 DB(printf("%s: ERR. Channel is already active\n", __func__)); 407 return MV_BUSY; 408 } 409 if (xor_chain_ptr == 0x0) { 410 DB(printf("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__)); 411 return MV_BAD_PARAM; 412 } 413 414 /* read configuration register and mask the operation mode field */ 415 temp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); 416 temp &= ~XEXCR_OPERATION_MODE_MASK; 417 418 switch (type) { 419 case MV_XOR: 420 if ((xor_chain_ptr & XEXDPR_DST_PTR_XOR_MASK) != 0) { 421 DB(printf("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n", 422 __func__)); 423 return MV_BAD_PARAM; 424 } 425 /* set the operation mode to XOR */ 426 temp |= XEXCR_OPERATION_MODE_XOR; 427 break; 428 case MV_DMA: 429 if ((xor_chain_ptr & XEXDPR_DST_PTR_DMA_MASK) != 0) { 430 DB(printf("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n", 431 __func__)); 432 return MV_BAD_PARAM; 433 } 434 /* set the operation mode to DMA */ 435 temp |= XEXCR_OPERATION_MODE_DMA; 436 break; 437 case MV_CRC32: 438 if ((xor_chain_ptr & XEXDPR_DST_PTR_CRC_MASK) != 0) { 439 DB(printf("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n", 440 __func__)); 441 return MV_BAD_PARAM; 442 } 443 /* set the operation mode to CRC32 */ 444 temp |= XEXCR_OPERATION_MODE_CRC; 445 break; 446 default: 447 return MV_BAD_PARAM; 448 } 449 450 /* write the operation mode to the register */ 451 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp); 452 /* 453 * update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor 454 * Pointer Register (XExNDPR) 455 */ 456 reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 457 xor_chain_ptr); 458 459 /* start transfer */ 460 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 461 XEXACTR_XESTART_MASK); 462 463 return MV_OK; 464 } 465