1*ff9112dfSStefan Roese /*
2*ff9112dfSStefan Roese * Copyright (C) Marvell International Ltd. and its affiliates
3*ff9112dfSStefan Roese *
4*ff9112dfSStefan Roese * SPDX-License-Identifier: GPL-2.0
5*ff9112dfSStefan Roese */
6*ff9112dfSStefan Roese
7*ff9112dfSStefan Roese #include <common.h>
8*ff9112dfSStefan Roese #include <i2c.h>
9*ff9112dfSStefan Roese #include <spl.h>
10*ff9112dfSStefan Roese #include <asm/io.h>
11*ff9112dfSStefan Roese #include <asm/arch/cpu.h>
12*ff9112dfSStefan Roese #include <asm/arch/soc.h>
13*ff9112dfSStefan Roese
14*ff9112dfSStefan Roese #include "ddr3_hw_training.h"
15*ff9112dfSStefan Roese
16*ff9112dfSStefan Roese /*
17*ff9112dfSStefan Roese * Debug
18*ff9112dfSStefan Roese */
19*ff9112dfSStefan Roese #define DEBUG_RL_C(s, d, l) \
20*ff9112dfSStefan Roese DEBUG_RL_S(s); DEBUG_RL_D(d, l); DEBUG_RL_S("\n")
21*ff9112dfSStefan Roese #define DEBUG_RL_FULL_C(s, d, l) \
22*ff9112dfSStefan Roese DEBUG_RL_FULL_S(s); DEBUG_RL_FULL_D(d, l); DEBUG_RL_FULL_S("\n")
23*ff9112dfSStefan Roese
24*ff9112dfSStefan Roese #ifdef MV_DEBUG_RL
25*ff9112dfSStefan Roese #define DEBUG_RL_S(s) \
26*ff9112dfSStefan Roese debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%s", s)
27*ff9112dfSStefan Roese #define DEBUG_RL_D(d, l) \
28*ff9112dfSStefan Roese debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%x", d)
29*ff9112dfSStefan Roese #else
30*ff9112dfSStefan Roese #define DEBUG_RL_S(s)
31*ff9112dfSStefan Roese #define DEBUG_RL_D(d, l)
32*ff9112dfSStefan Roese #endif
33*ff9112dfSStefan Roese
34*ff9112dfSStefan Roese #ifdef MV_DEBUG_RL_FULL
35*ff9112dfSStefan Roese #define DEBUG_RL_FULL_S(s) puts(s)
36*ff9112dfSStefan Roese #define DEBUG_RL_FULL_D(d, l) printf("%x", d)
37*ff9112dfSStefan Roese #else
38*ff9112dfSStefan Roese #define DEBUG_RL_FULL_S(s)
39*ff9112dfSStefan Roese #define DEBUG_RL_FULL_D(d, l)
40*ff9112dfSStefan Roese #endif
41*ff9112dfSStefan Roese
42*ff9112dfSStefan Roese extern u32 rl_pattern[LEN_STD_PATTERN];
43*ff9112dfSStefan Roese
44*ff9112dfSStefan Roese #ifdef RL_MODE
45*ff9112dfSStefan Roese static int ddr3_read_leveling_single_cs_rl_mode(u32 cs, u32 freq,
46*ff9112dfSStefan Roese int ratio_2to1, u32 ecc,
47*ff9112dfSStefan Roese MV_DRAM_INFO *dram_info);
48*ff9112dfSStefan Roese #else
49*ff9112dfSStefan Roese static int ddr3_read_leveling_single_cs_window_mode(u32 cs, u32 freq,
50*ff9112dfSStefan Roese int ratio_2to1, u32 ecc,
51*ff9112dfSStefan Roese MV_DRAM_INFO *dram_info);
52*ff9112dfSStefan Roese #endif
53*ff9112dfSStefan Roese
54*ff9112dfSStefan Roese /*
55*ff9112dfSStefan Roese * Name: ddr3_read_leveling_hw
56*ff9112dfSStefan Roese * Desc: Execute the Read leveling phase by HW
57*ff9112dfSStefan Roese * Args: dram_info - main struct
58*ff9112dfSStefan Roese * freq - current sequence frequency
59*ff9112dfSStefan Roese * Notes:
60*ff9112dfSStefan Roese * Returns: MV_OK if success, MV_FAIL if fail.
61*ff9112dfSStefan Roese */
ddr3_read_leveling_hw(u32 freq,MV_DRAM_INFO * dram_info)62*ff9112dfSStefan Roese int ddr3_read_leveling_hw(u32 freq, MV_DRAM_INFO *dram_info)
63*ff9112dfSStefan Roese {
64*ff9112dfSStefan Roese u32 reg;
65*ff9112dfSStefan Roese
66*ff9112dfSStefan Roese /* Debug message - Start Read leveling procedure */
67*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - Starting HW RL procedure\n");
68*ff9112dfSStefan Roese
69*ff9112dfSStefan Roese /* Start Auto Read Leveling procedure */
70*ff9112dfSStefan Roese reg = 1 << REG_DRAM_TRAINING_RL_OFFS;
71*ff9112dfSStefan Roese /* Config the retest number */
72*ff9112dfSStefan Roese reg |= (COUNT_HW_RL << REG_DRAM_TRAINING_RETEST_OFFS);
73*ff9112dfSStefan Roese
74*ff9112dfSStefan Roese /* Enable CS in the automatic process */
75*ff9112dfSStefan Roese reg |= (dram_info->cs_ena << REG_DRAM_TRAINING_CS_OFFS);
76*ff9112dfSStefan Roese
77*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
78*ff9112dfSStefan Roese
79*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) |
80*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_AUTO_OFFS);
81*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_SHADOW_ADDR, reg);
82*ff9112dfSStefan Roese
83*ff9112dfSStefan Roese /* Wait */
84*ff9112dfSStefan Roese do {
85*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) &
86*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_AUTO_OFFS);
87*ff9112dfSStefan Roese } while (reg); /* Wait for '0' */
88*ff9112dfSStefan Roese
89*ff9112dfSStefan Roese /* Check if Successful */
90*ff9112dfSStefan Roese if (reg_read(REG_DRAM_TRAINING_SHADOW_ADDR) &
91*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_ERROR_OFFS)) {
92*ff9112dfSStefan Roese u32 delay, phase, pup, cs;
93*ff9112dfSStefan Roese
94*ff9112dfSStefan Roese dram_info->rl_max_phase = 0;
95*ff9112dfSStefan Roese dram_info->rl_min_phase = 10;
96*ff9112dfSStefan Roese
97*ff9112dfSStefan Roese /* Read results to arrays */
98*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
99*ff9112dfSStefan Roese if (dram_info->cs_ena & (1 << cs)) {
100*ff9112dfSStefan Roese for (pup = 0;
101*ff9112dfSStefan Roese pup < dram_info->num_of_total_pups;
102*ff9112dfSStefan Roese pup++) {
103*ff9112dfSStefan Roese if (pup == dram_info->num_of_std_pups
104*ff9112dfSStefan Roese && dram_info->ecc_ena)
105*ff9112dfSStefan Roese pup = ECC_PUP;
106*ff9112dfSStefan Roese reg =
107*ff9112dfSStefan Roese ddr3_read_pup_reg(PUP_RL_MODE, cs,
108*ff9112dfSStefan Roese pup);
109*ff9112dfSStefan Roese phase = (reg >> REG_PHY_PHASE_OFFS) &
110*ff9112dfSStefan Roese PUP_PHASE_MASK;
111*ff9112dfSStefan Roese delay = reg & PUP_DELAY_MASK;
112*ff9112dfSStefan Roese dram_info->rl_val[cs][pup][P] = phase;
113*ff9112dfSStefan Roese if (phase > dram_info->rl_max_phase)
114*ff9112dfSStefan Roese dram_info->rl_max_phase = phase;
115*ff9112dfSStefan Roese if (phase < dram_info->rl_min_phase)
116*ff9112dfSStefan Roese dram_info->rl_min_phase = phase;
117*ff9112dfSStefan Roese dram_info->rl_val[cs][pup][D] = delay;
118*ff9112dfSStefan Roese dram_info->rl_val[cs][pup][S] =
119*ff9112dfSStefan Roese RL_FINAL_STATE;
120*ff9112dfSStefan Roese reg =
121*ff9112dfSStefan Roese ddr3_read_pup_reg(PUP_RL_MODE + 0x1,
122*ff9112dfSStefan Roese cs, pup);
123*ff9112dfSStefan Roese dram_info->rl_val[cs][pup][DQS] =
124*ff9112dfSStefan Roese (reg & 0x3F);
125*ff9112dfSStefan Roese }
126*ff9112dfSStefan Roese #ifdef MV_DEBUG_RL
127*ff9112dfSStefan Roese /* Print results */
128*ff9112dfSStefan Roese DEBUG_RL_C("DDR3 - Read Leveling - Results for CS - ",
129*ff9112dfSStefan Roese (u32) cs, 1);
130*ff9112dfSStefan Roese
131*ff9112dfSStefan Roese for (pup = 0;
132*ff9112dfSStefan Roese pup < (dram_info->num_of_total_pups);
133*ff9112dfSStefan Roese pup++) {
134*ff9112dfSStefan Roese if (pup == dram_info->num_of_std_pups
135*ff9112dfSStefan Roese && dram_info->ecc_ena)
136*ff9112dfSStefan Roese pup = ECC_PUP;
137*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - PUP: ");
138*ff9112dfSStefan Roese DEBUG_RL_D((u32) pup, 1);
139*ff9112dfSStefan Roese DEBUG_RL_S(", Phase: ");
140*ff9112dfSStefan Roese DEBUG_RL_D((u32) dram_info->
141*ff9112dfSStefan Roese rl_val[cs][pup][P], 1);
142*ff9112dfSStefan Roese DEBUG_RL_S(", Delay: ");
143*ff9112dfSStefan Roese DEBUG_RL_D((u32) dram_info->
144*ff9112dfSStefan Roese rl_val[cs][pup][D], 2);
145*ff9112dfSStefan Roese DEBUG_RL_S("\n");
146*ff9112dfSStefan Roese }
147*ff9112dfSStefan Roese #endif
148*ff9112dfSStefan Roese }
149*ff9112dfSStefan Roese }
150*ff9112dfSStefan Roese
151*ff9112dfSStefan Roese dram_info->rd_rdy_dly =
152*ff9112dfSStefan Roese reg_read(REG_READ_DATA_READY_DELAYS_ADDR) &
153*ff9112dfSStefan Roese REG_READ_DATA_SAMPLE_DELAYS_MASK;
154*ff9112dfSStefan Roese dram_info->rd_smpl_dly =
155*ff9112dfSStefan Roese reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR) &
156*ff9112dfSStefan Roese REG_READ_DATA_READY_DELAYS_MASK;
157*ff9112dfSStefan Roese #ifdef MV_DEBUG_RL
158*ff9112dfSStefan Roese DEBUG_RL_C("DDR3 - Read Leveling - Read Sample Delay: ",
159*ff9112dfSStefan Roese dram_info->rd_smpl_dly, 2);
160*ff9112dfSStefan Roese DEBUG_RL_C("DDR3 - Read Leveling - Read Ready Delay: ",
161*ff9112dfSStefan Roese dram_info->rd_rdy_dly, 2);
162*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - HW RL Ended Successfully\n");
163*ff9112dfSStefan Roese #endif
164*ff9112dfSStefan Roese return MV_OK;
165*ff9112dfSStefan Roese
166*ff9112dfSStefan Roese } else {
167*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - HW RL Error\n");
168*ff9112dfSStefan Roese return MV_FAIL;
169*ff9112dfSStefan Roese }
170*ff9112dfSStefan Roese }
171*ff9112dfSStefan Roese
172*ff9112dfSStefan Roese /*
173*ff9112dfSStefan Roese * Name: ddr3_read_leveling_sw
174*ff9112dfSStefan Roese * Desc: Execute the Read leveling phase by SW
175*ff9112dfSStefan Roese * Args: dram_info - main struct
176*ff9112dfSStefan Roese * freq - current sequence frequency
177*ff9112dfSStefan Roese * Notes:
178*ff9112dfSStefan Roese * Returns: MV_OK if success, MV_FAIL if fail.
179*ff9112dfSStefan Roese */
ddr3_read_leveling_sw(u32 freq,int ratio_2to1,MV_DRAM_INFO * dram_info)180*ff9112dfSStefan Roese int ddr3_read_leveling_sw(u32 freq, int ratio_2to1, MV_DRAM_INFO *dram_info)
181*ff9112dfSStefan Roese {
182*ff9112dfSStefan Roese u32 reg, cs, ecc, pup_num, phase, delay, pup;
183*ff9112dfSStefan Roese int status;
184*ff9112dfSStefan Roese
185*ff9112dfSStefan Roese /* Debug message - Start Read leveling procedure */
186*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - Starting SW RL procedure\n");
187*ff9112dfSStefan Roese
188*ff9112dfSStefan Roese /* Enable SW Read Leveling */
189*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
190*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
191*ff9112dfSStefan Roese reg &= ~(1 << REG_DRAM_TRAINING_2_RL_MODE_OFFS);
192*ff9112dfSStefan Roese /* [0]=1 - Enable SW override */
193*ff9112dfSStefan Roese /* 0x15B8 - Training SW 2 Register */
194*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
195*ff9112dfSStefan Roese
196*ff9112dfSStefan Roese #ifdef RL_MODE
197*ff9112dfSStefan Roese reg = (dram_info->cs_ena << REG_DRAM_TRAINING_CS_OFFS) |
198*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_AUTO_OFFS);
199*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */
200*ff9112dfSStefan Roese #endif
201*ff9112dfSStefan Roese
202*ff9112dfSStefan Roese /* Loop for each CS */
203*ff9112dfSStefan Roese for (cs = 0; cs < dram_info->num_cs; cs++) {
204*ff9112dfSStefan Roese DEBUG_RL_C("DDR3 - Read Leveling - CS - ", (u32) cs, 1);
205*ff9112dfSStefan Roese
206*ff9112dfSStefan Roese for (ecc = 0; ecc <= (dram_info->ecc_ena); ecc++) {
207*ff9112dfSStefan Roese /* ECC Support - Switch ECC Mux on ecc=1 */
208*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
209*ff9112dfSStefan Roese ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
210*ff9112dfSStefan Roese reg |= (dram_info->ecc_ena *
211*ff9112dfSStefan Roese ecc << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
212*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
213*ff9112dfSStefan Roese
214*ff9112dfSStefan Roese if (ecc)
215*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - ECC Mux Enabled\n");
216*ff9112dfSStefan Roese else
217*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - ECC Mux Disabled\n");
218*ff9112dfSStefan Roese
219*ff9112dfSStefan Roese /* Set current sample delays */
220*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR);
221*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK <<
222*ff9112dfSStefan Roese (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs));
223*ff9112dfSStefan Roese reg |= (dram_info->cl <<
224*ff9112dfSStefan Roese (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs));
225*ff9112dfSStefan Roese reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, reg);
226*ff9112dfSStefan Roese
227*ff9112dfSStefan Roese /* Set current Ready delay */
228*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR);
229*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_READY_DELAYS_MASK <<
230*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
231*ff9112dfSStefan Roese if (!ratio_2to1) {
232*ff9112dfSStefan Roese /* 1:1 mode */
233*ff9112dfSStefan Roese reg |= ((dram_info->cl + 1) <<
234*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
235*ff9112dfSStefan Roese } else {
236*ff9112dfSStefan Roese /* 2:1 mode */
237*ff9112dfSStefan Roese reg |= ((dram_info->cl + 2) <<
238*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
239*ff9112dfSStefan Roese }
240*ff9112dfSStefan Roese reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg);
241*ff9112dfSStefan Roese
242*ff9112dfSStefan Roese /* Read leveling Single CS[cs] */
243*ff9112dfSStefan Roese #ifdef RL_MODE
244*ff9112dfSStefan Roese status =
245*ff9112dfSStefan Roese ddr3_read_leveling_single_cs_rl_mode(cs, freq,
246*ff9112dfSStefan Roese ratio_2to1,
247*ff9112dfSStefan Roese ecc,
248*ff9112dfSStefan Roese dram_info);
249*ff9112dfSStefan Roese if (MV_OK != status)
250*ff9112dfSStefan Roese return status;
251*ff9112dfSStefan Roese #else
252*ff9112dfSStefan Roese status =
253*ff9112dfSStefan Roese ddr3_read_leveling_single_cs_window_mode(cs, freq,
254*ff9112dfSStefan Roese ratio_2to1,
255*ff9112dfSStefan Roese ecc,
256*ff9112dfSStefan Roese dram_info)
257*ff9112dfSStefan Roese if (MV_OK != status)
258*ff9112dfSStefan Roese return status;
259*ff9112dfSStefan Roese #endif
260*ff9112dfSStefan Roese }
261*ff9112dfSStefan Roese
262*ff9112dfSStefan Roese /* Print results */
263*ff9112dfSStefan Roese DEBUG_RL_C("DDR3 - Read Leveling - Results for CS - ", (u32) cs,
264*ff9112dfSStefan Roese 1);
265*ff9112dfSStefan Roese
266*ff9112dfSStefan Roese for (pup = 0;
267*ff9112dfSStefan Roese pup < (dram_info->num_of_std_pups + dram_info->ecc_ena);
268*ff9112dfSStefan Roese pup++) {
269*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - PUP: ");
270*ff9112dfSStefan Roese DEBUG_RL_D((u32) pup, 1);
271*ff9112dfSStefan Roese DEBUG_RL_S(", Phase: ");
272*ff9112dfSStefan Roese DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][P], 1);
273*ff9112dfSStefan Roese DEBUG_RL_S(", Delay: ");
274*ff9112dfSStefan Roese DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][D], 2);
275*ff9112dfSStefan Roese DEBUG_RL_S("\n");
276*ff9112dfSStefan Roese }
277*ff9112dfSStefan Roese
278*ff9112dfSStefan Roese DEBUG_RL_C("DDR3 - Read Leveling - Read Sample Delay: ",
279*ff9112dfSStefan Roese dram_info->rd_smpl_dly, 2);
280*ff9112dfSStefan Roese DEBUG_RL_C("DDR3 - Read Leveling - Read Ready Delay: ",
281*ff9112dfSStefan Roese dram_info->rd_rdy_dly, 2);
282*ff9112dfSStefan Roese
283*ff9112dfSStefan Roese /* Configure PHY with average of 3 locked leveling settings */
284*ff9112dfSStefan Roese for (pup = 0;
285*ff9112dfSStefan Roese pup < (dram_info->num_of_std_pups + dram_info->ecc_ena);
286*ff9112dfSStefan Roese pup++) {
287*ff9112dfSStefan Roese /* ECC support - bit 8 */
288*ff9112dfSStefan Roese pup_num = (pup == dram_info->num_of_std_pups) ? ECC_BIT : pup;
289*ff9112dfSStefan Roese
290*ff9112dfSStefan Roese /* For now, set last cnt result */
291*ff9112dfSStefan Roese phase = dram_info->rl_val[cs][pup][P];
292*ff9112dfSStefan Roese delay = dram_info->rl_val[cs][pup][D];
293*ff9112dfSStefan Roese ddr3_write_pup_reg(PUP_RL_MODE, cs, pup_num, phase,
294*ff9112dfSStefan Roese delay);
295*ff9112dfSStefan Roese }
296*ff9112dfSStefan Roese }
297*ff9112dfSStefan Roese
298*ff9112dfSStefan Roese /* Reset PHY read FIFO */
299*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
300*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
301*ff9112dfSStefan Roese /* 0x15B8 - Training SW 2 Register */
302*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
303*ff9112dfSStefan Roese
304*ff9112dfSStefan Roese do {
305*ff9112dfSStefan Roese reg = (reg_read(REG_DRAM_TRAINING_2_ADDR)) &
306*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
307*ff9112dfSStefan Roese } while (reg); /* Wait for '0' */
308*ff9112dfSStefan Roese
309*ff9112dfSStefan Roese /* ECC Support - Switch ECC Mux off ecc=0 */
310*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
311*ff9112dfSStefan Roese ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
312*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
313*ff9112dfSStefan Roese
314*ff9112dfSStefan Roese #ifdef RL_MODE
315*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_ADDR, 0); /* 0x15B0 - Training Register */
316*ff9112dfSStefan Roese #endif
317*ff9112dfSStefan Roese
318*ff9112dfSStefan Roese /* Disable SW Read Leveling */
319*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
320*ff9112dfSStefan Roese ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
321*ff9112dfSStefan Roese /* [0] = 0 - Disable SW override */
322*ff9112dfSStefan Roese reg = (reg | (0x1 << REG_DRAM_TRAINING_2_RL_MODE_OFFS));
323*ff9112dfSStefan Roese /* [3] = 1 - Disable RL MODE */
324*ff9112dfSStefan Roese /* 0x15B8 - Training SW 2 Register */
325*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
326*ff9112dfSStefan Roese
327*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - Finished RL procedure for all CS\n");
328*ff9112dfSStefan Roese return MV_OK;
329*ff9112dfSStefan Roese }
330*ff9112dfSStefan Roese
331*ff9112dfSStefan Roese #ifdef RL_MODE
332*ff9112dfSStefan Roese /*
333*ff9112dfSStefan Roese * overrun() extracted from ddr3_read_leveling_single_cs_rl_mode().
334*ff9112dfSStefan Roese * This just got too much indented making it hard to read / edit.
335*ff9112dfSStefan Roese */
overrun(u32 cs,MV_DRAM_INFO * info,u32 pup,u32 locked_pups,u32 * locked_sum,u32 ecc,int * first_octet_locked,int * counter_in_progress,int final_delay,u32 delay,u32 phase)336*ff9112dfSStefan Roese static void overrun(u32 cs, MV_DRAM_INFO *info, u32 pup, u32 locked_pups,
337*ff9112dfSStefan Roese u32 *locked_sum, u32 ecc, int *first_octet_locked,
338*ff9112dfSStefan Roese int *counter_in_progress, int final_delay, u32 delay,
339*ff9112dfSStefan Roese u32 phase)
340*ff9112dfSStefan Roese {
341*ff9112dfSStefan Roese /* If no OverRun */
342*ff9112dfSStefan Roese if (((~locked_pups >> pup) & 0x1) && (final_delay == 0)) {
343*ff9112dfSStefan Roese int idx;
344*ff9112dfSStefan Roese
345*ff9112dfSStefan Roese idx = pup + ecc * ECC_BIT;
346*ff9112dfSStefan Roese
347*ff9112dfSStefan Roese /* PUP passed, start examining */
348*ff9112dfSStefan Roese if (info->rl_val[cs][idx][S] == RL_UNLOCK_STATE) {
349*ff9112dfSStefan Roese /* Must be RL_UNLOCK_STATE */
350*ff9112dfSStefan Roese /* Match expected value ? - Update State Machine */
351*ff9112dfSStefan Roese if (info->rl_val[cs][idx][C] < RL_RETRY_COUNT) {
352*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - We have no overrun and a match on pup: ",
353*ff9112dfSStefan Roese (u32)pup, 1);
354*ff9112dfSStefan Roese info->rl_val[cs][idx][C]++;
355*ff9112dfSStefan Roese
356*ff9112dfSStefan Roese /* If pup got to last state - lock the delays */
357*ff9112dfSStefan Roese if (info->rl_val[cs][idx][C] == RL_RETRY_COUNT) {
358*ff9112dfSStefan Roese info->rl_val[cs][idx][C] = 0;
359*ff9112dfSStefan Roese info->rl_val[cs][idx][DS] = delay;
360*ff9112dfSStefan Roese info->rl_val[cs][idx][PS] = phase;
361*ff9112dfSStefan Roese
362*ff9112dfSStefan Roese /* Go to Final State */
363*ff9112dfSStefan Roese info->rl_val[cs][idx][S] = RL_FINAL_STATE;
364*ff9112dfSStefan Roese *locked_sum = *locked_sum + 1;
365*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - We have locked pup: ",
366*ff9112dfSStefan Roese (u32)pup, 1);
367*ff9112dfSStefan Roese
368*ff9112dfSStefan Roese /*
369*ff9112dfSStefan Roese * If first lock - need to lock delays
370*ff9112dfSStefan Roese */
371*ff9112dfSStefan Roese if (*first_octet_locked == 0) {
372*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got first lock on pup: ",
373*ff9112dfSStefan Roese (u32)pup, 1);
374*ff9112dfSStefan Roese *first_octet_locked = 1;
375*ff9112dfSStefan Roese }
376*ff9112dfSStefan Roese
377*ff9112dfSStefan Roese /*
378*ff9112dfSStefan Roese * If pup is in not in final state but
379*ff9112dfSStefan Roese * there was match - dont increment
380*ff9112dfSStefan Roese * counter
381*ff9112dfSStefan Roese */
382*ff9112dfSStefan Roese } else {
383*ff9112dfSStefan Roese *counter_in_progress = 1;
384*ff9112dfSStefan Roese }
385*ff9112dfSStefan Roese }
386*ff9112dfSStefan Roese }
387*ff9112dfSStefan Roese }
388*ff9112dfSStefan Roese }
389*ff9112dfSStefan Roese
390*ff9112dfSStefan Roese /*
391*ff9112dfSStefan Roese * Name: ddr3_read_leveling_single_cs_rl_mode
392*ff9112dfSStefan Roese * Desc: Execute Read leveling for single Chip select
393*ff9112dfSStefan Roese * Args: cs - current chip select
394*ff9112dfSStefan Roese * freq - current sequence frequency
395*ff9112dfSStefan Roese * ecc - ecc iteration indication
396*ff9112dfSStefan Roese * dram_info - main struct
397*ff9112dfSStefan Roese * Notes:
398*ff9112dfSStefan Roese * Returns: MV_OK if success, MV_FAIL if fail.
399*ff9112dfSStefan Roese */
ddr3_read_leveling_single_cs_rl_mode(u32 cs,u32 freq,int ratio_2to1,u32 ecc,MV_DRAM_INFO * dram_info)400*ff9112dfSStefan Roese static int ddr3_read_leveling_single_cs_rl_mode(u32 cs, u32 freq,
401*ff9112dfSStefan Roese int ratio_2to1, u32 ecc,
402*ff9112dfSStefan Roese MV_DRAM_INFO *dram_info)
403*ff9112dfSStefan Roese {
404*ff9112dfSStefan Roese u32 reg, delay, phase, pup, rd_sample_delay, add, locked_pups,
405*ff9112dfSStefan Roese repeat_max_cnt, sdram_offset, locked_sum;
406*ff9112dfSStefan Roese u32 phase_min, ui_max_delay;
407*ff9112dfSStefan Roese int all_locked, first_octet_locked, counter_in_progress;
408*ff9112dfSStefan Roese int final_delay = 0;
409*ff9112dfSStefan Roese
410*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - Single CS - ", (u32) cs, 1);
411*ff9112dfSStefan Roese
412*ff9112dfSStefan Roese /* Init values */
413*ff9112dfSStefan Roese phase = 0;
414*ff9112dfSStefan Roese delay = 0;
415*ff9112dfSStefan Roese rd_sample_delay = dram_info->cl;
416*ff9112dfSStefan Roese all_locked = 0;
417*ff9112dfSStefan Roese first_octet_locked = 0;
418*ff9112dfSStefan Roese repeat_max_cnt = 0;
419*ff9112dfSStefan Roese locked_sum = 0;
420*ff9112dfSStefan Roese
421*ff9112dfSStefan Roese for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc);
422*ff9112dfSStefan Roese pup++)
423*ff9112dfSStefan Roese dram_info->rl_val[cs][pup + ecc * ECC_BIT][S] = 0;
424*ff9112dfSStefan Roese
425*ff9112dfSStefan Roese /* Main loop */
426*ff9112dfSStefan Roese while (!all_locked) {
427*ff9112dfSStefan Roese counter_in_progress = 0;
428*ff9112dfSStefan Roese
429*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - RdSmplDly = ");
430*ff9112dfSStefan Roese DEBUG_RL_FULL_D(rd_sample_delay, 2);
431*ff9112dfSStefan Roese DEBUG_RL_FULL_S(", RdRdyDly = ");
432*ff9112dfSStefan Roese DEBUG_RL_FULL_D(dram_info->rd_rdy_dly, 2);
433*ff9112dfSStefan Roese DEBUG_RL_FULL_S(", Phase = ");
434*ff9112dfSStefan Roese DEBUG_RL_FULL_D(phase, 1);
435*ff9112dfSStefan Roese DEBUG_RL_FULL_S(", Delay = ");
436*ff9112dfSStefan Roese DEBUG_RL_FULL_D(delay, 2);
437*ff9112dfSStefan Roese DEBUG_RL_FULL_S("\n");
438*ff9112dfSStefan Roese
439*ff9112dfSStefan Roese /*
440*ff9112dfSStefan Roese * Broadcast to all PUPs current RL delays: DQS phase,
441*ff9112dfSStefan Roese * leveling delay
442*ff9112dfSStefan Roese */
443*ff9112dfSStefan Roese ddr3_write_pup_reg(PUP_RL_MODE, cs, PUP_BC, phase, delay);
444*ff9112dfSStefan Roese
445*ff9112dfSStefan Roese /* Reset PHY read FIFO */
446*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
447*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
448*ff9112dfSStefan Roese /* 0x15B8 - Training SW 2 Register */
449*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
450*ff9112dfSStefan Roese
451*ff9112dfSStefan Roese do {
452*ff9112dfSStefan Roese reg = (reg_read(REG_DRAM_TRAINING_2_ADDR)) &
453*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
454*ff9112dfSStefan Roese } while (reg); /* Wait for '0' */
455*ff9112dfSStefan Roese
456*ff9112dfSStefan Roese /* Read pattern from SDRAM */
457*ff9112dfSStefan Roese sdram_offset = cs * (SDRAM_CS_SIZE + 1) + SDRAM_RL_OFFS;
458*ff9112dfSStefan Roese locked_pups = 0;
459*ff9112dfSStefan Roese if (MV_OK !=
460*ff9112dfSStefan Roese ddr3_sdram_compare(dram_info, 0xFF, &locked_pups,
461*ff9112dfSStefan Roese rl_pattern, LEN_STD_PATTERN,
462*ff9112dfSStefan Roese sdram_offset, 0, 0, NULL, 0))
463*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_RD_LVL_RL_PATTERN;
464*ff9112dfSStefan Roese
465*ff9112dfSStefan Roese /* Octet evaluation */
466*ff9112dfSStefan Roese /* pup_num = Q or 1 for ECC */
467*ff9112dfSStefan Roese for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc); pup++) {
468*ff9112dfSStefan Roese /* Check Overrun */
469*ff9112dfSStefan Roese if (!((reg_read(REG_DRAM_TRAINING_2_ADDR) >>
470*ff9112dfSStefan Roese (REG_DRAM_TRAINING_2_OVERRUN_OFFS + pup)) & 0x1)) {
471*ff9112dfSStefan Roese overrun(cs, dram_info, pup, locked_pups,
472*ff9112dfSStefan Roese &locked_sum, ecc, &first_octet_locked,
473*ff9112dfSStefan Roese &counter_in_progress, final_delay,
474*ff9112dfSStefan Roese delay, phase);
475*ff9112dfSStefan Roese } else {
476*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got overrun on pup: ",
477*ff9112dfSStefan Roese (u32)pup, 1);
478*ff9112dfSStefan Roese }
479*ff9112dfSStefan Roese }
480*ff9112dfSStefan Roese
481*ff9112dfSStefan Roese if (locked_sum == (dram_info->num_of_std_pups *
482*ff9112dfSStefan Roese (1 - ecc) + ecc)) {
483*ff9112dfSStefan Roese all_locked = 1;
484*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - Single Cs - All pups locked\n");
485*ff9112dfSStefan Roese }
486*ff9112dfSStefan Roese
487*ff9112dfSStefan Roese /*
488*ff9112dfSStefan Roese * This is a fix for unstable condition where pups are
489*ff9112dfSStefan Roese * toggling between match and no match
490*ff9112dfSStefan Roese */
491*ff9112dfSStefan Roese /*
492*ff9112dfSStefan Roese * If some of the pups is >1 <3, check if we did it too
493*ff9112dfSStefan Roese * many times
494*ff9112dfSStefan Roese */
495*ff9112dfSStefan Roese if (counter_in_progress == 1) {
496*ff9112dfSStefan Roese /* Notify at least one Counter is >=1 and < 3 */
497*ff9112dfSStefan Roese if (repeat_max_cnt < RL_RETRY_COUNT) {
498*ff9112dfSStefan Roese repeat_max_cnt++;
499*ff9112dfSStefan Roese counter_in_progress = 1;
500*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - Counter is >=1 and <3\n");
501*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - So we will not increment the delay to see if locked again\n");
502*ff9112dfSStefan Roese } else {
503*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - repeat_max_cnt reached max so now we will increment the delay\n");
504*ff9112dfSStefan Roese counter_in_progress = 0;
505*ff9112dfSStefan Roese }
506*ff9112dfSStefan Roese }
507*ff9112dfSStefan Roese
508*ff9112dfSStefan Roese /*
509*ff9112dfSStefan Roese * Check some of the pups are in the middle of state machine
510*ff9112dfSStefan Roese * and don't increment the delays
511*ff9112dfSStefan Roese */
512*ff9112dfSStefan Roese if (!counter_in_progress && !all_locked) {
513*ff9112dfSStefan Roese int idx;
514*ff9112dfSStefan Roese
515*ff9112dfSStefan Roese idx = pup + ecc * ECC_BIT;
516*ff9112dfSStefan Roese
517*ff9112dfSStefan Roese repeat_max_cnt = 0;
518*ff9112dfSStefan Roese /* if 1:1 mode */
519*ff9112dfSStefan Roese if ((!ratio_2to1) && ((phase == 0) || (phase == 4)))
520*ff9112dfSStefan Roese ui_max_delay = MAX_DELAY_INV;
521*ff9112dfSStefan Roese else
522*ff9112dfSStefan Roese ui_max_delay = MAX_DELAY;
523*ff9112dfSStefan Roese
524*ff9112dfSStefan Roese /* Increment Delay */
525*ff9112dfSStefan Roese if (delay < ui_max_delay) {
526*ff9112dfSStefan Roese delay++;
527*ff9112dfSStefan Roese /*
528*ff9112dfSStefan Roese * Mark the last delay/pahse place for
529*ff9112dfSStefan Roese * window final place
530*ff9112dfSStefan Roese */
531*ff9112dfSStefan Roese if (delay == ui_max_delay) {
532*ff9112dfSStefan Roese if ((!ratio_2to1 && phase ==
533*ff9112dfSStefan Roese MAX_PHASE_RL_L_1TO1)
534*ff9112dfSStefan Roese || (ratio_2to1 && phase ==
535*ff9112dfSStefan Roese MAX_PHASE_RL_L_2TO1))
536*ff9112dfSStefan Roese final_delay = 1;
537*ff9112dfSStefan Roese }
538*ff9112dfSStefan Roese } else {
539*ff9112dfSStefan Roese /* Phase+CL Incrementation */
540*ff9112dfSStefan Roese delay = 0;
541*ff9112dfSStefan Roese
542*ff9112dfSStefan Roese if (!ratio_2to1) {
543*ff9112dfSStefan Roese /* 1:1 mode */
544*ff9112dfSStefan Roese if (first_octet_locked) {
545*ff9112dfSStefan Roese /* some Pup was Locked */
546*ff9112dfSStefan Roese if (phase < MAX_PHASE_RL_L_1TO1) {
547*ff9112dfSStefan Roese if (phase == 1) {
548*ff9112dfSStefan Roese phase = 4;
549*ff9112dfSStefan Roese } else {
550*ff9112dfSStefan Roese phase++;
551*ff9112dfSStefan Roese delay = MIN_DELAY_PHASE_1_LIMIT;
552*ff9112dfSStefan Roese }
553*ff9112dfSStefan Roese } else {
554*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n");
555*ff9112dfSStefan Roese DEBUG_RL_S("1)DDR3 - Read Leveling - ERROR - NOT all PUPs Locked n");
556*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_RD_LVL_RL_PUP_UNLOCK;
557*ff9112dfSStefan Roese }
558*ff9112dfSStefan Roese } else {
559*ff9112dfSStefan Roese /* NO Pup was Locked */
560*ff9112dfSStefan Roese if (phase < MAX_PHASE_RL_UL_1TO1) {
561*ff9112dfSStefan Roese phase++;
562*ff9112dfSStefan Roese delay =
563*ff9112dfSStefan Roese MIN_DELAY_PHASE_1_LIMIT;
564*ff9112dfSStefan Roese } else {
565*ff9112dfSStefan Roese phase = 0;
566*ff9112dfSStefan Roese }
567*ff9112dfSStefan Roese }
568*ff9112dfSStefan Roese } else {
569*ff9112dfSStefan Roese /* 2:1 mode */
570*ff9112dfSStefan Roese if (first_octet_locked) {
571*ff9112dfSStefan Roese /* some Pup was Locked */
572*ff9112dfSStefan Roese if (phase < MAX_PHASE_RL_L_2TO1) {
573*ff9112dfSStefan Roese phase++;
574*ff9112dfSStefan Roese } else {
575*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n");
576*ff9112dfSStefan Roese DEBUG_RL_S("2)DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n");
577*ff9112dfSStefan Roese for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc); pup++) {
578*ff9112dfSStefan Roese /* pup_num = Q or 1 for ECC */
579*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][S]
580*ff9112dfSStefan Roese == 0) {
581*ff9112dfSStefan Roese DEBUG_RL_C("Failed byte is = ",
582*ff9112dfSStefan Roese pup, 1);
583*ff9112dfSStefan Roese }
584*ff9112dfSStefan Roese }
585*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_RD_LVL_RL_PUP_UNLOCK;
586*ff9112dfSStefan Roese }
587*ff9112dfSStefan Roese } else {
588*ff9112dfSStefan Roese /* No Pup was Locked */
589*ff9112dfSStefan Roese if (phase < MAX_PHASE_RL_UL_2TO1)
590*ff9112dfSStefan Roese phase++;
591*ff9112dfSStefan Roese else
592*ff9112dfSStefan Roese phase = 0;
593*ff9112dfSStefan Roese }
594*ff9112dfSStefan Roese }
595*ff9112dfSStefan Roese
596*ff9112dfSStefan Roese /*
597*ff9112dfSStefan Roese * If we finished a full Phases cycle (so now
598*ff9112dfSStefan Roese * phase = 0, need to increment rd_sample_dly
599*ff9112dfSStefan Roese */
600*ff9112dfSStefan Roese if (phase == 0 && first_octet_locked == 0) {
601*ff9112dfSStefan Roese rd_sample_delay++;
602*ff9112dfSStefan Roese if (rd_sample_delay == 0x10) {
603*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n");
604*ff9112dfSStefan Roese DEBUG_RL_S("3)DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n");
605*ff9112dfSStefan Roese for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc); pup++) {
606*ff9112dfSStefan Roese /* pup_num = Q or 1 for ECC */
607*ff9112dfSStefan Roese if (dram_info->
608*ff9112dfSStefan Roese rl_val[cs][idx][S] == 0) {
609*ff9112dfSStefan Roese DEBUG_RL_C("Failed byte is = ",
610*ff9112dfSStefan Roese pup, 1);
611*ff9112dfSStefan Roese }
612*ff9112dfSStefan Roese }
613*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_RD_LVL_PUP_UNLOCK;
614*ff9112dfSStefan Roese }
615*ff9112dfSStefan Roese
616*ff9112dfSStefan Roese /* Set current rd_sample_delay */
617*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR);
618*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK
619*ff9112dfSStefan Roese << (REG_READ_DATA_SAMPLE_DELAYS_OFFS
620*ff9112dfSStefan Roese * cs));
621*ff9112dfSStefan Roese reg |= (rd_sample_delay <<
622*ff9112dfSStefan Roese (REG_READ_DATA_SAMPLE_DELAYS_OFFS *
623*ff9112dfSStefan Roese cs));
624*ff9112dfSStefan Roese reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR,
625*ff9112dfSStefan Roese reg);
626*ff9112dfSStefan Roese }
627*ff9112dfSStefan Roese
628*ff9112dfSStefan Roese /*
629*ff9112dfSStefan Roese * Set current rdReadyDelay according to the
630*ff9112dfSStefan Roese * hash table (Need to do this in every phase
631*ff9112dfSStefan Roese * change)
632*ff9112dfSStefan Roese */
633*ff9112dfSStefan Roese if (!ratio_2to1) {
634*ff9112dfSStefan Roese /* 1:1 mode */
635*ff9112dfSStefan Roese add = reg_read(REG_TRAINING_DEBUG_2_ADDR);
636*ff9112dfSStefan Roese switch (phase) {
637*ff9112dfSStefan Roese case 0:
638*ff9112dfSStefan Roese add = (add >>
639*ff9112dfSStefan Roese REG_TRAINING_DEBUG_2_OFFS);
640*ff9112dfSStefan Roese break;
641*ff9112dfSStefan Roese case 1:
642*ff9112dfSStefan Roese add = (add >>
643*ff9112dfSStefan Roese (REG_TRAINING_DEBUG_2_OFFS
644*ff9112dfSStefan Roese + 3));
645*ff9112dfSStefan Roese break;
646*ff9112dfSStefan Roese case 4:
647*ff9112dfSStefan Roese add = (add >>
648*ff9112dfSStefan Roese (REG_TRAINING_DEBUG_2_OFFS
649*ff9112dfSStefan Roese + 6));
650*ff9112dfSStefan Roese break;
651*ff9112dfSStefan Roese case 5:
652*ff9112dfSStefan Roese add = (add >>
653*ff9112dfSStefan Roese (REG_TRAINING_DEBUG_2_OFFS
654*ff9112dfSStefan Roese + 9));
655*ff9112dfSStefan Roese break;
656*ff9112dfSStefan Roese }
657*ff9112dfSStefan Roese add &= REG_TRAINING_DEBUG_2_MASK;
658*ff9112dfSStefan Roese } else {
659*ff9112dfSStefan Roese /* 2:1 mode */
660*ff9112dfSStefan Roese add = reg_read(REG_TRAINING_DEBUG_3_ADDR);
661*ff9112dfSStefan Roese add = (add >>
662*ff9112dfSStefan Roese (phase *
663*ff9112dfSStefan Roese REG_TRAINING_DEBUG_3_OFFS));
664*ff9112dfSStefan Roese add &= REG_TRAINING_DEBUG_3_MASK;
665*ff9112dfSStefan Roese }
666*ff9112dfSStefan Roese
667*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR);
668*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_READY_DELAYS_MASK <<
669*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
670*ff9112dfSStefan Roese reg |= ((rd_sample_delay + add) <<
671*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
672*ff9112dfSStefan Roese reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg);
673*ff9112dfSStefan Roese dram_info->rd_smpl_dly = rd_sample_delay;
674*ff9112dfSStefan Roese dram_info->rd_rdy_dly = rd_sample_delay + add;
675*ff9112dfSStefan Roese }
676*ff9112dfSStefan Roese
677*ff9112dfSStefan Roese /* Reset counters for pups with states<RD_STATE_COUNT */
678*ff9112dfSStefan Roese for (pup = 0; pup <
679*ff9112dfSStefan Roese (dram_info->num_of_std_pups * (1 - ecc) + ecc);
680*ff9112dfSStefan Roese pup++) {
681*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][C] < RL_RETRY_COUNT)
682*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][C] = 0;
683*ff9112dfSStefan Roese }
684*ff9112dfSStefan Roese }
685*ff9112dfSStefan Roese }
686*ff9112dfSStefan Roese
687*ff9112dfSStefan Roese phase_min = 10;
688*ff9112dfSStefan Roese
689*ff9112dfSStefan Roese for (pup = 0; pup < (dram_info->num_of_std_pups); pup++) {
690*ff9112dfSStefan Roese if (dram_info->rl_val[cs][pup][PS] < phase_min)
691*ff9112dfSStefan Roese phase_min = dram_info->rl_val[cs][pup][PS];
692*ff9112dfSStefan Roese }
693*ff9112dfSStefan Roese
694*ff9112dfSStefan Roese /*
695*ff9112dfSStefan Roese * Set current rdReadyDelay according to the hash table (Need to
696*ff9112dfSStefan Roese * do this in every phase change)
697*ff9112dfSStefan Roese */
698*ff9112dfSStefan Roese if (!ratio_2to1) {
699*ff9112dfSStefan Roese /* 1:1 mode */
700*ff9112dfSStefan Roese add = reg_read(REG_TRAINING_DEBUG_2_ADDR);
701*ff9112dfSStefan Roese switch (phase_min) {
702*ff9112dfSStefan Roese case 0:
703*ff9112dfSStefan Roese add = (add >> REG_TRAINING_DEBUG_2_OFFS);
704*ff9112dfSStefan Roese break;
705*ff9112dfSStefan Roese case 1:
706*ff9112dfSStefan Roese add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 3));
707*ff9112dfSStefan Roese break;
708*ff9112dfSStefan Roese case 4:
709*ff9112dfSStefan Roese add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 6));
710*ff9112dfSStefan Roese break;
711*ff9112dfSStefan Roese case 5:
712*ff9112dfSStefan Roese add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 9));
713*ff9112dfSStefan Roese break;
714*ff9112dfSStefan Roese }
715*ff9112dfSStefan Roese add &= REG_TRAINING_DEBUG_2_MASK;
716*ff9112dfSStefan Roese } else {
717*ff9112dfSStefan Roese /* 2:1 mode */
718*ff9112dfSStefan Roese add = reg_read(REG_TRAINING_DEBUG_3_ADDR);
719*ff9112dfSStefan Roese add = (add >> (phase_min * REG_TRAINING_DEBUG_3_OFFS));
720*ff9112dfSStefan Roese add &= REG_TRAINING_DEBUG_3_MASK;
721*ff9112dfSStefan Roese }
722*ff9112dfSStefan Roese
723*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR);
724*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_READY_DELAYS_MASK <<
725*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
726*ff9112dfSStefan Roese reg |= ((rd_sample_delay + add) << (REG_READ_DATA_READY_DELAYS_OFFS * cs));
727*ff9112dfSStefan Roese reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg);
728*ff9112dfSStefan Roese dram_info->rd_rdy_dly = rd_sample_delay + add;
729*ff9112dfSStefan Roese
730*ff9112dfSStefan Roese for (cs = 0; cs < dram_info->num_cs; cs++) {
731*ff9112dfSStefan Roese for (pup = 0; pup < dram_info->num_of_total_pups; pup++) {
732*ff9112dfSStefan Roese reg = ddr3_read_pup_reg(PUP_RL_MODE + 0x1, cs, pup);
733*ff9112dfSStefan Roese dram_info->rl_val[cs][pup][DQS] = (reg & 0x3F);
734*ff9112dfSStefan Roese }
735*ff9112dfSStefan Roese }
736*ff9112dfSStefan Roese
737*ff9112dfSStefan Roese return MV_OK;
738*ff9112dfSStefan Roese }
739*ff9112dfSStefan Roese
740*ff9112dfSStefan Roese #else
741*ff9112dfSStefan Roese
742*ff9112dfSStefan Roese /*
743*ff9112dfSStefan Roese * Name: ddr3_read_leveling_single_cs_window_mode
744*ff9112dfSStefan Roese * Desc: Execute Read leveling for single Chip select
745*ff9112dfSStefan Roese * Args: cs - current chip select
746*ff9112dfSStefan Roese * freq - current sequence frequency
747*ff9112dfSStefan Roese * ecc - ecc iteration indication
748*ff9112dfSStefan Roese * dram_info - main struct
749*ff9112dfSStefan Roese * Notes:
750*ff9112dfSStefan Roese * Returns: MV_OK if success, MV_FAIL if fail.
751*ff9112dfSStefan Roese */
ddr3_read_leveling_single_cs_window_mode(u32 cs,u32 freq,int ratio_2to1,u32 ecc,MV_DRAM_INFO * dram_info)752*ff9112dfSStefan Roese static int ddr3_read_leveling_single_cs_window_mode(u32 cs, u32 freq,
753*ff9112dfSStefan Roese int ratio_2to1, u32 ecc,
754*ff9112dfSStefan Roese MV_DRAM_INFO *dram_info)
755*ff9112dfSStefan Roese {
756*ff9112dfSStefan Roese u32 reg, delay, phase, sum, pup, rd_sample_delay, add, locked_pups,
757*ff9112dfSStefan Roese repeat_max_cnt, sdram_offset, final_sum, locked_sum;
758*ff9112dfSStefan Roese u32 delay_s, delay_e, tmp, phase_min, ui_max_delay;
759*ff9112dfSStefan Roese int all_locked, first_octet_locked, counter_in_progress;
760*ff9112dfSStefan Roese int final_delay = 0;
761*ff9112dfSStefan Roese
762*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - Single CS - ", (u32) cs, 1);
763*ff9112dfSStefan Roese
764*ff9112dfSStefan Roese /* Init values */
765*ff9112dfSStefan Roese phase = 0;
766*ff9112dfSStefan Roese delay = 0;
767*ff9112dfSStefan Roese rd_sample_delay = dram_info->cl;
768*ff9112dfSStefan Roese all_locked = 0;
769*ff9112dfSStefan Roese first_octet_locked = 0;
770*ff9112dfSStefan Roese repeat_max_cnt = 0;
771*ff9112dfSStefan Roese sum = 0;
772*ff9112dfSStefan Roese final_sum = 0;
773*ff9112dfSStefan Roese locked_sum = 0;
774*ff9112dfSStefan Roese
775*ff9112dfSStefan Roese for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc);
776*ff9112dfSStefan Roese pup++)
777*ff9112dfSStefan Roese dram_info->rl_val[cs][pup + ecc * ECC_BIT][S] = 0;
778*ff9112dfSStefan Roese
779*ff9112dfSStefan Roese /* Main loop */
780*ff9112dfSStefan Roese while (!all_locked) {
781*ff9112dfSStefan Roese counter_in_progress = 0;
782*ff9112dfSStefan Roese
783*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - RdSmplDly = ");
784*ff9112dfSStefan Roese DEBUG_RL_FULL_D(rd_sample_delay, 2);
785*ff9112dfSStefan Roese DEBUG_RL_FULL_S(", RdRdyDly = ");
786*ff9112dfSStefan Roese DEBUG_RL_FULL_D(dram_info->rd_rdy_dly, 2);
787*ff9112dfSStefan Roese DEBUG_RL_FULL_S(", Phase = ");
788*ff9112dfSStefan Roese DEBUG_RL_FULL_D(phase, 1);
789*ff9112dfSStefan Roese DEBUG_RL_FULL_S(", Delay = ");
790*ff9112dfSStefan Roese DEBUG_RL_FULL_D(delay, 2);
791*ff9112dfSStefan Roese DEBUG_RL_FULL_S("\n");
792*ff9112dfSStefan Roese
793*ff9112dfSStefan Roese /*
794*ff9112dfSStefan Roese * Broadcast to all PUPs current RL delays: DQS phase,leveling
795*ff9112dfSStefan Roese * delay
796*ff9112dfSStefan Roese */
797*ff9112dfSStefan Roese ddr3_write_pup_reg(PUP_RL_MODE, cs, PUP_BC, phase, delay);
798*ff9112dfSStefan Roese
799*ff9112dfSStefan Roese /* Reset PHY read FIFO */
800*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
801*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
802*ff9112dfSStefan Roese /* 0x15B8 - Training SW 2 Register */
803*ff9112dfSStefan Roese reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
804*ff9112dfSStefan Roese
805*ff9112dfSStefan Roese do {
806*ff9112dfSStefan Roese reg = (reg_read(REG_DRAM_TRAINING_2_ADDR)) &
807*ff9112dfSStefan Roese (1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
808*ff9112dfSStefan Roese } while (reg); /* Wait for '0' */
809*ff9112dfSStefan Roese
810*ff9112dfSStefan Roese /* Read pattern from SDRAM */
811*ff9112dfSStefan Roese sdram_offset = cs * (SDRAM_CS_SIZE + 1) + SDRAM_RL_OFFS;
812*ff9112dfSStefan Roese locked_pups = 0;
813*ff9112dfSStefan Roese if (MV_OK !=
814*ff9112dfSStefan Roese ddr3_sdram_compare(dram_info, 0xFF, &locked_pups,
815*ff9112dfSStefan Roese rl_pattern, LEN_STD_PATTERN,
816*ff9112dfSStefan Roese sdram_offset, 0, 0, NULL, 0))
817*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_RD_LVL_WIN_PATTERN;
818*ff9112dfSStefan Roese
819*ff9112dfSStefan Roese /* Octet evaluation */
820*ff9112dfSStefan Roese for (pup = 0; pup < (dram_info->num_of_std_pups *
821*ff9112dfSStefan Roese (1 - ecc) + ecc); pup++) {
822*ff9112dfSStefan Roese /* pup_num = Q or 1 for ECC */
823*ff9112dfSStefan Roese int idx;
824*ff9112dfSStefan Roese
825*ff9112dfSStefan Roese idx = pup + ecc * ECC_BIT;
826*ff9112dfSStefan Roese
827*ff9112dfSStefan Roese /* Check Overrun */
828*ff9112dfSStefan Roese if (!((reg_read(REG_DRAM_TRAINING_2_ADDR) >>
829*ff9112dfSStefan Roese (REG_DRAM_TRAINING_2_OVERRUN_OFFS +
830*ff9112dfSStefan Roese pup)) & 0x1)) {
831*ff9112dfSStefan Roese /* If no OverRun */
832*ff9112dfSStefan Roese
833*ff9112dfSStefan Roese /* Inside the window */
834*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][S] == RL_WINDOW_STATE) {
835*ff9112dfSStefan Roese /*
836*ff9112dfSStefan Roese * Match expected value ? - Update
837*ff9112dfSStefan Roese * State Machine
838*ff9112dfSStefan Roese */
839*ff9112dfSStefan Roese if (((~locked_pups >> pup) & 0x1)
840*ff9112dfSStefan Roese && (final_delay == 0)) {
841*ff9112dfSStefan Roese /* Match - Still inside the Window */
842*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got another match inside the window for pup: ",
843*ff9112dfSStefan Roese (u32)pup, 1);
844*ff9112dfSStefan Roese
845*ff9112dfSStefan Roese } else {
846*ff9112dfSStefan Roese /* We got fail -> this is the end of the window */
847*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][DE] = delay;
848*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][PE] = phase;
849*ff9112dfSStefan Roese /* Go to Final State */
850*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][S]++;
851*ff9112dfSStefan Roese final_sum++;
852*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - We finished the window for pup: ",
853*ff9112dfSStefan Roese (u32)pup, 1);
854*ff9112dfSStefan Roese }
855*ff9112dfSStefan Roese
856*ff9112dfSStefan Roese /* Before the start of the window */
857*ff9112dfSStefan Roese } else if (dram_info->rl_val[cs][idx][S] ==
858*ff9112dfSStefan Roese RL_UNLOCK_STATE) {
859*ff9112dfSStefan Roese /* Must be RL_UNLOCK_STATE */
860*ff9112dfSStefan Roese /*
861*ff9112dfSStefan Roese * Match expected value ? - Update
862*ff9112dfSStefan Roese * State Machine
863*ff9112dfSStefan Roese */
864*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][C] <
865*ff9112dfSStefan Roese RL_RETRY_COUNT) {
866*ff9112dfSStefan Roese if (((~locked_pups >> pup) & 0x1)) {
867*ff9112dfSStefan Roese /* Match */
868*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - We have no overrun and a match on pup: ",
869*ff9112dfSStefan Roese (u32)pup, 1);
870*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][C]++;
871*ff9112dfSStefan Roese
872*ff9112dfSStefan Roese /* If pup got to last state - lock the delays */
873*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][C] ==
874*ff9112dfSStefan Roese RL_RETRY_COUNT) {
875*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][C] = 0;
876*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][DS] =
877*ff9112dfSStefan Roese delay;
878*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][PS] =
879*ff9112dfSStefan Roese phase;
880*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][S]++; /* Go to Window State */
881*ff9112dfSStefan Roese locked_sum++;
882*ff9112dfSStefan Roese /* Will count the pups that got locked */
883*ff9112dfSStefan Roese
884*ff9112dfSStefan Roese /* IF First lock - need to lock delays */
885*ff9112dfSStefan Roese if (first_octet_locked == 0) {
886*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got first lock on pup: ",
887*ff9112dfSStefan Roese (u32)pup, 1);
888*ff9112dfSStefan Roese first_octet_locked
889*ff9112dfSStefan Roese =
890*ff9112dfSStefan Roese 1;
891*ff9112dfSStefan Roese }
892*ff9112dfSStefan Roese }
893*ff9112dfSStefan Roese
894*ff9112dfSStefan Roese /* if pup is in not in final state but there was match - dont increment counter */
895*ff9112dfSStefan Roese else {
896*ff9112dfSStefan Roese counter_in_progress
897*ff9112dfSStefan Roese = 1;
898*ff9112dfSStefan Roese }
899*ff9112dfSStefan Roese }
900*ff9112dfSStefan Roese }
901*ff9112dfSStefan Roese }
902*ff9112dfSStefan Roese } else {
903*ff9112dfSStefan Roese DEBUG_RL_FULL_C("DDR3 - Read Leveling - We got overrun on pup: ",
904*ff9112dfSStefan Roese (u32)pup, 1);
905*ff9112dfSStefan Roese counter_in_progress = 1;
906*ff9112dfSStefan Roese }
907*ff9112dfSStefan Roese }
908*ff9112dfSStefan Roese
909*ff9112dfSStefan Roese if (final_sum == (dram_info->num_of_std_pups * (1 - ecc) + ecc)) {
910*ff9112dfSStefan Roese all_locked = 1;
911*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - Single Cs - All pups locked\n");
912*ff9112dfSStefan Roese }
913*ff9112dfSStefan Roese
914*ff9112dfSStefan Roese /*
915*ff9112dfSStefan Roese * This is a fix for unstable condition where pups are
916*ff9112dfSStefan Roese * toggling between match and no match
917*ff9112dfSStefan Roese */
918*ff9112dfSStefan Roese /*
919*ff9112dfSStefan Roese * If some of the pups is >1 <3, check if we did it too many
920*ff9112dfSStefan Roese * times
921*ff9112dfSStefan Roese */
922*ff9112dfSStefan Roese if (counter_in_progress == 1) {
923*ff9112dfSStefan Roese if (repeat_max_cnt < RL_RETRY_COUNT) {
924*ff9112dfSStefan Roese /* Notify at least one Counter is >=1 and < 3 */
925*ff9112dfSStefan Roese repeat_max_cnt++;
926*ff9112dfSStefan Roese counter_in_progress = 1;
927*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - Counter is >=1 and <3\n");
928*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - So we will not increment the delay to see if locked again\n");
929*ff9112dfSStefan Roese } else {
930*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - repeat_max_cnt reached max so now we will increment the delay\n");
931*ff9112dfSStefan Roese counter_in_progress = 0;
932*ff9112dfSStefan Roese }
933*ff9112dfSStefan Roese }
934*ff9112dfSStefan Roese
935*ff9112dfSStefan Roese /*
936*ff9112dfSStefan Roese * Check some of the pups are in the middle of state machine
937*ff9112dfSStefan Roese * and don't increment the delays
938*ff9112dfSStefan Roese */
939*ff9112dfSStefan Roese if (!counter_in_progress && !all_locked) {
940*ff9112dfSStefan Roese repeat_max_cnt = 0;
941*ff9112dfSStefan Roese if (!ratio_2to1)
942*ff9112dfSStefan Roese ui_max_delay = MAX_DELAY_INV;
943*ff9112dfSStefan Roese else
944*ff9112dfSStefan Roese ui_max_delay = MAX_DELAY;
945*ff9112dfSStefan Roese
946*ff9112dfSStefan Roese /* Increment Delay */
947*ff9112dfSStefan Roese if (delay < ui_max_delay) {
948*ff9112dfSStefan Roese /* Delay Incrementation */
949*ff9112dfSStefan Roese delay++;
950*ff9112dfSStefan Roese if (delay == ui_max_delay) {
951*ff9112dfSStefan Roese /*
952*ff9112dfSStefan Roese * Mark the last delay/pahse place
953*ff9112dfSStefan Roese * for window final place
954*ff9112dfSStefan Roese */
955*ff9112dfSStefan Roese if ((!ratio_2to1
956*ff9112dfSStefan Roese && phase == MAX_PHASE_RL_L_1TO1)
957*ff9112dfSStefan Roese || (ratio_2to1
958*ff9112dfSStefan Roese && phase ==
959*ff9112dfSStefan Roese MAX_PHASE_RL_L_2TO1))
960*ff9112dfSStefan Roese final_delay = 1;
961*ff9112dfSStefan Roese }
962*ff9112dfSStefan Roese } else {
963*ff9112dfSStefan Roese /* Phase+CL Incrementation */
964*ff9112dfSStefan Roese delay = 0;
965*ff9112dfSStefan Roese if (!ratio_2to1) {
966*ff9112dfSStefan Roese /* 1:1 mode */
967*ff9112dfSStefan Roese if (first_octet_locked) {
968*ff9112dfSStefan Roese /* some pupet was Locked */
969*ff9112dfSStefan Roese if (phase < MAX_PHASE_RL_L_1TO1) {
970*ff9112dfSStefan Roese #ifdef RL_WINDOW_WA
971*ff9112dfSStefan Roese if (phase == 0)
972*ff9112dfSStefan Roese #else
973*ff9112dfSStefan Roese if (phase == 1)
974*ff9112dfSStefan Roese #endif
975*ff9112dfSStefan Roese phase = 4;
976*ff9112dfSStefan Roese else
977*ff9112dfSStefan Roese phase++;
978*ff9112dfSStefan Roese } else {
979*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n");
980*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_RD_LVL_WIN_PUP_UNLOCK;
981*ff9112dfSStefan Roese }
982*ff9112dfSStefan Roese } else {
983*ff9112dfSStefan Roese /* No Pup was Locked */
984*ff9112dfSStefan Roese if (phase < MAX_PHASE_RL_UL_1TO1) {
985*ff9112dfSStefan Roese #ifdef RL_WINDOW_WA
986*ff9112dfSStefan Roese if (phase == 0)
987*ff9112dfSStefan Roese phase = 4;
988*ff9112dfSStefan Roese #else
989*ff9112dfSStefan Roese phase++;
990*ff9112dfSStefan Roese #endif
991*ff9112dfSStefan Roese } else
992*ff9112dfSStefan Roese phase = 0;
993*ff9112dfSStefan Roese }
994*ff9112dfSStefan Roese } else {
995*ff9112dfSStefan Roese /* 2:1 mode */
996*ff9112dfSStefan Roese if (first_octet_locked) {
997*ff9112dfSStefan Roese /* Some Pup was Locked */
998*ff9112dfSStefan Roese if (phase < MAX_PHASE_RL_L_2TO1) {
999*ff9112dfSStefan Roese phase++;
1000*ff9112dfSStefan Roese } else {
1001*ff9112dfSStefan Roese DEBUG_RL_FULL_S("DDR3 - Read Leveling - ERROR - NOT all PUPs Locked\n");
1002*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_RD_LVL_WIN_PUP_UNLOCK;
1003*ff9112dfSStefan Roese }
1004*ff9112dfSStefan Roese } else {
1005*ff9112dfSStefan Roese /* No Pup was Locked */
1006*ff9112dfSStefan Roese if (phase < MAX_PHASE_RL_UL_2TO1)
1007*ff9112dfSStefan Roese phase++;
1008*ff9112dfSStefan Roese else
1009*ff9112dfSStefan Roese phase = 0;
1010*ff9112dfSStefan Roese }
1011*ff9112dfSStefan Roese }
1012*ff9112dfSStefan Roese
1013*ff9112dfSStefan Roese /*
1014*ff9112dfSStefan Roese * If we finished a full Phases cycle (so
1015*ff9112dfSStefan Roese * now phase = 0, need to increment
1016*ff9112dfSStefan Roese * rd_sample_dly
1017*ff9112dfSStefan Roese */
1018*ff9112dfSStefan Roese if (phase == 0 && first_octet_locked == 0) {
1019*ff9112dfSStefan Roese rd_sample_delay++;
1020*ff9112dfSStefan Roese
1021*ff9112dfSStefan Roese /* Set current rd_sample_delay */
1022*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_SAMPLE_DELAYS_ADDR);
1023*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_SAMPLE_DELAYS_MASK <<
1024*ff9112dfSStefan Roese (REG_READ_DATA_SAMPLE_DELAYS_OFFS
1025*ff9112dfSStefan Roese * cs));
1026*ff9112dfSStefan Roese reg |= (rd_sample_delay <<
1027*ff9112dfSStefan Roese (REG_READ_DATA_SAMPLE_DELAYS_OFFS *
1028*ff9112dfSStefan Roese cs));
1029*ff9112dfSStefan Roese reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR,
1030*ff9112dfSStefan Roese reg);
1031*ff9112dfSStefan Roese }
1032*ff9112dfSStefan Roese
1033*ff9112dfSStefan Roese /*
1034*ff9112dfSStefan Roese * Set current rdReadyDelay according to the
1035*ff9112dfSStefan Roese * hash table (Need to do this in every phase
1036*ff9112dfSStefan Roese * change)
1037*ff9112dfSStefan Roese */
1038*ff9112dfSStefan Roese if (!ratio_2to1) {
1039*ff9112dfSStefan Roese /* 1:1 mode */
1040*ff9112dfSStefan Roese add = reg_read(REG_TRAINING_DEBUG_2_ADDR);
1041*ff9112dfSStefan Roese switch (phase) {
1042*ff9112dfSStefan Roese case 0:
1043*ff9112dfSStefan Roese add = add >>
1044*ff9112dfSStefan Roese REG_TRAINING_DEBUG_2_OFFS;
1045*ff9112dfSStefan Roese break;
1046*ff9112dfSStefan Roese case 1:
1047*ff9112dfSStefan Roese add = add >>
1048*ff9112dfSStefan Roese (REG_TRAINING_DEBUG_2_OFFS
1049*ff9112dfSStefan Roese + 3);
1050*ff9112dfSStefan Roese break;
1051*ff9112dfSStefan Roese case 4:
1052*ff9112dfSStefan Roese add = add >>
1053*ff9112dfSStefan Roese (REG_TRAINING_DEBUG_2_OFFS
1054*ff9112dfSStefan Roese + 6);
1055*ff9112dfSStefan Roese break;
1056*ff9112dfSStefan Roese case 5:
1057*ff9112dfSStefan Roese add = add >>
1058*ff9112dfSStefan Roese (REG_TRAINING_DEBUG_2_OFFS
1059*ff9112dfSStefan Roese + 9);
1060*ff9112dfSStefan Roese break;
1061*ff9112dfSStefan Roese }
1062*ff9112dfSStefan Roese } else {
1063*ff9112dfSStefan Roese /* 2:1 mode */
1064*ff9112dfSStefan Roese add = reg_read(REG_TRAINING_DEBUG_3_ADDR);
1065*ff9112dfSStefan Roese add = (add >> phase *
1066*ff9112dfSStefan Roese REG_TRAINING_DEBUG_3_OFFS);
1067*ff9112dfSStefan Roese }
1068*ff9112dfSStefan Roese add &= REG_TRAINING_DEBUG_2_MASK;
1069*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR);
1070*ff9112dfSStefan Roese reg &= ~(REG_READ_DATA_READY_DELAYS_MASK <<
1071*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
1072*ff9112dfSStefan Roese reg |= ((rd_sample_delay + add) <<
1073*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
1074*ff9112dfSStefan Roese reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg);
1075*ff9112dfSStefan Roese dram_info->rd_smpl_dly = rd_sample_delay;
1076*ff9112dfSStefan Roese dram_info->rd_rdy_dly = rd_sample_delay + add;
1077*ff9112dfSStefan Roese }
1078*ff9112dfSStefan Roese
1079*ff9112dfSStefan Roese /* Reset counters for pups with states<RD_STATE_COUNT */
1080*ff9112dfSStefan Roese for (pup = 0;
1081*ff9112dfSStefan Roese pup <
1082*ff9112dfSStefan Roese (dram_info->num_of_std_pups * (1 - ecc) + ecc);
1083*ff9112dfSStefan Roese pup++) {
1084*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][C] < RL_RETRY_COUNT)
1085*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][C] = 0;
1086*ff9112dfSStefan Roese }
1087*ff9112dfSStefan Roese }
1088*ff9112dfSStefan Roese }
1089*ff9112dfSStefan Roese
1090*ff9112dfSStefan Roese phase_min = 10;
1091*ff9112dfSStefan Roese
1092*ff9112dfSStefan Roese for (pup = 0; pup < (dram_info->num_of_std_pups); pup++) {
1093*ff9112dfSStefan Roese DEBUG_RL_S("DDR3 - Read Leveling - Window info - PUP: ");
1094*ff9112dfSStefan Roese DEBUG_RL_D((u32) pup, 1);
1095*ff9112dfSStefan Roese DEBUG_RL_S(", PS: ");
1096*ff9112dfSStefan Roese DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][PS], 1);
1097*ff9112dfSStefan Roese DEBUG_RL_S(", DS: ");
1098*ff9112dfSStefan Roese DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][DS], 2);
1099*ff9112dfSStefan Roese DEBUG_RL_S(", PE: ");
1100*ff9112dfSStefan Roese DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][PE], 1);
1101*ff9112dfSStefan Roese DEBUG_RL_S(", DE: ");
1102*ff9112dfSStefan Roese DEBUG_RL_D((u32) dram_info->rl_val[cs][pup][DE], 2);
1103*ff9112dfSStefan Roese DEBUG_RL_S("\n");
1104*ff9112dfSStefan Roese }
1105*ff9112dfSStefan Roese
1106*ff9112dfSStefan Roese /* Find center of the window procedure */
1107*ff9112dfSStefan Roese for (pup = 0; pup < (dram_info->num_of_std_pups * (1 - ecc) + ecc);
1108*ff9112dfSStefan Roese pup++) {
1109*ff9112dfSStefan Roese #ifdef RL_WINDOW_WA
1110*ff9112dfSStefan Roese if (!ratio_2to1) { /* 1:1 mode */
1111*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][PS] == 4)
1112*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][PS] = 1;
1113*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][PE] == 4)
1114*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][PE] = 1;
1115*ff9112dfSStefan Roese
1116*ff9112dfSStefan Roese delay_s = dram_info->rl_val[cs][idx][PS] *
1117*ff9112dfSStefan Roese MAX_DELAY_INV + dram_info->rl_val[cs][idx][DS];
1118*ff9112dfSStefan Roese delay_e = dram_info->rl_val[cs][idx][PE] *
1119*ff9112dfSStefan Roese MAX_DELAY_INV + dram_info->rl_val[cs][idx][DE];
1120*ff9112dfSStefan Roese
1121*ff9112dfSStefan Roese tmp = (delay_e - delay_s) / 2 + delay_s;
1122*ff9112dfSStefan Roese phase = tmp / MAX_DELAY_INV;
1123*ff9112dfSStefan Roese if (phase == 1) /* 1:1 mode */
1124*ff9112dfSStefan Roese phase = 4;
1125*ff9112dfSStefan Roese
1126*ff9112dfSStefan Roese if (phase < phase_min) /* for the read ready delay */
1127*ff9112dfSStefan Roese phase_min = phase;
1128*ff9112dfSStefan Roese
1129*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][P] = phase;
1130*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][D] = tmp % MAX_DELAY_INV;
1131*ff9112dfSStefan Roese
1132*ff9112dfSStefan Roese } else {
1133*ff9112dfSStefan Roese delay_s = dram_info->rl_val[cs][idx][PS] *
1134*ff9112dfSStefan Roese MAX_DELAY + dram_info->rl_val[cs][idx][DS];
1135*ff9112dfSStefan Roese delay_e = dram_info->rl_val[cs][idx][PE] *
1136*ff9112dfSStefan Roese MAX_DELAY + dram_info->rl_val[cs][idx][DE];
1137*ff9112dfSStefan Roese
1138*ff9112dfSStefan Roese tmp = (delay_e - delay_s) / 2 + delay_s;
1139*ff9112dfSStefan Roese phase = tmp / MAX_DELAY;
1140*ff9112dfSStefan Roese
1141*ff9112dfSStefan Roese if (phase < phase_min) /* for the read ready delay */
1142*ff9112dfSStefan Roese phase_min = phase;
1143*ff9112dfSStefan Roese
1144*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][P] = phase;
1145*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][D] = tmp % MAX_DELAY;
1146*ff9112dfSStefan Roese }
1147*ff9112dfSStefan Roese #else
1148*ff9112dfSStefan Roese if (!ratio_2to1) { /* 1:1 mode */
1149*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][PS] > 1)
1150*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][PS] -= 2;
1151*ff9112dfSStefan Roese if (dram_info->rl_val[cs][idx][PE] > 1)
1152*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][PE] -= 2;
1153*ff9112dfSStefan Roese }
1154*ff9112dfSStefan Roese
1155*ff9112dfSStefan Roese delay_s = dram_info->rl_val[cs][idx][PS] * MAX_DELAY +
1156*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][DS];
1157*ff9112dfSStefan Roese delay_e = dram_info->rl_val[cs][idx][PE] * MAX_DELAY +
1158*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][DE];
1159*ff9112dfSStefan Roese
1160*ff9112dfSStefan Roese tmp = (delay_e - delay_s) / 2 + delay_s;
1161*ff9112dfSStefan Roese phase = tmp / MAX_DELAY;
1162*ff9112dfSStefan Roese if (!ratio_2to1 && phase > 1) /* 1:1 mode */
1163*ff9112dfSStefan Roese phase += 2;
1164*ff9112dfSStefan Roese
1165*ff9112dfSStefan Roese if (phase < phase_min) /* for the read ready delay */
1166*ff9112dfSStefan Roese phase_min = phase;
1167*ff9112dfSStefan Roese
1168*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][P] = phase;
1169*ff9112dfSStefan Roese dram_info->rl_val[cs][idx][D] = tmp % MAX_DELAY;
1170*ff9112dfSStefan Roese #endif
1171*ff9112dfSStefan Roese }
1172*ff9112dfSStefan Roese
1173*ff9112dfSStefan Roese /* Set current rdReadyDelay according to the hash table (Need to do this in every phase change) */
1174*ff9112dfSStefan Roese if (!ratio_2to1) { /* 1:1 mode */
1175*ff9112dfSStefan Roese add = reg_read(REG_TRAINING_DEBUG_2_ADDR);
1176*ff9112dfSStefan Roese switch (phase_min) {
1177*ff9112dfSStefan Roese case 0:
1178*ff9112dfSStefan Roese add = (add >> REG_TRAINING_DEBUG_2_OFFS);
1179*ff9112dfSStefan Roese break;
1180*ff9112dfSStefan Roese case 1:
1181*ff9112dfSStefan Roese add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 3));
1182*ff9112dfSStefan Roese break;
1183*ff9112dfSStefan Roese case 4:
1184*ff9112dfSStefan Roese add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 6));
1185*ff9112dfSStefan Roese break;
1186*ff9112dfSStefan Roese case 5:
1187*ff9112dfSStefan Roese add = (add >> (REG_TRAINING_DEBUG_2_OFFS + 9));
1188*ff9112dfSStefan Roese break;
1189*ff9112dfSStefan Roese }
1190*ff9112dfSStefan Roese } else { /* 2:1 mode */
1191*ff9112dfSStefan Roese add = reg_read(REG_TRAINING_DEBUG_3_ADDR);
1192*ff9112dfSStefan Roese add = (add >> phase_min * REG_TRAINING_DEBUG_3_OFFS);
1193*ff9112dfSStefan Roese }
1194*ff9112dfSStefan Roese
1195*ff9112dfSStefan Roese add &= REG_TRAINING_DEBUG_2_MASK;
1196*ff9112dfSStefan Roese reg = reg_read(REG_READ_DATA_READY_DELAYS_ADDR);
1197*ff9112dfSStefan Roese reg &=
1198*ff9112dfSStefan Roese ~(REG_READ_DATA_READY_DELAYS_MASK <<
1199*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
1200*ff9112dfSStefan Roese reg |=
1201*ff9112dfSStefan Roese ((rd_sample_delay + add) << (REG_READ_DATA_READY_DELAYS_OFFS * cs));
1202*ff9112dfSStefan Roese reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg);
1203*ff9112dfSStefan Roese dram_info->rd_rdy_dly = rd_sample_delay + add;
1204*ff9112dfSStefan Roese
1205*ff9112dfSStefan Roese for (cs = 0; cs < dram_info->num_cs; cs++) {
1206*ff9112dfSStefan Roese for (pup = 0; pup < dram_info->num_of_total_pups; pup++) {
1207*ff9112dfSStefan Roese reg = ddr3_read_pup_reg(PUP_RL_MODE + 0x1, cs, pup);
1208*ff9112dfSStefan Roese dram_info->rl_val[cs][pup][DQS] = (reg & 0x3F);
1209*ff9112dfSStefan Roese }
1210*ff9112dfSStefan Roese }
1211*ff9112dfSStefan Roese
1212*ff9112dfSStefan Roese return MV_OK;
1213*ff9112dfSStefan Roese }
1214*ff9112dfSStefan Roese #endif
1215