2 * Copyright (C) Marvell International Ltd. and its affiliates
4 * SPDX-License-Identifier: GPL-2.0
11 #include <asm/arch/cpu.h>
12 #include <asm/arch/soc.h>
14 #include "ddr3_hw_training.h"
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")
25 #define DEBUG_PBS_S(s) puts(s)
26 #define DEBUG_PBS_D(d, l) printf("%x", d)
28 #define DEBUG_PBS_S(s)
29 #define DEBUG_PBS_D(d, l)
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)
36 #define DEBUG_PBS_FULL_S(s)
37 #define DEBUG_PBS_FULL_D(d, l)
40 #if defined(MV88F78X60) || defined(MV88F672X)
42 /* Temp array for skew data storage */
43 static u32 skew_array[(MAX_PUP_NUM) * DQ_NUM] = { 0 };
45 /* PBS locked dq (per pup) */
46 extern u32 pbs_locked_dq[MAX_PUP_NUM][DQ_NUM];
47 extern u32 pbs_locked_dm[MAX_PUP_NUM];
48 extern u32 pbs_locked_value[MAX_PUP_NUM][DQ_NUM];
50 #if defined(MV88F672X)
51 extern u32 pbs_pattern[2][LEN_16BIT_PBS_PATTERN];
52 extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN];
54 extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN];
55 extern u32 pbs_pattern_64b[2][LEN_PBS_PATTERN];
58 extern u32 pbs_dq_mapping[PUP_NUM_64BIT + 1][DQ_NUM];
60 static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info,
61 u32 cur_pup, u32 pbs_pattern_idx, u32 ecc);
62 static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup,
63 u32 pbs_pattern_idx, u32 ecc);
64 static 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);
66 static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx);
67 static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay);
71 * Desc: Execute the PBS TX phase.
72 * Args: dram_info ddr3 training information struct
74 * Returns: MV_OK if success, other error code if fail.
76 int ddr3_pbs_tx(MV_DRAM_INFO *dram_info)
78 /* Array of Deskew results */
81 * Array to hold the total sum of skew from all iterations
82 * (for average purpose)
84 u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
87 * Array to hold the total average skew from both patterns
88 * (for average purpose)
90 u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
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 */
97 u32 pup, dq, pups, cur_max_pup, valid_pup, reg;
100 /* indicates whether we need to start the loop again */
103 DEBUG_PBS_S("DDR3 - PBS TX - Starting PBS TX procedure\n");
105 pups = dram_info->num_of_total_pups;
106 max_pup = dram_info->num_of_total_pups;
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");
116 reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS;
117 reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
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 - ",
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;
131 * Perform PBS several of times (3 for each pattern).
132 * At the end, we'll use the average
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++) {
139 * This parameter stores the current PUP
140 * num - ecc mode dependent - 4-8 / 1 pups
142 cur_max_pup = (1 - ecc) *
143 dram_info->num_of_std_pups + ecc;
146 /* Only 1 pup in this case */
148 } else if (cur_max_pup > 4) {
149 /* 64 bit - 8 pups */
151 } else if (cur_max_pup == 4) {
152 /* 32 bit - 4 pups */
155 /* 16 bit - 2 pups */
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);
167 DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Enabled\n");
169 DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Disabled\n");
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++) {
187 * Run loop On current Pattern and current
188 * pattern iteration (just to cover the false
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);
198 /* Set all PBS values to MIN (0) */
199 DEBUG_PBS_S("DDR3 - PBS Tx - Set all PBS values to MIN\n");
201 for (dq = 0; dq < DQ_NUM; dq++) {
207 [dq], CS0, (1 - ecc) *
208 PUP_BC + ecc * ECC_PUP, 0,
213 * Shift DQ ADLL right, One step before
216 DEBUG_PBS_S("DDR3 - PBS Tx - ADLL shift right one phase before fail\n");
218 if (MV_OK != ddr3_tx_shift_dqs_adll_step_before_fail
219 (dram_info, cur_pup, pattern_idx,
221 return MV_DDR3_TRAINING_ERR_PBS_ADLL_SHR_1PHASE;
223 /* PBS For each bit */
224 DEBUG_PBS_S("DDR3 - PBS Tx - perform PBS for each bit\n");
227 * In this stage - start_over = 0
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;
234 } while ((start_over == 1) &&
235 (++pbs_rep_time < COUNT_PBS_STARTOVER));
237 if (pbs_rep_time == COUNT_PBS_STARTOVER &&
239 DEBUG_PBS_S("DDR3 - PBS Tx - FAIL - Adll reach max value\n");
240 return MV_DDR3_TRAINING_ERR_PBS_TX_MAX_VAL;
243 DEBUG_PBS_FULL_C("DDR3 - PBS TX - values for iteration - ",
245 for (pup = 0; pup < cur_max_pup; pup++) {
247 * To minimize delay elements, inc
248 * from pbs value the min pbs val
250 DEBUG_PBS_S("DDR3 - PBS - PUP");
251 DEBUG_PBS_D((pup + (ecc * ECC_PUP)), 1);
254 for (dq = 0; dq < DQ_NUM; dq++) {
255 /* Set skew value for all dq */
257 * Bit# Deskew <- Bit# Deskew -
258 * last / first failing bit
259 * Deskew For all bits (per PUP)
260 * (minimize delay elements)
265 DEBUG_PBS_D(skew_array
274 * Collect the results we got on this trial
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))]
281 [((pup) * DQ_NUM) + dq];
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);
292 DEBUG_PBS_C("DDR3 - PBS TX - values for current pattern - ",
294 for (pup = 0; pup < max_pup; pup++) {
296 * To minimize delay elements, inc from pbs value the
299 DEBUG_PBS_S("DDR3 - PBS - PUP");
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) */
309 DEBUG_PBS_D(skew_sum_array[pup][dq] /
310 COUNT_PBS_REPEAT, 2);
317 * Calculate the average skew for current pattern for each
320 DEBUG_PBS_C("DDR3 - PBS TX - Average for pattern - ",
323 for (pup = 0; pup < max_pup; pup++) {
325 * FOR ECC only :: found min and max value for current
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] /
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;
344 DEBUG_PBS_S("DDR3 - PBS TX - Average for all patterns:\n");
345 for (pup = 0; pup < max_pup; pup++) {
347 * To minimize delay elements, inc from pbs value the min
350 DEBUG_PBS_S("DDR3 - PBS - PUP");
354 for (dq = 0; dq < DQ_NUM; dq++) {
355 /* Set skew value for all dq */
357 * Bit# Deskew <- Bit# Deskew - last / first
358 * failing bit Deskew For all bits (per PUP)
359 * (minimize delay elements)
364 DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2);
370 /* Return ADLL to default value */
371 for (pup = 0; pup < max_pup; pup++) {
372 if (pup == (max_pup - 1) && dram_info->ecc_ena)
374 ddr3_pbs_write_pup_dqs_reg(CS0, pup, INIT_WL_DELAY);
377 /* Set averaged PBS results */
378 ddr3_set_pbs_results(dram_info, 1);
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);
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);
391 DEBUG_PBS_S("DDR3 - PBS Tx - PBS TX ended successfuly\n");
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
403 * Returns: MV_OK if success, other error code if fail.
405 static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info,
407 u32 pbs_pattern_idx, u32 ecc)
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 };
417 switch (dram_info->ddr_width) {
418 #if defined(MV88F672X)
420 pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx];
424 pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx];
426 #if defined(MV88F78X60)
428 pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx];
435 /* Set current pup number */
436 if (cur_pup == 0x1) /* Ecc mode */
439 cur_max_pup = dram_info->num_of_std_pups;
441 unlock_pup = cur_pup; /* '1' for each unlocked pup */
443 /* Loop on all ADLL Vaules */
445 /* Loop until found first fail */
449 * Increment (Move to right - ADLL) DQ TX delay
450 * (broadcast to all Data PUPs)
452 for (pup = 0; pup < cur_max_pup; pup++)
453 ddr3_pbs_write_pup_dqs_reg(CS0,
455 ECC_PUP * ecc, adll_val);
458 * Write and Read, compare results (read was already verified)
463 if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup,
465 pattern_ptr, LEN_PBS_PATTERN,
466 SDRAM_PBS_TX_OFFS, 1, 0,
471 unlock_pup &= ~new_lockup_pup;
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);
477 /* If any PUP failed there is '1' to mark the PUP */
478 if (new_lockup_pup != 0) {
480 * Decrement (Move Back to Left two steps - ADLL)
481 * DQ TX delay for current failed pups and save
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;
489 } while ((unlock_pup != 0) && (adll_val != ADLL_MAX));
491 if (unlock_pup != 0) {
492 DEBUG_PBS_FULL_S("DDR3 - PBS Tx - Shift DQ - Adll value reached maximum\n");
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;
501 DEBUG_PBS_FULL_C("PBS TX one step before fail last pups locked Adll ",
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,
509 /* Found one phase before fail */
515 * Desc: Execute the PBS RX phase.
516 * Args: dram_info ddr3 training information struct
518 * Returns: MV_OK if success, other error code if fail.
520 int ddr3_pbs_rx(MV_DRAM_INFO *dram_info)
523 * Array to hold the total sum of skew from all iterations
524 * (for average purpose)
526 u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
529 * Array to hold the total average skew from both patterns
530 * (for average purpose)
532 u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
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 */
539 u32 pup, dq, pups, cur_max_pup, valid_pup, reg;
542 /* indicates whether we need to start the loop again */
546 DEBUG_PBS_S("DDR3 - PBS RX - Starting PBS RX procedure\n");
548 pups = dram_info->num_of_total_pups;
549 max_pup = dram_info->num_of_total_pups;
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");
559 reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS;
560 reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
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 - ",
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;
574 * Perform PBS several of times (3 for each pattern).
575 * At the end, we'll use the average
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++) {
581 * This parameter stores the current PUP
582 * num - ecc mode dependent - 4-8 / 1 pups
584 cur_max_pup = (1 - ecc) *
585 dram_info->num_of_std_pups + ecc;
588 /* Only 1 pup in this case */
590 } else if (cur_max_pup > 4) {
591 /* 64 bit - 8 pups */
593 } else if (cur_max_pup == 4) {
594 /* 32 bit - 4 pups */
597 /* 16 bit - 2 pups */
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);
609 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Enabled\n");
611 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Disabled\n");
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++) {
618 pup + ecc * (max_pup - 1)][dq] =
628 * Run loop On current Pattern and current
629 * pattern iteration (just to cover the false
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");
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++)
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 +
662 /* Shift DQS, To first Fail */
663 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Shift RX DQS to first fail\n");
665 status = ddr3_rx_shift_dqs_to_first_fail
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");
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);
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);
688 reg = (reg_read(REG_DRAM_TRAINING_2_ADDR))
689 & (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
690 } while (reg); /* Wait for '0' */
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);
699 for (pup = 0; pup < max_pup;
708 /* Set all PBS values to MIN (0) */
709 for (pup = 0; pup < cur_max_pup;
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,
733 DEBUG_PBS_S("DDR3 - PBS Rx - ddr3_pbs_per_bit failed.");
734 return MV_DDR3_TRAINING_ERR_PBS_RX_PER_BIT;
737 } while ((start_over == 1) &&
738 (++pbs_rep_time < COUNT_PBS_STARTOVER));
740 if (pbs_rep_time == COUNT_PBS_STARTOVER &&
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;
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,
753 DEBUG_PBS_FULL_C("DDR3 - PBS RX - values for iteration - ",
755 for (pup = 0; pup < cur_max_pup; pup++) {
757 * To minimize delay elements, inc from
758 * pbs value the min pbs val
760 DEBUG_PBS_FULL_S("DDR3 - PBS - PUP");
761 DEBUG_PBS_FULL_D((pup +
762 (ecc * ECC_PUP)), 1);
763 DEBUG_PBS_FULL_S(": ");
765 for (dq = 0; dq < DQ_NUM; dq++) {
766 /* Set skew value for all dq */
768 * Bit# Deskew <- Bit# Deskew -
769 * last / first failing bit
770 * Deskew For all bits (per PUP)
771 * (minimize delay elements)
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
780 DEBUG_PBS_FULL_S(", ");
782 DEBUG_PBS_FULL_S("\n");
786 * Collect the results we got on this trial
789 for (pup = 0; pup < cur_max_pup; pup++) {
790 for (dq = 0; dq < DQ_NUM; dq++) {
792 [pup + (ecc * (max_pup - 1))]
794 skew_array[((pup) * DQ_NUM) + dq];
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);
806 * Calculate the average skew for current pattern for each
809 DEBUG_PBS_FULL_C("DDR3 - PBS RX - Average for pattern - ",
811 for (pup = 0; pup < max_pup; pup++) {
813 * FOR ECC only :: found min and max value for
814 * current pattern skew array
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] /
824 DEBUG_PBS_C("DDR3 - PBS RX - values for current pattern - ",
826 for (pup = 0; pup < max_pup; pup++) {
828 * To minimize delay elements, inc from pbs value the
831 DEBUG_PBS_S("DDR3 - PBS RX - PUP");
835 for (dq = 0; dq < DQ_NUM; dq++) {
836 /* Set skew value for all dq */
838 * Bit# Deskew <- Bit# Deskew - last / first
839 * failing bit Deskew For all bits (per PUP)
840 * (minimize delay elements)
845 DEBUG_PBS_D(skew_sum_array[pup][dq] /
846 COUNT_PBS_REPEAT, 2);
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;
860 DEBUG_PBS_S("DDR3 - PBS RX - Average for all patterns:\n");
861 for (pup = 0; pup < max_pup; pup++) {
863 * To minimize delay elements, inc from pbs value the
866 DEBUG_PBS_S("DDR3 - PBS - PUP");
870 for (dq = 0; dq < DQ_NUM; dq++) {
871 /* Set skew value for all dq */
873 * Bit# Deskew <- Bit# Deskew - last / first
874 * failing bit Deskew For all bits (per PUP)
875 * (minimize delay elements)
880 DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2);
886 /* Return ADLL to default value */
887 ddr3_write_pup_reg(PUP_DQS_RD, CS0, PUP_BC, 0, INIT_RL_DELAY);
889 /* Set averaged PBS results */
890 ddr3_set_pbs_results(dram_info, 0);
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);
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);
903 DEBUG_PBS_FULL_S("DDR3 - PBS RX - ended successfuly\n");
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
915 * Returns: MV_OK if success, other error code if fail.
917 static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup,
918 u32 pbs_pattern_idx, u32 ecc)
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;
928 switch (dram_info->ddr_width) {
929 #if defined(MV88F672X)
931 pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx];
935 pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx];
937 #if defined(MV88F78X60)
939 pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx];
946 /* Set current pup number */
947 if (cur_pup == 0x1) /* Ecc mode */
950 cur_max_pup = dram_info->num_of_std_pups;
952 unlock_pup = cur_pup; /* '1' for each unlocked pup */
954 DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Starting...\n");
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,
962 /* Loop on all ADLL Vaules */
964 /* Loop until found fail for all pups */
966 if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup,
968 pattern_ptr, LEN_PBS_PATTERN,
970 pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS,
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;
976 if ((new_lockup_pup != 0) && (dqs_deskew_val <= 1)) {
977 /* Fail on start with first deskew value */
978 /* Decrement DQS ADLL */
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;
984 ddr3_write_pup_reg(PUP_DQS_RD, CS0, pup + ecc * ECC_PUP,
989 /* Update all new locked pups */
990 unlock_pup &= ~new_lockup_pup;
992 if ((unlock_pup == 0) || (dqs_deskew_val == MAX_PBS)) {
993 if (dqs_deskew_val == MAX_PBS) {
995 * Reach max value of dqs deskew or get fail
998 DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - DQS deskew reached maximum value\n");
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);
1007 /* Increment DQS deskew elements - Only for unlocked pups */
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,
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;
1022 /* Loop until pass compare for all pups */
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,
1028 pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS,
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;
1035 * Get mask for pup which passed so their adll will be
1036 * changed to 2 steps before fails
1038 pass_pup = unlock_pup & ~new_lockup_pup;
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);
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,
1053 /* Locked pups that compare success */
1054 unlock_pup &= new_lockup_pup;
1056 if (unlock_pup == 0) {
1057 /* All pups locked */
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;
1068 * Decrement (Move Back to Left one phase - ADLL) dqs RX delay
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,
1084 * lock_pups() extracted from ddr3_pbs_per_bit(). This just got too
1085 * much indented making it hard to read / edit.
1087 static 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)
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);
1098 idx = pup * (1 - ecc) + ecc * ECC_PUP;
1099 *pup_locked &= ~(1 << pup);
1101 for (dq = 0; dq < DQ_NUM; dq++) {
1102 if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup) == 1) {
1105 /* Lock current dq */
1106 unlock_pup_dq_array[dq] &= ~(1 << pup);
1107 skew_array[(pup * DQ_NUM) + dq] = pbs_curr_val;
1114 ddr3_write_pup_reg(offs +
1115 pbs_dq_mapping[idx][dq], CS0,
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
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.
1137 static 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)
1141 * Bit array to indicate if we already get fail on bit per pup & dq bit
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
1148 u8 cmp_unlock_pup_dq_array[COUNT_PBS_COMP_RETRY_NUM][DQ_NUM];
1150 /* value of pbs is according to RX or TX */
1151 u32 start_pbs, last_pbs;
1153 /* bit array that indicates all dq of the 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 */
1160 /* use to calculate diff between curr pbs to first fail pbs */
1165 /* Set init values for retry array - 8 retry */
1166 for (pbs_cmp_retry = 0; pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM;
1168 for (dq = 0; dq < DQ_NUM; dq++)
1169 cmp_unlock_pup_dq_array[pbs_cmp_retry][dq] = *pcur_pup;
1172 memset(&skew_array, 0, MAX_PUP_NUM * DQ_NUM * sizeof(u32));
1174 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Started\n");
1176 /* The pbs value depends if rx or tx */
1178 start_pbs = MIN_PBS;
1181 start_pbs = MAX_PBS;
1185 pbs_curr_val = start_pbs;
1186 pup_locked = *pcur_pup;
1188 /* Set current pup number */
1189 if (pup_locked == 0x1) /* Ecc mode */
1192 max_pup = dram_info->num_of_std_pups;
1195 /* Increment/ decrement PBS for un-lock bits only */
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");
1211 for (pup = 0; pup < max_pup; pup++) {
1214 idx = pup * (1 - ecc) + ecc * ECC_PUP;
1216 if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup)
1222 PUP_PBS_TX + pbs_dq_mapping[idx][dq],
1223 CS0, idx, 0, pbs_curr_val);
1226 PUP_PBS_RX + pbs_dq_mapping[idx][dq],
1227 CS0, idx, 0, pbs_curr_val);
1232 * Write Read and compare results - run the test
1233 * DDR_PBS_COMP_RETRY_NUM times
1235 /* Run number of read and write to verify */
1236 for (pbs_cmp_retry = 0;
1237 pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM;
1241 ddr3_sdram_pbs_compare(dram_info, pup_locked, is_tx,
1243 pbs_curr_val, start_pbs,
1245 cmp_unlock_pup_dq_array
1246 [pbs_cmp_retry], ecc))
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],
1253 && (IS_PUP_ACTIVE(cmp_unlock_pup_dq_array
1254 [pbs_cmp_retry][dq],
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");
1267 for (dq = 0; dq < DQ_NUM; dq++) {
1268 unlock_pup_dq_array[dq] &=
1269 cmp_unlock_pup_dq_array[pbs_cmp_retry][dq];
1274 sum_pup_fail = *pcur_pup;
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];
1281 /* Check if get fail */
1282 sum_pup_fail &= unlock_pup_dq_array[dq];
1285 /* If all PUPS are locked in all DQ - Break */
1286 if (pup_locked == 0) {
1287 /* All pups are locked */
1289 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - All bit in all pups are successfully locked\n");
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;
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");
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)",
1319 if (IS_PUP_ACTIVE(sum_pup_fail, pup)
1321 DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - Locking pup %d (even though it wasn't supposed to be locked)",
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(": ");
1331 for (dq = 0; dq < DQ_NUM; dq++) {
1333 (unlock_pup_dq_array[dq],
1335 DEBUG_PBS_FULL_D(dq, 1);
1336 DEBUG_PBS_FULL_S(",");
1337 /* set current PBS */
1345 if (*start_over == 1) {
1347 * Reset this pup bit - when
1348 * restart the PBS, ignore this
1351 *pcur_pup &= ~(1 << pup);
1353 DEBUG_PBS_FULL_S("\n");
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 - ",
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");
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) ==
1378 /* Get first fail */
1379 DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - First fail in pup ",
1381 first_failed[pup] = 1;
1382 first_fail[pup] = pbs_curr_val;
1385 /* Already got first fail */
1388 calc_pbs_diff = pbs_curr_val -
1392 calc_pbs_diff = first_fail[pup] -
1396 if (calc_pbs_diff >= PBS_DIFF_LIMIT) {
1397 lock_pups(pup, &pup_locked,
1398 unlock_pup_dq_array,
1400 start_pbs, ecc, is_tx);
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
1415 * Returns: MV_OK if success, other error code if fail.
1417 static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx)
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 */
1425 max_pup = dram_info->num_of_total_pups;
1426 DEBUG_PBS_FULL_S("DDR3 - PBS - ddr3_set_pbs_results:\n");
1428 /* Loop for all dqs & pups */
1429 for (pup = 0; pup < max_pup; pup++) {
1430 if (pup == (max_pup - 1) && dram_info->ecc_ena)
1436 * To minimize delay elements, inc from pbs value the min
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];
1445 if (pbs_max < skew_array[(pup * DQ_NUM) + dq])
1446 pbs_max = skew_array[(pup * DQ_NUM) + dq];
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);
1459 for (dq = 0; dq < DQ_NUM; dq++) {
1463 /* Set skew value for all dq */
1465 * Bit# Deskew <- Bit# Deskew - last / first
1466 * failing bit Deskew For all bits (per PUP)
1467 * (minimize delay elements)
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] -
1475 DEBUG_PBS_FULL_S(", ");
1477 idx = (pup * DQ_NUM) + dq;
1484 ddr3_write_pup_reg(offs + pbs_dq_mapping[phys_pup][dq],
1486 skew_array[idx] - pbs_min);
1489 val[pup] += skew_array[idx] - pbs_min;
1492 DEBUG_PBS_FULL_S("\n");
1494 /* Set the DQS the half of the Max PBS of the DQs */
1496 ddr3_write_pup_reg(PUP_PBS_TX + 8, CS0, phys_pup, 0,
1498 ddr3_write_pup_reg(PUP_PBS_TX + 0xa, CS0, phys_pup, 0,
1501 ddr3_write_pup_reg(PUP_PBS_RX + 8, CS0, phys_pup, 0,
1508 static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay)
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);
1519 reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */
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 */
1529 * Set training patterns
1531 int ddr3_load_pbs_patterns(MV_DRAM_INFO *dram_info)
1533 u32 cs, cs_count, cs_tmp;
1535 u32 *pattern_ptr0, *pattern_ptr1;
1537 /* Choose pattern */
1538 switch (dram_info->ddr_width) {
1539 #if defined(MV88F672X)
1541 pattern_ptr0 = (u32 *)&pbs_pattern[0];
1542 pattern_ptr1 = (u32 *)&pbs_pattern[1];
1546 pattern_ptr0 = (u32 *)&pbs_pattern_32b[0];
1547 pattern_ptr1 = (u32 *)&pbs_pattern_32b[1];
1549 #if defined(MV88F78X60)
1551 pattern_ptr0 = (u32 *)&pbs_pattern_64b[0];
1552 pattern_ptr1 = (u32 *)&pbs_pattern_64b[1];
1559 /* Loop for each CS */
1560 for (cs = 0; cs < MAX_CS; cs++) {
1561 if (dram_info->cs_ena & (1 << cs)) {
1563 for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) {
1564 if (dram_info->cs_ena & (1 << cs_tmp))
1568 /* Init PBS I pattern */
1569 sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
1572 ddr3_sdram_compare(dram_info, (u32) NULL, NULL,
1573 pattern_ptr0, LEN_STD_PATTERN,
1574 sdram_addr, 1, 0, NULL,
1578 /* Init PBS II pattern */
1579 sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
1582 ddr3_sdram_compare(dram_info, (u32) NULL, NULL,
1583 pattern_ptr1, LEN_STD_PATTERN,
1584 sdram_addr, 1, 0, NULL,