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