1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) Marvell International Ltd. and its affiliates
10 #include <asm/arch/cpu.h>
11 #include <asm/arch/soc.h>
13 #include "ddr3_hw_training.h"
18 #define DEBUG_PBS_FULL_C(s, d, l) \
19 DEBUG_PBS_FULL_S(s); DEBUG_PBS_FULL_D(d, l); DEBUG_PBS_FULL_S("\n")
20 #define DEBUG_PBS_C(s, d, l) \
21 DEBUG_PBS_S(s); DEBUG_PBS_D(d, l); DEBUG_PBS_S("\n")
24 #define DEBUG_PBS_S(s) puts(s)
25 #define DEBUG_PBS_D(d, l) printf("%x", d)
27 #define DEBUG_PBS_S(s)
28 #define DEBUG_PBS_D(d, l)
31 #ifdef MV_DEBUG_FULL_PBS
32 #define DEBUG_PBS_FULL_S(s) puts(s)
33 #define DEBUG_PBS_FULL_D(d, l) printf("%x", d)
35 #define DEBUG_PBS_FULL_S(s)
36 #define DEBUG_PBS_FULL_D(d, l)
39 #if defined(MV88F78X60) || defined(MV88F672X)
41 /* Temp array for skew data storage */
42 static u32 skew_array[(MAX_PUP_NUM) * DQ_NUM] = { 0 };
44 /* PBS locked dq (per pup) */
45 extern u32 pbs_locked_dq[MAX_PUP_NUM][DQ_NUM];
46 extern u32 pbs_locked_dm[MAX_PUP_NUM];
47 extern u32 pbs_locked_value[MAX_PUP_NUM][DQ_NUM];
49 #if defined(MV88F672X)
50 extern u32 pbs_pattern[2][LEN_16BIT_PBS_PATTERN];
51 extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN];
53 extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN];
54 extern u32 pbs_pattern_64b[2][LEN_PBS_PATTERN];
57 extern u32 pbs_dq_mapping[PUP_NUM_64BIT + 1][DQ_NUM];
59 static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info,
60 u32 cur_pup, u32 pbs_pattern_idx, u32 ecc);
61 static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup,
62 u32 pbs_pattern_idx, u32 ecc);
63 static int ddr3_pbs_per_bit(MV_DRAM_INFO *dram_info, int *start_over, int is_tx,
64 u32 *pcur_pup, u32 pbs_pattern_idx, u32 ecc);
65 static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx);
66 static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay);
70 * Desc: Execute the PBS TX phase.
71 * Args: dram_info ddr3 training information struct
73 * Returns: MV_OK if success, other error code if fail.
75 int ddr3_pbs_tx(MV_DRAM_INFO *dram_info)
77 /* Array of Deskew results */
80 * Array to hold the total sum of skew from all iterations
81 * (for average purpose)
83 u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
86 * Array to hold the total average skew from both patterns
87 * (for average purpose)
89 u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
91 u32 pbs_rep_time = 0; /* counts number of loop in case of fail */
92 /* bit array for unlock pups - used to repeat on the RX operation */
96 u32 pup, dq, pups, cur_max_pup, valid_pup, reg;
99 /* indicates whether we need to start the loop again */
102 DEBUG_PBS_S("DDR3 - PBS TX - Starting PBS TX procedure\n");
104 pups = dram_info->num_of_total_pups;
105 max_pup = dram_info->num_of_total_pups;
107 /* Enable SW override */
108 reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
109 (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
110 /* [0] = 1 - Enable SW override */
111 /* 0x15B8 - Training SW 2 Register */
112 reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
113 DEBUG_PBS_S("DDR3 - PBS RX - SW Override Enabled\n");
115 reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS;
116 reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
118 /* Running twice for 2 different patterns. each patterns - 3 times */
119 for (pattern_idx = 0; pattern_idx < COUNT_PBS_PATTERN; pattern_idx++) {
120 DEBUG_PBS_C("DDR3 - PBS TX - Working with pattern - ",
123 /* Reset sum array */
124 for (pup = 0; pup < pups; pup++) {
125 for (dq = 0; dq < DQ_NUM; dq++)
126 skew_sum_array[pup][dq] = 0;
130 * Perform PBS several of times (3 for each pattern).
131 * At the end, we'll use the average
133 /* If there is ECC, do each PBS again with mux change */
134 for (pbs_retry = 0; pbs_retry < COUNT_PBS_REPEAT; pbs_retry++) {
135 for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) {
138 * This parameter stores the current PUP
139 * num - ecc mode dependent - 4-8 / 1 pups
141 cur_max_pup = (1 - ecc) *
142 dram_info->num_of_std_pups + ecc;
145 /* Only 1 pup in this case */
147 } else if (cur_max_pup > 4) {
148 /* 64 bit - 8 pups */
150 } else if (cur_max_pup == 4) {
151 /* 32 bit - 4 pups */
154 /* 16 bit - 2 pups */
158 /* ECC Support - Switch ECC Mux on ecc=1 */
159 reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
160 ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
161 reg |= (dram_info->ecc_ena * ecc <<
162 REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
163 reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
166 DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Enabled\n");
168 DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Disabled\n");
170 /* Init iteration values */
171 /* Clear the locked DQs */
172 for (pup = 0; pup < cur_max_pup; pup++) {
173 for (dq = 0; dq < DQ_NUM; dq++) {
186 * Run loop On current Pattern and current
187 * pattern iteration (just to cover the false
191 DEBUG_PBS_S("DDR3 - PBS Tx - Pbs Rep Loop is ");
192 DEBUG_PBS_D(pbs_rep_time, 1);
193 DEBUG_PBS_S(", for Retry No.");
194 DEBUG_PBS_D(pbs_retry, 1);
197 /* Set all PBS values to MIN (0) */
198 DEBUG_PBS_S("DDR3 - PBS Tx - Set all PBS values to MIN\n");
200 for (dq = 0; dq < DQ_NUM; dq++) {
206 [dq], CS0, (1 - ecc) *
207 PUP_BC + ecc * ECC_PUP, 0,
212 * Shift DQ ADLL right, One step before
215 DEBUG_PBS_S("DDR3 - PBS Tx - ADLL shift right one phase before fail\n");
217 if (MV_OK != ddr3_tx_shift_dqs_adll_step_before_fail
218 (dram_info, cur_pup, pattern_idx,
220 return MV_DDR3_TRAINING_ERR_PBS_ADLL_SHR_1PHASE;
222 /* PBS For each bit */
223 DEBUG_PBS_S("DDR3 - PBS Tx - perform PBS for each bit\n");
226 * In this stage - start_over = 0
228 if (MV_OK != ddr3_pbs_per_bit(
229 dram_info, &start_over, 1,
230 &cur_pup, pattern_idx, ecc))
231 return MV_DDR3_TRAINING_ERR_PBS_TX_PER_BIT;
233 } while ((start_over == 1) &&
234 (++pbs_rep_time < COUNT_PBS_STARTOVER));
236 if (pbs_rep_time == COUNT_PBS_STARTOVER &&
238 DEBUG_PBS_S("DDR3 - PBS Tx - FAIL - Adll reach max value\n");
239 return MV_DDR3_TRAINING_ERR_PBS_TX_MAX_VAL;
242 DEBUG_PBS_FULL_C("DDR3 - PBS TX - values for iteration - ",
244 for (pup = 0; pup < cur_max_pup; pup++) {
246 * To minimize delay elements, inc
247 * from pbs value the min pbs val
249 DEBUG_PBS_S("DDR3 - PBS - PUP");
250 DEBUG_PBS_D((pup + (ecc * ECC_PUP)), 1);
253 for (dq = 0; dq < DQ_NUM; dq++) {
254 /* Set skew value for all dq */
256 * Bit# Deskew <- Bit# Deskew -
257 * last / first failing bit
258 * Deskew For all bits (per PUP)
259 * (minimize delay elements)
264 DEBUG_PBS_D(skew_array
273 * Collect the results we got on this trial
276 for (pup = 0; pup < cur_max_pup; pup++) {
277 for (dq = 0; dq < DQ_NUM; dq++) {
278 skew_sum_array[pup + (ecc * (max_pup - 1))]
280 [((pup) * DQ_NUM) + dq];
284 /* ECC Support - Disable ECC MUX */
285 reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
286 ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
287 reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
291 DEBUG_PBS_C("DDR3 - PBS TX - values for current pattern - ",
293 for (pup = 0; pup < max_pup; pup++) {
295 * To minimize delay elements, inc from pbs value the
298 DEBUG_PBS_S("DDR3 - PBS - PUP");
302 for (dq = 0; dq < DQ_NUM; dq++) {
303 /* set skew value for all dq */
304 /* Bit# Deskew <- Bit# Deskew - last / first failing bit Deskew For all bits (per PUP) (minimize delay elements) */
308 DEBUG_PBS_D(skew_sum_array[pup][dq] /
309 COUNT_PBS_REPEAT, 2);
316 * Calculate the average skew for current pattern for each
319 DEBUG_PBS_C("DDR3 - PBS TX - Average for pattern - ",
322 for (pup = 0; pup < max_pup; pup++) {
324 * FOR ECC only :: found min and max value for current
327 /* Loop for all dqs */
328 for (dq = 0; dq < DQ_NUM; dq++) {
329 pattern_skew_array[pup][dq] +=
330 (skew_sum_array[pup][dq] /
336 /* Calculate the average skew */
337 for (pup = 0; pup < max_pup; pup++) {
338 for (dq = 0; dq < DQ_NUM; dq++)
339 skew_array[((pup) * DQ_NUM) + dq] =
340 pattern_skew_array[pup][dq] / COUNT_PBS_PATTERN;
343 DEBUG_PBS_S("DDR3 - PBS TX - Average for all patterns:\n");
344 for (pup = 0; pup < max_pup; pup++) {
346 * To minimize delay elements, inc from pbs value the min
349 DEBUG_PBS_S("DDR3 - PBS - PUP");
353 for (dq = 0; dq < DQ_NUM; dq++) {
354 /* Set skew value for all dq */
356 * Bit# Deskew <- Bit# Deskew - last / first
357 * failing bit Deskew For all bits (per PUP)
358 * (minimize delay elements)
363 DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2);
369 /* Return ADLL to default value */
370 for (pup = 0; pup < max_pup; pup++) {
371 if (pup == (max_pup - 1) && dram_info->ecc_ena)
373 ddr3_pbs_write_pup_dqs_reg(CS0, pup, INIT_WL_DELAY);
376 /* Set averaged PBS results */
377 ddr3_set_pbs_results(dram_info, 1);
379 /* Disable SW override - Must be in a different stage */
380 /* [0]=0 - Enable SW override */
381 reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
382 reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
383 /* 0x15B8 - Training SW 2 Register */
384 reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
386 reg = reg_read(REG_DRAM_TRAINING_1_ADDR) |
387 (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS);
388 reg_write(REG_DRAM_TRAINING_1_ADDR, reg);
390 DEBUG_PBS_S("DDR3 - PBS Tx - PBS TX ended successfuly\n");
396 * Name: ddr3_tx_shift_dqs_adll_step_before_fail
397 * Desc: Execute the Tx shift DQ phase.
398 * Args: dram_info ddr3 training information struct
399 * cur_pup bit array of the function active pups.
400 * pbs_pattern_idx Index of PBS pattern
402 * Returns: MV_OK if success, other error code if fail.
404 static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info,
406 u32 pbs_pattern_idx, u32 ecc)
408 u32 unlock_pup; /* bit array of unlock pups */
409 u32 new_lockup_pup; /* bit array of compare failed pups */
410 u32 adll_val = 4; /* INIT_WL_DELAY */
411 u32 cur_max_pup, pup;
412 u32 dqs_dly_set[MAX_PUP_NUM] = { 0 };
416 switch (dram_info->ddr_width) {
417 #if defined(MV88F672X)
419 pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx];
423 pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx];
425 #if defined(MV88F78X60)
427 pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx];
434 /* Set current pup number */
435 if (cur_pup == 0x1) /* Ecc mode */
438 cur_max_pup = dram_info->num_of_std_pups;
440 unlock_pup = cur_pup; /* '1' for each unlocked pup */
442 /* Loop on all ADLL Vaules */
444 /* Loop until found first fail */
448 * Increment (Move to right - ADLL) DQ TX delay
449 * (broadcast to all Data PUPs)
451 for (pup = 0; pup < cur_max_pup; pup++)
452 ddr3_pbs_write_pup_dqs_reg(CS0,
454 ECC_PUP * ecc, adll_val);
457 * Write and Read, compare results (read was already verified)
462 if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup,
464 pattern_ptr, LEN_PBS_PATTERN,
465 SDRAM_PBS_TX_OFFS, 1, 0,
470 unlock_pup &= ~new_lockup_pup;
472 DEBUG_PBS_FULL_S("Shift DQS by 2 steps for PUPs: ");
473 DEBUG_PBS_FULL_D(unlock_pup, 2);
474 DEBUG_PBS_FULL_C(", Set ADLL value = ", adll_val, 2);
476 /* If any PUP failed there is '1' to mark the PUP */
477 if (new_lockup_pup != 0) {
479 * Decrement (Move Back to Left two steps - ADLL)
480 * DQ TX delay for current failed pups and save
482 for (pup = 0; pup < cur_max_pup; pup++) {
483 if (((new_lockup_pup >> pup) & 0x1) &&
484 dqs_dly_set[pup] == 0)
485 dqs_dly_set[pup] = adll_val - 1;
488 } while ((unlock_pup != 0) && (adll_val != ADLL_MAX));
490 if (unlock_pup != 0) {
491 DEBUG_PBS_FULL_S("DDR3 - PBS Tx - Shift DQ - Adll value reached maximum\n");
493 for (pup = 0; pup < cur_max_pup; pup++) {
494 if (((unlock_pup >> pup) & 0x1) &&
495 dqs_dly_set[pup] == 0)
496 dqs_dly_set[pup] = adll_val - 1;
500 DEBUG_PBS_FULL_C("PBS TX one step before fail last pups locked Adll ",
503 /* Set the PUP DQS DLY Values */
504 for (pup = 0; pup < cur_max_pup; pup++)
505 ddr3_pbs_write_pup_dqs_reg(CS0, pup * (1 - ecc) + ECC_PUP * ecc,
508 /* Found one phase before fail */
514 * Desc: Execute the PBS RX phase.
515 * Args: dram_info ddr3 training information struct
517 * Returns: MV_OK if success, other error code if fail.
519 int ddr3_pbs_rx(MV_DRAM_INFO *dram_info)
522 * Array to hold the total sum of skew from all iterations
523 * (for average purpose)
525 u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
528 * Array to hold the total average skew from both patterns
529 * (for average purpose)
531 u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} };
533 u32 pbs_rep_time = 0; /* counts number of loop in case of fail */
534 /* bit array for unlock pups - used to repeat on the RX operation */
538 u32 pup, dq, pups, cur_max_pup, valid_pup, reg;
541 /* indicates whether we need to start the loop again */
545 DEBUG_PBS_S("DDR3 - PBS RX - Starting PBS RX procedure\n");
547 pups = dram_info->num_of_total_pups;
548 max_pup = dram_info->num_of_total_pups;
550 /* Enable SW override */
551 reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
552 (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
553 /* [0] = 1 - Enable SW override */
554 /* 0x15B8 - Training SW 2 Register */
555 reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
556 DEBUG_PBS_FULL_S("DDR3 - PBS RX - SW Override Enabled\n");
558 reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS;
559 reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
561 /* Running twice for 2 different patterns. each patterns - 3 times */
562 for (pattern_idx = 0; pattern_idx < COUNT_PBS_PATTERN; pattern_idx++) {
563 DEBUG_PBS_FULL_C("DDR3 - PBS RX - Working with pattern - ",
566 /* Reset sum array */
567 for (pup = 0; pup < pups; pup++) {
568 for (dq = 0; dq < DQ_NUM; dq++)
569 skew_sum_array[pup][dq] = 0;
573 * Perform PBS several of times (3 for each pattern).
574 * At the end, we'll use the average
576 /* If there is ECC, do each PBS again with mux change */
577 for (pbs_retry = 0; pbs_retry < COUNT_PBS_REPEAT; pbs_retry++) {
578 for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) {
580 * This parameter stores the current PUP
581 * num - ecc mode dependent - 4-8 / 1 pups
583 cur_max_pup = (1 - ecc) *
584 dram_info->num_of_std_pups + ecc;
587 /* Only 1 pup in this case */
589 } else if (cur_max_pup > 4) {
590 /* 64 bit - 8 pups */
592 } else if (cur_max_pup == 4) {
593 /* 32 bit - 4 pups */
596 /* 16 bit - 2 pups */
600 /* ECC Support - Switch ECC Mux on ecc=1 */
601 reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
602 ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
603 reg |= (dram_info->ecc_ena * ecc <<
604 REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
605 reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
608 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Enabled\n");
610 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Disabled\n");
612 /* Init iteration values */
613 /* Clear the locked DQs */
614 for (pup = 0; pup < cur_max_pup; pup++) {
615 for (dq = 0; dq < DQ_NUM; dq++) {
617 pup + ecc * (max_pup - 1)][dq] =
627 * Run loop On current Pattern and current
628 * pattern iteration (just to cover the false
632 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Pbs Rep Loop is ");
633 DEBUG_PBS_FULL_D(pbs_rep_time, 1);
634 DEBUG_PBS_FULL_S(", for Retry No.");
635 DEBUG_PBS_FULL_D(pbs_retry, 1);
636 DEBUG_PBS_FULL_S("\n");
638 /* Set all PBS values to MAX (31) */
639 for (pup = 0; pup < cur_max_pup; pup++) {
640 for (dq = 0; dq < DQ_NUM; dq++)
651 /* Set all DQS PBS values to MIN (0) */
652 for (pup = 0; pup < cur_max_pup; pup++) {
653 ddr3_write_pup_reg(PUP_PBS_RX +
661 /* Shift DQS, To first Fail */
662 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Shift RX DQS to first fail\n");
664 status = ddr3_rx_shift_dqs_to_first_fail
667 if (MV_OK != status) {
668 DEBUG_PBS_S("DDR3 - PBS Rx - ddr3_rx_shift_dqs_to_first_fail failed.\n");
669 DEBUG_PBS_D(status, 8);
670 DEBUG_PBS_S("\nDDR3 - PBS Rx - SKIP.\n");
672 /* Reset read FIFO */
673 reg = reg_read(REG_DRAM_TRAINING_ADDR);
674 /* Start Auto Read Leveling procedure */
675 reg |= (1 << REG_DRAM_TRAINING_RL_OFFS);
676 /* 0x15B0 - Training Register */
677 reg_write(REG_DRAM_TRAINING_ADDR, reg);
679 reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
680 reg |= ((1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS)
681 + (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS));
682 /* [0] = 1 - Enable SW override, [4] = 1 - FIFO reset */
683 /* 0x15B8 - Training SW 2 Register */
684 reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
687 reg = (reg_read(REG_DRAM_TRAINING_2_ADDR))
688 & (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
689 } while (reg); /* Wait for '0' */
691 reg = reg_read(REG_DRAM_TRAINING_ADDR);
692 /* Clear Auto Read Leveling procedure */
693 reg &= ~(1 << REG_DRAM_TRAINING_RL_OFFS);
694 /* 0x15B0 - Training Register */
695 reg_write(REG_DRAM_TRAINING_ADDR, reg);
698 for (pup = 0; pup < max_pup;
707 /* Set all PBS values to MIN (0) */
708 for (pup = 0; pup < cur_max_pup;
725 /* PBS For each bit */
726 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - perform PBS for each bit\n");
727 /* in this stage - start_over = 0; */
728 if (MV_OK != ddr3_pbs_per_bit(
729 dram_info, &start_over,
732 DEBUG_PBS_S("DDR3 - PBS Rx - ddr3_pbs_per_bit failed.");
733 return MV_DDR3_TRAINING_ERR_PBS_RX_PER_BIT;
736 } while ((start_over == 1) &&
737 (++pbs_rep_time < COUNT_PBS_STARTOVER));
739 if (pbs_rep_time == COUNT_PBS_STARTOVER &&
741 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - FAIL - Algorithm failed doing RX PBS\n");
742 return MV_DDR3_TRAINING_ERR_PBS_RX_MAX_VAL;
745 /* Return DQS ADLL to default value - 15 */
746 /* Set all DQS PBS values to MIN (0) */
747 for (pup = 0; pup < cur_max_pup; pup++)
748 ddr3_write_pup_reg(PUP_DQS_RD, CS0,
752 DEBUG_PBS_FULL_C("DDR3 - PBS RX - values for iteration - ",
754 for (pup = 0; pup < cur_max_pup; pup++) {
756 * To minimize delay elements, inc from
757 * pbs value the min pbs val
759 DEBUG_PBS_FULL_S("DDR3 - PBS - PUP");
760 DEBUG_PBS_FULL_D((pup +
761 (ecc * ECC_PUP)), 1);
762 DEBUG_PBS_FULL_S(": ");
764 for (dq = 0; dq < DQ_NUM; dq++) {
765 /* Set skew value for all dq */
767 * Bit# Deskew <- Bit# Deskew -
768 * last / first failing bit
769 * Deskew For all bits (per PUP)
770 * (minimize delay elements)
772 DEBUG_PBS_FULL_S("DQ");
773 DEBUG_PBS_FULL_D(dq, 1);
774 DEBUG_PBS_FULL_S("-");
775 DEBUG_PBS_FULL_D(skew_array
779 DEBUG_PBS_FULL_S(", ");
781 DEBUG_PBS_FULL_S("\n");
785 * Collect the results we got on this trial
788 for (pup = 0; pup < cur_max_pup; pup++) {
789 for (dq = 0; dq < DQ_NUM; dq++) {
791 [pup + (ecc * (max_pup - 1))]
793 skew_array[((pup) * DQ_NUM) + dq];
797 /* ECC Support - Disable ECC MUX */
798 reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
799 ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
800 reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
805 * Calculate the average skew for current pattern for each
808 DEBUG_PBS_FULL_C("DDR3 - PBS RX - Average for pattern - ",
810 for (pup = 0; pup < max_pup; pup++) {
812 * FOR ECC only :: found min and max value for
813 * current pattern skew array
815 /* Loop for all dqs */
816 for (dq = 0; dq < DQ_NUM; dq++) {
817 pattern_skew_array[pup][dq] +=
818 (skew_sum_array[pup][dq] /
823 DEBUG_PBS_C("DDR3 - PBS RX - values for current pattern - ",
825 for (pup = 0; pup < max_pup; pup++) {
827 * To minimize delay elements, inc from pbs value the
830 DEBUG_PBS_S("DDR3 - PBS RX - PUP");
834 for (dq = 0; dq < DQ_NUM; dq++) {
835 /* Set skew value for all dq */
837 * Bit# Deskew <- Bit# Deskew - last / first
838 * failing bit Deskew For all bits (per PUP)
839 * (minimize delay elements)
844 DEBUG_PBS_D(skew_sum_array[pup][dq] /
845 COUNT_PBS_REPEAT, 2);
852 /* Calculate the average skew */
853 for (pup = 0; pup < max_pup; pup++) {
854 for (dq = 0; dq < DQ_NUM; dq++)
855 skew_array[((pup) * DQ_NUM) + dq] =
856 pattern_skew_array[pup][dq] / COUNT_PBS_PATTERN;
859 DEBUG_PBS_S("DDR3 - PBS RX - Average for all patterns:\n");
860 for (pup = 0; pup < max_pup; pup++) {
862 * To minimize delay elements, inc from pbs value the
865 DEBUG_PBS_S("DDR3 - PBS - PUP");
869 for (dq = 0; dq < DQ_NUM; dq++) {
870 /* Set skew value for all dq */
872 * Bit# Deskew <- Bit# Deskew - last / first
873 * failing bit Deskew For all bits (per PUP)
874 * (minimize delay elements)
879 DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2);
885 /* Return ADLL to default value */
886 ddr3_write_pup_reg(PUP_DQS_RD, CS0, PUP_BC, 0, INIT_RL_DELAY);
888 /* Set averaged PBS results */
889 ddr3_set_pbs_results(dram_info, 0);
891 /* Disable SW override - Must be in a different stage */
892 /* [0]=0 - Enable SW override */
893 reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
894 reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
895 /* 0x15B8 - Training SW 2 Register */
896 reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
898 reg = reg_read(REG_DRAM_TRAINING_1_ADDR) |
899 (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS);
900 reg_write(REG_DRAM_TRAINING_1_ADDR, reg);
902 DEBUG_PBS_FULL_S("DDR3 - PBS RX - ended successfuly\n");
908 * Name: ddr3_rx_shift_dqs_to_first_fail
909 * Desc: Execute the Rx shift DQ phase.
910 * Args: dram_info ddr3 training information struct
911 * cur_pup bit array of the function active pups.
912 * pbs_pattern_idx Index of PBS pattern
914 * Returns: MV_OK if success, other error code if fail.
916 static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup,
917 u32 pbs_pattern_idx, u32 ecc)
919 u32 unlock_pup; /* bit array of unlock pups */
920 u32 new_lockup_pup; /* bit array of compare failed pups */
921 u32 adll_val = MAX_DELAY;
922 u32 dqs_deskew_val = 0; /* current value of DQS PBS deskew */
923 u32 cur_max_pup, pup, pass_pup;
927 switch (dram_info->ddr_width) {
928 #if defined(MV88F672X)
930 pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx];
934 pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx];
936 #if defined(MV88F78X60)
938 pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx];
945 /* Set current pup number */
946 if (cur_pup == 0x1) /* Ecc mode */
949 cur_max_pup = dram_info->num_of_std_pups;
951 unlock_pup = cur_pup; /* '1' for each unlocked pup */
953 DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Starting...\n");
955 /* Set DQS ADLL to MAX */
956 DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Set DQS ADLL to Max for all PUPs\n");
957 for (pup = 0; pup < cur_max_pup; pup++)
958 ddr3_write_pup_reg(PUP_DQS_RD, CS0, pup + ecc * ECC_PUP, 0,
961 /* Loop on all ADLL Vaules */
963 /* Loop until found fail for all pups */
965 if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup,
967 pattern_ptr, LEN_PBS_PATTERN,
969 pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS,
971 DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP(ddr3_sdram_compare)\n");
972 return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP;
975 if ((new_lockup_pup != 0) && (dqs_deskew_val <= 1)) {
976 /* Fail on start with first deskew value */
977 /* Decrement DQS ADLL */
979 if (adll_val == ADLL_MIN) {
980 DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - fail on start with first deskew value\n");
981 return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP;
983 ddr3_write_pup_reg(PUP_DQS_RD, CS0, pup + ecc * ECC_PUP,
988 /* Update all new locked pups */
989 unlock_pup &= ~new_lockup_pup;
991 if ((unlock_pup == 0) || (dqs_deskew_val == MAX_PBS)) {
992 if (dqs_deskew_val == MAX_PBS) {
994 * Reach max value of dqs deskew or get fail
997 DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - DQS deskew reached maximum value\n");
1002 DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Inc DQS deskew for PUPs: ");
1003 DEBUG_PBS_FULL_D(unlock_pup, 2);
1004 DEBUG_PBS_FULL_C(", deskew = ", dqs_deskew_val, 2);
1006 /* Increment DQS deskew elements - Only for unlocked pups */
1008 for (pup = 0; pup < cur_max_pup; pup++) {
1009 if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
1010 ddr3_write_pup_reg(PUP_PBS_RX + DQS_DQ_NUM, CS0,
1011 pup + ecc * ECC_PUP, 0,
1017 DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - ADLL shift one step before fail\n");
1018 /* Continue to ADLL shift one step before fail */
1019 unlock_pup = cur_pup;
1021 /* Loop until pass compare for all pups */
1023 /* Read and compare results */
1024 if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup, &new_lockup_pup,
1025 pattern_ptr, LEN_PBS_PATTERN,
1027 pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS,
1029 DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP(ddr3_sdram_compare)\n");
1030 return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP;
1034 * Get mask for pup which passed so their adll will be
1035 * changed to 2 steps before fails
1037 pass_pup = unlock_pup & ~new_lockup_pup;
1039 DEBUG_PBS_FULL_S("Shift DQS by 2 steps for PUPs: ");
1040 DEBUG_PBS_FULL_D(pass_pup, 2);
1041 DEBUG_PBS_FULL_C(", Set ADLL value = ", (adll_val - 2), 2);
1043 /* Only for pass pups */
1044 for (pup = 0; pup < cur_max_pup; pup++) {
1045 if (IS_PUP_ACTIVE(pass_pup, pup) == 1) {
1046 ddr3_write_pup_reg(PUP_DQS_RD, CS0,
1047 pup + ecc * ECC_PUP, 0,
1052 /* Locked pups that compare success */
1053 unlock_pup &= new_lockup_pup;
1055 if (unlock_pup == 0) {
1056 /* All pups locked */
1061 if (adll_val == 0) {
1062 DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Shift DQS - Adll reach min value\n");
1063 return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_MAX_VAL;
1067 * Decrement (Move Back to Left one phase - ADLL) dqs RX delay
1070 for (pup = 0; pup < cur_max_pup; pup++) {
1071 if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
1072 ddr3_write_pup_reg(PUP_DQS_RD, CS0,
1073 pup + ecc * ECC_PUP, 0,
1083 * lock_pups() extracted from ddr3_pbs_per_bit(). This just got too
1084 * much indented making it hard to read / edit.
1086 static void lock_pups(u32 pup, u32 *pup_locked, u8 *unlock_pup_dq_array,
1087 u32 pbs_curr_val, u32 start_pbs, u32 ecc, int is_tx)
1092 /* Lock PBS value for all remaining PUPs bits */
1093 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Lock PBS value for all remaining PUPs bits, pup ");
1094 DEBUG_PBS_FULL_D(pup, 1);
1095 DEBUG_PBS_FULL_C(" pbs value ", pbs_curr_val, 2);
1097 idx = pup * (1 - ecc) + ecc * ECC_PUP;
1098 *pup_locked &= ~(1 << pup);
1100 for (dq = 0; dq < DQ_NUM; dq++) {
1101 if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup) == 1) {
1104 /* Lock current dq */
1105 unlock_pup_dq_array[dq] &= ~(1 << pup);
1106 skew_array[(pup * DQ_NUM) + dq] = pbs_curr_val;
1113 ddr3_write_pup_reg(offs +
1114 pbs_dq_mapping[idx][dq], CS0,
1121 * Name: ddr3_pbs_per_bit
1122 * Desc: Execute the Per Bit Skew phase.
1123 * Args: start_over Return whether need to start over the algorithm
1124 * is_tx Indicate whether Rx or Tx
1125 * pcur_pup bit array of the function active pups. return the
1126 * pups that need to repeat on the PBS
1127 * pbs_pattern_idx Index of PBS pattern
1129 * Notes: Current implementation supports double activation of this function.
1130 * i.e. in order to activate this function (using start_over) more than
1131 * twice, the implementation should change.
1132 * imlementation limitation are marked using
1133 * ' CHIP-ONLY! - Implementation Limitation '
1134 * Returns: MV_OK if success, other error code if fail.
1136 static int ddr3_pbs_per_bit(MV_DRAM_INFO *dram_info, int *start_over, int is_tx,
1137 u32 *pcur_pup, u32 pbs_pattern_idx, u32 ecc)
1140 * Bit array to indicate if we already get fail on bit per pup & dq bit
1142 u8 unlock_pup_dq_array[DQ_NUM] = {
1143 *pcur_pup, *pcur_pup, *pcur_pup, *pcur_pup, *pcur_pup,
1144 *pcur_pup, *pcur_pup, *pcur_pup
1147 u8 cmp_unlock_pup_dq_array[COUNT_PBS_COMP_RETRY_NUM][DQ_NUM];
1149 /* value of pbs is according to RX or TX */
1150 u32 start_pbs, last_pbs;
1152 /* bit array that indicates all dq of the pup locked */
1154 u32 first_fail[MAX_PUP_NUM] = { 0 }; /* count first fail per pup */
1155 /* indicates whether we get first fail per pup */
1156 int first_failed[MAX_PUP_NUM] = { 0 };
1157 /* bit array that indicates pup already get fail */
1159 /* use to calculate diff between curr pbs to first fail pbs */
1164 /* Set init values for retry array - 8 retry */
1165 for (pbs_cmp_retry = 0; pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM;
1167 for (dq = 0; dq < DQ_NUM; dq++)
1168 cmp_unlock_pup_dq_array[pbs_cmp_retry][dq] = *pcur_pup;
1171 memset(&skew_array, 0, MAX_PUP_NUM * DQ_NUM * sizeof(u32));
1173 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Started\n");
1175 /* The pbs value depends if rx or tx */
1177 start_pbs = MIN_PBS;
1180 start_pbs = MAX_PBS;
1184 pbs_curr_val = start_pbs;
1185 pup_locked = *pcur_pup;
1187 /* Set current pup number */
1188 if (pup_locked == 0x1) /* Ecc mode */
1191 max_pup = dram_info->num_of_std_pups;
1194 /* Increment/ decrement PBS for un-lock bits only */
1200 /* Set Current PBS delay */
1201 for (dq = 0; dq < DQ_NUM; dq++) {
1202 /* Check DQ bits to see if locked in all pups */
1203 if (unlock_pup_dq_array[dq] == 0) {
1204 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - All pups are locked for DQ ");
1205 DEBUG_PBS_FULL_D(dq, 1);
1206 DEBUG_PBS_FULL_S("\n");
1210 for (pup = 0; pup < max_pup; pup++) {
1213 idx = pup * (1 - ecc) + ecc * ECC_PUP;
1215 if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup)
1221 PUP_PBS_TX + pbs_dq_mapping[idx][dq],
1222 CS0, idx, 0, pbs_curr_val);
1225 PUP_PBS_RX + pbs_dq_mapping[idx][dq],
1226 CS0, idx, 0, pbs_curr_val);
1231 * Write Read and compare results - run the test
1232 * DDR_PBS_COMP_RETRY_NUM times
1234 /* Run number of read and write to verify */
1235 for (pbs_cmp_retry = 0;
1236 pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM;
1240 ddr3_sdram_pbs_compare(dram_info, pup_locked, is_tx,
1242 pbs_curr_val, start_pbs,
1244 cmp_unlock_pup_dq_array
1245 [pbs_cmp_retry], ecc))
1248 for (pup = 0; pup < max_pup; pup++) {
1249 for (dq = 0; dq < DQ_NUM; dq++) {
1250 if ((IS_PUP_ACTIVE(unlock_pup_dq_array[dq],
1252 && (IS_PUP_ACTIVE(cmp_unlock_pup_dq_array
1253 [pbs_cmp_retry][dq],
1255 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - PbsCurrVal: ");
1256 DEBUG_PBS_FULL_D(pbs_curr_val, 2);
1257 DEBUG_PBS_FULL_S(" PUP: ");
1258 DEBUG_PBS_FULL_D(pup, 1);
1259 DEBUG_PBS_FULL_S(" DQ: ");
1260 DEBUG_PBS_FULL_D(dq, 1);
1261 DEBUG_PBS_FULL_S(" - failed\n");
1266 for (dq = 0; dq < DQ_NUM; dq++) {
1267 unlock_pup_dq_array[dq] &=
1268 cmp_unlock_pup_dq_array[pbs_cmp_retry][dq];
1273 sum_pup_fail = *pcur_pup;
1275 /* Check which DQ is failed */
1276 for (dq = 0; dq < DQ_NUM; dq++) {
1277 /* Summarize the locked pup */
1278 pup_locked |= unlock_pup_dq_array[dq];
1280 /* Check if get fail */
1281 sum_pup_fail &= unlock_pup_dq_array[dq];
1284 /* If all PUPS are locked in all DQ - Break */
1285 if (pup_locked == 0) {
1286 /* All pups are locked */
1288 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - All bit in all pups are successfully locked\n");
1292 /* PBS deskew elements reach max ? */
1293 if (pbs_curr_val == last_pbs) {
1294 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - PBS deskew elements reach max\n");
1295 /* CHIP-ONLY! - Implementation Limitation */
1296 *start_over = (sum_pup_fail != 0) && (!(*start_over));
1297 *pcur_pup = pup_locked;
1299 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - StartOver: ");
1300 DEBUG_PBS_FULL_D(*start_over, 1);
1301 DEBUG_PBS_FULL_S(" pup_locked: ");
1302 DEBUG_PBS_FULL_D(pup_locked, 2);
1303 DEBUG_PBS_FULL_S(" sum_pup_fail: ");
1304 DEBUG_PBS_FULL_D(sum_pup_fail, 2);
1305 DEBUG_PBS_FULL_S("\n");
1307 /* Lock PBS value for all remaining bits */
1308 for (pup = 0; pup < max_pup; pup++) {
1309 /* Check if current pup already received error */
1310 if (IS_PUP_ACTIVE(pup_locked, pup) == 1) {
1311 /* Valid pup for current function */
1312 if (IS_PUP_ACTIVE(sum_pup_fail, pup) ==
1313 1 && (*start_over == 1)) {
1314 DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - skipping lock of pup (first loop of pbs)",
1318 if (IS_PUP_ACTIVE(sum_pup_fail, pup)
1320 DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - Locking pup %d (even though it wasn't supposed to be locked)",
1324 /* Already got fail on the PUP */
1325 /* Lock PBS value for all remaining bits */
1326 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Locking remaning DQs for pup - ");
1327 DEBUG_PBS_FULL_D(pup, 1);
1328 DEBUG_PBS_FULL_S(": ");
1330 for (dq = 0; dq < DQ_NUM; dq++) {
1332 (unlock_pup_dq_array[dq],
1334 DEBUG_PBS_FULL_D(dq, 1);
1335 DEBUG_PBS_FULL_S(",");
1336 /* set current PBS */
1344 if (*start_over == 1) {
1346 * Reset this pup bit - when
1347 * restart the PBS, ignore this
1350 *pcur_pup &= ~(1 << pup);
1352 DEBUG_PBS_FULL_S("\n");
1354 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Pup ");
1355 DEBUG_PBS_FULL_D(pup, 1);
1356 DEBUG_PBS_FULL_C(" is not set in puplocked - ",
1361 /* Need to start the PBS again */
1362 if (*start_over == 1) {
1363 DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - false fail - returning to start\n");
1370 for (pup = 0; pup < max_pup; pup++) {
1371 if (IS_PUP_ACTIVE(pup_locked, pup) == 1) {
1372 /* pup is not locked */
1373 if (first_failed[pup] == 0) {
1374 /* No first fail until now */
1375 if (IS_PUP_ACTIVE(sum_pup_fail, pup) ==
1377 /* Get first fail */
1378 DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - First fail in pup ",
1380 first_failed[pup] = 1;
1381 first_fail[pup] = pbs_curr_val;
1384 /* Already got first fail */
1387 calc_pbs_diff = pbs_curr_val -
1391 calc_pbs_diff = first_fail[pup] -
1395 if (calc_pbs_diff >= PBS_DIFF_LIMIT) {
1396 lock_pups(pup, &pup_locked,
1397 unlock_pup_dq_array,
1399 start_pbs, ecc, is_tx);
1410 * Name: ddr3_set_pbs_results
1411 * Desc: Set to HW the PBS phase results.
1412 * Args: is_tx Indicates whether to set Tx or RX results
1414 * Returns: MV_OK if success, other error code if fail.
1416 static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx)
1418 u32 pup, phys_pup, dq;
1419 u32 max_pup; /* number of valid pups */
1420 u32 pbs_min; /* minimal pbs val per pup */
1421 u32 pbs_max; /* maximum pbs val per pup */
1424 max_pup = dram_info->num_of_total_pups;
1425 DEBUG_PBS_FULL_S("DDR3 - PBS - ddr3_set_pbs_results:\n");
1427 /* Loop for all dqs & pups */
1428 for (pup = 0; pup < max_pup; pup++) {
1429 if (pup == (max_pup - 1) && dram_info->ecc_ena)
1435 * To minimize delay elements, inc from pbs value the min
1440 for (dq = 0; dq < DQ_NUM; dq++) {
1441 if (pbs_min > skew_array[(pup * DQ_NUM) + dq])
1442 pbs_min = skew_array[(pup * DQ_NUM) + dq];
1444 if (pbs_max < skew_array[(pup * DQ_NUM) + dq])
1445 pbs_max = skew_array[(pup * DQ_NUM) + dq];
1450 DEBUG_PBS_FULL_S("DDR3 - PBS - PUP");
1451 DEBUG_PBS_FULL_D(phys_pup, 1);
1452 DEBUG_PBS_FULL_S(": Min Val = ");
1453 DEBUG_PBS_FULL_D(pbs_min, 2);
1454 DEBUG_PBS_FULL_C(", Max Val = ", pbs_max, 2);
1458 for (dq = 0; dq < DQ_NUM; dq++) {
1462 /* Set skew value for all dq */
1464 * Bit# Deskew <- Bit# Deskew - last / first
1465 * failing bit Deskew For all bits (per PUP)
1466 * (minimize delay elements)
1469 DEBUG_PBS_FULL_S("DQ");
1470 DEBUG_PBS_FULL_D(dq, 1);
1471 DEBUG_PBS_FULL_S("-");
1472 DEBUG_PBS_FULL_D((skew_array[(pup * DQ_NUM) + dq] -
1474 DEBUG_PBS_FULL_S(", ");
1476 idx = (pup * DQ_NUM) + dq;
1483 ddr3_write_pup_reg(offs + pbs_dq_mapping[phys_pup][dq],
1485 skew_array[idx] - pbs_min);
1488 val[pup] += skew_array[idx] - pbs_min;
1491 DEBUG_PBS_FULL_S("\n");
1493 /* Set the DQS the half of the Max PBS of the DQs */
1495 ddr3_write_pup_reg(PUP_PBS_TX + 8, CS0, phys_pup, 0,
1497 ddr3_write_pup_reg(PUP_PBS_TX + 0xa, CS0, phys_pup, 0,
1500 ddr3_write_pup_reg(PUP_PBS_RX + 8, CS0, phys_pup, 0,
1507 static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay)
1511 reg = (ddr3_read_pup_reg(PUP_WL_MODE, cs, pup) & 0x3FF);
1512 delay = reg & PUP_DELAY_MASK;
1513 reg |= ((dqs_delay + delay) << REG_PHY_DQS_REF_DLY_OFFS);
1514 reg |= REG_PHY_REGISTRY_FILE_ACCESS_OP_WR;
1515 reg |= (pup << REG_PHY_PUP_OFFS);
1516 reg |= ((0x4 * cs + PUP_WL_MODE) << REG_PHY_CS_OFFS);
1518 reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg); /* 0x16A0 */
1520 reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) &
1521 REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE;
1522 } while (reg); /* Wait for '0' to mark the end of the transaction */
1528 * Set training patterns
1530 int ddr3_load_pbs_patterns(MV_DRAM_INFO *dram_info)
1532 u32 cs, cs_count, cs_tmp;
1534 u32 *pattern_ptr0, *pattern_ptr1;
1536 /* Choose pattern */
1537 switch (dram_info->ddr_width) {
1538 #if defined(MV88F672X)
1540 pattern_ptr0 = (u32 *)&pbs_pattern[0];
1541 pattern_ptr1 = (u32 *)&pbs_pattern[1];
1545 pattern_ptr0 = (u32 *)&pbs_pattern_32b[0];
1546 pattern_ptr1 = (u32 *)&pbs_pattern_32b[1];
1548 #if defined(MV88F78X60)
1550 pattern_ptr0 = (u32 *)&pbs_pattern_64b[0];
1551 pattern_ptr1 = (u32 *)&pbs_pattern_64b[1];
1558 /* Loop for each CS */
1559 for (cs = 0; cs < MAX_CS; cs++) {
1560 if (dram_info->cs_ena & (1 << cs)) {
1562 for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) {
1563 if (dram_info->cs_ena & (1 << cs_tmp))
1567 /* Init PBS I pattern */
1568 sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
1571 ddr3_sdram_compare(dram_info, (u32) NULL, NULL,
1572 pattern_ptr0, LEN_STD_PATTERN,
1573 sdram_addr, 1, 0, NULL,
1577 /* Init PBS II pattern */
1578 sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
1581 ddr3_sdram_compare(dram_info, (u32) NULL, NULL,
1582 pattern_ptr1, LEN_STD_PATTERN,
1583 sdram_addr, 1, 0, NULL,