1*f1df9364SStefan Roese /*
2*f1df9364SStefan Roese * Copyright (C) Marvell International Ltd. and its affiliates
3*f1df9364SStefan Roese *
4*f1df9364SStefan Roese * SPDX-License-Identifier: GPL-2.0
5*f1df9364SStefan Roese */
6*f1df9364SStefan Roese
7*f1df9364SStefan Roese #include <common.h>
8*f1df9364SStefan Roese #include <spl.h>
9*f1df9364SStefan Roese #include <asm/io.h>
10*f1df9364SStefan Roese #include <asm/arch/cpu.h>
11*f1df9364SStefan Roese #include <asm/arch/soc.h>
12*f1df9364SStefan Roese
13*f1df9364SStefan Roese #include "ddr3_init.h"
14*f1df9364SStefan Roese
15*f1df9364SStefan Roese #define WL_ITERATION_NUM 10
16*f1df9364SStefan Roese #define ONE_CLOCK_ERROR_SHIFT 2
17*f1df9364SStefan Roese #define ALIGN_ERROR_SHIFT -2
18*f1df9364SStefan Roese
19*f1df9364SStefan Roese static u32 pup_mask_table[] = {
20*f1df9364SStefan Roese 0x000000ff,
21*f1df9364SStefan Roese 0x0000ff00,
22*f1df9364SStefan Roese 0x00ff0000,
23*f1df9364SStefan Roese 0xff000000
24*f1df9364SStefan Roese };
25*f1df9364SStefan Roese
26*f1df9364SStefan Roese static struct write_supp_result wr_supp_res[MAX_INTERFACE_NUM][MAX_BUS_NUM];
27*f1df9364SStefan Roese
28*f1df9364SStefan Roese static int ddr3_tip_dynamic_write_leveling_seq(u32 dev_num);
29*f1df9364SStefan Roese static int ddr3_tip_dynamic_read_leveling_seq(u32 dev_num);
30*f1df9364SStefan Roese static int ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num);
31*f1df9364SStefan Roese static int ddr3_tip_wl_supp_align_err_shift(u32 dev_num, u32 if_id, u32 bus_id,
32*f1df9364SStefan Roese u32 bus_id_delta);
33*f1df9364SStefan Roese static int ddr3_tip_wl_supp_align_phase_shift(u32 dev_num, u32 if_id,
34*f1df9364SStefan Roese u32 bus_id, u32 offset,
35*f1df9364SStefan Roese u32 bus_id_delta);
36*f1df9364SStefan Roese static int ddr3_tip_xsb_compare_test(u32 dev_num, u32 if_id, u32 bus_id,
37*f1df9364SStefan Roese u32 edge_offset, u32 bus_id_delta);
38*f1df9364SStefan Roese static int ddr3_tip_wl_supp_one_clk_err_shift(u32 dev_num, u32 if_id,
39*f1df9364SStefan Roese u32 bus_id, u32 bus_id_delta);
40*f1df9364SStefan Roese
hws_ddr3_tip_max_cs_get(void)41*f1df9364SStefan Roese u32 hws_ddr3_tip_max_cs_get(void)
42*f1df9364SStefan Roese {
43*f1df9364SStefan Roese u32 c_cs;
44*f1df9364SStefan Roese static u32 max_cs;
45*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
46*f1df9364SStefan Roese
47*f1df9364SStefan Roese if (!max_cs) {
48*f1df9364SStefan Roese for (c_cs = 0; c_cs < NUM_OF_CS; c_cs++) {
49*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->
50*f1df9364SStefan Roese interface_params[0].as_bus_params[0].
51*f1df9364SStefan Roese cs_bitmask, c_cs);
52*f1df9364SStefan Roese max_cs++;
53*f1df9364SStefan Roese }
54*f1df9364SStefan Roese }
55*f1df9364SStefan Roese
56*f1df9364SStefan Roese return max_cs;
57*f1df9364SStefan Roese }
58*f1df9364SStefan Roese
59*f1df9364SStefan Roese /*****************************************************************************
60*f1df9364SStefan Roese Dynamic read leveling
61*f1df9364SStefan Roese ******************************************************************************/
ddr3_tip_dynamic_read_leveling(u32 dev_num,u32 freq)62*f1df9364SStefan Roese int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
63*f1df9364SStefan Roese {
64*f1df9364SStefan Roese u32 data, mask;
65*f1df9364SStefan Roese u32 max_cs = hws_ddr3_tip_max_cs_get();
66*f1df9364SStefan Roese u32 bus_num, if_id, cl_val;
67*f1df9364SStefan Roese enum hws_speed_bin speed_bin_index;
68*f1df9364SStefan Roese /* save current CS value */
69*f1df9364SStefan Roese u32 cs_enable_reg_val[MAX_INTERFACE_NUM] = { 0 };
70*f1df9364SStefan Roese int is_any_pup_fail = 0;
71*f1df9364SStefan Roese u32 data_read[MAX_INTERFACE_NUM + 1] = { 0 };
72*f1df9364SStefan Roese u8 rl_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM];
73*f1df9364SStefan Roese struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
74*f1df9364SStefan Roese u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
75*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
76*f1df9364SStefan Roese
77*f1df9364SStefan Roese if (rl_version == 0) {
78*f1df9364SStefan Roese /* OLD RL machine */
79*f1df9364SStefan Roese data = 0x40;
80*f1df9364SStefan Roese data |= (1 << 20);
81*f1df9364SStefan Roese
82*f1df9364SStefan Roese /* TBD multi CS */
83*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(
84*f1df9364SStefan Roese dev_num, ACCESS_TYPE_MULTICAST,
85*f1df9364SStefan Roese PARAM_NOT_CARE, TRAINING_REG,
86*f1df9364SStefan Roese data, 0x11ffff));
87*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(
88*f1df9364SStefan Roese dev_num, ACCESS_TYPE_MULTICAST,
89*f1df9364SStefan Roese PARAM_NOT_CARE,
90*f1df9364SStefan Roese TRAINING_PATTERN_BASE_ADDRESS_REG,
91*f1df9364SStefan Roese 0, 0xfffffff8));
92*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(
93*f1df9364SStefan Roese dev_num, ACCESS_TYPE_MULTICAST,
94*f1df9364SStefan Roese PARAM_NOT_CARE, TRAINING_REG,
95*f1df9364SStefan Roese (u32)(1 << 31), (u32)(1 << 31)));
96*f1df9364SStefan Roese
97*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
98*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
99*f1df9364SStefan Roese training_result[training_stage][if_id] = TEST_SUCCESS;
100*f1df9364SStefan Roese if (ddr3_tip_if_polling
101*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
102*f1df9364SStefan Roese (u32)(1 << 31), TRAINING_REG,
103*f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
104*f1df9364SStefan Roese DEBUG_LEVELING(
105*f1df9364SStefan Roese DEBUG_LEVEL_ERROR,
106*f1df9364SStefan Roese ("RL: DDR3 poll failed(1) IF %d\n",
107*f1df9364SStefan Roese if_id));
108*f1df9364SStefan Roese training_result[training_stage][if_id] =
109*f1df9364SStefan Roese TEST_FAILED;
110*f1df9364SStefan Roese
111*f1df9364SStefan Roese if (debug_mode == 0)
112*f1df9364SStefan Roese return MV_FAIL;
113*f1df9364SStefan Roese }
114*f1df9364SStefan Roese }
115*f1df9364SStefan Roese
116*f1df9364SStefan Roese /* read read-leveling result */
117*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
118*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
119*f1df9364SStefan Roese TRAINING_REG, data_read, 1 << 30));
120*f1df9364SStefan Roese /* exit read leveling mode */
121*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
122*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
123*f1df9364SStefan Roese TRAINING_SW_2_REG, 0x8, 0x9));
124*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
125*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
126*f1df9364SStefan Roese TRAINING_SW_1_REG, 1 << 16, 1 << 16));
127*f1df9364SStefan Roese
128*f1df9364SStefan Roese /* disable RL machine all Trn_CS[3:0] , [16:0] */
129*f1df9364SStefan Roese
130*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
131*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
132*f1df9364SStefan Roese TRAINING_REG, 0, 0xf1ffff));
133*f1df9364SStefan Roese
134*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
135*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
136*f1df9364SStefan Roese if ((data_read[if_id] & (1 << 30)) == 0) {
137*f1df9364SStefan Roese DEBUG_LEVELING(
138*f1df9364SStefan Roese DEBUG_LEVEL_ERROR,
139*f1df9364SStefan Roese ("\n_read Leveling failed for IF %d\n",
140*f1df9364SStefan Roese if_id));
141*f1df9364SStefan Roese training_result[training_stage][if_id] =
142*f1df9364SStefan Roese TEST_FAILED;
143*f1df9364SStefan Roese if (debug_mode == 0)
144*f1df9364SStefan Roese return MV_FAIL;
145*f1df9364SStefan Roese }
146*f1df9364SStefan Roese }
147*f1df9364SStefan Roese return MV_OK;
148*f1df9364SStefan Roese }
149*f1df9364SStefan Roese
150*f1df9364SStefan Roese /* NEW RL machine */
151*f1df9364SStefan Roese for (effective_cs = 0; effective_cs < NUM_OF_CS; effective_cs++)
152*f1df9364SStefan Roese for (bus_num = 0; bus_num < MAX_BUS_NUM; bus_num++)
153*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++)
154*f1df9364SStefan Roese rl_values[effective_cs][bus_num][if_id] = 0;
155*f1df9364SStefan Roese
156*f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
157*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
158*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
159*f1df9364SStefan Roese training_result[training_stage][if_id] = TEST_SUCCESS;
160*f1df9364SStefan Roese
161*f1df9364SStefan Roese /* save current cs enable reg val */
162*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
163*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
164*f1df9364SStefan Roese CS_ENABLE_REG, cs_enable_reg_val,
165*f1df9364SStefan Roese MASK_ALL_BITS));
166*f1df9364SStefan Roese /* enable single cs */
167*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
168*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
169*f1df9364SStefan Roese CS_ENABLE_REG, (1 << 3), (1 << 3)));
170*f1df9364SStefan Roese }
171*f1df9364SStefan Roese
172*f1df9364SStefan Roese ddr3_tip_reset_fifo_ptr(dev_num);
173*f1df9364SStefan Roese
174*f1df9364SStefan Roese /*
175*f1df9364SStefan Roese * Phase 1: Load pattern (using ODPG)
176*f1df9364SStefan Roese *
177*f1df9364SStefan Roese * enter Read Leveling mode
178*f1df9364SStefan Roese * only 27 bits are masked
179*f1df9364SStefan Roese * assuming non multi-CS configuration
180*f1df9364SStefan Roese * write to CS = 0 for the non multi CS configuration, note
181*f1df9364SStefan Roese * that the results shall be read back to the required CS !!!
182*f1df9364SStefan Roese */
183*f1df9364SStefan Roese
184*f1df9364SStefan Roese /* BUS count is 0 shifted 26 */
185*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
186*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
187*f1df9364SStefan Roese ODPG_DATA_CONTROL_REG, 0x3, 0x3));
188*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_configure_odpg
189*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0,
190*f1df9364SStefan Roese pattern_table[PATTERN_RL].num_of_phases_tx, 0,
191*f1df9364SStefan Roese pattern_table[PATTERN_RL].num_of_phases_rx, 0, 0,
192*f1df9364SStefan Roese effective_cs, STRESS_NONE, DURATION_SINGLE));
193*f1df9364SStefan Roese
194*f1df9364SStefan Roese /* load pattern to ODPG */
195*f1df9364SStefan Roese ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
196*f1df9364SStefan Roese PARAM_NOT_CARE, PATTERN_RL,
197*f1df9364SStefan Roese pattern_table[PATTERN_RL].
198*f1df9364SStefan Roese start_addr);
199*f1df9364SStefan Roese
200*f1df9364SStefan Roese /*
201*f1df9364SStefan Roese * Phase 2: ODPG to Read Leveling mode
202*f1df9364SStefan Roese */
203*f1df9364SStefan Roese
204*f1df9364SStefan Roese /* General Training Opcode register */
205*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
206*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
207*f1df9364SStefan Roese ODPG_WRITE_READ_MODE_ENABLE_REG, 0,
208*f1df9364SStefan Roese MASK_ALL_BITS));
209*f1df9364SStefan Roese
210*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
211*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
212*f1df9364SStefan Roese ODPG_TRAINING_CONTROL_REG,
213*f1df9364SStefan Roese (0x301b01 | effective_cs << 2), 0x3c3fef));
214*f1df9364SStefan Roese
215*f1df9364SStefan Roese /* Object1 opcode register 0 & 1 */
216*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
217*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
218*f1df9364SStefan Roese speed_bin_index =
219*f1df9364SStefan Roese tm->interface_params[if_id].speed_bin_index;
220*f1df9364SStefan Roese cl_val =
221*f1df9364SStefan Roese cas_latency_table[speed_bin_index].cl_val[freq];
222*f1df9364SStefan Roese data = (cl_val << 17) | (0x3 << 25);
223*f1df9364SStefan Roese mask = (0xff << 9) | (0x1f << 17) | (0x3 << 25);
224*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
225*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
226*f1df9364SStefan Roese ODPG_OBJ1_OPCODE_REG, data, mask));
227*f1df9364SStefan Roese }
228*f1df9364SStefan Roese
229*f1df9364SStefan Roese /* Set iteration count to max value */
230*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
231*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
232*f1df9364SStefan Roese TRAINING_OPCODE_1_REG, 0xd00, 0xd00));
233*f1df9364SStefan Roese
234*f1df9364SStefan Roese /*
235*f1df9364SStefan Roese * Phase 2: Mask config
236*f1df9364SStefan Roese */
237*f1df9364SStefan Roese
238*f1df9364SStefan Roese ddr3_tip_dynamic_read_leveling_seq(dev_num);
239*f1df9364SStefan Roese
240*f1df9364SStefan Roese /*
241*f1df9364SStefan Roese * Phase 3: Read Leveling execution
242*f1df9364SStefan Roese */
243*f1df9364SStefan Roese
244*f1df9364SStefan Roese /* temporary jira dunit=14751 */
245*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
246*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
247*f1df9364SStefan Roese TRAINING_DBG_1_REG, 0, (u32)(1 << 31)));
248*f1df9364SStefan Roese /* configure phy reset value */
249*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
250*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
251*f1df9364SStefan Roese TRAINING_DBG_3_REG, (0x7f << 24),
252*f1df9364SStefan Roese (u32)(0xff << 24)));
253*f1df9364SStefan Roese /* data pup rd reset enable */
254*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
255*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
256*f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, 0, (1 << 30)));
257*f1df9364SStefan Roese /* data pup rd reset disable */
258*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
259*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
260*f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, (1 << 30), (1 << 30)));
261*f1df9364SStefan Roese /* training SW override & training RL mode */
262*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
263*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
264*f1df9364SStefan Roese TRAINING_SW_2_REG, 0x1, 0x9));
265*f1df9364SStefan Roese /* training enable */
266*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
267*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
268*f1df9364SStefan Roese TRAINING_REG, (1 << 24) | (1 << 20),
269*f1df9364SStefan Roese (1 << 24) | (1 << 20)));
270*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
271*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
272*f1df9364SStefan Roese TRAINING_REG, (u32)(1 << 31), (u32)(1 << 31)));
273*f1df9364SStefan Roese
274*f1df9364SStefan Roese /********* trigger training *******************/
275*f1df9364SStefan Roese /* Trigger, poll on status and disable ODPG */
276*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
277*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
278*f1df9364SStefan Roese ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
279*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
280*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
281*f1df9364SStefan Roese ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
282*f1df9364SStefan Roese
283*f1df9364SStefan Roese /* check for training done + results pass */
284*f1df9364SStefan Roese if (ddr3_tip_if_polling
285*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2,
286*f1df9364SStefan Roese ODPG_TRAINING_STATUS_REG,
287*f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
288*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
289*f1df9364SStefan Roese ("Training Done Failed\n"));
290*f1df9364SStefan Roese return MV_FAIL;
291*f1df9364SStefan Roese }
292*f1df9364SStefan Roese
293*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
294*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
295*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
296*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
297*f1df9364SStefan Roese if_id,
298*f1df9364SStefan Roese ODPG_TRAINING_TRIGGER_REG, data_read,
299*f1df9364SStefan Roese 0x4));
300*f1df9364SStefan Roese data = data_read[if_id];
301*f1df9364SStefan Roese if (data != 0x0) {
302*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
303*f1df9364SStefan Roese ("Training Result Failed\n"));
304*f1df9364SStefan Roese }
305*f1df9364SStefan Roese }
306*f1df9364SStefan Roese
307*f1df9364SStefan Roese /*disable ODPG - Back to functional mode */
308*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
309*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
310*f1df9364SStefan Roese ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,
311*f1df9364SStefan Roese (0x1 << ODPG_DISABLE_OFFS)));
312*f1df9364SStefan Roese if (ddr3_tip_if_polling
313*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1,
314*f1df9364SStefan Roese ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
315*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
316*f1df9364SStefan Roese ("ODPG disable failed "));
317*f1df9364SStefan Roese return MV_FAIL;
318*f1df9364SStefan Roese }
319*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
320*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
321*f1df9364SStefan Roese ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
322*f1df9364SStefan Roese
323*f1df9364SStefan Roese /* double loop on bus, pup */
324*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
325*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
326*f1df9364SStefan Roese /* check training done */
327*f1df9364SStefan Roese is_any_pup_fail = 0;
328*f1df9364SStefan Roese for (bus_num = 0;
329*f1df9364SStefan Roese bus_num < tm->num_of_bus_per_interface;
330*f1df9364SStefan Roese bus_num++) {
331*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
332*f1df9364SStefan Roese if (ddr3_tip_if_polling
333*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
334*f1df9364SStefan Roese if_id, (1 << 25), (1 << 25),
335*f1df9364SStefan Roese mask_results_pup_reg_map[bus_num],
336*f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
337*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
338*f1df9364SStefan Roese ("\n_r_l: DDR3 poll failed(2) for bus %d",
339*f1df9364SStefan Roese bus_num));
340*f1df9364SStefan Roese is_any_pup_fail = 1;
341*f1df9364SStefan Roese } else {
342*f1df9364SStefan Roese /* read result per pup */
343*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
344*f1df9364SStefan Roese (dev_num,
345*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
346*f1df9364SStefan Roese if_id,
347*f1df9364SStefan Roese mask_results_pup_reg_map
348*f1df9364SStefan Roese [bus_num], data_read,
349*f1df9364SStefan Roese 0xff));
350*f1df9364SStefan Roese rl_values[effective_cs][bus_num]
351*f1df9364SStefan Roese [if_id] = (u8)data_read[if_id];
352*f1df9364SStefan Roese }
353*f1df9364SStefan Roese }
354*f1df9364SStefan Roese
355*f1df9364SStefan Roese if (is_any_pup_fail == 1) {
356*f1df9364SStefan Roese training_result[training_stage][if_id] =
357*f1df9364SStefan Roese TEST_FAILED;
358*f1df9364SStefan Roese if (debug_mode == 0)
359*f1df9364SStefan Roese return MV_FAIL;
360*f1df9364SStefan Roese }
361*f1df9364SStefan Roese }
362*f1df9364SStefan Roese
363*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("RL exit read leveling\n"));
364*f1df9364SStefan Roese
365*f1df9364SStefan Roese /*
366*f1df9364SStefan Roese * Phase 3: Exit Read Leveling
367*f1df9364SStefan Roese */
368*f1df9364SStefan Roese
369*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
370*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
371*f1df9364SStefan Roese TRAINING_SW_2_REG, (1 << 3), (1 << 3)));
372*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
373*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
374*f1df9364SStefan Roese TRAINING_SW_1_REG, (1 << 16), (1 << 16)));
375*f1df9364SStefan Roese /* set ODPG to functional */
376*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
377*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
378*f1df9364SStefan Roese ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
379*f1df9364SStefan Roese
380*f1df9364SStefan Roese /*
381*f1df9364SStefan Roese * Copy the result from the effective CS search to the
382*f1df9364SStefan Roese * real Functional CS
383*f1df9364SStefan Roese */
384*f1df9364SStefan Roese /*ddr3_tip_write_cs_result(dev_num, RL_PHY_REG); */
385*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
386*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
387*f1df9364SStefan Roese ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
388*f1df9364SStefan Roese }
389*f1df9364SStefan Roese
390*f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
391*f1df9364SStefan Roese /* double loop on bus, pup */
392*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
393*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
394*f1df9364SStefan Roese for (bus_num = 0;
395*f1df9364SStefan Roese bus_num < tm->num_of_bus_per_interface;
396*f1df9364SStefan Roese bus_num++) {
397*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
398*f1df9364SStefan Roese /* read result per pup from arry */
399*f1df9364SStefan Roese data = rl_values[effective_cs][bus_num][if_id];
400*f1df9364SStefan Roese data = (data & 0x1f) |
401*f1df9364SStefan Roese (((data & 0xe0) >> 5) << 6);
402*f1df9364SStefan Roese ddr3_tip_bus_write(dev_num,
403*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
404*f1df9364SStefan Roese if_id,
405*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
406*f1df9364SStefan Roese bus_num, DDR_PHY_DATA,
407*f1df9364SStefan Roese RL_PHY_REG +
408*f1df9364SStefan Roese ((effective_cs ==
409*f1df9364SStefan Roese 0) ? 0x0 : 0x4), data);
410*f1df9364SStefan Roese }
411*f1df9364SStefan Roese }
412*f1df9364SStefan Roese }
413*f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
414*f1df9364SStefan Roese effective_cs = 0;
415*f1df9364SStefan Roese
416*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
417*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
418*f1df9364SStefan Roese /* restore cs enable value */
419*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
420*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
421*f1df9364SStefan Roese CS_ENABLE_REG, cs_enable_reg_val[if_id],
422*f1df9364SStefan Roese MASK_ALL_BITS));
423*f1df9364SStefan Roese if (odt_config != 0) {
424*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_write_additional_odt_setting
425*f1df9364SStefan Roese (dev_num, if_id));
426*f1df9364SStefan Roese }
427*f1df9364SStefan Roese }
428*f1df9364SStefan Roese
429*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
430*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
431*f1df9364SStefan Roese if (training_result[training_stage][if_id] == TEST_FAILED)
432*f1df9364SStefan Roese return MV_FAIL;
433*f1df9364SStefan Roese }
434*f1df9364SStefan Roese
435*f1df9364SStefan Roese return MV_OK;
436*f1df9364SStefan Roese }
437*f1df9364SStefan Roese
438*f1df9364SStefan Roese /*
439*f1df9364SStefan Roese * Legacy Dynamic write leveling
440*f1df9364SStefan Roese */
ddr3_tip_legacy_dynamic_write_leveling(u32 dev_num)441*f1df9364SStefan Roese int ddr3_tip_legacy_dynamic_write_leveling(u32 dev_num)
442*f1df9364SStefan Roese {
443*f1df9364SStefan Roese u32 c_cs, if_id, cs_mask = 0;
444*f1df9364SStefan Roese u32 max_cs = hws_ddr3_tip_max_cs_get();
445*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
446*f1df9364SStefan Roese
447*f1df9364SStefan Roese /*
448*f1df9364SStefan Roese * In TRAINIUNG reg (0x15b0) write 0x80000008 | cs_mask:
449*f1df9364SStefan Roese * Trn_start
450*f1df9364SStefan Roese * cs_mask = 0x1 <<20 Trn_CS0 - CS0 is included in the DDR3 training
451*f1df9364SStefan Roese * cs_mask = 0x1 <<21 Trn_CS1 - CS1 is included in the DDR3 training
452*f1df9364SStefan Roese * cs_mask = 0x1 <<22 Trn_CS2 - CS2 is included in the DDR3 training
453*f1df9364SStefan Roese * cs_mask = 0x1 <<23 Trn_CS3 - CS3 is included in the DDR3 training
454*f1df9364SStefan Roese * Trn_auto_seq = write leveling
455*f1df9364SStefan Roese */
456*f1df9364SStefan Roese for (c_cs = 0; c_cs < max_cs; c_cs++)
457*f1df9364SStefan Roese cs_mask = cs_mask | 1 << (20 + c_cs);
458*f1df9364SStefan Roese
459*f1df9364SStefan Roese for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
460*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
461*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
462*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, 0,
463*f1df9364SStefan Roese TRAINING_REG, (0x80000008 | cs_mask),
464*f1df9364SStefan Roese 0xffffffff));
465*f1df9364SStefan Roese mdelay(20);
466*f1df9364SStefan Roese if (ddr3_tip_if_polling
467*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
468*f1df9364SStefan Roese (u32)0x80000000, TRAINING_REG,
469*f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
470*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
471*f1df9364SStefan Roese ("polling failed for Old WL result\n"));
472*f1df9364SStefan Roese return MV_FAIL;
473*f1df9364SStefan Roese }
474*f1df9364SStefan Roese }
475*f1df9364SStefan Roese
476*f1df9364SStefan Roese return MV_OK;
477*f1df9364SStefan Roese }
478*f1df9364SStefan Roese
479*f1df9364SStefan Roese /*
480*f1df9364SStefan Roese * Legacy Dynamic read leveling
481*f1df9364SStefan Roese */
ddr3_tip_legacy_dynamic_read_leveling(u32 dev_num)482*f1df9364SStefan Roese int ddr3_tip_legacy_dynamic_read_leveling(u32 dev_num)
483*f1df9364SStefan Roese {
484*f1df9364SStefan Roese u32 c_cs, if_id, cs_mask = 0;
485*f1df9364SStefan Roese u32 max_cs = hws_ddr3_tip_max_cs_get();
486*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
487*f1df9364SStefan Roese
488*f1df9364SStefan Roese /*
489*f1df9364SStefan Roese * In TRAINIUNG reg (0x15b0) write 0x80000040 | cs_mask:
490*f1df9364SStefan Roese * Trn_start
491*f1df9364SStefan Roese * cs_mask = 0x1 <<20 Trn_CS0 - CS0 is included in the DDR3 training
492*f1df9364SStefan Roese * cs_mask = 0x1 <<21 Trn_CS1 - CS1 is included in the DDR3 training
493*f1df9364SStefan Roese * cs_mask = 0x1 <<22 Trn_CS2 - CS2 is included in the DDR3 training
494*f1df9364SStefan Roese * cs_mask = 0x1 <<23 Trn_CS3 - CS3 is included in the DDR3 training
495*f1df9364SStefan Roese * Trn_auto_seq = Read Leveling using training pattern
496*f1df9364SStefan Roese */
497*f1df9364SStefan Roese for (c_cs = 0; c_cs < max_cs; c_cs++)
498*f1df9364SStefan Roese cs_mask = cs_mask | 1 << (20 + c_cs);
499*f1df9364SStefan Roese
500*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
501*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, 0, TRAINING_REG,
502*f1df9364SStefan Roese (0x80000040 | cs_mask), 0xffffffff));
503*f1df9364SStefan Roese mdelay(100);
504*f1df9364SStefan Roese
505*f1df9364SStefan Roese for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
506*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
507*f1df9364SStefan Roese if (ddr3_tip_if_polling
508*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
509*f1df9364SStefan Roese (u32)0x80000000, TRAINING_REG,
510*f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
511*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
512*f1df9364SStefan Roese ("polling failed for Old RL result\n"));
513*f1df9364SStefan Roese return MV_FAIL;
514*f1df9364SStefan Roese }
515*f1df9364SStefan Roese }
516*f1df9364SStefan Roese
517*f1df9364SStefan Roese return MV_OK;
518*f1df9364SStefan Roese }
519*f1df9364SStefan Roese
520*f1df9364SStefan Roese /*
521*f1df9364SStefan Roese * Dynamic per bit read leveling
522*f1df9364SStefan Roese */
ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num,u32 freq)523*f1df9364SStefan Roese int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
524*f1df9364SStefan Roese {
525*f1df9364SStefan Roese u32 data, mask;
526*f1df9364SStefan Roese u32 bus_num, if_id, cl_val, bit_num;
527*f1df9364SStefan Roese u32 curr_numb, curr_min_delay;
528*f1df9364SStefan Roese int adll_array[3] = { 0, -0xa, 0x14 };
529*f1df9364SStefan Roese u32 phyreg3_arr[MAX_INTERFACE_NUM][MAX_BUS_NUM];
530*f1df9364SStefan Roese enum hws_speed_bin speed_bin_index;
531*f1df9364SStefan Roese int is_any_pup_fail = 0;
532*f1df9364SStefan Roese int break_loop = 0;
533*f1df9364SStefan Roese u32 cs_enable_reg_val[MAX_INTERFACE_NUM]; /* save current CS value */
534*f1df9364SStefan Roese u32 data_read[MAX_INTERFACE_NUM];
535*f1df9364SStefan Roese int per_bit_rl_pup_status[MAX_INTERFACE_NUM][MAX_BUS_NUM];
536*f1df9364SStefan Roese u32 data2_write[MAX_INTERFACE_NUM][MAX_BUS_NUM];
537*f1df9364SStefan Roese struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
538*f1df9364SStefan Roese u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
539*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
540*f1df9364SStefan Roese
541*f1df9364SStefan Roese for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
542*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
543*f1df9364SStefan Roese for (bus_num = 0;
544*f1df9364SStefan Roese bus_num <= tm->num_of_bus_per_interface; bus_num++) {
545*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
546*f1df9364SStefan Roese per_bit_rl_pup_status[if_id][bus_num] = 0;
547*f1df9364SStefan Roese data2_write[if_id][bus_num] = 0;
548*f1df9364SStefan Roese /* read current value of phy register 0x3 */
549*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read
550*f1df9364SStefan Roese (dev_num, if_id, ACCESS_TYPE_UNICAST,
551*f1df9364SStefan Roese bus_num, DDR_PHY_DATA,
552*f1df9364SStefan Roese READ_CENTRALIZATION_PHY_REG,
553*f1df9364SStefan Roese &phyreg3_arr[if_id][bus_num]));
554*f1df9364SStefan Roese }
555*f1df9364SStefan Roese }
556*f1df9364SStefan Roese
557*f1df9364SStefan Roese /* NEW RL machine */
558*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
559*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
560*f1df9364SStefan Roese training_result[training_stage][if_id] = TEST_SUCCESS;
561*f1df9364SStefan Roese
562*f1df9364SStefan Roese /* save current cs enable reg val */
563*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
564*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
565*f1df9364SStefan Roese CS_ENABLE_REG, &cs_enable_reg_val[if_id],
566*f1df9364SStefan Roese MASK_ALL_BITS));
567*f1df9364SStefan Roese /* enable single cs */
568*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
569*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
570*f1df9364SStefan Roese CS_ENABLE_REG, (1 << 3), (1 << 3)));
571*f1df9364SStefan Roese }
572*f1df9364SStefan Roese
573*f1df9364SStefan Roese ddr3_tip_reset_fifo_ptr(dev_num);
574*f1df9364SStefan Roese for (curr_numb = 0; curr_numb < 3; curr_numb++) {
575*f1df9364SStefan Roese /*
576*f1df9364SStefan Roese * Phase 1: Load pattern (using ODPG)
577*f1df9364SStefan Roese *
578*f1df9364SStefan Roese * enter Read Leveling mode
579*f1df9364SStefan Roese * only 27 bits are masked
580*f1df9364SStefan Roese * assuming non multi-CS configuration
581*f1df9364SStefan Roese * write to CS = 0 for the non multi CS configuration, note that
582*f1df9364SStefan Roese * the results shall be read back to the required CS !!!
583*f1df9364SStefan Roese */
584*f1df9364SStefan Roese
585*f1df9364SStefan Roese /* BUS count is 0 shifted 26 */
586*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
587*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
588*f1df9364SStefan Roese ODPG_DATA_CONTROL_REG, 0x3, 0x3));
589*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_configure_odpg
590*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0,
591*f1df9364SStefan Roese pattern_table[PATTERN_TEST].num_of_phases_tx, 0,
592*f1df9364SStefan Roese pattern_table[PATTERN_TEST].num_of_phases_rx, 0,
593*f1df9364SStefan Roese 0, 0, STRESS_NONE, DURATION_SINGLE));
594*f1df9364SStefan Roese
595*f1df9364SStefan Roese /* load pattern to ODPG */
596*f1df9364SStefan Roese ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
597*f1df9364SStefan Roese PARAM_NOT_CARE, PATTERN_TEST,
598*f1df9364SStefan Roese pattern_table[PATTERN_TEST].
599*f1df9364SStefan Roese start_addr);
600*f1df9364SStefan Roese
601*f1df9364SStefan Roese /*
602*f1df9364SStefan Roese * Phase 2: ODPG to Read Leveling mode
603*f1df9364SStefan Roese */
604*f1df9364SStefan Roese
605*f1df9364SStefan Roese /* General Training Opcode register */
606*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
607*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
608*f1df9364SStefan Roese ODPG_WRITE_READ_MODE_ENABLE_REG, 0,
609*f1df9364SStefan Roese MASK_ALL_BITS));
610*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
611*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
612*f1df9364SStefan Roese ODPG_TRAINING_CONTROL_REG, 0x301b01, 0x3c3fef));
613*f1df9364SStefan Roese
614*f1df9364SStefan Roese /* Object1 opcode register 0 & 1 */
615*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
616*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
617*f1df9364SStefan Roese speed_bin_index =
618*f1df9364SStefan Roese tm->interface_params[if_id].speed_bin_index;
619*f1df9364SStefan Roese cl_val =
620*f1df9364SStefan Roese cas_latency_table[speed_bin_index].cl_val[freq];
621*f1df9364SStefan Roese data = (cl_val << 17) | (0x3 << 25);
622*f1df9364SStefan Roese mask = (0xff << 9) | (0x1f << 17) | (0x3 << 25);
623*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
624*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
625*f1df9364SStefan Roese ODPG_OBJ1_OPCODE_REG, data, mask));
626*f1df9364SStefan Roese }
627*f1df9364SStefan Roese
628*f1df9364SStefan Roese /* Set iteration count to max value */
629*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
630*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
631*f1df9364SStefan Roese TRAINING_OPCODE_1_REG, 0xd00, 0xd00));
632*f1df9364SStefan Roese
633*f1df9364SStefan Roese /*
634*f1df9364SStefan Roese * Phase 2: Mask config
635*f1df9364SStefan Roese */
636*f1df9364SStefan Roese
637*f1df9364SStefan Roese ddr3_tip_dynamic_per_bit_read_leveling_seq(dev_num);
638*f1df9364SStefan Roese
639*f1df9364SStefan Roese /*
640*f1df9364SStefan Roese * Phase 3: Read Leveling execution
641*f1df9364SStefan Roese */
642*f1df9364SStefan Roese
643*f1df9364SStefan Roese /* temporary jira dunit=14751 */
644*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
645*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
646*f1df9364SStefan Roese TRAINING_DBG_1_REG, 0, (u32)(1 << 31)));
647*f1df9364SStefan Roese /* configure phy reset value */
648*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
649*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
650*f1df9364SStefan Roese TRAINING_DBG_3_REG, (0x7f << 24),
651*f1df9364SStefan Roese (u32)(0xff << 24)));
652*f1df9364SStefan Roese /* data pup rd reset enable */
653*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
654*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
655*f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, 0, (1 << 30)));
656*f1df9364SStefan Roese /* data pup rd reset disable */
657*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
658*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
659*f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, (1 << 30), (1 << 30)));
660*f1df9364SStefan Roese /* training SW override & training RL mode */
661*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
662*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
663*f1df9364SStefan Roese TRAINING_SW_2_REG, 0x1, 0x9));
664*f1df9364SStefan Roese /* training enable */
665*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
666*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
667*f1df9364SStefan Roese TRAINING_REG, (1 << 24) | (1 << 20),
668*f1df9364SStefan Roese (1 << 24) | (1 << 20)));
669*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
670*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
671*f1df9364SStefan Roese TRAINING_REG, (u32)(1 << 31), (u32)(1 << 31)));
672*f1df9364SStefan Roese
673*f1df9364SStefan Roese /********* trigger training *******************/
674*f1df9364SStefan Roese /* Trigger, poll on status and disable ODPG */
675*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
676*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
677*f1df9364SStefan Roese ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
678*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
679*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
680*f1df9364SStefan Roese ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
681*f1df9364SStefan Roese
682*f1df9364SStefan Roese /*check for training done + results pass */
683*f1df9364SStefan Roese if (ddr3_tip_if_polling
684*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2,
685*f1df9364SStefan Roese ODPG_TRAINING_STATUS_REG,
686*f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
687*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
688*f1df9364SStefan Roese ("Training Done Failed\n"));
689*f1df9364SStefan Roese return MV_FAIL;
690*f1df9364SStefan Roese }
691*f1df9364SStefan Roese
692*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
693*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
694*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
695*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
696*f1df9364SStefan Roese if_id,
697*f1df9364SStefan Roese ODPG_TRAINING_TRIGGER_REG, data_read,
698*f1df9364SStefan Roese 0x4));
699*f1df9364SStefan Roese data = data_read[if_id];
700*f1df9364SStefan Roese if (data != 0x0) {
701*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
702*f1df9364SStefan Roese ("Training Result Failed\n"));
703*f1df9364SStefan Roese }
704*f1df9364SStefan Roese }
705*f1df9364SStefan Roese
706*f1df9364SStefan Roese /*disable ODPG - Back to functional mode */
707*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
708*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
709*f1df9364SStefan Roese ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,
710*f1df9364SStefan Roese (0x1 << ODPG_DISABLE_OFFS)));
711*f1df9364SStefan Roese if (ddr3_tip_if_polling
712*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1,
713*f1df9364SStefan Roese ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
714*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
715*f1df9364SStefan Roese ("ODPG disable failed "));
716*f1df9364SStefan Roese return MV_FAIL;
717*f1df9364SStefan Roese }
718*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
719*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
720*f1df9364SStefan Roese ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
721*f1df9364SStefan Roese
722*f1df9364SStefan Roese /* double loop on bus, pup */
723*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
724*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
725*f1df9364SStefan Roese /* check training done */
726*f1df9364SStefan Roese for (bus_num = 0;
727*f1df9364SStefan Roese bus_num < tm->num_of_bus_per_interface;
728*f1df9364SStefan Roese bus_num++) {
729*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
730*f1df9364SStefan Roese
731*f1df9364SStefan Roese if (per_bit_rl_pup_status[if_id][bus_num]
732*f1df9364SStefan Roese == 0) {
733*f1df9364SStefan Roese curr_min_delay = 0;
734*f1df9364SStefan Roese for (bit_num = 0; bit_num < 8;
735*f1df9364SStefan Roese bit_num++) {
736*f1df9364SStefan Roese if (ddr3_tip_if_polling
737*f1df9364SStefan Roese (dev_num,
738*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
739*f1df9364SStefan Roese if_id, (1 << 25),
740*f1df9364SStefan Roese (1 << 25),
741*f1df9364SStefan Roese mask_results_dq_reg_map
742*f1df9364SStefan Roese [bus_num * 8 + bit_num],
743*f1df9364SStefan Roese MAX_POLLING_ITERATIONS) !=
744*f1df9364SStefan Roese MV_OK) {
745*f1df9364SStefan Roese DEBUG_LEVELING
746*f1df9364SStefan Roese (DEBUG_LEVEL_ERROR,
747*f1df9364SStefan Roese ("\n_r_l: DDR3 poll failed(2) for bus %d bit %d\n",
748*f1df9364SStefan Roese bus_num,
749*f1df9364SStefan Roese bit_num));
750*f1df9364SStefan Roese } else {
751*f1df9364SStefan Roese /* read result per pup */
752*f1df9364SStefan Roese CHECK_STATUS
753*f1df9364SStefan Roese (ddr3_tip_if_read
754*f1df9364SStefan Roese (dev_num,
755*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
756*f1df9364SStefan Roese if_id,
757*f1df9364SStefan Roese mask_results_dq_reg_map
758*f1df9364SStefan Roese [bus_num * 8 +
759*f1df9364SStefan Roese bit_num],
760*f1df9364SStefan Roese data_read,
761*f1df9364SStefan Roese MASK_ALL_BITS));
762*f1df9364SStefan Roese data =
763*f1df9364SStefan Roese (data_read
764*f1df9364SStefan Roese [if_id] &
765*f1df9364SStefan Roese 0x1f) |
766*f1df9364SStefan Roese ((data_read
767*f1df9364SStefan Roese [if_id] &
768*f1df9364SStefan Roese 0xe0) << 1);
769*f1df9364SStefan Roese if (curr_min_delay == 0)
770*f1df9364SStefan Roese curr_min_delay =
771*f1df9364SStefan Roese data;
772*f1df9364SStefan Roese else if (data <
773*f1df9364SStefan Roese curr_min_delay)
774*f1df9364SStefan Roese curr_min_delay =
775*f1df9364SStefan Roese data;
776*f1df9364SStefan Roese if (data > data2_write[if_id][bus_num])
777*f1df9364SStefan Roese data2_write
778*f1df9364SStefan Roese [if_id]
779*f1df9364SStefan Roese [bus_num] =
780*f1df9364SStefan Roese data;
781*f1df9364SStefan Roese }
782*f1df9364SStefan Roese }
783*f1df9364SStefan Roese
784*f1df9364SStefan Roese if (data2_write[if_id][bus_num] <=
785*f1df9364SStefan Roese (curr_min_delay +
786*f1df9364SStefan Roese MAX_DQ_READ_LEVELING_DELAY)) {
787*f1df9364SStefan Roese per_bit_rl_pup_status[if_id]
788*f1df9364SStefan Roese [bus_num] = 1;
789*f1df9364SStefan Roese }
790*f1df9364SStefan Roese }
791*f1df9364SStefan Roese }
792*f1df9364SStefan Roese }
793*f1df9364SStefan Roese
794*f1df9364SStefan Roese /* check if there is need to search new phyreg3 value */
795*f1df9364SStefan Roese if (curr_numb < 2) {
796*f1df9364SStefan Roese /* if there is DLL that is not checked yet */
797*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
798*f1df9364SStefan Roese if_id++) {
799*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
800*f1df9364SStefan Roese for (bus_num = 0;
801*f1df9364SStefan Roese bus_num < tm->num_of_bus_per_interface;
802*f1df9364SStefan Roese bus_num++) {
803*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask,
804*f1df9364SStefan Roese bus_num);
805*f1df9364SStefan Roese if (per_bit_rl_pup_status[if_id]
806*f1df9364SStefan Roese [bus_num] != 1) {
807*f1df9364SStefan Roese /* go to next ADLL value */
808*f1df9364SStefan Roese CHECK_STATUS
809*f1df9364SStefan Roese (ddr3_tip_bus_write
810*f1df9364SStefan Roese (dev_num,
811*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
812*f1df9364SStefan Roese if_id,
813*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
814*f1df9364SStefan Roese bus_num, DDR_PHY_DATA,
815*f1df9364SStefan Roese READ_CENTRALIZATION_PHY_REG,
816*f1df9364SStefan Roese (phyreg3_arr[if_id]
817*f1df9364SStefan Roese [bus_num] +
818*f1df9364SStefan Roese adll_array[curr_numb])));
819*f1df9364SStefan Roese break_loop = 1;
820*f1df9364SStefan Roese break;
821*f1df9364SStefan Roese }
822*f1df9364SStefan Roese }
823*f1df9364SStefan Roese if (break_loop)
824*f1df9364SStefan Roese break;
825*f1df9364SStefan Roese }
826*f1df9364SStefan Roese } /* if (curr_numb < 2) */
827*f1df9364SStefan Roese if (!break_loop)
828*f1df9364SStefan Roese break;
829*f1df9364SStefan Roese } /* for ( curr_numb = 0; curr_numb <3; curr_numb++) */
830*f1df9364SStefan Roese
831*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
832*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
833*f1df9364SStefan Roese for (bus_num = 0; bus_num < tm->num_of_bus_per_interface;
834*f1df9364SStefan Roese bus_num++) {
835*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
836*f1df9364SStefan Roese if (per_bit_rl_pup_status[if_id][bus_num] == 1)
837*f1df9364SStefan Roese ddr3_tip_bus_write(dev_num,
838*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
839*f1df9364SStefan Roese if_id,
840*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
841*f1df9364SStefan Roese bus_num, DDR_PHY_DATA,
842*f1df9364SStefan Roese RL_PHY_REG +
843*f1df9364SStefan Roese CS_REG_VALUE(effective_cs),
844*f1df9364SStefan Roese data2_write[if_id]
845*f1df9364SStefan Roese [bus_num]);
846*f1df9364SStefan Roese else
847*f1df9364SStefan Roese is_any_pup_fail = 1;
848*f1df9364SStefan Roese }
849*f1df9364SStefan Roese
850*f1df9364SStefan Roese /* TBD flow does not support multi CS */
851*f1df9364SStefan Roese /*
852*f1df9364SStefan Roese * cs_bitmask = tm->interface_params[if_id].
853*f1df9364SStefan Roese * as_bus_params[bus_num].cs_bitmask;
854*f1df9364SStefan Roese */
855*f1df9364SStefan Roese /* divide by 4 is used for retrieving the CS number */
856*f1df9364SStefan Roese /*
857*f1df9364SStefan Roese * TBD BC2 - what is the PHY address for other
858*f1df9364SStefan Roese * CS ddr3_tip_write_cs_result() ???
859*f1df9364SStefan Roese */
860*f1df9364SStefan Roese /*
861*f1df9364SStefan Roese * find what should be written to PHY
862*f1df9364SStefan Roese * - max delay that is less than threshold
863*f1df9364SStefan Roese */
864*f1df9364SStefan Roese if (is_any_pup_fail == 1) {
865*f1df9364SStefan Roese training_result[training_stage][if_id] = TEST_FAILED;
866*f1df9364SStefan Roese if (debug_mode == 0)
867*f1df9364SStefan Roese return MV_FAIL;
868*f1df9364SStefan Roese }
869*f1df9364SStefan Roese }
870*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("RL exit read leveling\n"));
871*f1df9364SStefan Roese
872*f1df9364SStefan Roese /*
873*f1df9364SStefan Roese * Phase 3: Exit Read Leveling
874*f1df9364SStefan Roese */
875*f1df9364SStefan Roese
876*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
877*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
878*f1df9364SStefan Roese TRAINING_SW_2_REG, (1 << 3), (1 << 3)));
879*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
880*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
881*f1df9364SStefan Roese TRAINING_SW_1_REG, (1 << 16), (1 << 16)));
882*f1df9364SStefan Roese /* set ODPG to functional */
883*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
884*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
885*f1df9364SStefan Roese ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
886*f1df9364SStefan Roese /*
887*f1df9364SStefan Roese * Copy the result from the effective CS search to the real
888*f1df9364SStefan Roese * Functional CS
889*f1df9364SStefan Roese */
890*f1df9364SStefan Roese ddr3_tip_write_cs_result(dev_num, RL_PHY_REG);
891*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
892*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
893*f1df9364SStefan Roese ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
894*f1df9364SStefan Roese
895*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
896*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
897*f1df9364SStefan Roese /* restore cs enable value */
898*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
899*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
900*f1df9364SStefan Roese CS_ENABLE_REG, cs_enable_reg_val[if_id],
901*f1df9364SStefan Roese MASK_ALL_BITS));
902*f1df9364SStefan Roese if (odt_config != 0) {
903*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_write_additional_odt_setting
904*f1df9364SStefan Roese (dev_num, if_id));
905*f1df9364SStefan Roese }
906*f1df9364SStefan Roese }
907*f1df9364SStefan Roese
908*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
909*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
910*f1df9364SStefan Roese if (training_result[training_stage][if_id] == TEST_FAILED)
911*f1df9364SStefan Roese return MV_FAIL;
912*f1df9364SStefan Roese }
913*f1df9364SStefan Roese
914*f1df9364SStefan Roese return MV_OK;
915*f1df9364SStefan Roese }
916*f1df9364SStefan Roese
ddr3_tip_calc_cs_mask(u32 dev_num,u32 if_id,u32 effective_cs,u32 * cs_mask)917*f1df9364SStefan Roese int ddr3_tip_calc_cs_mask(u32 dev_num, u32 if_id, u32 effective_cs,
918*f1df9364SStefan Roese u32 *cs_mask)
919*f1df9364SStefan Roese {
920*f1df9364SStefan Roese u32 all_bus_cs = 0, same_bus_cs;
921*f1df9364SStefan Roese u32 bus_cnt;
922*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
923*f1df9364SStefan Roese
924*f1df9364SStefan Roese *cs_mask = same_bus_cs = CS_BIT_MASK;
925*f1df9364SStefan Roese
926*f1df9364SStefan Roese /*
927*f1df9364SStefan Roese * In some of the devices (such as BC2), the CS is per pup and there
928*f1df9364SStefan Roese * for mixed mode is valid on like other devices where CS configuration
929*f1df9364SStefan Roese * is per interface.
930*f1df9364SStefan Roese * In order to know that, we do 'Or' and 'And' operation between all
931*f1df9364SStefan Roese * CS (of the pups).
932*f1df9364SStefan Roese * If they are they are not the same then it's mixed mode so all CS
933*f1df9364SStefan Roese * should be configured (when configuring the MRS)
934*f1df9364SStefan Roese */
935*f1df9364SStefan Roese for (bus_cnt = 0; bus_cnt < tm->num_of_bus_per_interface; bus_cnt++) {
936*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
937*f1df9364SStefan Roese
938*f1df9364SStefan Roese all_bus_cs |= tm->interface_params[if_id].
939*f1df9364SStefan Roese as_bus_params[bus_cnt].cs_bitmask;
940*f1df9364SStefan Roese same_bus_cs &= tm->interface_params[if_id].
941*f1df9364SStefan Roese as_bus_params[bus_cnt].cs_bitmask;
942*f1df9364SStefan Roese
943*f1df9364SStefan Roese /* cs enable is active low */
944*f1df9364SStefan Roese *cs_mask &= ~tm->interface_params[if_id].
945*f1df9364SStefan Roese as_bus_params[bus_cnt].cs_bitmask;
946*f1df9364SStefan Roese }
947*f1df9364SStefan Roese
948*f1df9364SStefan Roese if (all_bus_cs == same_bus_cs)
949*f1df9364SStefan Roese *cs_mask = (*cs_mask | (~(1 << effective_cs))) & CS_BIT_MASK;
950*f1df9364SStefan Roese
951*f1df9364SStefan Roese return MV_OK;
952*f1df9364SStefan Roese }
953*f1df9364SStefan Roese
954*f1df9364SStefan Roese /*
955*f1df9364SStefan Roese * Dynamic write leveling
956*f1df9364SStefan Roese */
ddr3_tip_dynamic_write_leveling(u32 dev_num)957*f1df9364SStefan Roese int ddr3_tip_dynamic_write_leveling(u32 dev_num)
958*f1df9364SStefan Roese {
959*f1df9364SStefan Roese u32 reg_data = 0, iter, if_id, bus_cnt;
960*f1df9364SStefan Roese u32 cs_enable_reg_val[MAX_INTERFACE_NUM] = { 0 };
961*f1df9364SStefan Roese u32 cs_mask[MAX_INTERFACE_NUM];
962*f1df9364SStefan Roese u32 read_data_sample_delay_vals[MAX_INTERFACE_NUM] = { 0 };
963*f1df9364SStefan Roese u32 read_data_ready_delay_vals[MAX_INTERFACE_NUM] = { 0 };
964*f1df9364SStefan Roese /* 0 for failure */
965*f1df9364SStefan Roese u32 res_values[MAX_INTERFACE_NUM * MAX_BUS_NUM] = { 0 };
966*f1df9364SStefan Roese u32 test_res = 0; /* 0 - success for all pup */
967*f1df9364SStefan Roese u32 data_read[MAX_INTERFACE_NUM];
968*f1df9364SStefan Roese u8 wl_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM];
969*f1df9364SStefan Roese u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
970*f1df9364SStefan Roese u32 cs_mask0[MAX_INTERFACE_NUM] = { 0 };
971*f1df9364SStefan Roese u32 max_cs = hws_ddr3_tip_max_cs_get();
972*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
973*f1df9364SStefan Roese
974*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
975*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
976*f1df9364SStefan Roese
977*f1df9364SStefan Roese training_result[training_stage][if_id] = TEST_SUCCESS;
978*f1df9364SStefan Roese
979*f1df9364SStefan Roese /* save Read Data Sample Delay */
980*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
981*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
982*f1df9364SStefan Roese READ_DATA_SAMPLE_DELAY,
983*f1df9364SStefan Roese read_data_sample_delay_vals, MASK_ALL_BITS));
984*f1df9364SStefan Roese /* save Read Data Ready Delay */
985*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
986*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
987*f1df9364SStefan Roese READ_DATA_READY_DELAY, read_data_ready_delay_vals,
988*f1df9364SStefan Roese MASK_ALL_BITS));
989*f1df9364SStefan Roese /* save current cs reg val */
990*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
991*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
992*f1df9364SStefan Roese CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
993*f1df9364SStefan Roese }
994*f1df9364SStefan Roese
995*f1df9364SStefan Roese /*
996*f1df9364SStefan Roese * Phase 1: DRAM 2 Write Leveling mode
997*f1df9364SStefan Roese */
998*f1df9364SStefan Roese
999*f1df9364SStefan Roese /*Assert 10 refresh commands to DRAM to all CS */
1000*f1df9364SStefan Roese for (iter = 0; iter < WL_ITERATION_NUM; iter++) {
1001*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1002*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1003*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1004*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
1005*f1df9364SStefan Roese if_id, SDRAM_OPERATION_REG,
1006*f1df9364SStefan Roese (u32)((~(0xf) << 8) | 0x2), 0xf1f));
1007*f1df9364SStefan Roese }
1008*f1df9364SStefan Roese }
1009*f1df9364SStefan Roese /* check controller back to normal */
1010*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1011*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1012*f1df9364SStefan Roese if (ddr3_tip_if_polling
1013*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x1f,
1014*f1df9364SStefan Roese SDRAM_OPERATION_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
1015*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
1016*f1df9364SStefan Roese ("WL: DDR3 poll failed(3)"));
1017*f1df9364SStefan Roese }
1018*f1df9364SStefan Roese }
1019*f1df9364SStefan Roese
1020*f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
1021*f1df9364SStefan Roese /*enable write leveling to all cs - Q off , WL n */
1022*f1df9364SStefan Roese /* calculate interface cs mask */
1023*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask0, MRS1_CMD,
1024*f1df9364SStefan Roese 0x1000, 0x1080));
1025*f1df9364SStefan Roese
1026*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1027*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1028*f1df9364SStefan Roese /* cs enable is active low */
1029*f1df9364SStefan Roese ddr3_tip_calc_cs_mask(dev_num, if_id, effective_cs,
1030*f1df9364SStefan Roese &cs_mask[if_id]);
1031*f1df9364SStefan Roese }
1032*f1df9364SStefan Roese
1033*f1df9364SStefan Roese /* Enable Output buffer to relevant CS - Q on , WL on */
1034*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_write_mrs_cmd
1035*f1df9364SStefan Roese (dev_num, cs_mask, MRS1_CMD, 0x80, 0x1080));
1036*f1df9364SStefan Roese
1037*f1df9364SStefan Roese /*enable odt for relevant CS */
1038*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1039*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1040*f1df9364SStefan Roese 0x1498, (0x3 << (effective_cs * 2)), 0xf));
1041*f1df9364SStefan Roese
1042*f1df9364SStefan Roese /*
1043*f1df9364SStefan Roese * Phase 2: Set training IP to write leveling mode
1044*f1df9364SStefan Roese */
1045*f1df9364SStefan Roese
1046*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_dynamic_write_leveling_seq(dev_num));
1047*f1df9364SStefan Roese
1048*f1df9364SStefan Roese /*
1049*f1df9364SStefan Roese * Phase 3: Trigger training
1050*f1df9364SStefan Roese */
1051*f1df9364SStefan Roese
1052*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1053*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1054*f1df9364SStefan Roese ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
1055*f1df9364SStefan Roese
1056*f1df9364SStefan Roese for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
1057*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1058*f1df9364SStefan Roese
1059*f1df9364SStefan Roese /* training done */
1060*f1df9364SStefan Roese if (ddr3_tip_if_polling
1061*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1062*f1df9364SStefan Roese (1 << 1), (1 << 1), ODPG_TRAINING_STATUS_REG,
1063*f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
1064*f1df9364SStefan Roese DEBUG_LEVELING(
1065*f1df9364SStefan Roese DEBUG_LEVEL_ERROR,
1066*f1df9364SStefan Roese ("WL: DDR3 poll (4) failed (Data: 0x%x)\n",
1067*f1df9364SStefan Roese reg_data));
1068*f1df9364SStefan Roese }
1069*f1df9364SStefan Roese #if !defined(CONFIG_ARMADA_38X) /*Disabled. JIRA #1498 */
1070*f1df9364SStefan Roese else {
1071*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
1072*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
1073*f1df9364SStefan Roese if_id,
1074*f1df9364SStefan Roese ODPG_TRAINING_TRIGGER_REG,
1075*f1df9364SStefan Roese ®_data, (1 << 2)));
1076*f1df9364SStefan Roese if (reg_data != 0) {
1077*f1df9364SStefan Roese DEBUG_LEVELING(
1078*f1df9364SStefan Roese DEBUG_LEVEL_ERROR,
1079*f1df9364SStefan Roese ("WL: WL failed IF %d reg_data=0x%x\n",
1080*f1df9364SStefan Roese if_id, reg_data));
1081*f1df9364SStefan Roese }
1082*f1df9364SStefan Roese }
1083*f1df9364SStefan Roese #endif
1084*f1df9364SStefan Roese }
1085*f1df9364SStefan Roese
1086*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1087*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1088*f1df9364SStefan Roese /* training done */
1089*f1df9364SStefan Roese if (ddr3_tip_if_polling
1090*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1091*f1df9364SStefan Roese (1 << 1), (1 << 1), ODPG_TRAINING_STATUS_REG,
1092*f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
1093*f1df9364SStefan Roese DEBUG_LEVELING(
1094*f1df9364SStefan Roese DEBUG_LEVEL_ERROR,
1095*f1df9364SStefan Roese ("WL: DDR3 poll (4) failed (Data: 0x%x)\n",
1096*f1df9364SStefan Roese reg_data));
1097*f1df9364SStefan Roese } else {
1098*f1df9364SStefan Roese #if !defined(CONFIG_ARMADA_38X) /*Disabled. JIRA #1498 */
1099*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
1100*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
1101*f1df9364SStefan Roese if_id,
1102*f1df9364SStefan Roese ODPG_TRAINING_STATUS_REG,
1103*f1df9364SStefan Roese data_read, (1 << 2)));
1104*f1df9364SStefan Roese reg_data = data_read[if_id];
1105*f1df9364SStefan Roese if (reg_data != 0) {
1106*f1df9364SStefan Roese DEBUG_LEVELING(
1107*f1df9364SStefan Roese DEBUG_LEVEL_ERROR,
1108*f1df9364SStefan Roese ("WL: WL failed IF %d reg_data=0x%x\n",
1109*f1df9364SStefan Roese if_id, reg_data));
1110*f1df9364SStefan Roese }
1111*f1df9364SStefan Roese #endif
1112*f1df9364SStefan Roese
1113*f1df9364SStefan Roese /* check for training completion per bus */
1114*f1df9364SStefan Roese for (bus_cnt = 0;
1115*f1df9364SStefan Roese bus_cnt < tm->num_of_bus_per_interface;
1116*f1df9364SStefan Roese bus_cnt++) {
1117*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask,
1118*f1df9364SStefan Roese bus_cnt);
1119*f1df9364SStefan Roese /* training status */
1120*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
1121*f1df9364SStefan Roese (dev_num,
1122*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
1123*f1df9364SStefan Roese if_id,
1124*f1df9364SStefan Roese mask_results_pup_reg_map
1125*f1df9364SStefan Roese [bus_cnt], data_read,
1126*f1df9364SStefan Roese (1 << 25)));
1127*f1df9364SStefan Roese reg_data = data_read[if_id];
1128*f1df9364SStefan Roese DEBUG_LEVELING(
1129*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1130*f1df9364SStefan Roese ("WL: IF %d BUS %d reg 0x%x\n",
1131*f1df9364SStefan Roese if_id, bus_cnt, reg_data));
1132*f1df9364SStefan Roese if (reg_data == 0) {
1133*f1df9364SStefan Roese res_values[
1134*f1df9364SStefan Roese (if_id *
1135*f1df9364SStefan Roese tm->num_of_bus_per_interface)
1136*f1df9364SStefan Roese + bus_cnt] = 1;
1137*f1df9364SStefan Roese }
1138*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
1139*f1df9364SStefan Roese (dev_num,
1140*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
1141*f1df9364SStefan Roese if_id,
1142*f1df9364SStefan Roese mask_results_pup_reg_map
1143*f1df9364SStefan Roese [bus_cnt], data_read,
1144*f1df9364SStefan Roese 0xff));
1145*f1df9364SStefan Roese /*
1146*f1df9364SStefan Roese * Save the read value that should be
1147*f1df9364SStefan Roese * write to PHY register
1148*f1df9364SStefan Roese */
1149*f1df9364SStefan Roese wl_values[effective_cs]
1150*f1df9364SStefan Roese [bus_cnt][if_id] =
1151*f1df9364SStefan Roese (u8)data_read[if_id];
1152*f1df9364SStefan Roese }
1153*f1df9364SStefan Roese }
1154*f1df9364SStefan Roese }
1155*f1df9364SStefan Roese
1156*f1df9364SStefan Roese /*
1157*f1df9364SStefan Roese * Phase 4: Exit write leveling mode
1158*f1df9364SStefan Roese */
1159*f1df9364SStefan Roese
1160*f1df9364SStefan Roese /* disable DQs toggling */
1161*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1162*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1163*f1df9364SStefan Roese WR_LEVELING_DQS_PATTERN_REG, 0x0, 0x1));
1164*f1df9364SStefan Roese
1165*f1df9364SStefan Roese /* Update MRS 1 (WL off) */
1166*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask0, MRS1_CMD,
1167*f1df9364SStefan Roese 0x1000, 0x1080));
1168*f1df9364SStefan Roese
1169*f1df9364SStefan Roese /* Update MRS 1 (return to functional mode - Q on , WL off) */
1170*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_write_mrs_cmd
1171*f1df9364SStefan Roese (dev_num, cs_mask0, MRS1_CMD, 0x0, 0x1080));
1172*f1df9364SStefan Roese
1173*f1df9364SStefan Roese /* set phy to normal mode */
1174*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1175*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1176*f1df9364SStefan Roese TRAINING_SW_2_REG, 0x5, 0x7));
1177*f1df9364SStefan Roese
1178*f1df9364SStefan Roese /* exit sw override mode */
1179*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1180*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1181*f1df9364SStefan Roese TRAINING_SW_2_REG, 0x4, 0x7));
1182*f1df9364SStefan Roese }
1183*f1df9364SStefan Roese
1184*f1df9364SStefan Roese /*
1185*f1df9364SStefan Roese * Phase 5: Load WL values to each PHY
1186*f1df9364SStefan Roese */
1187*f1df9364SStefan Roese
1188*f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
1189*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1190*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1191*f1df9364SStefan Roese test_res = 0;
1192*f1df9364SStefan Roese for (bus_cnt = 0;
1193*f1df9364SStefan Roese bus_cnt < tm->num_of_bus_per_interface;
1194*f1df9364SStefan Roese bus_cnt++) {
1195*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
1196*f1df9364SStefan Roese /* check if result == pass */
1197*f1df9364SStefan Roese if (res_values
1198*f1df9364SStefan Roese [(if_id *
1199*f1df9364SStefan Roese tm->num_of_bus_per_interface) +
1200*f1df9364SStefan Roese bus_cnt] == 0) {
1201*f1df9364SStefan Roese /*
1202*f1df9364SStefan Roese * read result control register
1203*f1df9364SStefan Roese * according to pup
1204*f1df9364SStefan Roese */
1205*f1df9364SStefan Roese reg_data =
1206*f1df9364SStefan Roese wl_values[effective_cs][bus_cnt]
1207*f1df9364SStefan Roese [if_id];
1208*f1df9364SStefan Roese /*
1209*f1df9364SStefan Roese * Write into write leveling register
1210*f1df9364SStefan Roese * ([4:0] ADLL, [8:6] Phase, [15:10]
1211*f1df9364SStefan Roese * (centralization) ADLL + 0x10)
1212*f1df9364SStefan Roese */
1213*f1df9364SStefan Roese reg_data =
1214*f1df9364SStefan Roese (reg_data & 0x1f) |
1215*f1df9364SStefan Roese (((reg_data & 0xe0) >> 5) << 6) |
1216*f1df9364SStefan Roese (((reg_data & 0x1f) +
1217*f1df9364SStefan Roese phy_reg1_val) << 10);
1218*f1df9364SStefan Roese ddr3_tip_bus_write(
1219*f1df9364SStefan Roese dev_num,
1220*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
1221*f1df9364SStefan Roese if_id,
1222*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
1223*f1df9364SStefan Roese bus_cnt,
1224*f1df9364SStefan Roese DDR_PHY_DATA,
1225*f1df9364SStefan Roese WL_PHY_REG +
1226*f1df9364SStefan Roese effective_cs *
1227*f1df9364SStefan Roese CS_REGISTER_ADDR_OFFSET,
1228*f1df9364SStefan Roese reg_data);
1229*f1df9364SStefan Roese } else {
1230*f1df9364SStefan Roese test_res = 1;
1231*f1df9364SStefan Roese /*
1232*f1df9364SStefan Roese * read result control register
1233*f1df9364SStefan Roese * according to pup
1234*f1df9364SStefan Roese */
1235*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
1236*f1df9364SStefan Roese (dev_num,
1237*f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
1238*f1df9364SStefan Roese if_id,
1239*f1df9364SStefan Roese mask_results_pup_reg_map
1240*f1df9364SStefan Roese [bus_cnt], data_read,
1241*f1df9364SStefan Roese 0xff));
1242*f1df9364SStefan Roese reg_data = data_read[if_id];
1243*f1df9364SStefan Roese DEBUG_LEVELING(
1244*f1df9364SStefan Roese DEBUG_LEVEL_ERROR,
1245*f1df9364SStefan Roese ("WL: IF %d BUS %d failed, reg 0x%x\n",
1246*f1df9364SStefan Roese if_id, bus_cnt, reg_data));
1247*f1df9364SStefan Roese }
1248*f1df9364SStefan Roese }
1249*f1df9364SStefan Roese
1250*f1df9364SStefan Roese if (test_res != 0) {
1251*f1df9364SStefan Roese training_result[training_stage][if_id] =
1252*f1df9364SStefan Roese TEST_FAILED;
1253*f1df9364SStefan Roese }
1254*f1df9364SStefan Roese }
1255*f1df9364SStefan Roese }
1256*f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
1257*f1df9364SStefan Roese effective_cs = 0;
1258*f1df9364SStefan Roese
1259*f1df9364SStefan Roese /*
1260*f1df9364SStefan Roese * Copy the result from the effective CS search to the real
1261*f1df9364SStefan Roese * Functional CS
1262*f1df9364SStefan Roese */
1263*f1df9364SStefan Roese /* ddr3_tip_write_cs_result(dev_num, WL_PHY_REG); */
1264*f1df9364SStefan Roese /* restore saved values */
1265*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1266*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1267*f1df9364SStefan Roese /* restore Read Data Sample Delay */
1268*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1269*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1270*f1df9364SStefan Roese READ_DATA_SAMPLE_DELAY,
1271*f1df9364SStefan Roese read_data_sample_delay_vals[if_id],
1272*f1df9364SStefan Roese MASK_ALL_BITS));
1273*f1df9364SStefan Roese
1274*f1df9364SStefan Roese /* restore Read Data Ready Delay */
1275*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1276*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1277*f1df9364SStefan Roese READ_DATA_READY_DELAY,
1278*f1df9364SStefan Roese read_data_ready_delay_vals[if_id],
1279*f1df9364SStefan Roese MASK_ALL_BITS));
1280*f1df9364SStefan Roese
1281*f1df9364SStefan Roese /* enable multi cs */
1282*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1283*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1284*f1df9364SStefan Roese CS_ENABLE_REG, cs_enable_reg_val[if_id],
1285*f1df9364SStefan Roese MASK_ALL_BITS));
1286*f1df9364SStefan Roese }
1287*f1df9364SStefan Roese
1288*f1df9364SStefan Roese /* Disable modt0 for CS0 training - need to adjust for multy CS */
1289*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1290*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498,
1291*f1df9364SStefan Roese 0x0, 0xf));
1292*f1df9364SStefan Roese
1293*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1294*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1295*f1df9364SStefan Roese if (training_result[training_stage][if_id] == TEST_FAILED)
1296*f1df9364SStefan Roese return MV_FAIL;
1297*f1df9364SStefan Roese }
1298*f1df9364SStefan Roese
1299*f1df9364SStefan Roese return MV_OK;
1300*f1df9364SStefan Roese }
1301*f1df9364SStefan Roese
1302*f1df9364SStefan Roese /*
1303*f1df9364SStefan Roese * Dynamic write leveling supplementary
1304*f1df9364SStefan Roese */
ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)1305*f1df9364SStefan Roese int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)
1306*f1df9364SStefan Roese {
1307*f1df9364SStefan Roese int adll_offset;
1308*f1df9364SStefan Roese u32 if_id, bus_id, data, data_tmp;
1309*f1df9364SStefan Roese int is_if_fail = 0;
1310*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1311*f1df9364SStefan Roese
1312*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1313*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1314*f1df9364SStefan Roese is_if_fail = 0;
1315*f1df9364SStefan Roese
1316*f1df9364SStefan Roese for (bus_id = 0; bus_id < GET_TOPOLOGY_NUM_OF_BUSES();
1317*f1df9364SStefan Roese bus_id++) {
1318*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
1319*f1df9364SStefan Roese wr_supp_res[if_id][bus_id].is_pup_fail = 1;
1320*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read
1321*f1df9364SStefan Roese (dev_num, if_id, ACCESS_TYPE_UNICAST,
1322*f1df9364SStefan Roese bus_id, DDR_PHY_DATA,
1323*f1df9364SStefan Roese WRITE_CENTRALIZATION_PHY_REG +
1324*f1df9364SStefan Roese effective_cs * CS_REGISTER_ADDR_OFFSET,
1325*f1df9364SStefan Roese &data));
1326*f1df9364SStefan Roese DEBUG_LEVELING(
1327*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1328*f1df9364SStefan Roese ("WL Supp: adll_offset=0 data delay = %d\n",
1329*f1df9364SStefan Roese data));
1330*f1df9364SStefan Roese if (ddr3_tip_wl_supp_align_phase_shift
1331*f1df9364SStefan Roese (dev_num, if_id, bus_id, 0, 0) == MV_OK) {
1332*f1df9364SStefan Roese DEBUG_LEVELING(
1333*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1334*f1df9364SStefan Roese ("WL Supp: IF %d bus_id %d adll_offset=0 Success !\n",
1335*f1df9364SStefan Roese if_id, bus_id));
1336*f1df9364SStefan Roese continue;
1337*f1df9364SStefan Roese }
1338*f1df9364SStefan Roese
1339*f1df9364SStefan Roese /* change adll */
1340*f1df9364SStefan Roese adll_offset = 5;
1341*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_write
1342*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1343*f1df9364SStefan Roese ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
1344*f1df9364SStefan Roese WRITE_CENTRALIZATION_PHY_REG +
1345*f1df9364SStefan Roese effective_cs * CS_REGISTER_ADDR_OFFSET,
1346*f1df9364SStefan Roese data + adll_offset));
1347*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read
1348*f1df9364SStefan Roese (dev_num, if_id, ACCESS_TYPE_UNICAST,
1349*f1df9364SStefan Roese bus_id, DDR_PHY_DATA,
1350*f1df9364SStefan Roese WRITE_CENTRALIZATION_PHY_REG +
1351*f1df9364SStefan Roese effective_cs * CS_REGISTER_ADDR_OFFSET,
1352*f1df9364SStefan Roese &data_tmp));
1353*f1df9364SStefan Roese DEBUG_LEVELING(
1354*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1355*f1df9364SStefan Roese ("WL Supp: adll_offset= %d data delay = %d\n",
1356*f1df9364SStefan Roese adll_offset, data_tmp));
1357*f1df9364SStefan Roese
1358*f1df9364SStefan Roese if (ddr3_tip_wl_supp_align_phase_shift
1359*f1df9364SStefan Roese (dev_num, if_id, bus_id, adll_offset, 0) == MV_OK) {
1360*f1df9364SStefan Roese DEBUG_LEVELING(
1361*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1362*f1df9364SStefan Roese ("WL Supp: IF %d bus_id %d adll_offset= %d Success !\n",
1363*f1df9364SStefan Roese if_id, bus_id, adll_offset));
1364*f1df9364SStefan Roese continue;
1365*f1df9364SStefan Roese }
1366*f1df9364SStefan Roese
1367*f1df9364SStefan Roese /* change adll */
1368*f1df9364SStefan Roese adll_offset = -5;
1369*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_write
1370*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1371*f1df9364SStefan Roese ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
1372*f1df9364SStefan Roese WRITE_CENTRALIZATION_PHY_REG +
1373*f1df9364SStefan Roese effective_cs * CS_REGISTER_ADDR_OFFSET,
1374*f1df9364SStefan Roese data + adll_offset));
1375*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read
1376*f1df9364SStefan Roese (dev_num, if_id, ACCESS_TYPE_UNICAST,
1377*f1df9364SStefan Roese bus_id, DDR_PHY_DATA,
1378*f1df9364SStefan Roese WRITE_CENTRALIZATION_PHY_REG +
1379*f1df9364SStefan Roese effective_cs * CS_REGISTER_ADDR_OFFSET,
1380*f1df9364SStefan Roese &data_tmp));
1381*f1df9364SStefan Roese DEBUG_LEVELING(
1382*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1383*f1df9364SStefan Roese ("WL Supp: adll_offset= %d data delay = %d\n",
1384*f1df9364SStefan Roese adll_offset, data_tmp));
1385*f1df9364SStefan Roese if (ddr3_tip_wl_supp_align_phase_shift
1386*f1df9364SStefan Roese (dev_num, if_id, bus_id, adll_offset, 0) == MV_OK) {
1387*f1df9364SStefan Roese DEBUG_LEVELING(
1388*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1389*f1df9364SStefan Roese ("WL Supp: IF %d bus_id %d adll_offset= %d Success !\n",
1390*f1df9364SStefan Roese if_id, bus_id, adll_offset));
1391*f1df9364SStefan Roese continue;
1392*f1df9364SStefan Roese } else {
1393*f1df9364SStefan Roese DEBUG_LEVELING(
1394*f1df9364SStefan Roese DEBUG_LEVEL_ERROR,
1395*f1df9364SStefan Roese ("WL Supp: IF %d bus_id %d Failed !\n",
1396*f1df9364SStefan Roese if_id, bus_id));
1397*f1df9364SStefan Roese is_if_fail = 1;
1398*f1df9364SStefan Roese }
1399*f1df9364SStefan Roese }
1400*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
1401*f1df9364SStefan Roese ("WL Supp: IF %d bus_id %d is_pup_fail %d\n",
1402*f1df9364SStefan Roese if_id, bus_id, is_if_fail));
1403*f1df9364SStefan Roese
1404*f1df9364SStefan Roese if (is_if_fail == 1) {
1405*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
1406*f1df9364SStefan Roese ("WL Supp: IF %d failed\n", if_id));
1407*f1df9364SStefan Roese training_result[training_stage][if_id] = TEST_FAILED;
1408*f1df9364SStefan Roese } else {
1409*f1df9364SStefan Roese training_result[training_stage][if_id] = TEST_SUCCESS;
1410*f1df9364SStefan Roese }
1411*f1df9364SStefan Roese }
1412*f1df9364SStefan Roese
1413*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1414*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1415*f1df9364SStefan Roese if (training_result[training_stage][if_id] == TEST_FAILED)
1416*f1df9364SStefan Roese return MV_FAIL;
1417*f1df9364SStefan Roese }
1418*f1df9364SStefan Roese
1419*f1df9364SStefan Roese return MV_OK;
1420*f1df9364SStefan Roese }
1421*f1df9364SStefan Roese
1422*f1df9364SStefan Roese /*
1423*f1df9364SStefan Roese * Phase Shift
1424*f1df9364SStefan Roese */
ddr3_tip_wl_supp_align_phase_shift(u32 dev_num,u32 if_id,u32 bus_id,u32 offset,u32 bus_id_delta)1425*f1df9364SStefan Roese static int ddr3_tip_wl_supp_align_phase_shift(u32 dev_num, u32 if_id,
1426*f1df9364SStefan Roese u32 bus_id, u32 offset,
1427*f1df9364SStefan Roese u32 bus_id_delta)
1428*f1df9364SStefan Roese {
1429*f1df9364SStefan Roese wr_supp_res[if_id][bus_id].stage = PHASE_SHIFT;
1430*f1df9364SStefan Roese if (ddr3_tip_xsb_compare_test(dev_num, if_id, bus_id,
1431*f1df9364SStefan Roese 0, bus_id_delta) == MV_OK) {
1432*f1df9364SStefan Roese wr_supp_res[if_id][bus_id].is_pup_fail = 0;
1433*f1df9364SStefan Roese return MV_OK;
1434*f1df9364SStefan Roese } else if (ddr3_tip_xsb_compare_test(dev_num, if_id, bus_id,
1435*f1df9364SStefan Roese ONE_CLOCK_ERROR_SHIFT,
1436*f1df9364SStefan Roese bus_id_delta) == MV_OK) {
1437*f1df9364SStefan Roese /* 1 clock error */
1438*f1df9364SStefan Roese wr_supp_res[if_id][bus_id].stage = CLOCK_SHIFT;
1439*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
1440*f1df9364SStefan Roese ("Supp: 1 error clock for if %d pup %d with ofsset %d success\n",
1441*f1df9364SStefan Roese if_id, bus_id, offset));
1442*f1df9364SStefan Roese ddr3_tip_wl_supp_one_clk_err_shift(dev_num, if_id, bus_id, 0);
1443*f1df9364SStefan Roese wr_supp_res[if_id][bus_id].is_pup_fail = 0;
1444*f1df9364SStefan Roese return MV_OK;
1445*f1df9364SStefan Roese } else if (ddr3_tip_xsb_compare_test(dev_num, if_id, bus_id,
1446*f1df9364SStefan Roese ALIGN_ERROR_SHIFT,
1447*f1df9364SStefan Roese bus_id_delta) == MV_OK) {
1448*f1df9364SStefan Roese /* align error */
1449*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
1450*f1df9364SStefan Roese ("Supp: align error for if %d pup %d with ofsset %d success\n",
1451*f1df9364SStefan Roese if_id, bus_id, offset));
1452*f1df9364SStefan Roese wr_supp_res[if_id][bus_id].stage = ALIGN_SHIFT;
1453*f1df9364SStefan Roese ddr3_tip_wl_supp_align_err_shift(dev_num, if_id, bus_id, 0);
1454*f1df9364SStefan Roese wr_supp_res[if_id][bus_id].is_pup_fail = 0;
1455*f1df9364SStefan Roese return MV_OK;
1456*f1df9364SStefan Roese } else {
1457*f1df9364SStefan Roese wr_supp_res[if_id][bus_id].is_pup_fail = 1;
1458*f1df9364SStefan Roese return MV_FAIL;
1459*f1df9364SStefan Roese }
1460*f1df9364SStefan Roese }
1461*f1df9364SStefan Roese
1462*f1df9364SStefan Roese /*
1463*f1df9364SStefan Roese * Compare Test
1464*f1df9364SStefan Roese */
ddr3_tip_xsb_compare_test(u32 dev_num,u32 if_id,u32 bus_id,u32 edge_offset,u32 bus_id_delta)1465*f1df9364SStefan Roese static int ddr3_tip_xsb_compare_test(u32 dev_num, u32 if_id, u32 bus_id,
1466*f1df9364SStefan Roese u32 edge_offset, u32 bus_id_delta)
1467*f1df9364SStefan Roese {
1468*f1df9364SStefan Roese u32 num_of_succ_byte_compare, word_in_pattern, abs_offset;
1469*f1df9364SStefan Roese u32 word_offset, i;
1470*f1df9364SStefan Roese u32 read_pattern[TEST_PATTERN_LENGTH * 2];
1471*f1df9364SStefan Roese struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
1472*f1df9364SStefan Roese u32 pattern_test_pattern_table[8];
1473*f1df9364SStefan Roese
1474*f1df9364SStefan Roese for (i = 0; i < 8; i++) {
1475*f1df9364SStefan Roese pattern_test_pattern_table[i] =
1476*f1df9364SStefan Roese pattern_table_get_word(dev_num, PATTERN_TEST, (u8)i);
1477*f1df9364SStefan Roese }
1478*f1df9364SStefan Roese
1479*f1df9364SStefan Roese /* extern write, than read and compare */
1480*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_ext_write
1481*f1df9364SStefan Roese (dev_num, if_id,
1482*f1df9364SStefan Roese (pattern_table[PATTERN_TEST].start_addr +
1483*f1df9364SStefan Roese ((SDRAM_CS_SIZE + 1) * effective_cs)), 1,
1484*f1df9364SStefan Roese pattern_test_pattern_table));
1485*f1df9364SStefan Roese
1486*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_reset_fifo_ptr(dev_num));
1487*f1df9364SStefan Roese
1488*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_ext_read
1489*f1df9364SStefan Roese (dev_num, if_id,
1490*f1df9364SStefan Roese (pattern_table[PATTERN_TEST].start_addr +
1491*f1df9364SStefan Roese ((SDRAM_CS_SIZE + 1) * effective_cs)), 1, read_pattern));
1492*f1df9364SStefan Roese
1493*f1df9364SStefan Roese DEBUG_LEVELING(
1494*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1495*f1df9364SStefan Roese ("XSB-compt: IF %d bus_id %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1496*f1df9364SStefan Roese if_id, bus_id, read_pattern[0], read_pattern[1],
1497*f1df9364SStefan Roese read_pattern[2], read_pattern[3], read_pattern[4],
1498*f1df9364SStefan Roese read_pattern[5], read_pattern[6], read_pattern[7]));
1499*f1df9364SStefan Roese
1500*f1df9364SStefan Roese /* compare byte per pup */
1501*f1df9364SStefan Roese num_of_succ_byte_compare = 0;
1502*f1df9364SStefan Roese for (word_in_pattern = start_xsb_offset;
1503*f1df9364SStefan Roese word_in_pattern < (TEST_PATTERN_LENGTH * 2); word_in_pattern++) {
1504*f1df9364SStefan Roese word_offset = word_in_pattern + edge_offset;
1505*f1df9364SStefan Roese if ((word_offset > (TEST_PATTERN_LENGTH * 2 - 1)) ||
1506*f1df9364SStefan Roese (word_offset < 0))
1507*f1df9364SStefan Roese continue;
1508*f1df9364SStefan Roese
1509*f1df9364SStefan Roese if ((read_pattern[word_in_pattern] & pup_mask_table[bus_id]) ==
1510*f1df9364SStefan Roese (pattern_test_pattern_table[word_offset] &
1511*f1df9364SStefan Roese pup_mask_table[bus_id]))
1512*f1df9364SStefan Roese num_of_succ_byte_compare++;
1513*f1df9364SStefan Roese }
1514*f1df9364SStefan Roese
1515*f1df9364SStefan Roese abs_offset = (edge_offset > 0) ? edge_offset : -edge_offset;
1516*f1df9364SStefan Roese if (num_of_succ_byte_compare == ((TEST_PATTERN_LENGTH * 2) -
1517*f1df9364SStefan Roese abs_offset - start_xsb_offset)) {
1518*f1df9364SStefan Roese DEBUG_LEVELING(
1519*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1520*f1df9364SStefan Roese ("XSB-compt: IF %d bus_id %d num_of_succ_byte_compare %d - Success\n",
1521*f1df9364SStefan Roese if_id, bus_id, num_of_succ_byte_compare));
1522*f1df9364SStefan Roese return MV_OK;
1523*f1df9364SStefan Roese } else {
1524*f1df9364SStefan Roese DEBUG_LEVELING(
1525*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1526*f1df9364SStefan Roese ("XSB-compt: IF %d bus_id %d num_of_succ_byte_compare %d - Fail !\n",
1527*f1df9364SStefan Roese if_id, bus_id, num_of_succ_byte_compare));
1528*f1df9364SStefan Roese
1529*f1df9364SStefan Roese DEBUG_LEVELING(
1530*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1531*f1df9364SStefan Roese ("XSB-compt: expected 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1532*f1df9364SStefan Roese pattern_test_pattern_table[0],
1533*f1df9364SStefan Roese pattern_test_pattern_table[1],
1534*f1df9364SStefan Roese pattern_test_pattern_table[2],
1535*f1df9364SStefan Roese pattern_test_pattern_table[3],
1536*f1df9364SStefan Roese pattern_test_pattern_table[4],
1537*f1df9364SStefan Roese pattern_test_pattern_table[5],
1538*f1df9364SStefan Roese pattern_test_pattern_table[6],
1539*f1df9364SStefan Roese pattern_test_pattern_table[7]));
1540*f1df9364SStefan Roese DEBUG_LEVELING(
1541*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1542*f1df9364SStefan Roese ("XSB-compt: recieved 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1543*f1df9364SStefan Roese read_pattern[0], read_pattern[1],
1544*f1df9364SStefan Roese read_pattern[2], read_pattern[3],
1545*f1df9364SStefan Roese read_pattern[4], read_pattern[5],
1546*f1df9364SStefan Roese read_pattern[6], read_pattern[7]));
1547*f1df9364SStefan Roese
1548*f1df9364SStefan Roese DEBUG_LEVELING(
1549*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1550*f1df9364SStefan Roese ("XSB-compt: IF %d bus_id %d num_of_succ_byte_compare %d - Fail !\n",
1551*f1df9364SStefan Roese if_id, bus_id, num_of_succ_byte_compare));
1552*f1df9364SStefan Roese
1553*f1df9364SStefan Roese return MV_FAIL;
1554*f1df9364SStefan Roese }
1555*f1df9364SStefan Roese }
1556*f1df9364SStefan Roese
1557*f1df9364SStefan Roese /*
1558*f1df9364SStefan Roese * Clock error shift - function moves the write leveling delay 1cc forward
1559*f1df9364SStefan Roese */
ddr3_tip_wl_supp_one_clk_err_shift(u32 dev_num,u32 if_id,u32 bus_id,u32 bus_id_delta)1560*f1df9364SStefan Roese static int ddr3_tip_wl_supp_one_clk_err_shift(u32 dev_num, u32 if_id,
1561*f1df9364SStefan Roese u32 bus_id, u32 bus_id_delta)
1562*f1df9364SStefan Roese {
1563*f1df9364SStefan Roese int phase, adll;
1564*f1df9364SStefan Roese u32 data;
1565*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_TRACE, ("One_clk_err_shift\n"));
1566*f1df9364SStefan Roese
1567*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read
1568*f1df9364SStefan Roese (dev_num, if_id, ACCESS_TYPE_UNICAST, bus_id,
1569*f1df9364SStefan Roese DDR_PHY_DATA, WL_PHY_REG, &data));
1570*f1df9364SStefan Roese phase = ((data >> 6) & 0x7);
1571*f1df9364SStefan Roese adll = data & 0x1f;
1572*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
1573*f1df9364SStefan Roese ("One_clk_err_shift: IF %d bus_id %d phase %d adll %d\n",
1574*f1df9364SStefan Roese if_id, bus_id, phase, adll));
1575*f1df9364SStefan Roese
1576*f1df9364SStefan Roese if ((phase == 0) || (phase == 1)) {
1577*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1578*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, bus_id,
1579*f1df9364SStefan Roese DDR_PHY_DATA, 0, (phase + 2), 0x1f));
1580*f1df9364SStefan Roese } else if (phase == 2) {
1581*f1df9364SStefan Roese if (adll < 6) {
1582*f1df9364SStefan Roese data = (3 << 6) + (0x1f);
1583*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1584*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1585*f1df9364SStefan Roese bus_id, DDR_PHY_DATA, 0, data,
1586*f1df9364SStefan Roese (0x7 << 6 | 0x1f)));
1587*f1df9364SStefan Roese data = 0x2f;
1588*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1589*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1590*f1df9364SStefan Roese bus_id, DDR_PHY_DATA, 1, data, 0x3f));
1591*f1df9364SStefan Roese }
1592*f1df9364SStefan Roese } else {
1593*f1df9364SStefan Roese /* phase 3 */
1594*f1df9364SStefan Roese return MV_FAIL;
1595*f1df9364SStefan Roese }
1596*f1df9364SStefan Roese
1597*f1df9364SStefan Roese return MV_OK;
1598*f1df9364SStefan Roese }
1599*f1df9364SStefan Roese
1600*f1df9364SStefan Roese /*
1601*f1df9364SStefan Roese * Align error shift
1602*f1df9364SStefan Roese */
ddr3_tip_wl_supp_align_err_shift(u32 dev_num,u32 if_id,u32 bus_id,u32 bus_id_delta)1603*f1df9364SStefan Roese static int ddr3_tip_wl_supp_align_err_shift(u32 dev_num, u32 if_id,
1604*f1df9364SStefan Roese u32 bus_id, u32 bus_id_delta)
1605*f1df9364SStefan Roese {
1606*f1df9364SStefan Roese int phase, adll;
1607*f1df9364SStefan Roese u32 data;
1608*f1df9364SStefan Roese
1609*f1df9364SStefan Roese /* Shift WL result 1 phase back */
1610*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id, ACCESS_TYPE_UNICAST,
1611*f1df9364SStefan Roese bus_id, DDR_PHY_DATA, WL_PHY_REG,
1612*f1df9364SStefan Roese &data));
1613*f1df9364SStefan Roese phase = ((data >> 6) & 0x7);
1614*f1df9364SStefan Roese adll = data & 0x1f;
1615*f1df9364SStefan Roese DEBUG_LEVELING(
1616*f1df9364SStefan Roese DEBUG_LEVEL_TRACE,
1617*f1df9364SStefan Roese ("Wl_supp_align_err_shift: IF %d bus_id %d phase %d adll %d\n",
1618*f1df9364SStefan Roese if_id, bus_id, phase, adll));
1619*f1df9364SStefan Roese
1620*f1df9364SStefan Roese if (phase < 2) {
1621*f1df9364SStefan Roese if (adll > 0x1a) {
1622*f1df9364SStefan Roese if (phase == 0)
1623*f1df9364SStefan Roese return MV_FAIL;
1624*f1df9364SStefan Roese
1625*f1df9364SStefan Roese if (phase == 1) {
1626*f1df9364SStefan Roese data = 0;
1627*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1628*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
1629*f1df9364SStefan Roese if_id, bus_id, DDR_PHY_DATA,
1630*f1df9364SStefan Roese 0, data, (0x7 << 6 | 0x1f)));
1631*f1df9364SStefan Roese data = 0xf;
1632*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1633*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
1634*f1df9364SStefan Roese if_id, bus_id, DDR_PHY_DATA,
1635*f1df9364SStefan Roese 1, data, 0x1f));
1636*f1df9364SStefan Roese return MV_OK;
1637*f1df9364SStefan Roese }
1638*f1df9364SStefan Roese } else {
1639*f1df9364SStefan Roese return MV_FAIL;
1640*f1df9364SStefan Roese }
1641*f1df9364SStefan Roese } else if ((phase == 2) || (phase == 3)) {
1642*f1df9364SStefan Roese phase = phase - 2;
1643*f1df9364SStefan Roese data = (phase << 6) + (adll & 0x1f);
1644*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1645*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, bus_id,
1646*f1df9364SStefan Roese DDR_PHY_DATA, 0, data, (0x7 << 6 | 0x1f)));
1647*f1df9364SStefan Roese return MV_OK;
1648*f1df9364SStefan Roese } else {
1649*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
1650*f1df9364SStefan Roese ("Wl_supp_align_err_shift: unexpected phase\n"));
1651*f1df9364SStefan Roese
1652*f1df9364SStefan Roese return MV_FAIL;
1653*f1df9364SStefan Roese }
1654*f1df9364SStefan Roese
1655*f1df9364SStefan Roese return MV_OK;
1656*f1df9364SStefan Roese }
1657*f1df9364SStefan Roese
1658*f1df9364SStefan Roese /*
1659*f1df9364SStefan Roese * Dynamic write leveling sequence
1660*f1df9364SStefan Roese */
ddr3_tip_dynamic_write_leveling_seq(u32 dev_num)1661*f1df9364SStefan Roese static int ddr3_tip_dynamic_write_leveling_seq(u32 dev_num)
1662*f1df9364SStefan Roese {
1663*f1df9364SStefan Roese u32 bus_id, dq_id;
1664*f1df9364SStefan Roese u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
1665*f1df9364SStefan Roese u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
1666*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1667*f1df9364SStefan Roese
1668*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1669*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1670*f1df9364SStefan Roese TRAINING_SW_2_REG, 0x1, 0x5));
1671*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1672*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1673*f1df9364SStefan Roese TRAINING_WRITE_LEVELING_REG, 0x50, 0xff));
1674*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1675*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1676*f1df9364SStefan Roese TRAINING_WRITE_LEVELING_REG, 0x5c, 0xff));
1677*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1678*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1679*f1df9364SStefan Roese ODPG_TRAINING_CONTROL_REG, 0x381b82, 0x3c3faf));
1680*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1681*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1682*f1df9364SStefan Roese ODPG_OBJ1_OPCODE_REG, (0x3 << 25), (0x3ffff << 9)));
1683*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1684*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1685*f1df9364SStefan Roese ODPG_OBJ1_ITER_CNT_REG, 0x80, 0xffff));
1686*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1687*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1688*f1df9364SStefan Roese ODPG_WRITE_LEVELING_DONE_CNTR_REG, 0x14, 0xff));
1689*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1690*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1691*f1df9364SStefan Roese TRAINING_WRITE_LEVELING_REG, 0xff5c, 0xffff));
1692*f1df9364SStefan Roese
1693*f1df9364SStefan Roese /* mask PBS */
1694*f1df9364SStefan Roese for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
1695*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1696*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1697*f1df9364SStefan Roese mask_results_dq_reg_map[dq_id], 0x1 << 24,
1698*f1df9364SStefan Roese 0x1 << 24));
1699*f1df9364SStefan Roese }
1700*f1df9364SStefan Roese
1701*f1df9364SStefan Roese /* Mask all results */
1702*f1df9364SStefan Roese for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
1703*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1704*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1705*f1df9364SStefan Roese mask_results_pup_reg_map[bus_id], 0x1 << 24,
1706*f1df9364SStefan Roese 0x1 << 24));
1707*f1df9364SStefan Roese }
1708*f1df9364SStefan Roese
1709*f1df9364SStefan Roese /* Unmask only wanted */
1710*f1df9364SStefan Roese for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
1711*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
1712*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1713*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1714*f1df9364SStefan Roese mask_results_pup_reg_map[bus_id], 0, 0x1 << 24));
1715*f1df9364SStefan Roese }
1716*f1df9364SStefan Roese
1717*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1718*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1719*f1df9364SStefan Roese WR_LEVELING_DQS_PATTERN_REG, 0x1, 0x1));
1720*f1df9364SStefan Roese
1721*f1df9364SStefan Roese return MV_OK;
1722*f1df9364SStefan Roese }
1723*f1df9364SStefan Roese
1724*f1df9364SStefan Roese /*
1725*f1df9364SStefan Roese * Dynamic read leveling sequence
1726*f1df9364SStefan Roese */
ddr3_tip_dynamic_read_leveling_seq(u32 dev_num)1727*f1df9364SStefan Roese static int ddr3_tip_dynamic_read_leveling_seq(u32 dev_num)
1728*f1df9364SStefan Roese {
1729*f1df9364SStefan Roese u32 bus_id, dq_id;
1730*f1df9364SStefan Roese u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
1731*f1df9364SStefan Roese u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
1732*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1733*f1df9364SStefan Roese
1734*f1df9364SStefan Roese /* mask PBS */
1735*f1df9364SStefan Roese for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
1736*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1737*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1738*f1df9364SStefan Roese mask_results_dq_reg_map[dq_id], 0x1 << 24,
1739*f1df9364SStefan Roese 0x1 << 24));
1740*f1df9364SStefan Roese }
1741*f1df9364SStefan Roese
1742*f1df9364SStefan Roese /* Mask all results */
1743*f1df9364SStefan Roese for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
1744*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1745*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1746*f1df9364SStefan Roese mask_results_pup_reg_map[bus_id], 0x1 << 24,
1747*f1df9364SStefan Roese 0x1 << 24));
1748*f1df9364SStefan Roese }
1749*f1df9364SStefan Roese
1750*f1df9364SStefan Roese /* Unmask only wanted */
1751*f1df9364SStefan Roese for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
1752*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
1753*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1754*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1755*f1df9364SStefan Roese mask_results_pup_reg_map[bus_id], 0, 0x1 << 24));
1756*f1df9364SStefan Roese }
1757*f1df9364SStefan Roese
1758*f1df9364SStefan Roese return MV_OK;
1759*f1df9364SStefan Roese }
1760*f1df9364SStefan Roese
1761*f1df9364SStefan Roese /*
1762*f1df9364SStefan Roese * Dynamic read leveling sequence
1763*f1df9364SStefan Roese */
ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num)1764*f1df9364SStefan Roese static int ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num)
1765*f1df9364SStefan Roese {
1766*f1df9364SStefan Roese u32 bus_id, dq_id;
1767*f1df9364SStefan Roese u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
1768*f1df9364SStefan Roese u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
1769*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1770*f1df9364SStefan Roese
1771*f1df9364SStefan Roese /* mask PBS */
1772*f1df9364SStefan Roese for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
1773*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1774*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1775*f1df9364SStefan Roese mask_results_dq_reg_map[dq_id], 0x1 << 24,
1776*f1df9364SStefan Roese 0x1 << 24));
1777*f1df9364SStefan Roese }
1778*f1df9364SStefan Roese
1779*f1df9364SStefan Roese /* Mask all results */
1780*f1df9364SStefan Roese for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
1781*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1782*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1783*f1df9364SStefan Roese mask_results_pup_reg_map[bus_id], 0x1 << 24,
1784*f1df9364SStefan Roese 0x1 << 24));
1785*f1df9364SStefan Roese }
1786*f1df9364SStefan Roese
1787*f1df9364SStefan Roese /* Unmask only wanted */
1788*f1df9364SStefan Roese for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
1789*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, dq_id / 8);
1790*f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1791*f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1792*f1df9364SStefan Roese mask_results_dq_reg_map[dq_id], 0x0 << 24,
1793*f1df9364SStefan Roese 0x1 << 24));
1794*f1df9364SStefan Roese }
1795*f1df9364SStefan Roese
1796*f1df9364SStefan Roese return MV_OK;
1797*f1df9364SStefan Roese }
1798*f1df9364SStefan Roese
1799*f1df9364SStefan Roese /*
1800*f1df9364SStefan Roese * Print write leveling supplementary results
1801*f1df9364SStefan Roese */
ddr3_tip_print_wl_supp_result(u32 dev_num)1802*f1df9364SStefan Roese int ddr3_tip_print_wl_supp_result(u32 dev_num)
1803*f1df9364SStefan Roese {
1804*f1df9364SStefan Roese u32 bus_id = 0, if_id = 0;
1805*f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1806*f1df9364SStefan Roese
1807*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_INFO,
1808*f1df9364SStefan Roese ("I/F0 PUP0 Result[0 - success, 1-fail] ...\n"));
1809*f1df9364SStefan Roese
1810*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1811*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1812*f1df9364SStefan Roese for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
1813*f1df9364SStefan Roese bus_id++) {
1814*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
1815*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_INFO,
1816*f1df9364SStefan Roese ("%d ,", wr_supp_res[if_id]
1817*f1df9364SStefan Roese [bus_id].is_pup_fail));
1818*f1df9364SStefan Roese }
1819*f1df9364SStefan Roese }
1820*f1df9364SStefan Roese DEBUG_LEVELING(
1821*f1df9364SStefan Roese DEBUG_LEVEL_INFO,
1822*f1df9364SStefan Roese ("I/F0 PUP0 Stage[0-phase_shift, 1-clock_shift, 2-align_shift] ...\n"));
1823*f1df9364SStefan Roese
1824*f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1825*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1826*f1df9364SStefan Roese for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
1827*f1df9364SStefan Roese bus_id++) {
1828*f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
1829*f1df9364SStefan Roese DEBUG_LEVELING(DEBUG_LEVEL_INFO,
1830*f1df9364SStefan Roese ("%d ,", wr_supp_res[if_id]
1831*f1df9364SStefan Roese [bus_id].stage));
1832*f1df9364SStefan Roese }
1833*f1df9364SStefan Roese }
1834*f1df9364SStefan Roese
1835*f1df9364SStefan Roese return MV_OK;
1836*f1df9364SStefan Roese }
1837