xref: /rk3399_rockchip-uboot/drivers/ddr/marvell/axp/ddr3_read_leveling.c (revision 3c9cc70d7153da442575112d9a2643eecd17d534)
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