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