SPDX: Convert all of our single license tags to Linux Kernel style
[platform/kernel/u-boot.git] / drivers / ddr / marvell / a38x / ddr3_training_centralization.c
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 <spl.h>
8 #include <asm/io.h>
9 #include <asm/arch/cpu.h>
10 #include <asm/arch/soc.h>
11
12 #include "ddr3_init.h"
13
14 #define VALIDATE_WIN_LENGTH(e1, e2, maxsize)            \
15         (((e2) + 1 > (e1) + (u8)MIN_WINDOW_SIZE) &&     \
16          ((e2) + 1 < (e1) + (u8)maxsize))
17 #define IS_WINDOW_OUT_BOUNDARY(e1, e2, maxsize)                 \
18         (((e1) == 0 && (e2) != 0) ||                            \
19          ((e1) != (maxsize - 1) && (e2) == (maxsize - 1)))
20 #define CENTRAL_TX              0
21 #define CENTRAL_RX              1
22 #define NUM_OF_CENTRAL_TYPES    2
23
24 u32 start_pattern = PATTERN_KILLER_DQ0, end_pattern = PATTERN_KILLER_DQ7;
25 u32 start_if = 0, end_if = (MAX_INTERFACE_NUM - 1);
26 u8 bus_end_window[NUM_OF_CENTRAL_TYPES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
27 u8 bus_start_window[NUM_OF_CENTRAL_TYPES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
28 u8 centralization_state[MAX_INTERFACE_NUM][MAX_BUS_NUM];
29 static u8 ddr3_tip_special_rx_run_once_flag;
30
31 static int ddr3_tip_centralization(u32 dev_num, u32 mode);
32
33 /*
34  * Centralization RX Flow
35  */
36 int ddr3_tip_centralization_rx(u32 dev_num)
37 {
38         CHECK_STATUS(ddr3_tip_special_rx(dev_num));
39         CHECK_STATUS(ddr3_tip_centralization(dev_num, CENTRAL_RX));
40
41         return MV_OK;
42 }
43
44 /*
45  * Centralization TX Flow
46  */
47 int ddr3_tip_centralization_tx(u32 dev_num)
48 {
49         CHECK_STATUS(ddr3_tip_centralization(dev_num, CENTRAL_TX));
50
51         return MV_OK;
52 }
53
54 /*
55  * Centralization Flow
56  */
57 static int ddr3_tip_centralization(u32 dev_num, u32 mode)
58 {
59         enum hws_training_ip_stat training_result[MAX_INTERFACE_NUM];
60         u32 if_id, pattern_id, bit_id;
61         u8 bus_id;
62         u8 cur_start_win[BUS_WIDTH_IN_BITS];
63         u8 centralization_result[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
64         u8 cur_end_win[BUS_WIDTH_IN_BITS];
65         u8 current_window[BUS_WIDTH_IN_BITS];
66         u8 opt_window, waste_window, start_window_skew, end_window_skew;
67         u8 final_pup_window[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
68         struct hws_topology_map *tm = ddr3_get_topology_map();
69         enum hws_training_result result_type = RESULT_PER_BIT;
70         enum hws_dir direction;
71         u32 *result[HWS_SEARCH_DIR_LIMIT];
72         u32 reg_phy_off, reg;
73         u8 max_win_size;
74         int lock_success = 1;
75         u8 cur_end_win_min, cur_start_win_max;
76         u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
77         int is_if_fail = 0;
78         enum hws_result *flow_result = ddr3_tip_get_result_ptr(training_stage);
79         u32 pup_win_length = 0;
80         enum hws_search_dir search_dir_id;
81         u8 cons_tap = (mode == CENTRAL_TX) ? (64) : (0);
82
83         for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
84                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
85                 /* save current cs enable reg val */
86                 CHECK_STATUS(ddr3_tip_if_read
87                              (dev_num, ACCESS_TYPE_UNICAST, if_id,
88                               CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
89                 /* enable single cs */
90                 CHECK_STATUS(ddr3_tip_if_write
91                              (dev_num, ACCESS_TYPE_UNICAST, if_id,
92                               CS_ENABLE_REG, (1 << 3), (1 << 3)));
93         }
94
95         if (mode == CENTRAL_TX) {
96                 max_win_size = MAX_WINDOW_SIZE_TX;
97                 reg_phy_off = WRITE_CENTRALIZATION_PHY_REG + (effective_cs * 4);
98                 direction = OPER_WRITE;
99         } else {
100                 max_win_size = MAX_WINDOW_SIZE_RX;
101                 reg_phy_off = READ_CENTRALIZATION_PHY_REG + (effective_cs * 4);
102                 direction = OPER_READ;
103         }
104
105         /* DB initialization */
106         for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
107                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
108                 for (bus_id = 0;
109                      bus_id < tm->num_of_bus_per_interface; bus_id++) {
110                         VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
111                         centralization_state[if_id][bus_id] = 0;
112                         bus_end_window[mode][if_id][bus_id] =
113                                 (max_win_size - 1) + cons_tap;
114                         bus_start_window[mode][if_id][bus_id] = 0;
115                         centralization_result[if_id][bus_id] = 0;
116                 }
117         }
118
119         /* start flow */
120         for (pattern_id = start_pattern; pattern_id <= end_pattern;
121              pattern_id++) {
122                 ddr3_tip_ip_training_wrapper(dev_num, ACCESS_TYPE_MULTICAST,
123                                              PARAM_NOT_CARE,
124                                              ACCESS_TYPE_MULTICAST,
125                                              PARAM_NOT_CARE, result_type,
126                                              HWS_CONTROL_ELEMENT_ADLL,
127                                              PARAM_NOT_CARE, direction,
128                                              tm->
129                                              if_act_mask, 0x0,
130                                              max_win_size - 1,
131                                              max_win_size - 1,
132                                              pattern_id, EDGE_FPF, CS_SINGLE,
133                                              PARAM_NOT_CARE, training_result);
134
135                 for (if_id = start_if; if_id <= end_if; if_id++) {
136                         VALIDATE_ACTIVE(tm->if_act_mask, if_id);
137                         for (bus_id = 0;
138                              bus_id <= tm->num_of_bus_per_interface - 1;
139                              bus_id++) {
140                                 VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
141
142                                 for (search_dir_id = HWS_LOW2HIGH;
143                                      search_dir_id <= HWS_HIGH2LOW;
144                                      search_dir_id++) {
145                                         CHECK_STATUS
146                                                 (ddr3_tip_read_training_result
147                                                  (dev_num, if_id,
148                                                   ACCESS_TYPE_UNICAST, bus_id,
149                                                   ALL_BITS_PER_PUP,
150                                                   search_dir_id,
151                                                   direction, result_type,
152                                                   TRAINING_LOAD_OPERATION_UNLOAD,
153                                                   CS_SINGLE,
154                                                   &result[search_dir_id],
155                                                   1, 0, 0));
156                                         DEBUG_CENTRALIZATION_ENGINE
157                                                 (DEBUG_LEVEL_INFO,
158                                                  ("%s pat %d IF %d pup %d Regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
159                                                   ((mode ==
160                                                     CENTRAL_TX) ? "TX" : "RX"),
161                                                   pattern_id, if_id, bus_id,
162                                                   result[search_dir_id][0],
163                                                   result[search_dir_id][1],
164                                                   result[search_dir_id][2],
165                                                   result[search_dir_id][3],
166                                                   result[search_dir_id][4],
167                                                   result[search_dir_id][5],
168                                                   result[search_dir_id][6],
169                                                   result[search_dir_id][7]));
170                                 }
171
172                                 for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS;
173                                      bit_id++) {
174                                         /* check if this code is valid for 2 edge, probably not :( */
175                                         cur_start_win[bit_id] =
176                                                 GET_TAP_RESULT(result
177                                                                [HWS_LOW2HIGH]
178                                                                [bit_id],
179                                                                EDGE_1);
180                                         cur_end_win[bit_id] =
181                                                 GET_TAP_RESULT(result
182                                                                [HWS_HIGH2LOW]
183                                                                [bit_id],
184                                                                EDGE_1);
185                                         /* window length */
186                                         current_window[bit_id] =
187                                                 cur_end_win[bit_id] -
188                                                 cur_start_win[bit_id] + 1;
189                                         DEBUG_CENTRALIZATION_ENGINE
190                                                 (DEBUG_LEVEL_TRACE,
191                                                  ("cs %x patern %d IF %d pup %d cur_start_win %d cur_end_win %d current_window %d\n",
192                                                   effective_cs, pattern_id,
193                                                   if_id, bus_id,
194                                                   cur_start_win[bit_id],
195                                                   cur_end_win[bit_id],
196                                                   current_window[bit_id]));
197                                 }
198
199                                 if ((ddr3_tip_is_pup_lock
200                                      (result[HWS_LOW2HIGH], result_type)) &&
201                                     (ddr3_tip_is_pup_lock
202                                      (result[HWS_HIGH2LOW], result_type))) {
203                                         /* read result success */
204                                         DEBUG_CENTRALIZATION_ENGINE
205                                                 (DEBUG_LEVEL_INFO,
206                                                  ("Pup locked, pat %d IF %d pup %d\n",
207                                                   pattern_id, if_id, bus_id));
208                                 } else {
209                                         /* read result failure */
210                                         DEBUG_CENTRALIZATION_ENGINE
211                                                 (DEBUG_LEVEL_INFO,
212                                                  ("fail Lock, pat %d IF %d pup %d\n",
213                                                   pattern_id, if_id, bus_id));
214                                         if (centralization_state[if_id][bus_id]
215                                             == 1) {
216                                                 /* continue with next pup */
217                                                 DEBUG_CENTRALIZATION_ENGINE
218                                                         (DEBUG_LEVEL_TRACE,
219                                                          ("continue to next pup %d %d\n",
220                                                           if_id, bus_id));
221                                                 continue;
222                                         }
223
224                                         for (bit_id = 0;
225                                              bit_id < BUS_WIDTH_IN_BITS;
226                                              bit_id++) {
227                                                 /*
228                                                  * the next check is relevant
229                                                  * only when using search
230                                                  * machine 2 edges
231                                                  */
232                                                 if (cur_start_win[bit_id] > 0 &&
233                                                     cur_end_win[bit_id] == 0) {
234                                                         cur_end_win
235                                                                 [bit_id] =
236                                                                 max_win_size - 1;
237                                                         DEBUG_CENTRALIZATION_ENGINE
238                                                                 (DEBUG_LEVEL_TRACE,
239                                                                  ("fail, IF %d pup %d bit %d fail #1\n",
240                                                                   if_id, bus_id,
241                                                                   bit_id));
242                                                         /* the next bit */
243                                                         continue;
244                                                 } else {
245                                                         centralization_state
246                                                                 [if_id][bus_id] = 1;
247                                                         DEBUG_CENTRALIZATION_ENGINE
248                                                                 (DEBUG_LEVEL_TRACE,
249                                                                  ("fail, IF %d pup %d bit %d fail #2\n",
250                                                                   if_id, bus_id,
251                                                                   bit_id));
252                                                 }
253                                         }
254
255                                         if (centralization_state[if_id][bus_id]
256                                             == 1) {
257                                                 /* going to next pup */
258                                                 continue;
259                                         }
260                                 }       /*bit */
261
262                                 opt_window =
263                                         ddr3_tip_get_buf_min(current_window);
264                                 /* final pup window length */
265                                 final_pup_window[if_id][bus_id] =
266                                         ddr3_tip_get_buf_min(cur_end_win) -
267                                         ddr3_tip_get_buf_max(cur_start_win) +
268                                         1;
269                                 waste_window =
270                                         opt_window -
271                                         final_pup_window[if_id][bus_id];
272                                 start_window_skew =
273                                         ddr3_tip_get_buf_max(cur_start_win) -
274                                         ddr3_tip_get_buf_min(
275                                                 cur_start_win);
276                                 end_window_skew =
277                                         ddr3_tip_get_buf_max(
278                                                 cur_end_win) -
279                                         ddr3_tip_get_buf_min(
280                                                 cur_end_win);
281                                 /* min/max updated with pattern change */
282                                 cur_end_win_min =
283                                         ddr3_tip_get_buf_min(
284                                                 cur_end_win);
285                                 cur_start_win_max =
286                                         ddr3_tip_get_buf_max(
287                                                 cur_start_win);
288                                 bus_end_window[mode][if_id][bus_id] =
289                                         GET_MIN(bus_end_window[mode][if_id]
290                                                 [bus_id],
291                                                 cur_end_win_min);
292                                 bus_start_window[mode][if_id][bus_id] =
293                                         GET_MAX(bus_start_window[mode][if_id]
294                                                 [bus_id],
295                                                 cur_start_win_max);
296                                 DEBUG_CENTRALIZATION_ENGINE(
297                                         DEBUG_LEVEL_INFO,
298                                         ("pat %d IF %d pup %d opt_win %d final_win %d waste_win %d st_win_skew %d end_win_skew %d cur_st_win_max %d cur_end_win_min %d bus_st_win %d bus_end_win %d\n",
299                                          pattern_id, if_id, bus_id, opt_window,
300                                          final_pup_window[if_id][bus_id],
301                                          waste_window, start_window_skew,
302                                          end_window_skew,
303                                          cur_start_win_max,
304                                          cur_end_win_min,
305                                          bus_start_window[mode][if_id][bus_id],
306                                          bus_end_window[mode][if_id][bus_id]));
307
308                                 /* check if window is valid */
309                                 if (ddr3_tip_centr_skip_min_win_check == 0) {
310                                         if ((VALIDATE_WIN_LENGTH
311                                              (bus_start_window[mode][if_id]
312                                               [bus_id],
313                                               bus_end_window[mode][if_id]
314                                               [bus_id],
315                                               max_win_size) == 1) ||
316                                             (IS_WINDOW_OUT_BOUNDARY
317                                              (bus_start_window[mode][if_id]
318                                               [bus_id],
319                                               bus_end_window[mode][if_id]
320                                               [bus_id],
321                                               max_win_size) == 1)) {
322                                                 DEBUG_CENTRALIZATION_ENGINE
323                                                         (DEBUG_LEVEL_INFO,
324                                                          ("win valid, pat %d IF %d pup %d\n",
325                                                           pattern_id, if_id,
326                                                           bus_id));
327                                                 /* window is valid */
328                                         } else {
329                                                 DEBUG_CENTRALIZATION_ENGINE
330                                                         (DEBUG_LEVEL_INFO,
331                                                          ("fail win, pat %d IF %d pup %d bus_st_win %d bus_end_win %d\n",
332                                                           pattern_id, if_id, bus_id,
333                                                           bus_start_window[mode]
334                                                           [if_id][bus_id],
335                                                           bus_end_window[mode]
336                                                           [if_id][bus_id]));
337                                                 centralization_state[if_id]
338                                                         [bus_id] = 1;
339                                                 if (debug_mode == 0)
340                                                         return MV_FAIL;
341                                         }
342                                 }       /* ddr3_tip_centr_skip_min_win_check */
343                         }       /* pup */
344                 }               /* interface */
345         }                       /* pattern */
346
347         for (if_id = start_if; if_id <= end_if; if_id++) {
348                 if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
349                         continue;
350
351                 is_if_fail = 0;
352                 flow_result[if_id] = TEST_SUCCESS;
353
354                 for (bus_id = 0;
355                      bus_id <= (tm->num_of_bus_per_interface - 1); bus_id++) {
356                         VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
357
358                         /* continue only if lock */
359                         if (centralization_state[if_id][bus_id] != 1) {
360                                 if (ddr3_tip_centr_skip_min_win_check == 0)     {
361                                         if ((bus_end_window
362                                              [mode][if_id][bus_id] ==
363                                              (max_win_size - 1)) &&
364                                             ((bus_end_window
365                                               [mode][if_id][bus_id] -
366                                               bus_start_window[mode][if_id]
367                                               [bus_id]) < MIN_WINDOW_SIZE) &&
368                                             ((bus_end_window[mode][if_id]
369                                               [bus_id] - bus_start_window
370                                               [mode][if_id][bus_id]) > 2)) {
371                                                 /* prevent false lock */
372                                                 /* TBD change to enum */
373                                                 centralization_state
374                                                         [if_id][bus_id] = 2;
375                                         }
376
377                                         if ((bus_end_window[mode][if_id][bus_id]
378                                              == 0) &&
379                                             ((bus_end_window[mode][if_id]
380                                               [bus_id] -
381                                               bus_start_window[mode][if_id]
382                                               [bus_id]) < MIN_WINDOW_SIZE) &&
383                                             ((bus_end_window[mode][if_id]
384                                               [bus_id] -
385                                               bus_start_window[mode][if_id]
386                                               [bus_id]) > 2))
387                                                 /*prevent false lock */
388                                                 centralization_state[if_id]
389                                                         [bus_id] = 3;
390                                 }
391
392                                 if ((bus_end_window[mode][if_id][bus_id] >
393                                      (max_win_size - 1)) && direction ==
394                                     OPER_WRITE) {
395                                         DEBUG_CENTRALIZATION_ENGINE
396                                                 (DEBUG_LEVEL_INFO,
397                                                  ("Tx special pattern\n"));
398                                         cons_tap = 64;
399                                 }
400                         }
401
402                         /* check states */
403                         if (centralization_state[if_id][bus_id] == 3) {
404                                 DEBUG_CENTRALIZATION_ENGINE(
405                                         DEBUG_LEVEL_INFO,
406                                         ("SSW - TBD IF %d pup %d\n",
407                                          if_id, bus_id));
408                                 lock_success = 1;
409                         } else if (centralization_state[if_id][bus_id] == 2) {
410                                 DEBUG_CENTRALIZATION_ENGINE(
411                                         DEBUG_LEVEL_INFO,
412                                         ("SEW - TBD IF %d pup %d\n",
413                                          if_id, bus_id));
414                                 lock_success = 1;
415                         } else if (centralization_state[if_id][bus_id] == 0) {
416                                 lock_success = 1;
417                         } else {
418                                 DEBUG_CENTRALIZATION_ENGINE(
419                                         DEBUG_LEVEL_ERROR,
420                                         ("fail, IF %d pup %d\n",
421                                          if_id, bus_id));
422                                 lock_success = 0;
423                         }
424
425                         if (lock_success == 1) {
426                                 centralization_result[if_id][bus_id] =
427                                         (bus_end_window[mode][if_id][bus_id] +
428                                          bus_start_window[mode][if_id][bus_id])
429                                         / 2 - cons_tap;
430                                 DEBUG_CENTRALIZATION_ENGINE(
431                                         DEBUG_LEVEL_TRACE,
432                                         (" bus_id %d Res= %d\n", bus_id,
433                                          centralization_result[if_id][bus_id]));
434                                 /* copy results to registers  */
435                                 pup_win_length =
436                                         bus_end_window[mode][if_id][bus_id] -
437                                         bus_start_window[mode][if_id][bus_id] +
438                                         1;
439
440                                 ddr3_tip_bus_read(dev_num, if_id,
441                                                   ACCESS_TYPE_UNICAST, bus_id,
442                                                   DDR_PHY_DATA,
443                                                   RESULT_DB_PHY_REG_ADDR +
444                                                   effective_cs, &reg);
445                                 reg = (reg & (~0x1f <<
446                                               ((mode == CENTRAL_TX) ?
447                                                (RESULT_DB_PHY_REG_TX_OFFSET) :
448                                                (RESULT_DB_PHY_REG_RX_OFFSET))))
449                                         | pup_win_length <<
450                                         ((mode == CENTRAL_TX) ?
451                                          (RESULT_DB_PHY_REG_TX_OFFSET) :
452                                          (RESULT_DB_PHY_REG_RX_OFFSET));
453                                 CHECK_STATUS(ddr3_tip_bus_write
454                                              (dev_num, ACCESS_TYPE_UNICAST,
455                                               if_id, ACCESS_TYPE_UNICAST,
456                                               bus_id, DDR_PHY_DATA,
457                                               RESULT_DB_PHY_REG_ADDR +
458                                               effective_cs, reg));
459
460                                 /* offset per CS is calculated earlier */
461                                 CHECK_STATUS(
462                                         ddr3_tip_bus_write(dev_num,
463                                                            ACCESS_TYPE_UNICAST,
464                                                            if_id,
465                                                            ACCESS_TYPE_UNICAST,
466                                                            bus_id,
467                                                            DDR_PHY_DATA,
468                                                            reg_phy_off,
469                                                            centralization_result
470                                                            [if_id]
471                                                            [bus_id]));
472                         } else {
473                                 is_if_fail = 1;
474                         }
475                 }
476
477                 if (is_if_fail == 1)
478                         flow_result[if_id] = TEST_FAILED;
479         }
480
481         for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
482                 /* restore cs enable value */
483                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
484                 CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_UNICAST,
485                                                if_id, CS_ENABLE_REG,
486                                                cs_enable_reg_val[if_id],
487                                                MASK_ALL_BITS));
488         }
489
490         return is_if_fail;
491 }
492
493 /*
494  * Centralization Flow
495  */
496 int ddr3_tip_special_rx(u32 dev_num)
497 {
498         enum hws_training_ip_stat training_result[MAX_INTERFACE_NUM];
499         u32 if_id, pup_id, pattern_id, bit_id;
500         u8 cur_start_win[BUS_WIDTH_IN_BITS];
501         u8 cur_end_win[BUS_WIDTH_IN_BITS];
502         enum hws_training_result result_type = RESULT_PER_BIT;
503         enum hws_dir direction;
504         enum hws_search_dir search_dir_id;
505         u32 *result[HWS_SEARCH_DIR_LIMIT];
506         u32 max_win_size;
507         u8 cur_end_win_min, cur_start_win_max;
508         u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
509         u32 temp = 0;
510         int pad_num = 0;
511         struct hws_topology_map *tm = ddr3_get_topology_map();
512
513         if (ddr3_tip_special_rx_run_once_flag != 0)
514                 return MV_OK;
515
516         ddr3_tip_special_rx_run_once_flag = 1;
517
518         for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
519                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
520                 /* save current cs enable reg val */
521                 CHECK_STATUS(ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST,
522                                               if_id, CS_ENABLE_REG,
523                                               cs_enable_reg_val,
524                                               MASK_ALL_BITS));
525                 /* enable single cs */
526                 CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_UNICAST,
527                                                if_id, CS_ENABLE_REG,
528                                                (1 << 3), (1 << 3)));
529         }
530
531         max_win_size = MAX_WINDOW_SIZE_RX;
532         direction = OPER_READ;
533         pattern_id = PATTERN_VREF;
534
535         /* start flow */
536         ddr3_tip_ip_training_wrapper(dev_num, ACCESS_TYPE_MULTICAST,
537                                      PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
538                                      PARAM_NOT_CARE, result_type,
539                                      HWS_CONTROL_ELEMENT_ADLL,
540                                      PARAM_NOT_CARE, direction,
541                                      tm->if_act_mask, 0x0,
542                                      max_win_size - 1, max_win_size - 1,
543                                      pattern_id, EDGE_FPF, CS_SINGLE,
544                                      PARAM_NOT_CARE, training_result);
545
546         for (if_id = start_if; if_id <= end_if; if_id++) {
547                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
548                 for (pup_id = 0;
549                      pup_id <= tm->num_of_bus_per_interface; pup_id++) {
550                         VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
551
552                         for (search_dir_id = HWS_LOW2HIGH;
553                              search_dir_id <= HWS_HIGH2LOW;
554                              search_dir_id++) {
555                                 CHECK_STATUS(ddr3_tip_read_training_result
556                                              (dev_num, if_id,
557                                               ACCESS_TYPE_UNICAST, pup_id,
558                                               ALL_BITS_PER_PUP, search_dir_id,
559                                               direction, result_type,
560                                               TRAINING_LOAD_OPERATION_UNLOAD,
561                                               CS_SINGLE, &result[search_dir_id],
562                                               1, 0, 0));
563                                 DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_INFO,
564                                                             ("Special: pat %d IF %d pup %d Regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
565                                                              pattern_id, if_id,
566                                                              pup_id,
567                                                              result
568                                                              [search_dir_id][0],
569                                                              result
570                                                              [search_dir_id][1],
571                                                              result
572                                                              [search_dir_id][2],
573                                                              result
574                                                              [search_dir_id][3],
575                                                              result
576                                                              [search_dir_id][4],
577                                                              result
578                                                              [search_dir_id][5],
579                                                              result
580                                                              [search_dir_id][6],
581                                                              result
582                                                              [search_dir_id]
583                                                              [7]));
584                         }
585
586                         for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS; bit_id++) {
587                                 /*
588                                  * check if this code is valid for 2 edge,
589                                  * probably not :(
590                                  */
591                                 cur_start_win[bit_id] =
592                                         GET_TAP_RESULT(result[HWS_LOW2HIGH]
593                                                        [bit_id], EDGE_1);
594                                 cur_end_win[bit_id] =
595                                         GET_TAP_RESULT(result[HWS_HIGH2LOW]
596                                                        [bit_id], EDGE_1);
597                         }
598                         if (!((ddr3_tip_is_pup_lock
599                                (result[HWS_LOW2HIGH], result_type)) &&
600                               (ddr3_tip_is_pup_lock
601                                (result[HWS_HIGH2LOW], result_type)))) {
602                                 DEBUG_CENTRALIZATION_ENGINE(
603                                         DEBUG_LEVEL_ERROR,
604                                         ("Special: Pup lock fail, pat %d IF %d pup %d\n",
605                                          pattern_id, if_id, pup_id));
606                                 return MV_FAIL;
607                         }
608
609                         cur_end_win_min =
610                                 ddr3_tip_get_buf_min(cur_end_win);
611                         cur_start_win_max =
612                                 ddr3_tip_get_buf_max(cur_start_win);
613
614                         if (cur_start_win_max <= 1) {   /* Align left */
615                                 for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS;
616                                      bit_id++) {
617                                         pad_num =
618                                                 dq_map_table[bit_id +
619                                                              pup_id *
620                                                              BUS_WIDTH_IN_BITS +
621                                                              if_id *
622                                                              BUS_WIDTH_IN_BITS *
623                                                              tm->
624                                                              num_of_bus_per_interface];
625                                         CHECK_STATUS(ddr3_tip_bus_read
626                                                      (dev_num, if_id,
627                                                       ACCESS_TYPE_UNICAST,
628                                                       pup_id, DDR_PHY_DATA,
629                                                       PBS_RX_PHY_REG + pad_num,
630                                                       &temp));
631                                         temp = (temp + 0xa > 31) ?
632                                                 (31) : (temp + 0xa);
633                                         CHECK_STATUS(ddr3_tip_bus_write
634                                                      (dev_num,
635                                                       ACCESS_TYPE_UNICAST,
636                                                       if_id,
637                                                       ACCESS_TYPE_UNICAST,
638                                                       pup_id, DDR_PHY_DATA,
639                                                       PBS_RX_PHY_REG + pad_num,
640                                                       temp));
641                                 }
642                                 DEBUG_CENTRALIZATION_ENGINE(
643                                         DEBUG_LEVEL_INFO,
644                                         ("Special: PBS:: I/F# %d , Bus# %d fix align to the Left\n",
645                                          if_id, pup_id));
646                         }
647
648                         if (cur_end_win_min > 30) { /* Align right */
649                                 CHECK_STATUS(ddr3_tip_bus_read
650                                              (dev_num, if_id,
651                                               ACCESS_TYPE_UNICAST, pup_id,
652                                               DDR_PHY_DATA, PBS_RX_PHY_REG + 4,
653                                               &temp));
654                                 temp += 0xa;
655                                 CHECK_STATUS(ddr3_tip_bus_write
656                                              (dev_num, ACCESS_TYPE_UNICAST,
657                                               if_id, ACCESS_TYPE_UNICAST,
658                                               pup_id, DDR_PHY_DATA,
659                                               PBS_RX_PHY_REG + 4, temp));
660                                 CHECK_STATUS(ddr3_tip_bus_read
661                                              (dev_num, if_id,
662                                               ACCESS_TYPE_UNICAST, pup_id,
663                                               DDR_PHY_DATA, PBS_RX_PHY_REG + 5,
664                                               &temp));
665                                 temp += 0xa;
666                                 CHECK_STATUS(ddr3_tip_bus_write
667                                              (dev_num, ACCESS_TYPE_UNICAST,
668                                               if_id, ACCESS_TYPE_UNICAST,
669                                               pup_id, DDR_PHY_DATA,
670                                               PBS_RX_PHY_REG + 5, temp));
671                                 DEBUG_CENTRALIZATION_ENGINE(
672                                         DEBUG_LEVEL_INFO,
673                                         ("Special: PBS:: I/F# %d , Bus# %d fix align to the right\n",
674                                          if_id, pup_id));
675                         }
676
677                         vref_window_size[if_id][pup_id] =
678                                 cur_end_win_min -
679                                 cur_start_win_max + 1;
680                         DEBUG_CENTRALIZATION_ENGINE(
681                                 DEBUG_LEVEL_INFO,
682                                 ("Special: Winsize I/F# %d , Bus# %d is %d\n",
683                                  if_id, pup_id, vref_window_size
684                                  [if_id][pup_id]));
685                 }               /* pup */
686         }                       /* end of interface */
687
688         return MV_OK;
689 }
690
691 /*
692  * Print Centralization Result
693  */
694 int ddr3_tip_print_centralization_result(u32 dev_num)
695 {
696         u32 if_id = 0, bus_id = 0;
697         struct hws_topology_map *tm = ddr3_get_topology_map();
698
699         printf("Centralization Results\n");
700         printf("I/F0 Result[0 - success 1-fail 2 - state_2 3 - state_3] ...\n");
701         for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
702                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
703                 for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
704                      bus_id++) {
705                         VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
706                         printf("%d ,\n", centralization_state[if_id][bus_id]);
707                 }
708         }
709
710         return MV_OK;
711 }