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, ®); 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