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