ARM: mvebu: a38x: sync ddr training code with upstream
[oweals/u-boot.git] / drivers / ddr / marvell / a38x / xor.c
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         mv_sys_xor_init(max_cs, cs_ena, cs_mem_size, 0);
351         total_mem_size = max_cs * cs_mem_size;
352         mv_xor_mem_init(0, 0, total_mem_size, 0xdeadbeef, 0xdeadbeef);
353         /* wait for previous transfer completion */
354         while (mv_xor_state_get(0) != MV_IDLE)
355                 ;
356         /* Return XOR State */
357         mv_sys_xor_finish();
358
359         printf("DDR3 Training Sequence - End scrubbing\n");
360 }
361
362 /*
363 * mv_xor_transfer - Transfer data from source to destination in one of
364 *                   three modes: XOR, CRC32 or DMA
365 *
366 * DESCRIPTION:
367 *       This function initiates XOR channel, according to function parameters,
368 *       in order to perform XOR, CRC32 or DMA transaction.
369 *       To gain maximum performance the user is asked to keep the following
370 *       restrictions:
371 *       1) Selected engine is available (not busy).
372 *       2) This module does not take into consideration CPU MMU issues.
373 *          In order for the XOR engine to access the appropriate source
374 *          and destination, address parameters must be given in system
375 *          physical mode.
376 *       3) This API does not take care of cache coherency issues. The source,
377 *          destination and, in case of chain, the descriptor list are assumed
378 *          to be cache coherent.
379 *       4) Parameters validity.
380 *
381 * INPUT:
382 *       chan            - XOR channel number.
383 *       type    - One of three: XOR, CRC32 and DMA operations.
384 *       xor_chain_ptr   - address of chain pointer
385 *
386 * OUTPUT:
387 *       None.
388 *
389 * RETURN:
390 *       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
391 *
392 *******************************************************************************/
393 int mv_xor_transfer(u32 chan, enum xor_type type, u32 xor_chain_ptr)
394 {
395         u32 temp;
396
397         /* Parameter checking */
398         if (chan >= MV_XOR_MAX_CHAN) {
399                 DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
400                 return MV_BAD_PARAM;
401         }
402         if (mv_xor_state_get(chan) == MV_ACTIVE) {
403                 DB(printf("%s: ERR. Channel is already active\n", __func__));
404                 return MV_BUSY;
405         }
406         if (xor_chain_ptr == 0x0) {
407                 DB(printf("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__));
408                 return MV_BAD_PARAM;
409         }
410
411         /* read configuration register and mask the operation mode field */
412         temp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
413         temp &= ~XEXCR_OPERATION_MODE_MASK;
414
415         switch (type) {
416         case MV_XOR:
417                 if ((xor_chain_ptr & XEXDPR_DST_PTR_XOR_MASK) != 0) {
418                         DB(printf("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n",
419                                   __func__));
420                         return MV_BAD_PARAM;
421                 }
422                 /* set the operation mode to XOR */
423                 temp |= XEXCR_OPERATION_MODE_XOR;
424                 break;
425         case MV_DMA:
426                 if ((xor_chain_ptr & XEXDPR_DST_PTR_DMA_MASK) != 0) {
427                         DB(printf("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
428                                   __func__));
429                         return MV_BAD_PARAM;
430                 }
431                 /* set the operation mode to DMA */
432                 temp |= XEXCR_OPERATION_MODE_DMA;
433                 break;
434         case MV_CRC32:
435                 if ((xor_chain_ptr & XEXDPR_DST_PTR_CRC_MASK) != 0) {
436                         DB(printf("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
437                                   __func__));
438                         return MV_BAD_PARAM;
439                 }
440                 /* set the operation mode to CRC32 */
441                 temp |= XEXCR_OPERATION_MODE_CRC;
442                 break;
443         default:
444                 return MV_BAD_PARAM;
445         }
446
447         /* write the operation mode to the register */
448         reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);
449         /*
450          * update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor
451          * Pointer Register (XExNDPR)
452          */
453         reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
454                   xor_chain_ptr);
455
456         /* start transfer */
457         reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
458                     XEXACTR_XESTART_MASK);
459
460         return MV_OK;
461 }