uboot/drivers/ddr/marvell/axp/ddr3_pbs.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 <i2c.h>
   9#include <spl.h>
  10#include <asm/io.h>
  11#include <asm/arch/cpu.h>
  12#include <asm/arch/soc.h>
  13
  14#include "ddr3_hw_training.h"
  15
  16/*
  17 * Debug
  18 */
  19#define DEBUG_PBS_FULL_C(s, d, l) \
  20        DEBUG_PBS_FULL_S(s); DEBUG_PBS_FULL_D(d, l); DEBUG_PBS_FULL_S("\n")
  21#define DEBUG_PBS_C(s, d, l) \
  22        DEBUG_PBS_S(s); DEBUG_PBS_D(d, l); DEBUG_PBS_S("\n")
  23
  24#ifdef MV_DEBUG_PBS
  25#define DEBUG_PBS_S(s)                  puts(s)
  26#define DEBUG_PBS_D(d, l)               printf("%x", d)
  27#else
  28#define DEBUG_PBS_S(s)
  29#define DEBUG_PBS_D(d, l)
  30#endif
  31
  32#ifdef MV_DEBUG_FULL_PBS
  33#define DEBUG_PBS_FULL_S(s)             puts(s)
  34#define DEBUG_PBS_FULL_D(d, l)          printf("%x", d)
  35#else
  36#define DEBUG_PBS_FULL_S(s)
  37#define DEBUG_PBS_FULL_D(d, l)
  38#endif
  39
  40#if defined(MV88F78X60) || defined(MV88F672X)
  41
  42/* Temp array for skew data storage */
  43static u32 skew_array[(MAX_PUP_NUM) * DQ_NUM] = { 0 };
  44
  45/* PBS locked dq (per pup) */
  46extern u32 pbs_locked_dq[MAX_PUP_NUM][DQ_NUM];
  47extern u32 pbs_locked_dm[MAX_PUP_NUM];
  48extern u32 pbs_locked_value[MAX_PUP_NUM][DQ_NUM];
  49
  50#if defined(MV88F672X)
  51extern u32 pbs_pattern[2][LEN_16BIT_PBS_PATTERN];
  52extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN];
  53#else
  54extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN];
  55extern u32 pbs_pattern_64b[2][LEN_PBS_PATTERN];
  56#endif
  57
  58extern u32 pbs_dq_mapping[PUP_NUM_64BIT + 1][DQ_NUM];
  59
  60static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info,
  61                u32 cur_pup, u32 pbs_pattern_idx, u32 ecc);
  62static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup,
  63                u32 pbs_pattern_idx, u32 ecc);
  64static int ddr3_pbs_per_bit(MV_DRAM_INFO *dram_info, int *start_over, int is_tx,
  65                u32 *pcur_pup, u32 pbs_pattern_idx, u32 ecc);
  66static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx);
  67static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay);
  68
  69/*
  70 * Name:     ddr3_pbs_tx
  71 * Desc:     Execute the PBS TX phase.
  72 * Args:     dram_info   ddr3 training information struct
  73 * Notes:
  74 * Returns:  MV_OK if success, other error code if fail.
  75 */
  76int ddr3_pbs_tx(MV_DRAM_INFO *dram_info)
  77{
  78        /* Array of Deskew results */
  79
  80        /*
  81         * Array to hold the total sum of skew from all iterations
  82         * (for average purpose)
  83         */
  84        u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
  85
  86        /*
  87         * Array to hold the total average skew from both patterns
  88         * (for average purpose)
  89         */
  90        u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
  91
  92        u32 pbs_rep_time = 0;   /* counts number of loop in case of fail */
  93        /* bit array for unlock pups - used to repeat on the RX operation */
  94        u32 cur_pup;
  95        u32 max_pup;
  96        u32 pbs_retry;
  97        u32 pup, dq, pups, cur_max_pup, valid_pup, reg;
  98        u32 pattern_idx;
  99        u32 ecc;
 100        /* indicates whether we need to start the loop again */
 101        int start_over;
 102
 103        DEBUG_PBS_S("DDR3 - PBS TX - Starting PBS TX procedure\n");
 104
 105        pups = dram_info->num_of_total_pups;
 106        max_pup = dram_info->num_of_total_pups;
 107
 108        /* Enable SW override */
 109        reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
 110                (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
 111        /* [0] = 1 - Enable SW override  */
 112        /* 0x15B8 - Training SW 2 Register */
 113        reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
 114        DEBUG_PBS_S("DDR3 - PBS RX - SW Override Enabled\n");
 115
 116        reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS;
 117        reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
 118
 119        /* Running twice for 2 different patterns. each patterns - 3 times */
 120        for (pattern_idx = 0; pattern_idx < COUNT_PBS_PATTERN; pattern_idx++) {
 121                DEBUG_PBS_C("DDR3 - PBS TX - Working with pattern - ",
 122                            pattern_idx, 1);
 123
 124                /* Reset sum array */
 125                for (pup = 0; pup < pups; pup++) {
 126                        for (dq = 0; dq < DQ_NUM; dq++)
 127                                skew_sum_array[pup][dq] = 0;
 128                }
 129
 130                /*
 131                 * Perform PBS several of times (3 for each pattern).
 132                 * At the end, we'll use the average
 133                 */
 134                /* If there is ECC, do each PBS again with mux change */
 135                for (pbs_retry = 0; pbs_retry < COUNT_PBS_REPEAT; pbs_retry++) {
 136                        for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) {
 137
 138                                /*
 139                                 * This parameter stores the current PUP
 140                                 * num - ecc mode dependent - 4-8 / 1 pups
 141                                 */
 142                                cur_max_pup = (1 - ecc) *
 143                                        dram_info->num_of_std_pups + ecc;
 144
 145                                if (ecc) {
 146                                        /* Only 1 pup in this case */
 147                                        valid_pup = 0x1;
 148                                } else if (cur_max_pup > 4) {
 149                                        /* 64 bit - 8 pups */
 150                                        valid_pup = 0xFF;
 151                                } else if (cur_max_pup == 4) {
 152                                        /* 32 bit - 4 pups */
 153                                        valid_pup = 0xF;
 154                                } else {
 155                                        /* 16 bit - 2 pups */
 156                                        valid_pup = 0x3;
 157                                }
 158
 159                                /* ECC Support - Switch ECC Mux on ecc=1 */
 160                                reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
 161                                        ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
 162                                reg |= (dram_info->ecc_ena * ecc <<
 163                                        REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
 164                                reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
 165
 166                                if (ecc)
 167                                        DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Enabled\n");
 168                                else
 169                                        DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Disabled\n");
 170
 171                                /* Init iteration values */
 172                                /* Clear the locked DQs */
 173                                for (pup = 0; pup < cur_max_pup; pup++) {
 174                                        for (dq = 0; dq < DQ_NUM; dq++) {
 175                                                pbs_locked_dq[
 176                                                        pup + ecc *
 177                                                        (max_pup - 1)][dq] =
 178                                                        0;
 179                                        }
 180                                }
 181
 182                                pbs_rep_time = 0;
 183                                cur_pup = valid_pup;
 184                                start_over = 0;
 185
 186                                /*
 187                                 * Run loop On current Pattern and current
 188                                 * pattern iteration (just to cover the false
 189                                 * fail problem)
 190                                 */
 191                                do {
 192                                        DEBUG_PBS_S("DDR3 - PBS Tx - Pbs Rep Loop is ");
 193                                        DEBUG_PBS_D(pbs_rep_time, 1);
 194                                        DEBUG_PBS_S(", for Retry No.");
 195                                        DEBUG_PBS_D(pbs_retry, 1);
 196                                        DEBUG_PBS_S("\n");
 197
 198                                        /* Set all PBS values to MIN (0) */
 199                                        DEBUG_PBS_S("DDR3 - PBS Tx - Set all PBS values to MIN\n");
 200
 201                                        for (dq = 0; dq < DQ_NUM; dq++) {
 202                                                ddr3_write_pup_reg(
 203                                                        PUP_PBS_TX +
 204                                                        pbs_dq_mapping[pup *
 205                                                                (1 - ecc) +
 206                                                                ecc * ECC_PUP]
 207                                                        [dq], CS0, (1 - ecc) *
 208                                                        PUP_BC + ecc * ECC_PUP, 0,
 209                                                        0);
 210                                        }
 211
 212                                        /*
 213                                         * Shift DQ ADLL right, One step before
 214                                         * fail
 215                                         */
 216                                        DEBUG_PBS_S("DDR3 - PBS Tx - ADLL shift right one phase before fail\n");
 217
 218                                        if (MV_OK != ddr3_tx_shift_dqs_adll_step_before_fail
 219                                            (dram_info, cur_pup, pattern_idx,
 220                                             ecc))
 221                                                return MV_DDR3_TRAINING_ERR_PBS_ADLL_SHR_1PHASE;
 222
 223                                        /* PBS For each bit */
 224                                        DEBUG_PBS_S("DDR3 - PBS Tx - perform PBS for each bit\n");
 225
 226                                        /*
 227                                         * In this stage - start_over = 0
 228                                         */
 229                                        if (MV_OK != ddr3_pbs_per_bit(
 230                                                    dram_info, &start_over, 1,
 231                                                    &cur_pup, pattern_idx, ecc))
 232                                                return MV_DDR3_TRAINING_ERR_PBS_TX_PER_BIT;
 233
 234                                } while ((start_over == 1) &&
 235                                         (++pbs_rep_time < COUNT_PBS_STARTOVER));
 236
 237                                if (pbs_rep_time == COUNT_PBS_STARTOVER &&
 238                                    start_over == 1) {
 239                                        DEBUG_PBS_S("DDR3 - PBS Tx - FAIL - Adll reach max value\n");
 240                                        return MV_DDR3_TRAINING_ERR_PBS_TX_MAX_VAL;
 241                                }
 242
 243                                DEBUG_PBS_FULL_C("DDR3 - PBS TX - values for iteration - ",
 244                                                 pbs_retry, 1);
 245                                for (pup = 0; pup < cur_max_pup; pup++) {
 246                                        /*
 247                                         * To minimize delay elements, inc
 248                                         * from pbs value the min pbs val
 249                                         */
 250                                        DEBUG_PBS_S("DDR3 - PBS - PUP");
 251                                        DEBUG_PBS_D((pup + (ecc * ECC_PUP)), 1);
 252                                        DEBUG_PBS_S(": ");
 253
 254                                        for (dq = 0; dq < DQ_NUM; dq++) {
 255                                                /* Set skew value for all dq */
 256                                                /*
 257                                                 * Bit# Deskew <- Bit# Deskew -
 258                                                 * last / first  failing bit
 259                                                 * Deskew For all bits (per PUP)
 260                                                 * (minimize delay elements)
 261                                                 */
 262                                                DEBUG_PBS_S("DQ");
 263                                                DEBUG_PBS_D(dq, 1);
 264                                                DEBUG_PBS_S("-");
 265                                                DEBUG_PBS_D(skew_array
 266                                                            [((pup) * DQ_NUM) +
 267                                                             dq], 2);
 268                                                DEBUG_PBS_S(", ");
 269                                        }
 270                                        DEBUG_PBS_S("\n");
 271                                }
 272
 273                                /*
 274                                 * Collect the results we got on this trial
 275                                 * of PBS
 276                                 */
 277                                for (pup = 0; pup < cur_max_pup; pup++) {
 278                                        for (dq = 0; dq < DQ_NUM; dq++) {
 279                                                skew_sum_array[pup + (ecc * (max_pup - 1))]
 280                                                        [dq] += skew_array
 281                                                        [((pup) * DQ_NUM) + dq];
 282                                        }
 283                                }
 284
 285                                /* ECC Support - Disable ECC MUX */
 286                                reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
 287                                        ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
 288                                reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
 289                        }
 290                }
 291
 292                DEBUG_PBS_C("DDR3 - PBS TX - values for current pattern - ",
 293                            pattern_idx, 1);
 294                for (pup = 0; pup < max_pup; pup++) {
 295                        /*
 296                         * To minimize delay elements, inc from pbs value the
 297                         * min pbs val
 298                         */
 299                        DEBUG_PBS_S("DDR3 - PBS - PUP");
 300                        DEBUG_PBS_D(pup, 1);
 301                        DEBUG_PBS_S(": ");
 302
 303                        for (dq = 0; dq < DQ_NUM; dq++) {
 304                                /* set skew value for all dq */
 305                                /* Bit# Deskew <- Bit# Deskew - last / first  failing bit Deskew For all bits (per PUP) (minimize delay elements) */
 306                                DEBUG_PBS_S("DQ");
 307                                DEBUG_PBS_D(dq, 1);
 308                                DEBUG_PBS_S("-");
 309                                DEBUG_PBS_D(skew_sum_array[pup][dq] /
 310                                            COUNT_PBS_REPEAT, 2);
 311                                DEBUG_PBS_S(", ");
 312                        }
 313                        DEBUG_PBS_S("\n");
 314                }
 315
 316                /*
 317                 * Calculate the average skew for current pattern for each
 318                 * pup and each bit
 319                 */
 320                DEBUG_PBS_C("DDR3 - PBS TX - Average for pattern - ",
 321                            pattern_idx, 1);
 322
 323                for (pup = 0; pup < max_pup; pup++) {
 324                        /*
 325                         * FOR ECC only :: found min and max value for current
 326                         * pattern skew array
 327                         */
 328                        /* Loop for all dqs */
 329                        for (dq = 0; dq < DQ_NUM; dq++) {
 330                                pattern_skew_array[pup][dq] +=
 331                                        (skew_sum_array[pup][dq] /
 332                                         COUNT_PBS_REPEAT);
 333                        }
 334                }
 335        }
 336
 337        /* Calculate the average skew */
 338        for (pup = 0; pup < max_pup; pup++) {
 339                for (dq = 0; dq < DQ_NUM; dq++)
 340                        skew_array[((pup) * DQ_NUM) + dq] =
 341                                pattern_skew_array[pup][dq] / COUNT_PBS_PATTERN;
 342        }
 343
 344        DEBUG_PBS_S("DDR3 - PBS TX - Average for all patterns:\n");
 345        for (pup = 0; pup < max_pup; pup++) {
 346                /*
 347                 * To minimize delay elements, inc from pbs value the min
 348                 * pbs val
 349                 */
 350                DEBUG_PBS_S("DDR3 - PBS - PUP");
 351                DEBUG_PBS_D(pup, 1);
 352                DEBUG_PBS_S(": ");
 353
 354                for (dq = 0; dq < DQ_NUM; dq++) {
 355                        /* Set skew value for all dq */
 356                        /*
 357                         * Bit# Deskew <- Bit# Deskew - last / first
 358                         * failing bit Deskew For all bits (per PUP)
 359                         * (minimize delay elements)
 360                         */
 361                        DEBUG_PBS_S("DQ");
 362                        DEBUG_PBS_D(dq, 1);
 363                        DEBUG_PBS_S("-");
 364                        DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2);
 365                        DEBUG_PBS_S(", ");
 366                }
 367                DEBUG_PBS_S("\n");
 368        }
 369
 370        /* Return ADLL to default value */
 371        for (pup = 0; pup < max_pup; pup++) {
 372                if (pup == (max_pup - 1) && dram_info->ecc_ena)
 373                        pup = ECC_PUP;
 374                ddr3_pbs_write_pup_dqs_reg(CS0, pup, INIT_WL_DELAY);
 375        }
 376
 377        /* Set averaged PBS results */
 378        ddr3_set_pbs_results(dram_info, 1);
 379
 380        /* Disable SW override - Must be in a different stage */
 381        /* [0]=0 - Enable SW override  */
 382        reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
 383        reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
 384        /* 0x15B8 - Training SW 2 Register */
 385        reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
 386
 387        reg = reg_read(REG_DRAM_TRAINING_1_ADDR) |
 388                (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS);
 389        reg_write(REG_DRAM_TRAINING_1_ADDR, reg);
 390
 391        DEBUG_PBS_S("DDR3 - PBS Tx - PBS TX ended successfuly\n");
 392
 393        return MV_OK;
 394}
 395
 396/*
 397 * Name:     ddr3_tx_shift_dqs_adll_step_before_fail
 398 * Desc:     Execute the Tx shift DQ phase.
 399 * Args:     dram_info            ddr3 training information struct
 400 *           cur_pup              bit array of the function active pups.
 401 *           pbs_pattern_idx      Index of PBS pattern
 402 * Notes:
 403 * Returns:  MV_OK if success, other error code if fail.
 404 */
 405static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info,
 406                                                   u32 cur_pup,
 407                                                   u32 pbs_pattern_idx, u32 ecc)
 408{
 409        u32 unlock_pup;         /* bit array of unlock pups  */
 410        u32 new_lockup_pup;     /* bit array of compare failed pups */
 411        u32 adll_val = 4;       /* INIT_WL_DELAY */
 412        u32 cur_max_pup, pup;
 413        u32 dqs_dly_set[MAX_PUP_NUM] = { 0 };
 414        u32 *pattern_ptr;
 415
 416        /* Choose pattern */
 417        switch (dram_info->ddr_width) {
 418#if defined(MV88F672X)
 419        case 16:
 420                pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx];
 421                break;
 422#endif
 423        case 32:
 424                pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx];
 425                break;
 426#if defined(MV88F78X60)
 427        case 64:
 428                pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx];
 429                break;
 430#endif
 431        default:
 432                return MV_FAIL;
 433        }
 434
 435        /* Set current pup number */
 436        if (cur_pup == 0x1)     /* Ecc mode */
 437                cur_max_pup = 1;
 438        else
 439                cur_max_pup = dram_info->num_of_std_pups;
 440
 441        unlock_pup = cur_pup;   /* '1' for each unlocked pup */
 442
 443        /* Loop on all ADLL Vaules */
 444        do {
 445                /* Loop until found first fail */
 446                adll_val++;
 447
 448                /*
 449                 * Increment (Move to right - ADLL) DQ TX delay
 450                 * (broadcast to all Data PUPs)
 451                 */
 452                for (pup = 0; pup < cur_max_pup; pup++)
 453                        ddr3_pbs_write_pup_dqs_reg(CS0,
 454                                                   pup * (1 - ecc) +
 455                                                   ECC_PUP * ecc, adll_val);
 456
 457                /*
 458                 * Write and Read, compare results (read was already verified)
 459                 */
 460                /* 0 - all locked */
 461                new_lockup_pup = 0;
 462
 463                if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup,
 464                                                &new_lockup_pup,
 465                                                pattern_ptr, LEN_PBS_PATTERN,
 466                                                SDRAM_PBS_TX_OFFS, 1, 0,
 467                                                NULL,
 468                                                0))
 469                        return MV_FAIL;
 470
 471                unlock_pup &= ~new_lockup_pup;
 472
 473                DEBUG_PBS_FULL_S("Shift DQS by 2 steps for PUPs: ");
 474                DEBUG_PBS_FULL_D(unlock_pup, 2);
 475                DEBUG_PBS_FULL_C(", Set ADLL value = ", adll_val, 2);
 476
 477                /* If any PUP failed there is '1' to mark the PUP */
 478                if (new_lockup_pup != 0) {
 479                        /*
 480                         * Decrement (Move Back to Left two steps - ADLL)
 481                         * DQ TX delay for current failed pups and save
 482                         */
 483                        for (pup = 0; pup < cur_max_pup; pup++) {
 484                                if (((new_lockup_pup >> pup) & 0x1) &&
 485                                    dqs_dly_set[pup] == 0)
 486                                        dqs_dly_set[pup] = adll_val - 1;
 487                        }
 488                }
 489        } while ((unlock_pup != 0) && (adll_val != ADLL_MAX));
 490
 491        if (unlock_pup != 0) {
 492                DEBUG_PBS_FULL_S("DDR3 - PBS Tx - Shift DQ - Adll value reached maximum\n");
 493
 494                for (pup = 0; pup < cur_max_pup; pup++) {
 495                        if (((unlock_pup >> pup) & 0x1) &&
 496                            dqs_dly_set[pup] == 0)
 497                                dqs_dly_set[pup] = adll_val - 1;
 498                }
 499        }
 500
 501        DEBUG_PBS_FULL_C("PBS TX one step before fail last pups locked Adll ",
 502                         adll_val - 2, 2);
 503
 504        /* Set the PUP DQS DLY Values */
 505        for (pup = 0; pup < cur_max_pup; pup++)
 506                ddr3_pbs_write_pup_dqs_reg(CS0, pup * (1 - ecc) + ECC_PUP * ecc,
 507                                           dqs_dly_set[pup]);
 508
 509        /* Found one phase before fail */
 510        return MV_OK;
 511}
 512
 513/*
 514 * Name:     ddr3_pbs_rx
 515 * Desc:     Execute the PBS RX phase.
 516 * Args:     dram_info   ddr3 training information struct
 517 * Notes:
 518 * Returns:  MV_OK if success, other error code if fail.
 519 */
 520int ddr3_pbs_rx(MV_DRAM_INFO *dram_info)
 521{
 522        /*
 523         * Array to hold the total sum of skew from all iterations
 524         * (for average purpose)
 525         */
 526        u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
 527
 528        /*
 529         * Array to hold the total average skew from both patterns
 530         * (for average purpose)
 531         */
 532        u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
 533
 534        u32 pbs_rep_time = 0;   /* counts number of loop in case of fail */
 535        /* bit array for unlock pups - used to repeat on the RX operation */
 536        u32 cur_pup;
 537        u32 max_pup;
 538        u32 pbs_retry;
 539        u32 pup, dq, pups, cur_max_pup, valid_pup, reg;
 540        u32 pattern_idx;
 541        u32 ecc;
 542        /* indicates whether we need to start the loop again */
 543        int start_over;
 544        int status;
 545
 546        DEBUG_PBS_S("DDR3 - PBS RX - Starting PBS RX procedure\n");
 547
 548        pups = dram_info->num_of_total_pups;
 549        max_pup = dram_info->num_of_total_pups;
 550
 551        /* Enable SW override */
 552        reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
 553                (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
 554        /* [0] = 1 - Enable SW override  */
 555        /* 0x15B8 - Training SW 2 Register */
 556        reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
 557        DEBUG_PBS_FULL_S("DDR3 - PBS RX - SW Override Enabled\n");
 558
 559        reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS;
 560        reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
 561
 562        /* Running twice for 2 different patterns. each patterns - 3 times */
 563        for (pattern_idx = 0; pattern_idx < COUNT_PBS_PATTERN; pattern_idx++) {
 564                DEBUG_PBS_FULL_C("DDR3 - PBS RX - Working with pattern - ",
 565                                 pattern_idx, 1);
 566
 567                /* Reset sum array */
 568                for (pup = 0; pup < pups; pup++) {
 569                        for (dq = 0; dq < DQ_NUM; dq++)
 570                                skew_sum_array[pup][dq] = 0;
 571                }
 572
 573                /*
 574                 * Perform PBS several of times (3 for each pattern).
 575                 * At the end, we'll use the average
 576                 */
 577                /* If there is ECC, do each PBS again with mux change */
 578                for (pbs_retry = 0; pbs_retry < COUNT_PBS_REPEAT; pbs_retry++) {
 579                        for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) {
 580                                /*
 581                                 * This parameter stores the current PUP
 582                                 * num - ecc mode dependent - 4-8 / 1 pups
 583                                 */
 584                                cur_max_pup = (1 - ecc) *
 585                                        dram_info->num_of_std_pups + ecc;
 586
 587                                if (ecc) {
 588                                        /* Only 1 pup in this case */
 589                                        valid_pup = 0x1;
 590                                } else if (cur_max_pup > 4) {
 591                                        /* 64 bit - 8 pups */
 592                                        valid_pup = 0xFF;
 593                                } else if (cur_max_pup == 4) {
 594                                        /* 32 bit - 4 pups */
 595                                        valid_pup = 0xF;
 596                                } else {
 597                                        /* 16 bit - 2 pups */
 598                                        valid_pup = 0x3;
 599                                }
 600
 601                                /* ECC Support - Switch ECC Mux on ecc=1 */
 602                                reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
 603                                        ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
 604                                reg |= (dram_info->ecc_ena * ecc <<
 605                                        REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
 606                                reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
 607
 608                                if (ecc)
 609                                        DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Enabled\n");
 610                                else
 611                                        DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Disabled\n");
 612
 613                                /* Init iteration values */
 614                                /* Clear the locked DQs */
 615                                for (pup = 0; pup < cur_max_pup; pup++) {
 616                                        for (dq = 0; dq < DQ_NUM; dq++) {
 617                                                pbs_locked_dq[
 618                                                        pup + ecc * (max_pup - 1)][dq] =
 619                                                        0;
 620                                        }
 621                                }
 622
 623                                pbs_rep_time = 0;
 624                                cur_pup = valid_pup;
 625                                start_over = 0;
 626
 627                                /*
 628                                 * Run loop On current Pattern and current
 629                                 * pattern iteration (just to cover the false
 630                                 * fail problem
 631                                 */
 632                                do {
 633                                        DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Pbs Rep Loop is ");
 634                                        DEBUG_PBS_FULL_D(pbs_rep_time, 1);
 635                                        DEBUG_PBS_FULL_S(", for Retry No.");
 636                                        DEBUG_PBS_FULL_D(pbs_retry, 1);
 637                                        DEBUG_PBS_FULL_S("\n");
 638
 639                                        /* Set all PBS values to MAX (31) */
 640                                        for (pup = 0; pup < cur_max_pup; pup++) {
 641                                                for (dq = 0; dq < DQ_NUM; dq++)
 642                                                        ddr3_write_pup_reg(
 643                                                                PUP_PBS_RX +
 644                                                                pbs_dq_mapping[
 645                                                                pup * (1 - ecc)
 646                                                                + ecc * ECC_PUP]
 647                                                                [dq], CS0,
 648                                                                pup + ecc * ECC_PUP,
 649                                                                0, MAX_PBS);
 650                                        }
 651
 652                                        /* Set all DQS PBS values to MIN (0) */
 653                                        for (pup = 0; pup < cur_max_pup; pup++) {
 654                                                ddr3_write_pup_reg(PUP_PBS_RX +
 655                                                                   DQ_NUM, CS0,
 656                                                                   pup +
 657                                                                   ecc *
 658                                                                   ECC_PUP, 0,
 659                                                                   0);
 660                                        }
 661
 662                                        /* Shift DQS, To first Fail */
 663                                        DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Shift RX DQS to first fail\n");
 664
 665                                        status = ddr3_rx_shift_dqs_to_first_fail
 666                                                (dram_info, cur_pup,
 667                                                 pattern_idx, ecc);
 668                                        if (MV_OK != status) {
 669                                                DEBUG_PBS_S("DDR3 - PBS Rx - ddr3_rx_shift_dqs_to_first_fail failed.\n");
 670                                                DEBUG_PBS_D(status, 8);
 671                                                DEBUG_PBS_S("\nDDR3 - PBS Rx - SKIP.\n");
 672
 673                                                /* Reset read FIFO */
 674                                                reg = reg_read(REG_DRAM_TRAINING_ADDR);
 675                                                /* Start Auto Read Leveling procedure */
 676                                                reg |= (1 << REG_DRAM_TRAINING_RL_OFFS);
 677                                                /* 0x15B0 - Training Register */
 678                                                reg_write(REG_DRAM_TRAINING_ADDR, reg);
 679
 680                                                reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
 681                                                reg |= ((1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS)
 682                                                        + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS));
 683                                                /* [0] = 1 - Enable SW override, [4] = 1 - FIFO reset  */
 684                                                /* 0x15B8 - Training SW 2 Register */
 685                                                reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
 686
 687                                                do {
 688                                                        reg = (reg_read(REG_DRAM_TRAINING_2_ADDR))
 689                                                                & (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
 690                                                } while (reg);  /* Wait for '0' */
 691
 692                                                reg = reg_read(REG_DRAM_TRAINING_ADDR);
 693                                                /* Clear Auto Read Leveling procedure */
 694                                                reg &= ~(1 << REG_DRAM_TRAINING_RL_OFFS);
 695                                                /* 0x15B0 - Training Register */
 696                                                reg_write(REG_DRAM_TRAINING_ADDR, reg);
 697
 698                                                /* Set ADLL to 15 */
 699                                                for (pup = 0; pup < max_pup;
 700                                                     pup++) {
 701                                                        ddr3_write_pup_reg
 702                                                            (PUP_DQS_RD, CS0,
 703                                                             pup +
 704                                                             (ecc * ECC_PUP), 0,
 705                                                             15);
 706                                                }
 707
 708                                                /* Set all PBS values to MIN (0) */
 709                                                for (pup = 0; pup < cur_max_pup;
 710                                                     pup++) {
 711                                                        for (dq = 0;
 712                                                             dq < DQ_NUM; dq++)
 713                                                                ddr3_write_pup_reg
 714                                                                    (PUP_PBS_RX +
 715                                                                     pbs_dq_mapping
 716                                                                     [pup * (1 - ecc) +
 717                                                                      ecc * ECC_PUP]
 718                                                                     [dq], CS0,
 719                                                                     pup + ecc * ECC_PUP,
 720                                                                     0, MIN_PBS);
 721                                                }
 722
 723                                                return MV_OK;
 724                                        }
 725
 726                                        /* PBS For each bit */
 727                                        DEBUG_PBS_FULL_S("DDR3 - PBS Rx - perform PBS for each bit\n");
 728                                        /* in this stage - start_over = 0; */
 729                                        if (MV_OK != ddr3_pbs_per_bit(
 730                                                    dram_info, &start_over,
 731                                                    0, &cur_pup,
 732                                                    pattern_idx, ecc)) {
 733                                                DEBUG_PBS_S("DDR3 - PBS Rx - ddr3_pbs_per_bit failed.");
 734                                                return MV_DDR3_TRAINING_ERR_PBS_RX_PER_BIT;
 735                                        }
 736
 737                                } while ((start_over == 1) &&
 738                                         (++pbs_rep_time < COUNT_PBS_STARTOVER));
 739
 740                                if (pbs_rep_time == COUNT_PBS_STARTOVER &&
 741                                    start_over == 1) {
 742                                        DEBUG_PBS_FULL_S("DDR3 - PBS Rx - FAIL - Algorithm failed doing RX PBS\n");
 743                                        return MV_DDR3_TRAINING_ERR_PBS_RX_MAX_VAL;
 744                                }
 745
 746                                /* Return DQS ADLL to default value - 15 */
 747                                /* Set all DQS PBS values to MIN (0) */
 748                                for (pup = 0; pup < cur_max_pup; pup++)
 749                                        ddr3_write_pup_reg(PUP_DQS_RD, CS0,
 750                                                           pup + ecc * ECC_PUP,
 751                                                           0, INIT_RL_DELAY);
 752
 753                                DEBUG_PBS_FULL_C("DDR3 - PBS RX - values for iteration - ",
 754                                                 pbs_retry, 1);
 755                                for (pup = 0; pup < cur_max_pup; pup++) {
 756                                        /*
 757                                         * To minimize delay elements, inc from
 758                                         * pbs value the min pbs val
 759                                         */
 760                                        DEBUG_PBS_FULL_S("DDR3 - PBS - PUP");
 761                                        DEBUG_PBS_FULL_D((pup +
 762                                                          (ecc * ECC_PUP)), 1);
 763                                        DEBUG_PBS_FULL_S(": ");
 764
 765                                        for (dq = 0; dq < DQ_NUM; dq++) {
 766                                                /* Set skew value for all dq */
 767                                                /*
 768                                                 * Bit# Deskew <- Bit# Deskew -
 769                                                 * last / first  failing bit
 770                                                 * Deskew For all bits (per PUP)
 771                                                 * (minimize delay elements)
 772                                                 */
 773                                                DEBUG_PBS_FULL_S("DQ");
 774                                                DEBUG_PBS_FULL_D(dq, 1);
 775                                                DEBUG_PBS_FULL_S("-");
 776                                                DEBUG_PBS_FULL_D(skew_array
 777                                                                 [((pup) *
 778                                                                   DQ_NUM) +
 779                                                                  dq], 2);
 780                                                DEBUG_PBS_FULL_S(", ");
 781                                        }
 782                                        DEBUG_PBS_FULL_S("\n");
 783                                }
 784
 785                                /*
 786                                 * Collect the results we got on this trial
 787                                 * of PBS
 788                                 */
 789                                for (pup = 0; pup < cur_max_pup; pup++) {
 790                                        for (dq = 0; dq < DQ_NUM; dq++) {
 791                                                skew_sum_array
 792                                                        [pup + (ecc * (max_pup - 1))]
 793                                                        [dq] +=
 794                                                        skew_array[((pup) * DQ_NUM) + dq];
 795                                        }
 796                                }
 797
 798                                /* ECC Support - Disable ECC MUX */
 799                                reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
 800                                        ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
 801                                reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
 802                        }
 803                }
 804
 805                /*
 806                 * Calculate the average skew for current pattern for each
 807                 * pup and each bit
 808                 */
 809                DEBUG_PBS_FULL_C("DDR3 - PBS RX - Average for pattern - ",
 810                                 pattern_idx, 1);
 811                for (pup = 0; pup < max_pup; pup++) {
 812                        /*
 813                         * FOR ECC only :: found min and max value for
 814                         * current pattern skew array
 815                         */
 816                        /* Loop for all dqs */
 817                        for (dq = 0; dq < DQ_NUM; dq++) {
 818                                pattern_skew_array[pup][dq] +=
 819                                        (skew_sum_array[pup][dq] /
 820                                         COUNT_PBS_REPEAT);
 821                        }
 822                }
 823
 824                DEBUG_PBS_C("DDR3 - PBS RX - values for current pattern - ",
 825                            pattern_idx, 1);
 826                for (pup = 0; pup < max_pup; pup++) {
 827                        /*
 828                         * To minimize delay elements, inc from pbs value the
 829                         * min pbs val
 830                         */
 831                        DEBUG_PBS_S("DDR3 - PBS RX - PUP");
 832                        DEBUG_PBS_D(pup, 1);
 833                        DEBUG_PBS_S(": ");
 834
 835                        for (dq = 0; dq < DQ_NUM; dq++) {
 836                                /* Set skew value for all dq */
 837                                /*
 838                                 * Bit# Deskew <- Bit# Deskew - last / first
 839                                 * failing bit Deskew For all bits (per PUP)
 840                                 * (minimize delay elements)
 841                                 */
 842                                DEBUG_PBS_S("DQ");
 843                                DEBUG_PBS_D(dq, 1);
 844                                DEBUG_PBS_S("-");
 845                                DEBUG_PBS_D(skew_sum_array[pup][dq] /
 846                                            COUNT_PBS_REPEAT, 2);
 847                                DEBUG_PBS_S(", ");
 848                        }
 849                        DEBUG_PBS_S("\n");
 850                }
 851        }
 852
 853        /* Calculate the average skew */
 854        for (pup = 0; pup < max_pup; pup++) {
 855                for (dq = 0; dq < DQ_NUM; dq++)
 856                        skew_array[((pup) * DQ_NUM) + dq] =
 857                                pattern_skew_array[pup][dq] / COUNT_PBS_PATTERN;
 858        }
 859
 860        DEBUG_PBS_S("DDR3 - PBS RX - Average for all patterns:\n");
 861        for (pup = 0; pup < max_pup; pup++) {
 862                /*
 863                 * To minimize delay elements, inc from pbs value the
 864                 * min pbs val
 865                 */
 866                DEBUG_PBS_S("DDR3 - PBS - PUP");
 867                DEBUG_PBS_D(pup, 1);
 868                DEBUG_PBS_S(": ");
 869
 870                for (dq = 0; dq < DQ_NUM; dq++) {
 871                        /* Set skew value for all dq */
 872                        /*
 873                         * Bit# Deskew <- Bit# Deskew - last / first
 874                         * failing bit Deskew For all bits (per PUP)
 875                         * (minimize delay elements)
 876                         */
 877                        DEBUG_PBS_S("DQ");
 878                        DEBUG_PBS_D(dq, 1);
 879                        DEBUG_PBS_S("-");
 880                        DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2);
 881                        DEBUG_PBS_S(", ");
 882                }
 883                DEBUG_PBS_S("\n");
 884        }
 885
 886        /* Return ADLL to default value */
 887        ddr3_write_pup_reg(PUP_DQS_RD, CS0, PUP_BC, 0, INIT_RL_DELAY);
 888
 889        /* Set averaged PBS results */
 890        ddr3_set_pbs_results(dram_info, 0);
 891
 892        /* Disable SW override - Must be in a different stage */
 893        /* [0]=0 - Enable SW override  */
 894        reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
 895        reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
 896        /* 0x15B8 - Training SW 2 Register */
 897        reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
 898
 899        reg = reg_read(REG_DRAM_TRAINING_1_ADDR) |
 900                (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS);
 901        reg_write(REG_DRAM_TRAINING_1_ADDR, reg);
 902
 903        DEBUG_PBS_FULL_S("DDR3 - PBS RX - ended successfuly\n");
 904
 905        return MV_OK;
 906}
 907
 908/*
 909 * Name:     ddr3_rx_shift_dqs_to_first_fail
 910 * Desc:     Execute the Rx shift DQ phase.
 911 * Args:     dram_info           ddr3 training information struct
 912 *           cur_pup             bit array of the function active pups.
 913 *           pbs_pattern_idx     Index of PBS pattern
 914 * Notes:
 915 * Returns:  MV_OK if success, other error code if fail.
 916 */
 917static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup,
 918                                           u32 pbs_pattern_idx, u32 ecc)
 919{
 920        u32 unlock_pup;         /* bit array of unlock pups  */
 921        u32 new_lockup_pup;     /* bit array of compare failed pups */
 922        u32 adll_val = MAX_DELAY;
 923        u32 dqs_deskew_val = 0; /* current value of DQS PBS deskew */
 924        u32 cur_max_pup, pup, pass_pup;
 925        u32 *pattern_ptr;
 926
 927        /* Choose pattern */
 928        switch (dram_info->ddr_width) {
 929#if defined(MV88F672X)
 930        case 16:
 931                pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx];
 932                break;
 933#endif
 934        case 32:
 935                pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx];
 936                break;
 937#if defined(MV88F78X60)
 938        case 64:
 939                pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx];
 940                break;
 941#endif
 942        default:
 943                return MV_FAIL;
 944        }
 945
 946        /* Set current pup number */
 947        if (cur_pup == 0x1)     /* Ecc mode */
 948                cur_max_pup = 1;
 949        else
 950                cur_max_pup = dram_info->num_of_std_pups;
 951
 952        unlock_pup = cur_pup;   /* '1' for each unlocked pup */
 953
 954        DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Starting...\n");
 955
 956        /* Set DQS ADLL to MAX */
 957        DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Set DQS ADLL to Max for all PUPs\n");
 958        for (pup = 0; pup < cur_max_pup; pup++)
 959                ddr3_write_pup_reg(PUP_DQS_RD, CS0, pup + ecc * ECC_PUP, 0,
 960                                   MAX_DELAY);
 961
 962        /* Loop on all ADLL Vaules */
 963        do {
 964                /* Loop until found fail for all pups */
 965                new_lockup_pup = 0;
 966                if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup,
 967                                                &new_lockup_pup,
 968                                                pattern_ptr, LEN_PBS_PATTERN,
 969                                                SDRAM_PBS_I_OFFS +
 970                                                pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS,
 971                                                0, 0, NULL, 0)) {
 972                        DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP(ddr3_sdram_compare)\n");
 973                        return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP;
 974                }
 975
 976                if ((new_lockup_pup != 0) && (dqs_deskew_val <= 1)) {
 977                        /* Fail on start with first deskew value */
 978                        /* Decrement DQS ADLL */
 979                        --adll_val;
 980                        if (adll_val == ADLL_MIN) {
 981                                DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - fail on start with first deskew value\n");
 982                                return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP;
 983                        }
 984                        ddr3_write_pup_reg(PUP_DQS_RD, CS0, pup + ecc * ECC_PUP,
 985                                           0, adll_val);
 986                        continue;
 987                }
 988
 989                /* Update all new locked pups */
 990                unlock_pup &= ~new_lockup_pup;
 991
 992                if ((unlock_pup == 0) || (dqs_deskew_val == MAX_PBS)) {
 993                        if (dqs_deskew_val == MAX_PBS) {
 994                                /*
 995                                 * Reach max value of dqs deskew or get fail
 996                                 * for all pups
 997                                 */
 998                                DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - DQS deskew reached maximum value\n");
 999                        }
1000                        break;
1001                }
1002
1003                DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Inc DQS deskew for PUPs: ");
1004                DEBUG_PBS_FULL_D(unlock_pup, 2);
1005                DEBUG_PBS_FULL_C(", deskew = ", dqs_deskew_val, 2);
1006
1007                /* Increment DQS deskew elements - Only for unlocked pups */
1008                dqs_deskew_val++;
1009                for (pup = 0; pup < cur_max_pup; pup++) {
1010                        if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
1011                                ddr3_write_pup_reg(PUP_PBS_RX + DQS_DQ_NUM, CS0,
1012                                                   pup + ecc * ECC_PUP, 0,
1013                                                   dqs_deskew_val);
1014                        }
1015                }
1016        } while (1);
1017
1018        DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - ADLL shift one step before fail\n");
1019        /* Continue to ADLL shift one step before fail */
1020        unlock_pup = cur_pup;
1021        do {
1022                /* Loop until pass compare for all pups */
1023                new_lockup_pup = 0;
1024                /* Read and compare results  */
1025                if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup, &new_lockup_pup,
1026                                                pattern_ptr, LEN_PBS_PATTERN,
1027                                                SDRAM_PBS_I_OFFS +
1028                                                pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS,
1029                                                1, 0, NULL, 0)) {
1030                        DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP(ddr3_sdram_compare)\n");
1031                        return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP;
1032                }
1033
1034                /*
1035                 * Get mask for pup which passed so their adll will be
1036                 * changed to 2 steps before fails
1037                 */
1038                pass_pup = unlock_pup & ~new_lockup_pup;
1039
1040                DEBUG_PBS_FULL_S("Shift DQS by 2 steps for PUPs: ");
1041                DEBUG_PBS_FULL_D(pass_pup, 2);
1042                DEBUG_PBS_FULL_C(", Set ADLL value = ", (adll_val - 2), 2);
1043
1044                /* Only for pass pups   */
1045                for (pup = 0; pup < cur_max_pup; pup++) {
1046                        if (IS_PUP_ACTIVE(pass_pup, pup) == 1) {
1047                                ddr3_write_pup_reg(PUP_DQS_RD, CS0,
1048                                                   pup + ecc * ECC_PUP, 0,
1049                                                   (adll_val - 2));
1050                        }
1051                }
1052
1053                /* Locked pups that compare success  */
1054                unlock_pup &= new_lockup_pup;
1055
1056                if (unlock_pup == 0) {
1057                        /* All pups locked */
1058                        break;
1059                }
1060
1061                /* Found error */
1062                if (adll_val == 0) {
1063                        DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Shift DQS - Adll reach min value\n");
1064                        return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_MAX_VAL;
1065                }
1066
1067                /*
1068                 * Decrement (Move Back to Left one phase - ADLL) dqs RX delay
1069                 */
1070                adll_val--;
1071                for (pup = 0; pup < cur_max_pup; pup++) {
1072                        if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
1073                                ddr3_write_pup_reg(PUP_DQS_RD, CS0,
1074                                                   pup + ecc * ECC_PUP, 0,
1075                                                   adll_val);
1076                        }
1077                }
1078        } while (1);
1079
1080        return MV_OK;
1081}
1082
1083/*
1084 * lock_pups() extracted from ddr3_pbs_per_bit(). This just got too
1085 * much indented making it hard to read / edit.
1086 */
1087static void lock_pups(u32 pup, u32 *pup_locked, u8 *unlock_pup_dq_array,
1088                      u32 pbs_curr_val, u32 start_pbs, u32 ecc, int is_tx)
1089{
1090        u32 dq;
1091        int idx;
1092
1093        /* Lock PBS value for all remaining PUPs bits */
1094        DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Lock PBS value for all remaining PUPs bits, pup ");
1095        DEBUG_PBS_FULL_D(pup, 1);
1096        DEBUG_PBS_FULL_C(" pbs value ", pbs_curr_val, 2);
1097
1098        idx = pup * (1 - ecc) + ecc * ECC_PUP;
1099        *pup_locked &= ~(1 << pup);
1100
1101        for (dq = 0; dq < DQ_NUM; dq++) {
1102                if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup) == 1) {
1103                        int offs;
1104
1105                        /* Lock current dq */
1106                        unlock_pup_dq_array[dq] &= ~(1 << pup);
1107                        skew_array[(pup * DQ_NUM) + dq] = pbs_curr_val;
1108
1109                        if (is_tx == 1)
1110                                offs = PUP_PBS_TX;
1111                        else
1112                                offs = PUP_PBS_RX;
1113
1114                        ddr3_write_pup_reg(offs +
1115                                           pbs_dq_mapping[idx][dq], CS0,
1116                                           idx, 0, start_pbs);
1117                }
1118        }
1119}
1120
1121/*
1122 * Name:     ddr3_pbs_per_bit
1123 * Desc:     Execute the Per Bit Skew phase.
1124 * Args:     start_over      Return whether need to start over the algorithm
1125 *           is_tx           Indicate whether Rx or Tx
1126 *           pcur_pup        bit array of the function active pups. return the
1127 *                           pups that need to repeat on the PBS
1128 *           pbs_pattern_idx Index of PBS pattern
1129 *
1130 * Notes:    Current implementation supports double activation of this function.
1131 *           i.e. in order to activate this function (using start_over) more than
1132 *           twice, the implementation should change.
1133 *           imlementation limitation are marked using
1134 *           ' CHIP-ONLY! - Implementation Limitation '
1135 * Returns:  MV_OK if success, other error code if fail.
1136 */
1137static int ddr3_pbs_per_bit(MV_DRAM_INFO *dram_info, int *start_over, int is_tx,
1138                            u32 *pcur_pup, u32 pbs_pattern_idx, u32 ecc)
1139{
1140        /*
1141         * Bit array to indicate if we already get fail on bit per pup & dq bit
1142         */
1143        u8 unlock_pup_dq_array[DQ_NUM] = {
1144                *pcur_pup, *pcur_pup, *pcur_pup, *pcur_pup, *pcur_pup,
1145                *pcur_pup, *pcur_pup, *pcur_pup
1146        };
1147
1148        u8 cmp_unlock_pup_dq_array[COUNT_PBS_COMP_RETRY_NUM][DQ_NUM];
1149        u32 pup, dq;
1150        /* value of pbs is according to RX or TX */
1151        u32 start_pbs, last_pbs;
1152        u32 pbs_curr_val;
1153        /* bit array that indicates all dq of the pup locked */
1154        u32 pup_locked;
1155        u32 first_fail[MAX_PUP_NUM] = { 0 };    /* count first fail per pup */
1156        /* indicates whether we get first fail per pup */
1157        int first_failed[MAX_PUP_NUM] = { 0 };
1158        /* bit array that indicates pup already get fail */
1159        u32 sum_pup_fail;
1160        /* use to calculate diff between curr pbs to first fail pbs */
1161        u32 calc_pbs_diff;
1162        u32 pbs_cmp_retry;
1163        u32 max_pup;
1164
1165        /* Set init values for retry array - 8 retry */
1166        for (pbs_cmp_retry = 0; pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM;
1167             pbs_cmp_retry++) {
1168                for (dq = 0; dq < DQ_NUM; dq++)
1169                        cmp_unlock_pup_dq_array[pbs_cmp_retry][dq] = *pcur_pup;
1170        }
1171
1172        memset(&skew_array, 0, MAX_PUP_NUM * DQ_NUM * sizeof(u32));
1173
1174        DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Started\n");
1175
1176        /* The pbs value depends if rx or tx */
1177        if (is_tx == 1) {
1178                start_pbs = MIN_PBS;
1179                last_pbs = MAX_PBS;
1180        } else {
1181                start_pbs = MAX_PBS;
1182                last_pbs = MIN_PBS;
1183        }
1184
1185        pbs_curr_val = start_pbs;
1186        pup_locked = *pcur_pup;
1187
1188        /* Set current pup number */
1189        if (pup_locked == 0x1)  /* Ecc mode */
1190                max_pup = 1;
1191        else
1192                max_pup = dram_info->num_of_std_pups;
1193
1194        do {
1195                /* Increment/ decrement PBS for un-lock bits only */
1196                if (is_tx == 1)
1197                        pbs_curr_val++;
1198                else
1199                        pbs_curr_val--;
1200
1201                /* Set Current PBS delay  */
1202                for (dq = 0; dq < DQ_NUM; dq++) {
1203                        /* Check DQ bits to see if locked in all pups */
1204                        if (unlock_pup_dq_array[dq] == 0) {
1205                                DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - All pups are locked for DQ ");
1206                                DEBUG_PBS_FULL_D(dq, 1);
1207                                DEBUG_PBS_FULL_S("\n");
1208                                continue;
1209                        }
1210
1211                        for (pup = 0; pup < max_pup; pup++) {
1212                                int idx;
1213
1214                                idx = pup * (1 - ecc) + ecc * ECC_PUP;
1215
1216                                if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup)
1217                                    == 0)
1218                                        continue;
1219
1220                                if (is_tx == 1)
1221                                        ddr3_write_pup_reg(
1222                                                PUP_PBS_TX + pbs_dq_mapping[idx][dq],
1223                                                CS0, idx, 0, pbs_curr_val);
1224                                else
1225                                        ddr3_write_pup_reg(
1226                                                PUP_PBS_RX + pbs_dq_mapping[idx][dq],
1227                                                CS0, idx, 0, pbs_curr_val);
1228                        }
1229                }
1230
1231                /*
1232                 * Write Read and compare results - run the test
1233                 * DDR_PBS_COMP_RETRY_NUM times
1234                 */
1235                /* Run number of read and write to verify */
1236                for (pbs_cmp_retry = 0;
1237                     pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM;
1238                     pbs_cmp_retry++) {
1239
1240                        if (MV_OK !=
1241                            ddr3_sdram_pbs_compare(dram_info, pup_locked, is_tx,
1242                                                   pbs_pattern_idx,
1243                                                   pbs_curr_val, start_pbs,
1244                                                   skew_array,
1245                                                   cmp_unlock_pup_dq_array
1246                                                   [pbs_cmp_retry], ecc))
1247                                return MV_FAIL;
1248
1249                        for (pup = 0; pup < max_pup; pup++) {
1250                                for (dq = 0; dq < DQ_NUM; dq++) {
1251                                        if ((IS_PUP_ACTIVE(unlock_pup_dq_array[dq],
1252                                                           pup) == 1)
1253                                            && (IS_PUP_ACTIVE(cmp_unlock_pup_dq_array
1254                                              [pbs_cmp_retry][dq],
1255                                              pup) == 0)) {
1256                                                DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - PbsCurrVal: ");
1257                                                DEBUG_PBS_FULL_D(pbs_curr_val, 2);
1258                                                DEBUG_PBS_FULL_S(" PUP: ");
1259                                                DEBUG_PBS_FULL_D(pup, 1);
1260                                                DEBUG_PBS_FULL_S(" DQ: ");
1261                                                DEBUG_PBS_FULL_D(dq, 1);
1262                                                DEBUG_PBS_FULL_S(" - failed\n");
1263                                        }
1264                                }
1265                        }
1266
1267                        for (dq = 0; dq < DQ_NUM; dq++) {
1268                                unlock_pup_dq_array[dq] &=
1269                                    cmp_unlock_pup_dq_array[pbs_cmp_retry][dq];
1270                        }
1271                }
1272
1273                pup_locked = 0;
1274                sum_pup_fail = *pcur_pup;
1275
1276                /* Check which DQ is failed */
1277                for (dq = 0; dq < DQ_NUM; dq++) {
1278                        /* Summarize the locked pup */
1279                        pup_locked |= unlock_pup_dq_array[dq];
1280
1281                        /* Check if get fail */
1282                        sum_pup_fail &= unlock_pup_dq_array[dq];
1283                }
1284
1285                /* If all PUPS are locked in all DQ - Break */
1286                if (pup_locked == 0) {
1287                        /* All pups are locked */
1288                        *start_over = 0;
1289                        DEBUG_PBS_FULL_S("DDR3 - PBS Per bit -  All bit in all pups are successfully locked\n");
1290                        break;
1291                }
1292
1293                /* PBS deskew elements reach max ? */
1294                if (pbs_curr_val == last_pbs) {
1295                        DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - PBS deskew elements reach max\n");
1296                        /* CHIP-ONLY! - Implementation Limitation */
1297                        *start_over = (sum_pup_fail != 0) && (!(*start_over));
1298                        *pcur_pup = pup_locked;
1299
1300                        DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - StartOver: ");
1301                        DEBUG_PBS_FULL_D(*start_over, 1);
1302                        DEBUG_PBS_FULL_S("  pup_locked: ");
1303                        DEBUG_PBS_FULL_D(pup_locked, 2);
1304                        DEBUG_PBS_FULL_S("  sum_pup_fail: ");
1305                        DEBUG_PBS_FULL_D(sum_pup_fail, 2);
1306                        DEBUG_PBS_FULL_S("\n");
1307
1308                        /* Lock PBS value for all remaining  bits */
1309                        for (pup = 0; pup < max_pup; pup++) {
1310                                /* Check if current pup already received error */
1311                                if (IS_PUP_ACTIVE(pup_locked, pup) == 1) {
1312                                        /* Valid pup for current function */
1313                                        if (IS_PUP_ACTIVE(sum_pup_fail, pup) ==
1314                                            1 && (*start_over == 1)) {
1315                                                DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - skipping lock of pup (first loop of pbs)",
1316                                                                 pup, 1);
1317                                                continue;
1318                                        } else
1319                                            if (IS_PUP_ACTIVE(sum_pup_fail, pup)
1320                                                == 1) {
1321                                                DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - Locking pup %d (even though it wasn't supposed to be locked)",
1322                                                                 pup, 1);
1323                                        }
1324
1325                                        /* Already got fail on the PUP */
1326                                        /* Lock PBS value for all remaining bits */
1327                                        DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Locking remaning DQs for pup - ");
1328                                        DEBUG_PBS_FULL_D(pup, 1);
1329                                        DEBUG_PBS_FULL_S(": ");
1330
1331                                        for (dq = 0; dq < DQ_NUM; dq++) {
1332                                                if (IS_PUP_ACTIVE
1333                                                    (unlock_pup_dq_array[dq],
1334                                                     pup) == 1) {
1335                                                        DEBUG_PBS_FULL_D(dq, 1);
1336                                                        DEBUG_PBS_FULL_S(",");
1337                                                        /* set current PBS */
1338                                                        skew_array[((pup) *
1339                                                                    DQ_NUM) +
1340                                                                   dq] =
1341                                                            pbs_curr_val;
1342                                                }
1343                                        }
1344
1345                                        if (*start_over == 1) {
1346                                                /*
1347                                                 * Reset this pup bit - when
1348                                                 * restart the PBS, ignore this
1349                                                 * pup
1350                                                 */
1351                                                *pcur_pup &= ~(1 << pup);
1352                                        }
1353                                        DEBUG_PBS_FULL_S("\n");
1354                                } else {
1355                                        DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Pup ");
1356                                        DEBUG_PBS_FULL_D(pup, 1);
1357                                        DEBUG_PBS_FULL_C(" is not set in puplocked - ",
1358                                                         pup_locked, 1);
1359                                }
1360                        }
1361
1362                        /* Need to start the PBS again */
1363                        if (*start_over == 1) {
1364                                DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - false fail - returning to start\n");
1365                                return MV_OK;
1366                        }
1367                        break;
1368                }
1369
1370                /* Diff Check */
1371                for (pup = 0; pup < max_pup; pup++) {
1372                        if (IS_PUP_ACTIVE(pup_locked, pup) == 1) {
1373                                /* pup is not locked */
1374                                if (first_failed[pup] == 0) {
1375                                        /* No first fail until now */
1376                                        if (IS_PUP_ACTIVE(sum_pup_fail, pup) ==
1377                                            0) {
1378                                                /* Get first fail */
1379                                                DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - First fail in pup ",
1380                                                                 pup, 1);
1381                                                first_failed[pup] = 1;
1382                                                first_fail[pup] = pbs_curr_val;
1383                                        }
1384                                } else {
1385                                        /* Already got first fail */
1386                                        if (is_tx == 1) {
1387                                                /* TX - inc pbs */
1388                                                calc_pbs_diff = pbs_curr_val -
1389                                                        first_fail[pup];
1390                                        } else {
1391                                                /* RX - dec pbs */
1392                                                calc_pbs_diff = first_fail[pup] -
1393                                                        pbs_curr_val;
1394                                        }
1395
1396                                        if (calc_pbs_diff >= PBS_DIFF_LIMIT) {
1397                                                lock_pups(pup, &pup_locked,
1398                                                          unlock_pup_dq_array,
1399                                                          pbs_curr_val,
1400                                                          start_pbs, ecc, is_tx);
1401                                        }
1402                                }
1403                        }
1404                }
1405        } while (1);
1406
1407        return MV_OK;
1408}
1409
1410/*
1411 * Name:         ddr3_set_pbs_results
1412 * Desc:         Set to HW the PBS phase results.
1413 * Args:         is_tx       Indicates whether to set Tx or RX results
1414 * Notes:
1415 * Returns:      MV_OK if success, other error code if fail.
1416 */
1417static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx)
1418{
1419        u32 pup, phys_pup, dq;
1420        u32 max_pup;            /* number of valid pups */
1421        u32 pbs_min;            /* minimal pbs val per pup */
1422        u32 pbs_max;            /* maximum pbs val per pup */
1423        u32 val[9];
1424
1425        max_pup = dram_info->num_of_total_pups;
1426        DEBUG_PBS_FULL_S("DDR3 - PBS - ddr3_set_pbs_results:\n");
1427
1428        /* Loop for all dqs & pups */
1429        for (pup = 0; pup < max_pup; pup++) {
1430                if (pup == (max_pup - 1) && dram_info->ecc_ena)
1431                        phys_pup = ECC_PUP;
1432                else
1433                        phys_pup = pup;
1434
1435                /*
1436                 * To minimize delay elements, inc from pbs value the min
1437                 * pbs val
1438                 */
1439                pbs_min = MAX_PBS;
1440                pbs_max = 0;
1441                for (dq = 0; dq < DQ_NUM; dq++) {
1442                        if (pbs_min > skew_array[(pup * DQ_NUM) + dq])
1443                                pbs_min = skew_array[(pup * DQ_NUM) + dq];
1444
1445                        if (pbs_max < skew_array[(pup * DQ_NUM) + dq])
1446                                pbs_max = skew_array[(pup * DQ_NUM) + dq];
1447                }
1448
1449                pbs_max -= pbs_min;
1450
1451                DEBUG_PBS_FULL_S("DDR3 - PBS - PUP");
1452                DEBUG_PBS_FULL_D(phys_pup, 1);
1453                DEBUG_PBS_FULL_S(": Min Val = ");
1454                DEBUG_PBS_FULL_D(pbs_min, 2);
1455                DEBUG_PBS_FULL_C(", Max Val = ", pbs_max, 2);
1456
1457                val[pup] = 0;
1458
1459                for (dq = 0; dq < DQ_NUM; dq++) {
1460                        int idx;
1461                        int offs;
1462
1463                        /* Set skew value for all dq */
1464                        /*
1465                         * Bit# Deskew <- Bit# Deskew - last / first
1466                         * failing bit Deskew For all bits (per PUP)
1467                         * (minimize delay elements)
1468                         */
1469
1470                        DEBUG_PBS_FULL_S("DQ");
1471                        DEBUG_PBS_FULL_D(dq, 1);
1472                        DEBUG_PBS_FULL_S("-");
1473                        DEBUG_PBS_FULL_D((skew_array[(pup * DQ_NUM) + dq] -
1474                                          pbs_min), 2);
1475                        DEBUG_PBS_FULL_S(", ");
1476
1477                        idx = (pup * DQ_NUM) + dq;
1478
1479                        if (is_tx == 1)
1480                                offs = PUP_PBS_TX;
1481                        else
1482                                offs = PUP_PBS_RX;
1483
1484                        ddr3_write_pup_reg(offs + pbs_dq_mapping[phys_pup][dq],
1485                                           CS0, phys_pup, 0,
1486                                           skew_array[idx] - pbs_min);
1487
1488                        if (is_tx == 1)
1489                                val[pup] += skew_array[idx] - pbs_min;
1490                }
1491
1492                DEBUG_PBS_FULL_S("\n");
1493
1494                /* Set the DQS the half of the Max PBS of the DQs  */
1495                if (is_tx == 1) {
1496                        ddr3_write_pup_reg(PUP_PBS_TX + 8, CS0, phys_pup, 0,
1497                                           pbs_max / 2);
1498                        ddr3_write_pup_reg(PUP_PBS_TX + 0xa, CS0, phys_pup, 0,
1499                                           val[pup] / 8);
1500                } else
1501                        ddr3_write_pup_reg(PUP_PBS_RX + 8, CS0, phys_pup, 0,
1502                                           pbs_max / 2);
1503        }
1504
1505        return MV_OK;
1506}
1507
1508static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay)
1509{
1510        u32 reg, delay;
1511
1512        reg = (ddr3_read_pup_reg(PUP_WL_MODE, cs, pup) & 0x3FF);
1513        delay = reg & PUP_DELAY_MASK;
1514        reg |= ((dqs_delay + delay) << REG_PHY_DQS_REF_DLY_OFFS);
1515        reg |= REG_PHY_REGISTRY_FILE_ACCESS_OP_WR;
1516        reg |= (pup << REG_PHY_PUP_OFFS);
1517        reg |= ((0x4 * cs + PUP_WL_MODE) << REG_PHY_CS_OFFS);
1518
1519        reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg);      /* 0x16A0 */
1520        do {
1521                reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) &
1522                        REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE;
1523        } while (reg);  /* Wait for '0' to mark the end of the transaction */
1524
1525        udelay(10);
1526}
1527
1528/*
1529 * Set training patterns
1530 */
1531int ddr3_load_pbs_patterns(MV_DRAM_INFO *dram_info)
1532{
1533        u32 cs, cs_count, cs_tmp;
1534        u32 sdram_addr;
1535        u32 *pattern_ptr0, *pattern_ptr1;
1536
1537        /* Choose pattern */
1538        switch (dram_info->ddr_width) {
1539#if defined(MV88F672X)
1540        case 16:
1541                pattern_ptr0 = (u32 *)&pbs_pattern[0];
1542                pattern_ptr1 = (u32 *)&pbs_pattern[1];
1543                break;
1544#endif
1545        case 32:
1546                pattern_ptr0 = (u32 *)&pbs_pattern_32b[0];
1547                pattern_ptr1 = (u32 *)&pbs_pattern_32b[1];
1548                break;
1549#if defined(MV88F78X60)
1550        case 64:
1551                pattern_ptr0 = (u32 *)&pbs_pattern_64b[0];
1552                pattern_ptr1 = (u32 *)&pbs_pattern_64b[1];
1553                break;
1554#endif
1555        default:
1556                return MV_FAIL;
1557        }
1558
1559        /* Loop for each CS */
1560        for (cs = 0; cs < MAX_CS; cs++) {
1561                if (dram_info->cs_ena & (1 << cs)) {
1562                        cs_count = 0;
1563                        for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) {
1564                                if (dram_info->cs_ena & (1 << cs_tmp))
1565                                        cs_count++;
1566                        }
1567
1568                        /* Init PBS I pattern */
1569                        sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
1570                                      SDRAM_PBS_I_OFFS);
1571                        if (MV_OK !=
1572                            ddr3_sdram_compare(dram_info, (u32) NULL, NULL,
1573                                               pattern_ptr0, LEN_STD_PATTERN,
1574                                               sdram_addr, 1, 0, NULL,
1575                                               0))
1576                                return MV_FAIL;
1577
1578                        /* Init PBS II pattern */
1579                        sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
1580                                      SDRAM_PBS_II_OFFS);
1581                        if (MV_OK !=
1582                            ddr3_sdram_compare(dram_info, (u32) NULL, NULL,
1583                                               pattern_ptr1, LEN_STD_PATTERN,
1584                                               sdram_addr, 1, 0, NULL,
1585                                               0))
1586                                return MV_FAIL;
1587                }
1588        }
1589
1590        return MV_OK;
1591}
1592#endif
1593