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 "xor.h" 15 #include "xor_regs.h" 16 17 static u32 xor_regs_ctrl_backup; 18 static u32 xor_regs_base_backup[MAX_CS]; 19 static u32 xor_regs_mask_backup[MAX_CS]; 20 21 static void mv_xor_hal_init(u32 chan_num); 22 static int mv_xor_cmd_set(u32 chan, int command); 23 static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl); 24 25 void mv_sys_xor_init(MV_DRAM_INFO *dram_info) 26 { 27 u32 reg, ui, base, cs_count; 28 29 xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0)); 30 for (ui = 0; ui < MAX_CS; ui++) 31 xor_regs_base_backup[ui] = reg_read(XOR_BASE_ADDR_REG(0, ui)); 32 for (ui = 0; ui < MAX_CS; ui++) 33 xor_regs_mask_backup[ui] = reg_read(XOR_SIZE_MASK_REG(0, ui)); 34 35 reg = 0; 36 for (ui = 0; ui < (dram_info->num_cs + 1); ui++) { 37 /* Enable Window x for each CS */ 38 reg |= (0x1 << (ui)); 39 /* Enable Window x for each CS */ 40 reg |= (0x3 << ((ui * 2) + 16)); 41 } 42 43 reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg); 44 45 /* Last window - Base - 0x40000000, Attribute 0x1E - SRAM */ 46 base = (SRAM_BASE & 0xFFFF0000) | 0x1E00; 47 reg_write(XOR_BASE_ADDR_REG(0, dram_info->num_cs), base); 48 /* Last window - Size - 64 MB */ 49 reg_write(XOR_SIZE_MASK_REG(0, dram_info->num_cs), 0x03FF0000); 50 51 cs_count = 0; 52 for (ui = 0; ui < MAX_CS; ui++) { 53 if (dram_info->cs_ena & (1 << ui)) { 54 /* 55 * Window x - Base - 0x00000000, Attribute 0x0E - DRAM 56 */ 57 base = 0; 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 - 256 MB */ 76 reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x0FFF0000); 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), xor_regs_ctrl_backup); 91 for (ui = 0; ui < MAX_CS; ui++) 92 reg_write(XOR_BASE_ADDR_REG(0, ui), xor_regs_base_backup[ui]); 93 for (ui = 0; ui < MAX_CS; ui++) 94 reg_write(XOR_SIZE_MASK_REG(0, ui), xor_regs_mask_backup[ui]); 95 96 reg_write(XOR_ADDR_OVRD_REG(0, 0), 0); 97 } 98 99 /* 100 * mv_xor_hal_init - Initialize XOR engine 101 * 102 * DESCRIPTION: 103 * This function initialize XOR unit. 104 * INPUT: 105 * None. 106 * 107 * OUTPUT: 108 * None. 109 * 110 * RETURN: 111 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. 112 */ 113 static void mv_xor_hal_init(u32 chan_num) 114 { 115 u32 i; 116 117 /* Abort any XOR activity & set default configuration */ 118 for (i = 0; i < chan_num; i++) { 119 mv_xor_cmd_set(i, MV_STOP); 120 mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) | 121 (4 << XEXCR_DST_BURST_LIMIT_OFFS) | 122 (4 << XEXCR_SRC_BURST_LIMIT_OFFS)); 123 } 124 } 125 126 /* 127 * mv_xor_ctrl_set - Set XOR channel control registers 128 * 129 * DESCRIPTION: 130 * 131 * INPUT: 132 * 133 * OUTPUT: 134 * None. 135 * 136 * RETURN: 137 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. 138 * NOTE: 139 * This function does not modify the OperationMode field of control register. 140 * 141 */ 142 static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl) 143 { 144 u32 val; 145 146 /* Update the XOR Engine [0..1] Configuration Registers (XExCR) */ 147 val = 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 |= val; 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, u32 init_val_high, 157 u32 init_val_low) 158 { 159 u32 tmp; 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 tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); 174 tmp &= ~XEXCR_OPERATION_MODE_MASK; 175 tmp |= XEXCR_OPERATION_MODE_MEM_INIT; 176 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp); 177 178 /* 179 * Update the start_ptr field in XOR Engine [0..1] Destination Pointer 180 * Register (XExDPR0) 181 */ 182 reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr); 183 184 /* 185 * Update the BlockSize field in the XOR Engine[0..1] Block Size 186 * Registers (XExBSR) 187 */ 188 reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 189 block_size); 190 191 /* 192 * Update the field InitValL 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 InitValH 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_transfer - Transfer data from source to destination on one of 212 * three modes (XOR,CRC32,DMA) 213 * 214 * DESCRIPTION: 215 * This function initiates XOR channel, according to function parameters, 216 * in order to perform XOR or CRC32 or DMA transaction. 217 * To gain maximum performance the user is asked to keep the following 218 * restrictions: 219 * 1) Selected engine is available (not busy). 220 * 1) This module does not take into consideration CPU MMU issues. 221 * In order for the XOR engine to access the appropreate source 222 * and destination, address parameters must be given in system 223 * physical mode. 224 * 2) This API does not take care of cache coherency issues. The source, 225 * destination and in case of chain the descriptor list are assumed 226 * to be cache coherent. 227 * 4) Parameters validity. For example, does size parameter exceeds 228 * maximum byte count of descriptor mode (16M or 64K). 229 * 230 * INPUT: 231 * chan - XOR channel number. See MV_XOR_CHANNEL enumerator. 232 * xor_type - One of three: XOR, CRC32 and DMA operations. 233 * xor_chain_ptr - address of chain pointer 234 * 235 * OUTPUT: 236 * None. 237 * 238 * RETURS: 239 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. 240 * 241 */ 242 int mv_xor_transfer(u32 chan, int xor_type, u32 xor_chain_ptr) 243 { 244 u32 tmp; 245 246 /* Parameter checking */ 247 if (chan >= MV_XOR_MAX_CHAN) { 248 debug("%s: ERR. Invalid chan num %d\n", __func__, chan); 249 return MV_BAD_PARAM; 250 } 251 252 if (MV_ACTIVE == mv_xor_state_get(chan)) { 253 debug("%s: ERR. Channel is already active\n", __func__); 254 return MV_BUSY; 255 } 256 257 if (0x0 == xor_chain_ptr) { 258 debug("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__); 259 return MV_BAD_PARAM; 260 } 261 262 /* Read configuration register and mask the operation mode field */ 263 tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); 264 tmp &= ~XEXCR_OPERATION_MODE_MASK; 265 266 switch (xor_type) { 267 case MV_XOR: 268 if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_XOR_MASK)) { 269 debug("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n", 270 __func__); 271 return MV_BAD_PARAM; 272 } 273 274 /* Set the operation mode to XOR */ 275 tmp |= XEXCR_OPERATION_MODE_XOR; 276 break; 277 278 case MV_DMA: 279 if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_DMA_MASK)) { 280 debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n", 281 __func__); 282 return MV_BAD_PARAM; 283 } 284 285 /* Set the operation mode to DMA */ 286 tmp |= XEXCR_OPERATION_MODE_DMA; 287 break; 288 289 case MV_CRC32: 290 if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_CRC_MASK)) { 291 debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n", 292 __func__); 293 return MV_BAD_PARAM; 294 } 295 296 /* Set the operation mode to CRC32 */ 297 tmp |= XEXCR_OPERATION_MODE_CRC; 298 break; 299 300 default: 301 return MV_BAD_PARAM; 302 } 303 304 /* Write the operation mode to the register */ 305 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp); 306 307 /* 308 * Update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor 309 * Pointer Register (XExNDPR) 310 */ 311 reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 312 xor_chain_ptr); 313 314 /* Start transfer */ 315 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 316 XEXACTR_XESTART_MASK); 317 318 return MV_OK; 319 } 320 321 /* 322 * mv_xor_state_get - Get XOR channel state. 323 * 324 * DESCRIPTION: 325 * XOR channel activity state can be active, idle, paused. 326 * This function retrunes the channel activity state. 327 * 328 * INPUT: 329 * chan - the channel number 330 * 331 * OUTPUT: 332 * None. 333 * 334 * RETURN: 335 * XOR_CHANNEL_IDLE - If the engine is idle. 336 * XOR_CHANNEL_ACTIVE - If the engine is busy. 337 * XOR_CHANNEL_PAUSED - If the engine is paused. 338 * MV_UNDEFINED_STATE - If the engine state is undefind or there is no 339 * such engine 340 * 341 */ 342 int mv_xor_state_get(u32 chan) 343 { 344 u32 state; 345 346 /* Parameter checking */ 347 if (chan >= MV_XOR_MAX_CHAN) { 348 debug("%s: ERR. Invalid chan num %d\n", __func__, chan); 349 return MV_UNDEFINED_STATE; 350 } 351 352 /* Read the current state */ 353 state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan))); 354 state &= XEXACTR_XESTATUS_MASK; 355 356 /* Return the state */ 357 switch (state) { 358 case XEXACTR_XESTATUS_IDLE: 359 return MV_IDLE; 360 case XEXACTR_XESTATUS_ACTIVE: 361 return MV_ACTIVE; 362 case XEXACTR_XESTATUS_PAUSED: 363 return MV_PAUSED; 364 } 365 366 return MV_UNDEFINED_STATE; 367 } 368 369 /* 370 * mv_xor_cmd_set - Set command of XOR channel 371 * 372 * DESCRIPTION: 373 * XOR channel can be started, idle, paused and restarted. 374 * Paused can be set only if channel is active. 375 * Start can be set only if channel is idle or paused. 376 * Restart can be set only if channel is paused. 377 * Stop can be set only if channel is active. 378 * 379 * INPUT: 380 * chan - The channel number 381 * command - The command type (start, stop, restart, pause) 382 * 383 * OUTPUT: 384 * None. 385 * 386 * RETURN: 387 * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on 388 * undefind XOR engine mode 389 * 390 */ 391 static int mv_xor_cmd_set(u32 chan, int command) 392 { 393 int state; 394 395 /* Parameter checking */ 396 if (chan >= MV_XOR_MAX_CHAN) { 397 debug("%s: ERR. Invalid chan num %d\n", __func__, chan); 398 return MV_BAD_PARAM; 399 } 400 401 /* Get the current state */ 402 state = mv_xor_state_get(chan); 403 404 /* Command is start and current state is idle */ 405 if ((command == MV_START) && (state == MV_IDLE)) { 406 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 407 XEXACTR_XESTART_MASK); 408 return MV_OK; 409 } 410 /* Command is stop and current state is active */ 411 else if ((command == MV_STOP) && (state == MV_ACTIVE)) { 412 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 413 XEXACTR_XESTOP_MASK); 414 return MV_OK; 415 } 416 /* Command is paused and current state is active */ 417 else if ((command == MV_PAUSED) && (state == MV_ACTIVE)) { 418 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 419 XEXACTR_XEPAUSE_MASK); 420 return MV_OK; 421 } 422 /* Command is restart and current state is paused */ 423 else if ((command == MV_RESTART) && (state == MV_PAUSED)) { 424 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), 425 XEXACTR_XERESTART_MASK); 426 return MV_OK; 427 } 428 /* Command is stop and current state is active */ 429 else if ((command == MV_STOP) && (state == MV_IDLE)) 430 return MV_OK; 431 432 /* Illegal command */ 433 debug("%s: ERR. Illegal command\n", __func__); 434 435 return MV_BAD_PARAM; 436 } 437