]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c
Merge branch 'master' of git://www.denx.de/git/u-boot-imx
[karo-tx-uboot.git] / drivers / ddr / marvell / a38x / ddr3_training_ip_engine.c
1 /*
2  * Copyright (C) Marvell International Ltd. and its affiliates
3  *
4  * SPDX-License-Identifier:     GPL-2.0
5  */
6
7 #include <common.h>
8 #include <spl.h>
9 #include <asm/io.h>
10 #include <asm/arch/cpu.h>
11 #include <asm/arch/soc.h>
12
13 #include "ddr3_init.h"
14
15 #define PATTERN_1       0x55555555
16 #define PATTERN_2       0xaaaaaaaa
17
18 #define VALIDATE_TRAINING_LIMIT(e1, e2)                 \
19         ((((e2) - (e1) + 1) > 33) && ((e1) < 67))
20
21 u32 phy_reg_bk[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
22
23 u32 training_res[MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS *
24                  HWS_SEARCH_DIR_LIMIT];
25
26 u16 mask_results_dq_reg_map[] = {
27         RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
28         RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
29         RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
30         RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
31         RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
32         RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
33         RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
34         RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
35         RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
36         RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
37         RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
38         RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
39         RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG,
40         RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
41         RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG,
42         RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG,
43         RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
44         RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
45         RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
46         RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
47 };
48
49 u16 mask_results_pup_reg_map[] = {
50         RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
51         RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_3_REG,
52         RESULT_CONTROL_BYTE_PUP_4_REG
53 };
54
55 u16 mask_results_dq_reg_map_pup3_ecc[] = {
56         RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
57         RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
58         RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
59         RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
60         RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
61         RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
62         RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
63         RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
64         RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
65         RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
66         RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
67         RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
68         RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
69         RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
70         RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
71         RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
72         RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
73         RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
74         RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
75         RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
76 };
77
78 u16 mask_results_pup_reg_map_pup3_ecc[] = {
79         RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
80         RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_4_REG,
81         RESULT_CONTROL_BYTE_PUP_4_REG
82 };
83
84 struct pattern_info pattern_table_16[] = {
85         /*
86          * num tx phases, tx burst, delay between, rx pattern,
87          * start_address, pattern_len
88          */
89         {1, 1, 2, 1, 0x0080, 2},        /* PATTERN_PBS1 */
90         {1, 1, 2, 1, 0x00c0, 2},        /* PATTERN_PBS2 */
91         {1, 1, 2, 1, 0x0100, 2},        /* PATTERN_RL */
92         {0xf, 0x7, 2, 0x7, 0x0140, 16}, /* PATTERN_STATIC_PBS */
93         {0xf, 0x7, 2, 0x7, 0x0190, 16}, /* PATTERN_KILLER_DQ0 */
94         {0xf, 0x7, 2, 0x7, 0x01d0, 16}, /* PATTERN_KILLER_DQ1 */
95         {0xf, 0x7, 2, 0x7, 0x0210, 16}, /* PATTERN_KILLER_DQ2 */
96         {0xf, 0x7, 2, 0x7, 0x0250, 16}, /* PATTERN_KILLER_DQ3 */
97         {0xf, 0x7, 2, 0x7, 0x0290, 16}, /* PATTERN_KILLER_DQ4 */
98         {0xf, 0x7, 2, 0x7, 0x02d0, 16}, /* PATTERN_KILLER_DQ5 */
99         {0xf, 0x7, 2, 0x7, 0x0310, 16}, /* PATTERN_KILLER_DQ6 */
100         {0xf, 0x7, 2, 0x7, 0x0350, 16}, /* PATTERN_KILLER_DQ7 */
101         {1, 1, 2, 1, 0x0380, 2},        /* PATTERN_PBS3 */
102         {1, 1, 2, 1, 0x0000, 2},        /* PATTERN_RL2 */
103         {1, 1, 2, 1, 0x0040, 2},        /* PATTERN_TEST */
104         {0xf, 0x7, 2, 0x7, 0x03c0, 16}, /* PATTERN_FULL_SSO_1T */
105         {0xf, 0x7, 2, 0x7, 0x0400, 16}, /* PATTERN_FULL_SSO_2T */
106         {0xf, 0x7, 2, 0x7, 0x0440, 16}, /* PATTERN_FULL_SSO_3T */
107         {0xf, 0x7, 2, 0x7, 0x0480, 16}, /* PATTERN_FULL_SSO_4T */
108         {0xf, 0x7, 2, 0x7, 0x04c0, 16}  /* PATTERN_VREF */
109         /*Note: actual start_address is <<3 of defined addess */
110 };
111
112 struct pattern_info pattern_table_32[] = {
113         /*
114          * num tx phases, tx burst, delay between, rx pattern,
115          * start_address, pattern_len
116          */
117         {3, 3, 2, 3, 0x0080, 4},        /* PATTERN_PBS1 */
118         {3, 3, 2, 3, 0x00c0, 4},        /* PATTERN_PBS2 */
119         {3, 3, 2, 3, 0x0100, 4},        /* PATTERN_RL */
120         {0x1f, 0xf, 2, 0xf, 0x0140, 32},        /* PATTERN_STATIC_PBS */
121         {0x1f, 0xf, 2, 0xf, 0x0190, 32},        /* PATTERN_KILLER_DQ0 */
122         {0x1f, 0xf, 2, 0xf, 0x01d0, 32},        /* PATTERN_KILLER_DQ1 */
123         {0x1f, 0xf, 2, 0xf, 0x0210, 32},        /* PATTERN_KILLER_DQ2 */
124         {0x1f, 0xf, 2, 0xf, 0x0250, 32},        /* PATTERN_KILLER_DQ3 */
125         {0x1f, 0xf, 2, 0xf, 0x0290, 32},        /* PATTERN_KILLER_DQ4 */
126         {0x1f, 0xf, 2, 0xf, 0x02d0, 32},        /* PATTERN_KILLER_DQ5 */
127         {0x1f, 0xf, 2, 0xf, 0x0310, 32},        /* PATTERN_KILLER_DQ6 */
128         {0x1f, 0xf, 2, 0xf, 0x0350, 32},        /* PATTERN_KILLER_DQ7 */
129         {3, 3, 2, 3, 0x0380, 4},        /* PATTERN_PBS3 */
130         {3, 3, 2, 3, 0x0000, 4},        /* PATTERN_RL2 */
131         {3, 3, 2, 3, 0x0040, 4},        /* PATTERN_TEST */
132         {0x1f, 0xf, 2, 0xf, 0x03c0, 32},        /* PATTERN_FULL_SSO_1T */
133         {0x1f, 0xf, 2, 0xf, 0x0400, 32},        /* PATTERN_FULL_SSO_2T */
134         {0x1f, 0xf, 2, 0xf, 0x0440, 32},        /* PATTERN_FULL_SSO_3T */
135         {0x1f, 0xf, 2, 0xf, 0x0480, 32},        /* PATTERN_FULL_SSO_4T */
136         {0x1f, 0xf, 2, 0xf, 0x04c0, 32} /* PATTERN_VREF */
137         /*Note: actual start_address is <<3 of defined addess */
138 };
139
140 u32 train_dev_num;
141 enum hws_ddr_cs traintrain_cs_type;
142 u32 train_pup_num;
143 enum hws_training_result train_result_type;
144 enum hws_control_element train_control_element;
145 enum hws_search_dir traine_search_dir;
146 enum hws_dir train_direction;
147 u32 train_if_select;
148 u32 train_init_value;
149 u32 train_number_iterations;
150 enum hws_pattern train_pattern;
151 enum hws_edge_compare train_edge_compare;
152 u32 train_cs_num;
153 u32 train_if_acess, train_if_id, train_pup_access;
154 u32 max_polling_for_done = 1000000;
155
156 u32 *ddr3_tip_get_buf_ptr(u32 dev_num, enum hws_search_dir search,
157                           enum hws_training_result result_type,
158                           u32 interface_num)
159 {
160         u32 *buf_ptr = NULL;
161
162         buf_ptr = &training_res
163                 [MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS * search +
164                  interface_num * MAX_BUS_NUM * BUS_WIDTH_IN_BITS];
165
166         return buf_ptr;
167 }
168
169 /*
170  * IP Training search
171  * Note: for one edge search only from fail to pass, else jitter can
172  * be be entered into solution.
173  */
174 int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
175                          u32 interface_num,
176                          enum hws_access_type pup_access_type,
177                          u32 pup_num, enum hws_training_result result_type,
178                          enum hws_control_element control_element,
179                          enum hws_search_dir search_dir, enum hws_dir direction,
180                          u32 interface_mask, u32 init_value, u32 num_iter,
181                          enum hws_pattern pattern,
182                          enum hws_edge_compare edge_comp,
183                          enum hws_ddr_cs cs_type, u32 cs_num,
184                          enum hws_training_ip_stat *train_status)
185 {
186         u32 mask_dq_num_of_regs, mask_pup_num_of_regs, index_cnt, poll_cnt,
187                 reg_data, pup_id;
188         u32 tx_burst_size;
189         u32 delay_between_burst;
190         u32 rd_mode;
191         u32 read_data[MAX_INTERFACE_NUM];
192         struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
193         u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
194         u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
195         struct hws_topology_map *tm = ddr3_get_topology_map();
196
197         if (pup_num >= tm->num_of_bus_per_interface) {
198                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
199                                          ("pup_num %d not valid\n", pup_num));
200         }
201         if (interface_num >= MAX_INTERFACE_NUM) {
202                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
203                                          ("if_id %d not valid\n",
204                                           interface_num));
205         }
206         if (train_status == NULL) {
207                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
208                                          ("error param 4\n"));
209                 return MV_BAD_PARAM;
210         }
211
212         /* load pattern */
213         if (cs_type == CS_SINGLE) {
214                 /* All CSs to CS0     */
215                 CHECK_STATUS(ddr3_tip_if_write
216                              (dev_num, access_type, interface_num,
217                               CS_ENABLE_REG, 1 << 3, 1 << 3));
218                 /* All CSs to CS0     */
219                 CHECK_STATUS(ddr3_tip_if_write
220                              (dev_num, access_type, interface_num,
221                               ODPG_DATA_CONTROL_REG,
222                               (0x3 | (effective_cs << 26)), 0xc000003));
223         } else {
224                 CHECK_STATUS(ddr3_tip_if_write
225                              (dev_num, access_type, interface_num,
226                               CS_ENABLE_REG, 0, 1 << 3));
227                 /*  CS select */
228                 CHECK_STATUS(ddr3_tip_if_write
229                              (dev_num, access_type, interface_num,
230                               ODPG_DATA_CONTROL_REG, 0x3 | cs_num << 26,
231                               0x3 | 3 << 26));
232         }
233
234         /* load pattern to ODPG */
235         ddr3_tip_load_pattern_to_odpg(dev_num, access_type, interface_num,
236                                       pattern,
237                                       pattern_table[pattern].start_addr);
238         tx_burst_size = (direction == OPER_WRITE) ?
239                 pattern_table[pattern].tx_burst_size : 0;
240         delay_between_burst = (direction == OPER_WRITE) ? 2 : 0;
241         rd_mode = (direction == OPER_WRITE) ? 1 : 0;
242         CHECK_STATUS(ddr3_tip_configure_odpg
243                      (dev_num, access_type, interface_num, direction,
244                       pattern_table[pattern].num_of_phases_tx, tx_burst_size,
245                       pattern_table[pattern].num_of_phases_rx,
246                       delay_between_burst, rd_mode, effective_cs, STRESS_NONE,
247                       DURATION_SINGLE));
248         reg_data = (direction == OPER_READ) ? 0 : (0x3 << 30);
249         reg_data |= (direction == OPER_READ) ? 0x60 : 0xfa;
250         CHECK_STATUS(ddr3_tip_if_write
251                      (dev_num, access_type, interface_num,
252                       ODPG_WRITE_READ_MODE_ENABLE_REG, reg_data,
253                       MASK_ALL_BITS));
254         reg_data = (edge_comp == EDGE_PF || edge_comp == EDGE_FP) ? 0 : 1 << 6;
255         reg_data |= (edge_comp == EDGE_PF || edge_comp == EDGE_PFP) ?
256                 (1 << 7) : 0;
257
258         /* change from Pass to Fail will lock the result */
259         if (pup_access_type == ACCESS_TYPE_MULTICAST)
260                 reg_data |= 0xe << 14;
261         else
262                 reg_data |= pup_num << 14;
263
264         if (edge_comp == EDGE_FP) {
265                 /* don't search for readl edge change, only the state */
266                 reg_data |= (0 << 20);
267         } else if (edge_comp == EDGE_FPF) {
268                 reg_data |= (0 << 20);
269         } else {
270                 reg_data |= (3 << 20);
271         }
272
273         CHECK_STATUS(ddr3_tip_if_write
274                      (dev_num, access_type, interface_num,
275                       ODPG_TRAINING_CONTROL_REG,
276                       reg_data | (0x7 << 8) | (0x7 << 11),
277                       (0x3 | (0x3 << 2) | (0x3 << 6) | (1 << 5) | (0x7 << 8) |
278                        (0x7 << 11) | (0xf << 14) | (0x3 << 18) | (3 << 20))));
279         reg_data = (search_dir == HWS_LOW2HIGH) ? 0 : (1 << 8);
280         CHECK_STATUS(ddr3_tip_if_write
281                      (dev_num, access_type, interface_num, ODPG_OBJ1_OPCODE_REG,
282                       1 | reg_data | init_value << 9 | (1 << 25) | (1 << 26),
283                       0xff | (1 << 8) | (0xffff << 9) | (1 << 25) | (1 << 26)));
284
285         /*
286          * Write2_dunit(0x10b4, Number_iteration , [15:0])
287          * Max number of iterations
288          */
289         CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
290                                        ODPG_OBJ1_ITER_CNT_REG, num_iter,
291                                        0xffff));
292         if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
293             direction == OPER_READ) {
294                 /*
295                  * Write2_dunit(0x10c0, 0x5f , [7:0])
296                  * MC PBS Reg Address at DDR PHY
297                  */
298                 reg_data = 0x5f +
299                         effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
300         } else if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
301                    direction == OPER_WRITE) {
302                 reg_data = 0x1f +
303                         effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
304         } else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
305                    direction == OPER_WRITE) {
306                 /*
307                  * LOOP         0x00000001 + 4*n:
308                  * where n (0-3) represents M_CS number
309                  */
310                 /*
311                  * Write2_dunit(0x10c0, 0x1 , [7:0])
312                  * ADLL WR Reg Address at DDR PHY
313                  */
314                 reg_data = 1 + effective_cs * CS_REGISTER_ADDR_OFFSET;
315         } else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
316                    direction == OPER_READ) {
317                 /* ADLL RD Reg Address at DDR PHY */
318                 reg_data = 3 + effective_cs * CS_REGISTER_ADDR_OFFSET;
319         } else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
320                    direction == OPER_WRITE) {
321                 /* TBD not defined in 0.5.0 requirement  */
322         } else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
323                    direction == OPER_READ) {
324                 /* TBD not defined in 0.5.0 requirement */
325         }
326
327         reg_data |= (0x6 << 28);
328         CHECK_STATUS(ddr3_tip_if_write
329                      (dev_num, access_type, interface_num, CALIB_OBJ_PRFA_REG,
330                       reg_data | (init_value << 8),
331                       0xff | (0xffff << 8) | (0xf << 24) | (u32) (0xf << 28)));
332
333         mask_dq_num_of_regs = tm->num_of_bus_per_interface * BUS_WIDTH_IN_BITS;
334         mask_pup_num_of_regs = tm->num_of_bus_per_interface;
335
336         if (result_type == RESULT_PER_BIT) {
337                 for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
338                      index_cnt++) {
339                         CHECK_STATUS(ddr3_tip_if_write
340                                      (dev_num, access_type, interface_num,
341                                       mask_results_dq_reg_map[index_cnt], 0,
342                                       1 << 24));
343                 }
344
345                 /* Mask disabled buses */
346                 for (pup_id = 0; pup_id < tm->num_of_bus_per_interface;
347                      pup_id++) {
348                         if (IS_ACTIVE(tm->bus_act_mask, pup_id) == 1)
349                                 continue;
350
351                         for (index_cnt = (mask_dq_num_of_regs - pup_id * 8);
352                              index_cnt <
353                                      (mask_dq_num_of_regs - (pup_id + 1) * 8);
354                              index_cnt++) {
355                                 CHECK_STATUS(ddr3_tip_if_write
356                                              (dev_num, access_type,
357                                               interface_num,
358                                               mask_results_dq_reg_map
359                                               [index_cnt], (1 << 24), 1 << 24));
360                         }
361                 }
362
363                 for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
364                      index_cnt++) {
365                         CHECK_STATUS(ddr3_tip_if_write
366                                      (dev_num, access_type, interface_num,
367                                       mask_results_pup_reg_map[index_cnt],
368                                       (1 << 24), 1 << 24));
369                 }
370         } else if (result_type == RESULT_PER_BYTE) {
371                 /* write to adll */
372                 for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
373                      index_cnt++) {
374                         CHECK_STATUS(ddr3_tip_if_write
375                                      (dev_num, access_type, interface_num,
376                                       mask_results_pup_reg_map[index_cnt], 0,
377                                       1 << 24));
378                 }
379                 for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
380                      index_cnt++) {
381                         CHECK_STATUS(ddr3_tip_if_write
382                                      (dev_num, access_type, interface_num,
383                                       mask_results_dq_reg_map[index_cnt],
384                                       (1 << 24), (1 << 24)));
385                 }
386         }
387
388         /* Start Training Trigger */
389         CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
390                                        ODPG_TRAINING_TRIGGER_REG, 1, 1));
391         /* wait for all RFU tests to finish (or timeout) */
392         /* WA for 16 bit mode, more investigation needed */
393         mdelay(1);
394
395         /* Training "Done ?" */
396         for (index_cnt = 0; index_cnt < MAX_INTERFACE_NUM; index_cnt++) {
397                 if (IS_ACTIVE(tm->if_act_mask, index_cnt) == 0)
398                         continue;
399
400                 if (interface_mask & (1 << index_cnt)) {
401                         /* need to check results for this Dunit */
402                         for (poll_cnt = 0; poll_cnt < max_polling_for_done;
403                              poll_cnt++) {
404                                 CHECK_STATUS(ddr3_tip_if_read
405                                              (dev_num, ACCESS_TYPE_UNICAST,
406                                               index_cnt,
407                                               ODPG_TRAINING_STATUS_REG,
408                                               &reg_data, MASK_ALL_BITS));
409                                 if ((reg_data & 0x2) != 0) {
410                                         /*done */
411                                         train_status[index_cnt] =
412                                                 HWS_TRAINING_IP_STATUS_SUCCESS;
413                                         break;
414                                 }
415                         }
416
417                         if (poll_cnt == max_polling_for_done) {
418                                 train_status[index_cnt] =
419                                         HWS_TRAINING_IP_STATUS_TIMEOUT;
420                         }
421                 }
422                 /* Be sure that ODPG done */
423                 CHECK_STATUS(is_odpg_access_done(dev_num, index_cnt));
424         }
425
426         /* Write ODPG done in Dunit */
427         CHECK_STATUS(ddr3_tip_if_write
428                      (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
429                       ODPG_STATUS_DONE_REG, 0, 0x1));
430
431         /* wait for all Dunit tests to finish (or timeout) */
432         /* Training "Done ?" */
433         /* Training "Pass ?" */
434         for (index_cnt = 0; index_cnt < MAX_INTERFACE_NUM; index_cnt++) {
435                 if (IS_ACTIVE(tm->if_act_mask, index_cnt) == 0)
436                         continue;
437
438                 if (interface_mask & (1 << index_cnt)) {
439                         /* need to check results for this Dunit */
440                         for (poll_cnt = 0; poll_cnt < max_polling_for_done;
441                              poll_cnt++) {
442                                 CHECK_STATUS(ddr3_tip_if_read
443                                              (dev_num, ACCESS_TYPE_UNICAST,
444                                               index_cnt,
445                                               ODPG_TRAINING_TRIGGER_REG,
446                                               read_data, MASK_ALL_BITS));
447                                 reg_data = read_data[index_cnt];
448                                 if ((reg_data & 0x2) != 0) {
449                                         /* done */
450                                         if ((reg_data & 0x4) == 0) {
451                                                 train_status[index_cnt] =
452                                                         HWS_TRAINING_IP_STATUS_SUCCESS;
453                                         } else {
454                                                 train_status[index_cnt] =
455                                                         HWS_TRAINING_IP_STATUS_FAIL;
456                                         }
457                                         break;
458                                 }
459                         }
460
461                         if (poll_cnt == max_polling_for_done) {
462                                 train_status[index_cnt] =
463                                         HWS_TRAINING_IP_STATUS_TIMEOUT;
464                         }
465                 }
466         }
467
468         CHECK_STATUS(ddr3_tip_if_write
469                      (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
470                       ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
471
472         return MV_OK;
473 }
474
475 /*
476  * Load expected Pattern to ODPG
477  */
478 int ddr3_tip_load_pattern_to_odpg(u32 dev_num, enum hws_access_type access_type,
479                                   u32 if_id, enum hws_pattern pattern,
480                                   u32 load_addr)
481 {
482         u32 pattern_length_cnt = 0;
483         struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
484
485         for (pattern_length_cnt = 0;
486              pattern_length_cnt < pattern_table[pattern].pattern_len;
487              pattern_length_cnt++) {
488                 CHECK_STATUS(ddr3_tip_if_write
489                              (dev_num, access_type, if_id,
490                               ODPG_PATTERN_DATA_LOW_REG,
491                               pattern_table_get_word(dev_num, pattern,
492                                                      (u8) (pattern_length_cnt *
493                                                            2)), MASK_ALL_BITS));
494                 CHECK_STATUS(ddr3_tip_if_write
495                              (dev_num, access_type, if_id,
496                               ODPG_PATTERN_DATA_HI_REG,
497                               pattern_table_get_word(dev_num, pattern,
498                                                      (u8) (pattern_length_cnt *
499                                                            2 + 1)),
500                               MASK_ALL_BITS));
501                 CHECK_STATUS(ddr3_tip_if_write
502                              (dev_num, access_type, if_id,
503                               ODPG_PATTERN_ADDR_REG, pattern_length_cnt,
504                               MASK_ALL_BITS));
505         }
506
507         CHECK_STATUS(ddr3_tip_if_write
508                      (dev_num, access_type, if_id,
509                       ODPG_PATTERN_ADDR_OFFSET_REG, load_addr, MASK_ALL_BITS));
510
511         return MV_OK;
512 }
513
514 /*
515  * Configure ODPG
516  */
517 int ddr3_tip_configure_odpg(u32 dev_num, enum hws_access_type access_type,
518                             u32 if_id, enum hws_dir direction, u32 tx_phases,
519                             u32 tx_burst_size, u32 rx_phases,
520                             u32 delay_between_burst, u32 rd_mode, u32 cs_num,
521                             u32 addr_stress_jump, u32 single_pattern)
522 {
523         u32 data_value = 0;
524         int ret;
525
526         data_value = ((single_pattern << 2) | (tx_phases << 5) |
527                       (tx_burst_size << 11) | (delay_between_burst << 15) |
528                       (rx_phases << 21) | (rd_mode << 25) | (cs_num << 26) |
529                       (addr_stress_jump << 29));
530         ret = ddr3_tip_if_write(dev_num, access_type, if_id,
531                                 ODPG_DATA_CONTROL_REG, data_value, 0xaffffffc);
532         if (ret != MV_OK)
533                 return ret;
534
535         return MV_OK;
536 }
537
538 int ddr3_tip_process_result(u32 *ar_result, enum hws_edge e_edge,
539                             enum hws_edge_search e_edge_search,
540                             u32 *edge_result)
541 {
542         u32 i, res;
543         int tap_val, max_val = -10000, min_val = 10000;
544         int lock_success = 1;
545
546         for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
547                 res = GET_LOCK_RESULT(ar_result[i]);
548                 if (res == 0) {
549                         lock_success = 0;
550                         break;
551                 }
552                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
553                                          ("lock failed for bit %d\n", i));
554         }
555
556         if (lock_success == 1) {
557                 for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
558                         tap_val = GET_TAP_RESULT(ar_result[i], e_edge);
559                         if (tap_val > max_val)
560                                 max_val = tap_val;
561                         if (tap_val < min_val)
562                                 min_val = tap_val;
563                         if (e_edge_search == TRAINING_EDGE_MAX)
564                                 *edge_result = (u32) max_val;
565                         else
566                                 *edge_result = (u32) min_val;
567
568                         DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
569                                                  ("i %d ar_result[i] 0x%x tap_val %d max_val %d min_val %d Edge_result %d\n",
570                                                   i, ar_result[i], tap_val,
571                                                   max_val, min_val,
572                                                   *edge_result));
573                 }
574         } else {
575                 return MV_FAIL;
576         }
577
578         return MV_OK;
579 }
580
581 /*
582  * Read training search result
583  */
584 int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
585                                   enum hws_access_type pup_access_type,
586                                   u32 pup_num, u32 bit_num,
587                                   enum hws_search_dir search,
588                                   enum hws_dir direction,
589                                   enum hws_training_result result_type,
590                                   enum hws_training_load_op operation,
591                                   u32 cs_num_type, u32 **load_res,
592                                   int is_read_from_db, u8 cons_tap,
593                                   int is_check_result_validity)
594 {
595         u32 reg_offset, pup_cnt, start_pup, end_pup, start_reg, end_reg;
596         u32 *interface_train_res = NULL;
597         u16 *reg_addr = NULL;
598         u32 read_data[MAX_INTERFACE_NUM];
599         u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
600         u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
601         struct hws_topology_map *tm = ddr3_get_topology_map();
602
603         /*
604          * Agreed assumption: all CS mask contain same number of bits,
605          * i.e. in multi CS, the number of CS per memory is the same for
606          * all pups
607          */
608         CHECK_STATUS(ddr3_tip_if_write
609                      (dev_num, ACCESS_TYPE_UNICAST, if_id, CS_ENABLE_REG,
610                       (cs_num_type == 0) ? 1 << 3 : 0, (1 << 3)));
611         CHECK_STATUS(ddr3_tip_if_write
612                      (dev_num, ACCESS_TYPE_UNICAST, if_id,
613                       ODPG_DATA_CONTROL_REG, (cs_num_type << 26), (3 << 26)));
614         DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
615                                  ("Read_from_d_b %d cs_type %d oper %d result_type %d direction %d search %d pup_num %d if_id %d pup_access_type %d\n",
616                                   is_read_from_db, cs_num_type, operation,
617                                   result_type, direction, search, pup_num,
618                                   if_id, pup_access_type));
619
620         if ((load_res == NULL) && (is_read_from_db == 1)) {
621                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
622                                          ("ddr3_tip_read_training_result load_res = NULL"));
623                 return MV_FAIL;
624         }
625         if (pup_num >= tm->num_of_bus_per_interface) {
626                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
627                                          ("pup_num %d not valid\n", pup_num));
628         }
629         if (if_id >= MAX_INTERFACE_NUM) {
630                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
631                                          ("if_id %d not valid\n", if_id));
632         }
633         if (result_type == RESULT_PER_BIT)
634                 reg_addr = mask_results_dq_reg_map;
635         else
636                 reg_addr = mask_results_pup_reg_map;
637         if (pup_access_type == ACCESS_TYPE_UNICAST) {
638                 start_pup = pup_num;
639                 end_pup = pup_num;
640         } else {                /*pup_access_type == ACCESS_TYPE_MULTICAST) */
641
642                 start_pup = 0;
643                 end_pup = tm->num_of_bus_per_interface - 1;
644         }
645
646         for (pup_cnt = start_pup; pup_cnt <= end_pup; pup_cnt++) {
647                 VALIDATE_ACTIVE(tm->bus_act_mask, pup_cnt);
648                 DEBUG_TRAINING_IP_ENGINE(
649                         DEBUG_LEVEL_TRACE,
650                         ("if_id %d start_pup %d end_pup %d pup_cnt %d\n",
651                          if_id, start_pup, end_pup, pup_cnt));
652                 if (result_type == RESULT_PER_BIT) {
653                         if (bit_num == ALL_BITS_PER_PUP) {
654                                 start_reg = pup_cnt * BUS_WIDTH_IN_BITS;
655                                 end_reg = (pup_cnt + 1) * BUS_WIDTH_IN_BITS - 1;
656                         } else {
657                                 start_reg =
658                                         pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
659                                 end_reg = pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
660                         }
661                 } else {
662                         start_reg = pup_cnt;
663                         end_reg = pup_cnt;
664                 }
665
666                 interface_train_res =
667                         ddr3_tip_get_buf_ptr(dev_num, search, result_type,
668                                              if_id);
669                 DEBUG_TRAINING_IP_ENGINE(
670                         DEBUG_LEVEL_TRACE,
671                         ("start_reg %d end_reg %d interface %p\n",
672                          start_reg, end_reg, interface_train_res));
673                 if (interface_train_res == NULL) {
674                         DEBUG_TRAINING_IP_ENGINE(
675                                 DEBUG_LEVEL_ERROR,
676                                 ("interface_train_res is NULL\n"));
677                         return MV_FAIL;
678                 }
679
680                 for (reg_offset = start_reg; reg_offset <= end_reg;
681                      reg_offset++) {
682                         if (operation == TRAINING_LOAD_OPERATION_UNLOAD) {
683                                 if (is_read_from_db == 0) {
684                                         CHECK_STATUS(ddr3_tip_if_read
685                                                      (dev_num,
686                                                       ACCESS_TYPE_UNICAST,
687                                                       if_id,
688                                                       reg_addr[reg_offset],
689                                                       read_data,
690                                                       MASK_ALL_BITS));
691                                         if (is_check_result_validity == 1) {
692                                                 if ((read_data[if_id] &
693                                                      0x02000000) == 0) {
694                                                         interface_train_res
695                                                                 [reg_offset] =
696                                                                 0x02000000 +
697                                                                 64 + cons_tap;
698                                                 } else {
699                                                         interface_train_res
700                                                                 [reg_offset] =
701                                                                 read_data
702                                                                 [if_id] +
703                                                                 cons_tap;
704                                                 }
705                                         } else {
706                                                 interface_train_res[reg_offset]
707                                                         = read_data[if_id] +
708                                                         cons_tap;
709                                         }
710                                         DEBUG_TRAINING_IP_ENGINE
711                                                 (DEBUG_LEVEL_TRACE,
712                                                  ("reg_offset %d value 0x%x addr %p\n",
713                                                   reg_offset,
714                                                   interface_train_res
715                                                   [reg_offset],
716                                                   &interface_train_res
717                                                   [reg_offset]));
718                                 } else {
719                                         *load_res =
720                                                 &interface_train_res[start_reg];
721                                         DEBUG_TRAINING_IP_ENGINE
722                                                 (DEBUG_LEVEL_TRACE,
723                                                  ("*load_res %p\n", *load_res));
724                                 }
725                         } else {
726                                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
727                                                          ("not supported\n"));
728                         }
729                 }
730         }
731
732         return MV_OK;
733 }
734
735 /*
736  * Load all pattern to memory using ODPG
737  */
738 int ddr3_tip_load_all_pattern_to_mem(u32 dev_num)
739 {
740         u32 pattern = 0, if_id;
741         struct hws_topology_map *tm = ddr3_get_topology_map();
742
743         for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
744                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
745                 training_result[training_stage][if_id] = TEST_SUCCESS;
746         }
747
748         for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
749                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
750                 /* enable single cs */
751                 CHECK_STATUS(ddr3_tip_if_write
752                              (dev_num, ACCESS_TYPE_UNICAST, if_id,
753                               CS_ENABLE_REG, (1 << 3), (1 << 3)));
754         }
755
756         for (pattern = 0; pattern < PATTERN_LIMIT; pattern++)
757                 ddr3_tip_load_pattern_to_mem(dev_num, pattern);
758
759         return MV_OK;
760 }
761
762 /*
763  * Wait till ODPG access is ready
764  */
765 int is_odpg_access_done(u32 dev_num, u32 if_id)
766 {
767         u32 poll_cnt = 0, data_value;
768         u32 read_data[MAX_INTERFACE_NUM];
769
770         for (poll_cnt = 0; poll_cnt < MAX_POLLING_ITERATIONS; poll_cnt++) {
771                 CHECK_STATUS(ddr3_tip_if_read
772                              (dev_num, ACCESS_TYPE_UNICAST, if_id,
773                               ODPG_BIST_DONE, read_data, MASK_ALL_BITS));
774                 data_value = read_data[if_id];
775                 if (((data_value >> ODPG_BIST_DONE_BIT_OFFS) & 0x1) ==
776                     ODPG_BIST_DONE_BIT_VALUE) {
777                                 data_value = data_value & 0xfffffffe;
778                                 CHECK_STATUS(ddr3_tip_if_write
779                                              (dev_num, ACCESS_TYPE_UNICAST,
780                                               if_id, ODPG_BIST_DONE, data_value,
781                                               MASK_ALL_BITS));
782                                 break;
783                         }
784         }
785
786         if (poll_cnt >= MAX_POLLING_ITERATIONS) {
787                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
788                                          ("Bist Activate: poll failure 2\n"));
789                 return MV_FAIL;
790         }
791
792         return MV_OK;
793 }
794
795 /*
796  * Load specific pattern to memory using ODPG
797  */
798 int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern pattern)
799 {
800         u32 reg_data, if_id;
801         struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
802         struct hws_topology_map *tm = ddr3_get_topology_map();
803
804         /* load pattern to memory */
805         /*
806          * Write Tx mode, CS0, phases, Tx burst size, delay between burst,
807          * rx pattern phases
808          */
809         reg_data =
810                 0x1 | (pattern_table[pattern].num_of_phases_tx << 5) |
811                 (pattern_table[pattern].tx_burst_size << 11) |
812                 (pattern_table[pattern].delay_between_bursts << 15) |
813                 (pattern_table[pattern].num_of_phases_rx << 21) | (0x1 << 25) |
814                 (effective_cs << 26);
815         CHECK_STATUS(ddr3_tip_if_write
816                      (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
817                       ODPG_DATA_CONTROL_REG, reg_data, MASK_ALL_BITS));
818         /* ODPG Write enable from BIST */
819         CHECK_STATUS(ddr3_tip_if_write
820                      (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
821                       ODPG_DATA_CONTROL_REG, (0x1 | (effective_cs << 26)),
822                       0xc000003));
823         /* disable error injection */
824         CHECK_STATUS(ddr3_tip_if_write
825                      (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
826                       ODPG_WRITE_DATA_ERROR_REG, 0, 0x1));
827         /* load pattern to ODPG */
828         ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
829                                       PARAM_NOT_CARE, pattern,
830                                       pattern_table[pattern].start_addr);
831
832         for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
833                 if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
834                         continue;
835
836                 CHECK_STATUS(ddr3_tip_if_write
837                              (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1498,
838                               0x3, 0xf));
839         }
840
841         CHECK_STATUS(ddr3_tip_if_write
842                      (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
843                       ODPG_ENABLE_REG, 0x1 << ODPG_ENABLE_OFFS,
844                       (0x1 << ODPG_ENABLE_OFFS)));
845
846         mdelay(1);
847
848         for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
849                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
850                 CHECK_STATUS(is_odpg_access_done(dev_num, if_id));
851         }
852
853         /* Disable ODPG and stop write to memory */
854         CHECK_STATUS(ddr3_tip_if_write
855                      (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
856                       ODPG_DATA_CONTROL_REG, (0x1 << 30), (u32) (0x3 << 30)));
857
858         /* return to default */
859         CHECK_STATUS(ddr3_tip_if_write
860                      (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
861                       ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
862
863         /* Disable odt0 for CS0 training - need to adjust for multy CS */
864         CHECK_STATUS(ddr3_tip_if_write
865                      (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498,
866                       0x0, 0xf));
867
868         /* temporary added */
869         mdelay(1);
870
871         return MV_OK;
872 }
873
874 /*
875  * Load specific pattern to memory using CPU
876  */
877 int ddr3_tip_load_pattern_to_mem_by_cpu(u32 dev_num, enum hws_pattern pattern,
878                                         u32 offset)
879 {
880         /* eranba - TBD */
881         return MV_OK;
882 }
883
884 /*
885  * Training search routine
886  */
887 int ddr3_tip_ip_training_wrapper_int(u32 dev_num,
888                                      enum hws_access_type access_type,
889                                      u32 if_id,
890                                      enum hws_access_type pup_access_type,
891                                      u32 pup_num, u32 bit_num,
892                                      enum hws_training_result result_type,
893                                      enum hws_control_element control_element,
894                                      enum hws_search_dir search_dir,
895                                      enum hws_dir direction,
896                                      u32 interface_mask, u32 init_value_l2h,
897                                      u32 init_value_h2l, u32 num_iter,
898                                      enum hws_pattern pattern,
899                                      enum hws_edge_compare edge_comp,
900                                      enum hws_ddr_cs train_cs_type, u32 cs_num,
901                                      enum hws_training_ip_stat *train_status)
902 {
903         u32 interface_num = 0, start_if, end_if, init_value_used;
904         enum hws_search_dir search_dir_id, start_search, end_search;
905         enum hws_edge_compare edge_comp_used;
906         u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
907         struct hws_topology_map *tm = ddr3_get_topology_map();
908
909         if (train_status == NULL) {
910                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
911                                          ("train_status is NULL\n"));
912                 return MV_FAIL;
913         }
914
915         if ((train_cs_type > CS_NON_SINGLE) ||
916             (edge_comp >= EDGE_PFP) ||
917             (pattern >= PATTERN_LIMIT) ||
918             (direction > OPER_WRITE_AND_READ) ||
919             (search_dir > HWS_HIGH2LOW) ||
920             (control_element > HWS_CONTROL_ELEMENT_DQS_SKEW) ||
921             (result_type > RESULT_PER_BYTE) ||
922             (pup_num >= tm->num_of_bus_per_interface) ||
923             (pup_access_type > ACCESS_TYPE_MULTICAST) ||
924             (if_id > 11) || (access_type > ACCESS_TYPE_MULTICAST)) {
925                 DEBUG_TRAINING_IP_ENGINE(
926                         DEBUG_LEVEL_ERROR,
927                         ("wrong parameter train_cs_type %d edge_comp %d pattern %d direction %d search_dir %d control_element %d result_type %d pup_num %d pup_access_type %d if_id %d access_type %d\n",
928                          train_cs_type, edge_comp, pattern, direction,
929                          search_dir, control_element, result_type, pup_num,
930                          pup_access_type, if_id, access_type));
931                 return MV_FAIL;
932         }
933
934         if (edge_comp == EDGE_FPF) {
935                 start_search = HWS_LOW2HIGH;
936                 end_search = HWS_HIGH2LOW;
937                 edge_comp_used = EDGE_FP;
938         } else {
939                 start_search = search_dir;
940                 end_search = search_dir;
941                 edge_comp_used = edge_comp;
942         }
943
944         for (search_dir_id = start_search; search_dir_id <= end_search;
945              search_dir_id++) {
946                 init_value_used = (search_dir_id == HWS_LOW2HIGH) ?
947                         init_value_l2h : init_value_h2l;
948                 DEBUG_TRAINING_IP_ENGINE(
949                         DEBUG_LEVEL_TRACE,
950                         ("dev_num %d, access_type %d, if_id %d, pup_access_type %d,pup_num %d, result_type %d, control_element %d search_dir_id %d, direction %d, interface_mask %d,init_value_used %d, num_iter %d, pattern %d, edge_comp_used %d, train_cs_type %d, cs_num %d\n",
951                          dev_num, access_type, if_id, pup_access_type, pup_num,
952                          result_type, control_element, search_dir_id,
953                          direction, interface_mask, init_value_used, num_iter,
954                          pattern, edge_comp_used, train_cs_type, cs_num));
955
956                 ddr3_tip_ip_training(dev_num, access_type, if_id,
957                                      pup_access_type, pup_num, result_type,
958                                      control_element, search_dir_id, direction,
959                                      interface_mask, init_value_used, num_iter,
960                                      pattern, edge_comp_used, train_cs_type,
961                                      cs_num, train_status);
962                 if (access_type == ACCESS_TYPE_MULTICAST) {
963                         start_if = 0;
964                         end_if = MAX_INTERFACE_NUM - 1;
965                 } else {
966                         start_if = if_id;
967                         end_if = if_id;
968                 }
969
970                 for (interface_num = start_if; interface_num <= end_if;
971                      interface_num++) {
972                         VALIDATE_ACTIVE(tm->if_act_mask, interface_num);
973                         cs_num = 0;
974                         CHECK_STATUS(ddr3_tip_read_training_result
975                                      (dev_num, interface_num, pup_access_type,
976                                       pup_num, bit_num, search_dir_id,
977                                       direction, result_type,
978                                       TRAINING_LOAD_OPERATION_UNLOAD,
979                                       train_cs_type, NULL, 0, cons_tap,
980                                       0));
981                 }
982         }
983
984         return MV_OK;
985 }
986
987 /*
988  * Training search & read result routine
989  */
990 int ddr3_tip_ip_training_wrapper(u32 dev_num, enum hws_access_type access_type,
991                                  u32 if_id,
992                                  enum hws_access_type pup_access_type,
993                                  u32 pup_num,
994                                  enum hws_training_result result_type,
995                                  enum hws_control_element control_element,
996                                  enum hws_search_dir search_dir,
997                                  enum hws_dir direction, u32 interface_mask,
998                                  u32 init_value_l2h, u32 init_value_h2l,
999                                  u32 num_iter, enum hws_pattern pattern,
1000                                  enum hws_edge_compare edge_comp,
1001                                  enum hws_ddr_cs train_cs_type, u32 cs_num,
1002                                  enum hws_training_ip_stat *train_status)
1003 {
1004         u8 e1, e2;
1005         u32 interface_cnt, bit_id, start_if, end_if, bit_end = 0;
1006         u32 *result[HWS_SEARCH_DIR_LIMIT] = { 0 };
1007         u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
1008         u8 bit_bit_mask[MAX_BUS_NUM] = { 0 }, bit_bit_mask_active = 0;
1009         u8 pup_id;
1010         struct hws_topology_map *tm = ddr3_get_topology_map();
1011
1012         if (pup_num >= tm->num_of_bus_per_interface) {
1013                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
1014                                          ("pup_num %d not valid\n", pup_num));
1015         }
1016
1017         if (if_id >= MAX_INTERFACE_NUM) {
1018                 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
1019                                          ("if_id %d not valid\n", if_id));
1020         }
1021
1022         CHECK_STATUS(ddr3_tip_ip_training_wrapper_int
1023                      (dev_num, access_type, if_id, pup_access_type, pup_num,
1024                       ALL_BITS_PER_PUP, result_type, control_element,
1025                       search_dir, direction, interface_mask, init_value_l2h,
1026                       init_value_h2l, num_iter, pattern, edge_comp,
1027                       train_cs_type, cs_num, train_status));
1028
1029         if (access_type == ACCESS_TYPE_MULTICAST) {
1030                 start_if = 0;
1031                 end_if = MAX_INTERFACE_NUM - 1;
1032         } else {
1033                 start_if = if_id;
1034                 end_if = if_id;
1035         }
1036
1037         for (interface_cnt = start_if; interface_cnt <= end_if;
1038              interface_cnt++) {
1039                 VALIDATE_ACTIVE(tm->if_act_mask, interface_cnt);
1040                 for (pup_id = 0;
1041                      pup_id <= (tm->num_of_bus_per_interface - 1); pup_id++) {
1042                         VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
1043                         if (result_type == RESULT_PER_BIT)
1044                                 bit_end = BUS_WIDTH_IN_BITS - 1;
1045                         else
1046                                 bit_end = 0;
1047
1048                         bit_bit_mask[pup_id] = 0;
1049                         for (bit_id = 0; bit_id <= bit_end; bit_id++) {
1050                                 enum hws_search_dir search_dir_id;
1051                                 for (search_dir_id = HWS_LOW2HIGH;
1052                                      search_dir_id <= HWS_HIGH2LOW;
1053                                      search_dir_id++) {
1054                                         CHECK_STATUS
1055                                                 (ddr3_tip_read_training_result
1056                                                  (dev_num, interface_cnt,
1057                                                   ACCESS_TYPE_UNICAST, pup_id,
1058                                                   bit_id, search_dir_id,
1059                                                   direction, result_type,
1060                                                   TRAINING_LOAD_OPERATION_UNLOAD,
1061                                                   CS_SINGLE,
1062                                                   &result[search_dir_id],
1063                                                   1, 0, 0));
1064                                 }
1065                                 e1 = GET_TAP_RESULT(result[HWS_LOW2HIGH][0],
1066                                                     EDGE_1);
1067                                 e2 = GET_TAP_RESULT(result[HWS_HIGH2LOW][0],
1068                                                     EDGE_1);
1069                                 DEBUG_TRAINING_IP_ENGINE(
1070                                         DEBUG_LEVEL_INFO,
1071                                         ("wrapper if_id %d pup_id %d bit %d l2h 0x%x (e1 0x%x) h2l 0x%x (e2 0x%x)\n",
1072                                          interface_cnt, pup_id, bit_id,
1073                                          result[HWS_LOW2HIGH][0], e1,
1074                                          result[HWS_HIGH2LOW][0], e2));
1075                                 /* TBD validate is valid only for tx */
1076                                 if (VALIDATE_TRAINING_LIMIT(e1, e2) == 1 &&
1077                                     GET_LOCK_RESULT(result[HWS_LOW2HIGH][0]) &&
1078                                     GET_LOCK_RESULT(result[HWS_LOW2HIGH][0])) {
1079                                         /* Mark problem bits */
1080                                         bit_bit_mask[pup_id] |= 1 << bit_id;
1081                                         bit_bit_mask_active = 1;
1082                                 }
1083                         }       /* For all bits */
1084                 }               /* For all PUPs */
1085
1086                 /* Fix problem bits */
1087                 if (bit_bit_mask_active != 0) {
1088                         u32 *l2h_if_train_res = NULL;
1089                         u32 *h2l_if_train_res = NULL;
1090                         l2h_if_train_res =
1091                                 ddr3_tip_get_buf_ptr(dev_num, HWS_LOW2HIGH,
1092                                                      result_type,
1093                                                      interface_cnt);
1094                         h2l_if_train_res =
1095                                 ddr3_tip_get_buf_ptr(dev_num, HWS_HIGH2LOW,
1096                                                      result_type,
1097                                                      interface_cnt);
1098
1099                         ddr3_tip_ip_training(dev_num, ACCESS_TYPE_UNICAST,
1100                                              interface_cnt,
1101                                              ACCESS_TYPE_MULTICAST,
1102                                              PARAM_NOT_CARE, result_type,
1103                                              control_element, HWS_LOW2HIGH,
1104                                              direction, interface_mask,
1105                                              num_iter / 2, num_iter / 2,
1106                                              pattern, EDGE_FP, train_cs_type,
1107                                              cs_num, train_status);
1108
1109                         for (pup_id = 0;
1110                              pup_id <= (tm->num_of_bus_per_interface - 1);
1111                              pup_id++) {
1112                                 VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
1113
1114                                 if (bit_bit_mask[pup_id] == 0)
1115                                         continue;
1116
1117                                 for (bit_id = 0; bit_id <= bit_end; bit_id++) {
1118                                         if ((bit_bit_mask[pup_id] &
1119                                              (1 << bit_id)) == 0)
1120                                                 continue;
1121                                         CHECK_STATUS
1122                                                 (ddr3_tip_read_training_result
1123                                                  (dev_num, interface_cnt,
1124                                                   ACCESS_TYPE_UNICAST, pup_id,
1125                                                   bit_id, HWS_LOW2HIGH,
1126                                                   direction,
1127                                                   result_type,
1128                                                   TRAINING_LOAD_OPERATION_UNLOAD,
1129                                                   CS_SINGLE, &l2h_if_train_res,
1130                                                   0, 0, 1));
1131                                 }
1132                         }
1133
1134                         ddr3_tip_ip_training(dev_num, ACCESS_TYPE_UNICAST,
1135                                              interface_cnt,
1136                                              ACCESS_TYPE_MULTICAST,
1137                                              PARAM_NOT_CARE, result_type,
1138                                              control_element, HWS_HIGH2LOW,
1139                                              direction, interface_mask,
1140                                              num_iter / 2, num_iter / 2,
1141                                              pattern, EDGE_FP, train_cs_type,
1142                                              cs_num, train_status);
1143
1144                         for (pup_id = 0;
1145                              pup_id <= (tm->num_of_bus_per_interface - 1);
1146                              pup_id++) {
1147                                 VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
1148
1149                                 if (bit_bit_mask[pup_id] == 0)
1150                                         continue;
1151
1152                                 for (bit_id = 0; bit_id <= bit_end; bit_id++) {
1153                                         if ((bit_bit_mask[pup_id] &
1154                                              (1 << bit_id)) == 0)
1155                                                 continue;
1156                                         CHECK_STATUS
1157                                                 (ddr3_tip_read_training_result
1158                                                  (dev_num, interface_cnt,
1159                                                   ACCESS_TYPE_UNICAST, pup_id,
1160                                                   bit_id, HWS_HIGH2LOW, direction,
1161                                                   result_type,
1162                                                   TRAINING_LOAD_OPERATION_UNLOAD,
1163                                                   CS_SINGLE, &h2l_if_train_res,
1164                                                   0, cons_tap, 1));
1165                                 }
1166                         }
1167                 }               /* if bit_bit_mask_active */
1168         }                       /* For all Interfacess */
1169
1170         return MV_OK;
1171 }
1172
1173 /*
1174  * Load phy values
1175  */
1176 int ddr3_tip_load_phy_values(int b_load)
1177 {
1178         u32 bus_cnt = 0, if_id, dev_num = 0;
1179         struct hws_topology_map *tm = ddr3_get_topology_map();
1180
1181         for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1182                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1183                 for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
1184                      bus_cnt++) {
1185                         VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
1186                         if (b_load == 1) {
1187                                 CHECK_STATUS(ddr3_tip_bus_read
1188                                              (dev_num, if_id,
1189                                               ACCESS_TYPE_UNICAST, bus_cnt,
1190                                               DDR_PHY_DATA,
1191                                               WRITE_CENTRALIZATION_PHY_REG +
1192                                               (effective_cs *
1193                                                CS_REGISTER_ADDR_OFFSET),
1194                                               &phy_reg_bk[if_id][bus_cnt]
1195                                               [0]));
1196                                 CHECK_STATUS(ddr3_tip_bus_read
1197                                              (dev_num, if_id,
1198                                               ACCESS_TYPE_UNICAST, bus_cnt,
1199                                               DDR_PHY_DATA,
1200                                               RL_PHY_REG +
1201                                               (effective_cs *
1202                                                CS_REGISTER_ADDR_OFFSET),
1203                                               &phy_reg_bk[if_id][bus_cnt]
1204                                               [1]));
1205                                 CHECK_STATUS(ddr3_tip_bus_read
1206                                              (dev_num, if_id,
1207                                               ACCESS_TYPE_UNICAST, bus_cnt,
1208                                               DDR_PHY_DATA,
1209                                               READ_CENTRALIZATION_PHY_REG +
1210                                               (effective_cs *
1211                                                CS_REGISTER_ADDR_OFFSET),
1212                                               &phy_reg_bk[if_id][bus_cnt]
1213                                               [2]));
1214                         } else {
1215                                 CHECK_STATUS(ddr3_tip_bus_write
1216                                              (dev_num, ACCESS_TYPE_UNICAST,
1217                                               if_id, ACCESS_TYPE_UNICAST,
1218                                               bus_cnt, DDR_PHY_DATA,
1219                                               WRITE_CENTRALIZATION_PHY_REG +
1220                                               (effective_cs *
1221                                                CS_REGISTER_ADDR_OFFSET),
1222                                               phy_reg_bk[if_id][bus_cnt]
1223                                               [0]));
1224                                 CHECK_STATUS(ddr3_tip_bus_write
1225                                              (dev_num, ACCESS_TYPE_UNICAST,
1226                                               if_id, ACCESS_TYPE_UNICAST,
1227                                               bus_cnt, DDR_PHY_DATA,
1228                                               RL_PHY_REG +
1229                                               (effective_cs *
1230                                                CS_REGISTER_ADDR_OFFSET),
1231                                               phy_reg_bk[if_id][bus_cnt]
1232                                               [1]));
1233                                 CHECK_STATUS(ddr3_tip_bus_write
1234                                              (dev_num, ACCESS_TYPE_UNICAST,
1235                                               if_id, ACCESS_TYPE_UNICAST,
1236                                               bus_cnt, DDR_PHY_DATA,
1237                                               READ_CENTRALIZATION_PHY_REG +
1238                                               (effective_cs *
1239                                                CS_REGISTER_ADDR_OFFSET),
1240                                               phy_reg_bk[if_id][bus_cnt]
1241                                               [2]));
1242                         }
1243                 }
1244         }
1245
1246         return MV_OK;
1247 }
1248
1249 int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
1250                               enum hws_search_dir search_dir,
1251                               enum hws_dir direction,
1252                               enum hws_edge_compare edge,
1253                               u32 init_val1, u32 init_val2,
1254                               u32 num_of_iterations,
1255                               u32 start_pattern, u32 end_pattern)
1256 {
1257         u32 pattern, if_id, pup_id;
1258         enum hws_training_ip_stat train_status[MAX_INTERFACE_NUM];
1259         u32 *res = NULL;
1260         u32 search_state = 0;
1261         struct hws_topology_map *tm = ddr3_get_topology_map();
1262
1263         ddr3_tip_load_phy_values(1);
1264
1265         for (pattern = start_pattern; pattern <= end_pattern; pattern++) {
1266                 for (search_state = 0; search_state < HWS_SEARCH_DIR_LIMIT;
1267                      search_state++) {
1268                         ddr3_tip_ip_training_wrapper(dev_num,
1269                                                      ACCESS_TYPE_MULTICAST, 0,
1270                                                      ACCESS_TYPE_MULTICAST, 0,
1271                                                      result_type,
1272                                                      HWS_CONTROL_ELEMENT_ADLL,
1273                                                      search_dir, direction,
1274                                                      0xfff, init_val1,
1275                                                      init_val2,
1276                                                      num_of_iterations, pattern,
1277                                                      edge, CS_SINGLE,
1278                                                      PARAM_NOT_CARE,
1279                                                      train_status);
1280
1281                         for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
1282                              if_id++) {
1283                                 VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1284                                 for (pup_id = 0; pup_id <
1285                                              tm->num_of_bus_per_interface;
1286                                      pup_id++) {
1287                                         VALIDATE_ACTIVE(tm->bus_act_mask,
1288                                                         pup_id);
1289                                         CHECK_STATUS
1290                                                 (ddr3_tip_read_training_result
1291                                                  (dev_num, if_id,
1292                                                   ACCESS_TYPE_UNICAST, pup_id,
1293                                                   ALL_BITS_PER_PUP,
1294                                                   search_state,
1295                                                   direction, result_type,
1296                                                   TRAINING_LOAD_OPERATION_UNLOAD,
1297                                                   CS_SINGLE, &res, 1, 0,
1298                                                   0));
1299                                         if (result_type == RESULT_PER_BYTE) {
1300                                                 DEBUG_TRAINING_IP_ENGINE
1301                                                         (DEBUG_LEVEL_INFO,
1302                                                          ("search_state %d if_id %d pup_id %d 0x%x\n",
1303                                                           search_state, if_id,
1304                                                           pup_id, res[0]));
1305                                         } else {
1306                                                 DEBUG_TRAINING_IP_ENGINE
1307                                                         (DEBUG_LEVEL_INFO,
1308                                                          ("search_state %d if_id %d pup_id %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1309                                                           search_state, if_id,
1310                                                           pup_id, res[0],
1311                                                           res[1], res[2],
1312                                                           res[3], res[4],
1313                                                           res[5], res[6],
1314                                                           res[7]));
1315                                         }
1316                                 }
1317                         }       /* interface */
1318                 }               /* search */
1319         }                       /* pattern */
1320
1321         ddr3_tip_load_phy_values(0);
1322
1323         return MV_OK;
1324 }
1325
1326 struct pattern_info *ddr3_tip_get_pattern_table()
1327 {
1328         struct hws_topology_map *tm = ddr3_get_topology_map();
1329
1330         if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0)
1331                 return pattern_table_32;
1332         else
1333                 return pattern_table_16;
1334 }
1335
1336 u16 *ddr3_tip_get_mask_results_dq_reg()
1337 {
1338         struct hws_topology_map *tm = ddr3_get_topology_map();
1339
1340         if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
1341                 return mask_results_dq_reg_map_pup3_ecc;
1342         else
1343                 return mask_results_dq_reg_map;
1344 }
1345
1346 u16 *ddr3_tip_get_mask_results_pup_reg_map()
1347 {
1348         struct hws_topology_map *tm = ddr3_get_topology_map();
1349
1350         if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
1351                 return mask_results_pup_reg_map_pup3_ecc;
1352         else
1353                 return mask_results_pup_reg_map;
1354 }