1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) Marvell International Ltd. and its affiliates
10 #include <asm/arch/cpu.h>
11 #include <asm/arch/soc.h>
16 static u32 xor_regs_ctrl_backup
;
17 static u32 xor_regs_base_backup
[MAX_CS
];
18 static u32 xor_regs_mask_backup
[MAX_CS
];
20 static int mv_xor_cmd_set(u32 chan
, int command
);
21 static int mv_xor_ctrl_set(u32 chan
, u32 xor_ctrl
);
23 void mv_sys_xor_init(MV_DRAM_INFO
*dram_info
)
25 u32 reg
, ui
, base
, cs_count
;
27 xor_regs_ctrl_backup
= reg_read(XOR_WINDOW_CTRL_REG(0, 0));
28 for (ui
= 0; ui
< MAX_CS
; ui
++)
29 xor_regs_base_backup
[ui
] = reg_read(XOR_BASE_ADDR_REG(0, ui
));
30 for (ui
= 0; ui
< MAX_CS
; ui
++)
31 xor_regs_mask_backup
[ui
] = reg_read(XOR_SIZE_MASK_REG(0, ui
));
34 for (ui
= 0; ui
< (dram_info
->num_cs
+ 1); ui
++) {
35 /* Enable Window x for each CS */
37 /* Enable Window x for each CS */
38 reg
|= (0x3 << ((ui
* 2) + 16));
41 reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg
);
43 /* Last window - Base - 0x40000000, Attribute 0x1E - SRAM */
44 base
= (SRAM_BASE
& 0xFFFF0000) | 0x1E00;
45 reg_write(XOR_BASE_ADDR_REG(0, dram_info
->num_cs
), base
);
46 /* Last window - Size - 64 MB */
47 reg_write(XOR_SIZE_MASK_REG(0, dram_info
->num_cs
), 0x03FF0000);
50 for (ui
= 0; ui
< MAX_CS
; ui
++) {
51 if (dram_info
->cs_ena
& (1 << ui
)) {
53 * Window x - Base - 0x00000000, Attribute 0x0E - DRAM
71 reg_write(XOR_BASE_ADDR_REG(0, cs_count
), base
);
73 /* Window x - Size - 256 MB */
74 reg_write(XOR_SIZE_MASK_REG(0, cs_count
), 0x0FFF0000);
84 void mv_sys_xor_finish(void)
88 reg_write(XOR_WINDOW_CTRL_REG(0, 0), xor_regs_ctrl_backup
);
89 for (ui
= 0; ui
< MAX_CS
; ui
++)
90 reg_write(XOR_BASE_ADDR_REG(0, ui
), xor_regs_base_backup
[ui
]);
91 for (ui
= 0; ui
< MAX_CS
; ui
++)
92 reg_write(XOR_SIZE_MASK_REG(0, ui
), xor_regs_mask_backup
[ui
]);
94 reg_write(XOR_ADDR_OVRD_REG(0, 0), 0);
98 * mv_xor_hal_init - Initialize XOR engine
101 * This function initialize XOR unit.
109 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
111 void mv_xor_hal_init(u32 chan_num
)
115 /* Abort any XOR activity & set default configuration */
116 for (i
= 0; i
< chan_num
; i
++) {
117 mv_xor_cmd_set(i
, MV_STOP
);
118 mv_xor_ctrl_set(i
, (1 << XEXCR_REG_ACC_PROTECT_OFFS
) |
119 (4 << XEXCR_DST_BURST_LIMIT_OFFS
) |
120 (4 << XEXCR_SRC_BURST_LIMIT_OFFS
));
125 * mv_xor_ctrl_set - Set XOR channel control registers
135 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
137 * This function does not modify the OperationMode field of control register.
140 static int mv_xor_ctrl_set(u32 chan
, u32 xor_ctrl
)
144 /* Update the XOR Engine [0..1] Configuration Registers (XExCR) */
145 val
= reg_read(XOR_CONFIG_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)))
146 & XEXCR_OPERATION_MODE_MASK
;
147 xor_ctrl
&= ~XEXCR_OPERATION_MODE_MASK
;
149 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)), xor_ctrl
);
154 int mv_xor_mem_init(u32 chan
, u32 start_ptr
, u32 block_size
, u32 init_val_high
,
159 /* Parameter checking */
160 if (chan
>= MV_XOR_MAX_CHAN
)
163 if (MV_ACTIVE
== mv_xor_state_get(chan
))
166 if ((block_size
< XEXBSR_BLOCK_SIZE_MIN_VALUE
) ||
167 (block_size
> XEXBSR_BLOCK_SIZE_MAX_VALUE
))
170 /* Set the operation mode to Memory Init */
171 tmp
= reg_read(XOR_CONFIG_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)));
172 tmp
&= ~XEXCR_OPERATION_MODE_MASK
;
173 tmp
|= XEXCR_OPERATION_MODE_MEM_INIT
;
174 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)), tmp
);
177 * Update the start_ptr field in XOR Engine [0..1] Destination Pointer
180 reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)), start_ptr
);
183 * Update the BlockSize field in the XOR Engine[0..1] Block Size
186 reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)),
190 * Update the field InitValL in the XOR Engine Initial Value Register
193 reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan
)), init_val_low
);
196 * Update the field InitValH in the XOR Engine Initial Value Register
199 reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan
)), init_val_high
);
202 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)),
203 XEXACTR_XESTART_MASK
);
209 * mv_xor_transfer - Transfer data from source to destination on one of
210 * three modes (XOR,CRC32,DMA)
213 * This function initiates XOR channel, according to function parameters,
214 * in order to perform XOR or CRC32 or DMA transaction.
215 * To gain maximum performance the user is asked to keep the following
217 * 1) Selected engine is available (not busy).
218 * 1) This module does not take into consideration CPU MMU issues.
219 * In order for the XOR engine to access the appropreate source
220 * and destination, address parameters must be given in system
222 * 2) This API does not take care of cache coherency issues. The source,
223 * destination and in case of chain the descriptor list are assumed
224 * to be cache coherent.
225 * 4) Parameters validity. For example, does size parameter exceeds
226 * maximum byte count of descriptor mode (16M or 64K).
229 * chan - XOR channel number. See MV_XOR_CHANNEL enumerator.
230 * xor_type - One of three: XOR, CRC32 and DMA operations.
231 * xor_chain_ptr - address of chain pointer
237 * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
240 int mv_xor_transfer(u32 chan
, int xor_type
, u32 xor_chain_ptr
)
244 /* Parameter checking */
245 if (chan
>= MV_XOR_MAX_CHAN
) {
246 debug("%s: ERR. Invalid chan num %d\n", __func__
, chan
);
250 if (MV_ACTIVE
== mv_xor_state_get(chan
)) {
251 debug("%s: ERR. Channel is already active\n", __func__
);
255 if (0x0 == xor_chain_ptr
) {
256 debug("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__
);
260 /* Read configuration register and mask the operation mode field */
261 tmp
= reg_read(XOR_CONFIG_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)));
262 tmp
&= ~XEXCR_OPERATION_MODE_MASK
;
266 if (0 != (xor_chain_ptr
& XEXDPR_DST_PTR_XOR_MASK
)) {
267 debug("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n",
272 /* Set the operation mode to XOR */
273 tmp
|= XEXCR_OPERATION_MODE_XOR
;
277 if (0 != (xor_chain_ptr
& XEXDPR_DST_PTR_DMA_MASK
)) {
278 debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
283 /* Set the operation mode to DMA */
284 tmp
|= XEXCR_OPERATION_MODE_DMA
;
288 if (0 != (xor_chain_ptr
& XEXDPR_DST_PTR_CRC_MASK
)) {
289 debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
294 /* Set the operation mode to CRC32 */
295 tmp
|= XEXCR_OPERATION_MODE_CRC
;
302 /* Write the operation mode to the register */
303 reg_write(XOR_CONFIG_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)), tmp
);
306 * Update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor
307 * Pointer Register (XExNDPR)
309 reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)),
313 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)),
314 XEXACTR_XESTART_MASK
);
320 * mv_xor_state_get - Get XOR channel state.
323 * XOR channel activity state can be active, idle, paused.
324 * This function retrunes the channel activity state.
327 * chan - the channel number
333 * XOR_CHANNEL_IDLE - If the engine is idle.
334 * XOR_CHANNEL_ACTIVE - If the engine is busy.
335 * XOR_CHANNEL_PAUSED - If the engine is paused.
336 * MV_UNDEFINED_STATE - If the engine state is undefind or there is no
340 int mv_xor_state_get(u32 chan
)
344 /* Parameter checking */
345 if (chan
>= MV_XOR_MAX_CHAN
) {
346 debug("%s: ERR. Invalid chan num %d\n", __func__
, chan
);
347 return MV_UNDEFINED_STATE
;
350 /* Read the current state */
351 state
= reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)));
352 state
&= XEXACTR_XESTATUS_MASK
;
354 /* Return the state */
356 case XEXACTR_XESTATUS_IDLE
:
358 case XEXACTR_XESTATUS_ACTIVE
:
360 case XEXACTR_XESTATUS_PAUSED
:
364 return MV_UNDEFINED_STATE
;
368 * mv_xor_cmd_set - Set command of XOR channel
371 * XOR channel can be started, idle, paused and restarted.
372 * Paused can be set only if channel is active.
373 * Start can be set only if channel is idle or paused.
374 * Restart can be set only if channel is paused.
375 * Stop can be set only if channel is active.
378 * chan - The channel number
379 * command - The command type (start, stop, restart, pause)
385 * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on
386 * undefind XOR engine mode
389 static int mv_xor_cmd_set(u32 chan
, int command
)
393 /* Parameter checking */
394 if (chan
>= MV_XOR_MAX_CHAN
) {
395 debug("%s: ERR. Invalid chan num %d\n", __func__
, chan
);
399 /* Get the current state */
400 state
= mv_xor_state_get(chan
);
402 /* Command is start and current state is idle */
403 if ((command
== MV_START
) && (state
== MV_IDLE
)) {
404 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)),
405 XEXACTR_XESTART_MASK
);
408 /* Command is stop and current state is active */
409 else if ((command
== MV_STOP
) && (state
== MV_ACTIVE
)) {
410 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)),
411 XEXACTR_XESTOP_MASK
);
414 /* Command is paused and current state is active */
415 else if ((command
== MV_PAUSED
) && (state
== MV_ACTIVE
)) {
416 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)),
417 XEXACTR_XEPAUSE_MASK
);
420 /* Command is restart and current state is paused */
421 else if ((command
== MV_RESTART
) && (state
== MV_PAUSED
)) {
422 reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan
), XOR_CHAN(chan
)),
423 XEXACTR_XERESTART_MASK
);
426 /* Command is stop and current state is active */
427 else if ((command
== MV_STOP
) && (state
== MV_IDLE
))
430 /* Illegal command */
431 debug("%s: ERR. Illegal command\n", __func__
);