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