1
2
3
4
5
6#include "ddr3_init.h"
7#include "mv_ddr_regs.h"
8#include "ddr_training_ip_db.h"
9
10#define PATTERN_1 0x55555555
11#define PATTERN_2 0xaaaaaaaa
12
13#define VALIDATE_TRAINING_LIMIT(e1, e2) \
14 ((((e2) - (e1) + 1) > 33) && ((e1) < 67))
15
16u32 phy_reg_bk[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
17
18u32 training_res[MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS *
19 HWS_SEARCH_DIR_LIMIT];
20u8 byte_status[MAX_INTERFACE_NUM][MAX_BUS_NUM];
21
22u16 mask_results_dq_reg_map[] = {
23 RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
24 RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
25 RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
26 RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
27 RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
28 RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
29 RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
30 RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
31 RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
32 RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
33 RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
34 RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
35 RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG,
36 RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
37 RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG,
38 RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG,
39 RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
40 RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
41 RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
42 RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
43#if MAX_BUS_NUM == 9
44 RESULT_CONTROL_PUP_5_BIT_0_REG, RESULT_CONTROL_PUP_5_BIT_1_REG,
45 RESULT_CONTROL_PUP_5_BIT_2_REG, RESULT_CONTROL_PUP_5_BIT_3_REG,
46 RESULT_CONTROL_PUP_5_BIT_4_REG, RESULT_CONTROL_PUP_5_BIT_5_REG,
47 RESULT_CONTROL_PUP_5_BIT_6_REG, RESULT_CONTROL_PUP_5_BIT_7_REG,
48 RESULT_CONTROL_PUP_6_BIT_0_REG, RESULT_CONTROL_PUP_6_BIT_1_REG,
49 RESULT_CONTROL_PUP_6_BIT_2_REG, RESULT_CONTROL_PUP_6_BIT_3_REG,
50 RESULT_CONTROL_PUP_6_BIT_4_REG, RESULT_CONTROL_PUP_6_BIT_5_REG,
51 RESULT_CONTROL_PUP_6_BIT_6_REG, RESULT_CONTROL_PUP_6_BIT_7_REG,
52 RESULT_CONTROL_PUP_7_BIT_0_REG, RESULT_CONTROL_PUP_7_BIT_1_REG,
53 RESULT_CONTROL_PUP_7_BIT_2_REG, RESULT_CONTROL_PUP_7_BIT_3_REG,
54 RESULT_CONTROL_PUP_7_BIT_4_REG, RESULT_CONTROL_PUP_7_BIT_5_REG,
55 RESULT_CONTROL_PUP_7_BIT_6_REG, RESULT_CONTROL_PUP_7_BIT_7_REG,
56 RESULT_CONTROL_PUP_8_BIT_0_REG, RESULT_CONTROL_PUP_8_BIT_1_REG,
57 RESULT_CONTROL_PUP_8_BIT_2_REG, RESULT_CONTROL_PUP_8_BIT_3_REG,
58 RESULT_CONTROL_PUP_8_BIT_4_REG, RESULT_CONTROL_PUP_8_BIT_5_REG,
59 RESULT_CONTROL_PUP_8_BIT_6_REG, RESULT_CONTROL_PUP_8_BIT_7_REG,
60#endif
61 0xffff
62};
63
64u16 mask_results_pup_reg_map[] = {
65 RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
66 RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_3_REG,
67 RESULT_CONTROL_BYTE_PUP_4_REG,
68#if MAX_BUS_NUM == 9
69 RESULT_CONTROL_BYTE_PUP_5_REG, RESULT_CONTROL_BYTE_PUP_6_REG,
70 RESULT_CONTROL_BYTE_PUP_7_REG, RESULT_CONTROL_BYTE_PUP_8_REG,
71#endif
72 0xffff
73};
74
75#if MAX_BUS_NUM == 5
76u16 mask_results_dq_reg_map_pup3_ecc[] = {
77 RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
78 RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
79 RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
80 RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
81 RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
82 RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
83 RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
84 RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
85 RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
86 RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
87 RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
88 RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
89 RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
90 RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
91 RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
92 RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
93 RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG,
94 RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
95 RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG,
96 RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG
97};
98#endif
99
100#if MAX_BUS_NUM == 5
101u16 mask_results_pup_reg_map_pup3_ecc[] = {
102 RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
103 RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_4_REG,
104 RESULT_CONTROL_BYTE_PUP_4_REG
105};
106#endif
107
108struct pattern_info pattern_table_64[] = {
109
110
111
112
113
114 {0x7, 0x7, 2, 0x7, 0x00000, 8},
115 {0x7, 0x7, 2, 0x7, 0x00080, 8},
116 {0x7, 0x7, 2, 0x7, 0x00100, 8},
117 {0x7, 0x7, 2, 0x7, 0x00030, 8},
118 {0x7, 0x7, 2, 0x7, 0x00100, 8},
119 {0x7, 0x7, 2, 0x7, 0x00100, 8},
120 {0x1f, 0xf, 2, 0xf, 0x00680, 32},
121 {0x1f, 0xf, 2, 0xf, 0x00a80, 32},
122 {0x1f, 0xf, 2, 0xf, 0x01280, 32},
123 {0x1f, 0xf, 2, 0xf, 0x01a80, 32},
124 {0x1f, 0xf, 2, 0xf, 0x02280, 32},
125 {0x1f, 0xf, 2, 0xf, 0x02a80, 32},
126 {0x1f, 0xf, 2, 0xf, 0x03280, 32},
127 {0x1f, 0xf, 2, 0xf, 0x03a80, 32},
128 {0x1f, 0xf, 2, 0xf, 0x04280, 32},
129 {0x1f, 0xf, 2, 0xf, 0x00e80, 32},
130 {0x1f, 0xf, 2, 0xf, 0x01680, 32},
131 {0x1f, 0xf, 2, 0xf, 0x01e80, 32},
132 {0x1f, 0xf, 2, 0xf, 0x02680, 32},
133 {0x1f, 0xf, 2, 0xf, 0x02e80, 32},
134 {0x1f, 0xf, 2, 0xf, 0x03680, 32},
135 {0x1f, 0xf, 2, 0xf, 0x03e80, 32},
136 {0x1f, 0xf, 2, 0xf, 0x04680, 32},
137 {0x1f, 0xf, 2, 0xf, 0x04a80, 32},
138 {0x1f, 0xf, 2, 0xf, 0x05280, 32},
139 {0x1f, 0xf, 2, 0xf, 0x05a80, 32},
140 {0x1f, 0xf, 2, 0xf, 0x06280, 32},
141 {0x1f, 0xf, 2, 0xf, 0x06a80, 32},
142 {0x1f, 0xf, 2, 0xf, 0x07280, 32},
143 {0x1f, 0xf, 2, 0xf, 0x07a80, 32},
144 {0x1f, 0xf, 2, 0xf, 0x08280, 32},
145 {0x1f, 0xf, 2, 0xf, 0x04e80, 32},
146 {0x1f, 0xf, 2, 0xf, 0x05680, 32},
147 {0x1f, 0xf, 2, 0xf, 0x05e80, 32},
148 {0x1f, 0xf, 2, 0xf, 0x06680, 32},
149 {0x1f, 0xf, 2, 0xf, 0x06e80, 32},
150 {0x1f, 0xf, 2, 0xf, 0x07680, 32},
151 {0x1f, 0xf, 2, 0xf, 0x07e80, 32},
152 {0x1f, 0xf, 2, 0xf, 0x08680, 32},
153 {0x1f, 0xf, 2, 0xf, 0x08a80, 32},
154 {0x1f, 0xf, 2, 0xf, 0x09280, 32},
155 {0x1f, 0xf, 2, 0xf, 0x09a80, 32},
156 {0x1f, 0xf, 2, 0xf, 0x0a280, 32},
157 {0x1f, 0xf, 2, 0xf, 0x0aa80, 32},
158 {0x1f, 0xf, 2, 0xf, 0x0b280, 32},
159 {0x1f, 0xf, 2, 0xf, 0x0ba80, 32},
160 {0x1f, 0xf, 2, 0xf, 0x0c280, 32},
161 {0x1f, 0xf, 2, 0xf, 0x08e80, 32},
162 {0x1f, 0xf, 2, 0xf, 0x09680, 32},
163 {0x1f, 0xf, 2, 0xf, 0x09e80, 32},
164 {0x1f, 0xf, 2, 0xf, 0x0a680, 32},
165 {0x1f, 0xf, 2, 0xf, 0x0ae80, 32},
166 {0x1f, 0xf, 2, 0xf, 0x0b680, 32},
167 {0x1f, 0xf, 2, 0xf, 0x0be80, 32},
168 {0x1f, 0xf, 2, 0xf, 0x0c680, 32},
169 {0x1f, 0xf, 2, 0xf, 0x0ca80, 32},
170 {0x1f, 0xf, 2, 0xf, 0x0d280, 32},
171 {0x1f, 0xf, 2, 0xf, 0x0da80, 32},
172 {0x1f, 0xf, 2, 0xf, 0x0e280, 32},
173 {0x1f, 0xf, 2, 0xf, 0x0ea80, 32},
174 {0x1f, 0xf, 2, 0xf, 0x0f280, 32},
175 {0x1f, 0xf, 2, 0xf, 0x0fa80, 32},
176 {0x1f, 0xf, 2, 0xf, 0x10280, 32},
177 {0x1f, 0xf, 2, 0xf, 0x0ce80, 32},
178 {0x1f, 0xf, 2, 0xf, 0x0d680, 32},
179 {0x1f, 0xf, 2, 0xf, 0x0de80, 32},
180 {0x1f, 0xf, 2, 0xf, 0x0e680, 32},
181 {0x1f, 0xf, 2, 0xf, 0x0ee80, 32},
182 {0x1f, 0xf, 2, 0xf, 0x0f680, 32},
183 {0x1f, 0xf, 2, 0xf, 0x0fe80, 32},
184 {0x1f, 0xf, 2, 0xf, 0x10680, 32},
185 {0x1f, 0xf, 2, 0xf, 0x10a80, 32},
186 {0x1f, 0xf, 2, 0xf, 0x10e80, 32},
187 {0x1f, 0xf, 2, 0xf, 0x11280, 32},
188 {0x1f, 0xf, 2, 0xf, 0x11680, 32},
189 {0x1f, 0xf, 2, 0xf, 0x11a80, 32},
190 {0x1f, 0xf, 2, 0xf, 0x11e80, 32},
191 {0x1f, 0xf, 2, 0xf, 0x12280, 32},
192 {0x1f, 0xf, 2, 0xf, 0x12680, 32},
193 {0x1f, 0xf, 2, 0xf, 0x12a80, 32},
194 {0x1f, 0xf, 2, 0xf, 0x12e80, 32},
195 {0x1f, 0xf, 2, 0xf, 0x13280, 32},
196 {0x1f, 0xf, 2, 0xf, 0x13680, 32},
197 {0x1f, 0xf, 2, 0xf, 0x13a80, 32},
198 {0x1f, 0xf, 2, 0xf, 0x13e80, 32},
199 {0x1f, 0xf, 2, 0xf, 0x14280, 32},
200 {0x1f, 0xf, 2, 0xf, 0x14680, 32},
201 {0x1f, 0xf, 2, 0xf, 0x14a80, 32},
202 {0x1f, 0xf, 2, 0xf, 0x14e80, 32},
203 {0x1f, 0xf, 2, 0xf, 0x15280, 32},
204 {0x1f, 0xf, 2, 0xf, 0x15680, 32}
205
206};
207
208#if defined(CONFIG_DDR4)
209struct pattern_info pattern_table_16[] = {
210
211
212
213
214 {0x1, 0x1, 2, 0x1, 0x0000, 2},
215 {0x1, 0x1, 2, 0x1, 0x0080, 2},
216 {0x1, 0x1, 2, 0x1, 0x0100, 2},
217 {0x1, 0x1, 2, 0x1, 0x0180, 2},
218 {0x1, 0x1, 2, 0x1, 0x0200, 2},
219 {0x1, 0x1, 2, 0x1, 0x0280, 2},
220 {0xf, 0x7, 2, 0x7, 0x0680, 16},
221 {0xf, 0x7, 2, 0x7, 0x0A80, 16},
222 {0xf, 0x7, 2, 0x7, 0x0E80, 16},
223 {0xf, 0x7, 2, 0x7, 0x1280, 16},
224 {0xf, 0x7, 2, 0x7, 0x1680, 16},
225 {0xf, 0x7, 2, 0x7, 0x1A80, 16},
226 {0xf, 0x7, 2, 0x7, 0x1E80, 16},
227 {0xf, 0x7, 2, 0x7, 0x2280, 16},
228 {0xf, 0x7, 2, 0x7, 0x2680, 16},
229 {0xf, 0x7, 2, 0x7, 0x2A80, 16},
230 {0xf, 0x7, 2, 0x7, 0x2E80, 16},
231 {0xf, 0x7, 2, 0x7, 0x3280, 16},
232 {0xf, 0x7, 2, 0x7, 0x3680, 16},
233 {0xf, 0x7, 2, 0x7, 0x3A80, 16},
234 {0xf, 0x7, 2, 0x7, 0x3E80, 16},
235 {0xf, 0x7, 2, 0x7, 0x4280, 16},
236 {0xf, 0x7, 2, 0x7, 0x4680, 16},
237 {0xf, 0x7, 2, 0x7, 0x4A80, 16},
238 {0xf, 0x7, 2, 0x7, 0x4E80, 16},
239 {0xf, 0x7, 2, 0x7, 0x5280, 16},
240 {0xf, 0x7, 2, 0x7, 0x5680, 16},
241 {0xf, 0x7, 2, 0x7, 0x5A80, 16},
242 {0xf, 0x7, 2, 0x7, 0x5E80, 16},
243 {0xf, 0x7, 2, 0x7, 0x6280, 16},
244 {0xf, 0x7, 2, 0x7, 0x6680, 16},
245 {0xf, 0x7, 2, 0x7, 0x6A80, 16},
246 {0xf, 0x7, 2, 0x7, 0x6E80, 16},
247 {0xf, 0x7, 2, 0x7, 0x7280, 16},
248 {0xf, 0x7, 2, 0x7, 0x7680, 16},
249 {0xf, 0x7, 2, 0x7, 0x7A80, 16},
250 {0xf, 0x7, 2, 0x7, 0x7E80, 16},
251 {0xf, 0x7, 2, 0x7, 0x8280, 16},
252 {0xf, 0x7, 2, 0x7, 0x8680, 16},
253 {0xf, 0x7, 2, 0x7, 0x8A80, 16},
254 {0xf, 0x7, 2, 0x7, 0x8E80, 16},
255 {0xf, 0x7, 2, 0x7, 0x9280, 16},
256 {0xf, 0x7, 2, 0x7, 0x9680, 16},
257 {0xf, 0x7, 2, 0x7, 0x9A80, 16},
258 {0xf, 0x7, 2, 0x7, 0x9E80, 16},
259 {0xf, 0x7, 2, 0x7, 0xA280, 16},
260 {0xf, 0x7, 2, 0x7, 0xA680, 16},
261 {0xf, 0x7, 2, 0x7, 0xAA80, 16},
262 {0xf, 0x7, 2, 0x7, 0xAE80, 16},
263 {0xf, 0x7, 2, 0x7, 0xB280, 16},
264 {0xf, 0x7, 2, 0x7, 0xB680, 16},
265 {0xf, 0x7, 2, 0x7, 0xBA80, 16},
266 {0xf, 0x7, 2, 0x7, 0xBE80, 16},
267 {0xf, 0x7, 2, 0x7, 0xC280, 16},
268 {0xf, 0x7, 2, 0x7, 0xC680, 16},
269 {0xf, 0x7, 2, 0x7, 0xca80, 16},
270 {0xf, 0x7, 2, 0x7, 0xce80, 16}
271
272};
273
274struct pattern_info pattern_table_32[] = {
275
276
277
278
279 {0x3, 0x3, 2, 0x3, 0x0000, 4},
280 {0x3, 0x3, 2, 0x3, 0x0020, 4},
281 {0x3, 0x3, 2, 0x3, 0x0040, 4},
282 {0x3, 0x3, 2, 0x3, 0x0060, 4},
283 {0x3, 0x3, 2, 0x3, 0x0080, 4},
284 {0x3, 0x3, 2, 0x3, 0x00a0, 4},
285 {0x1f, 0xf, 2, 0xf, 0x00c0, 32},
286 {0x1f, 0xf, 2, 0xf, 0x00e0, 32},
287 {0x1f, 0xf, 2, 0xf, 0x0100, 32},
288 {0x1f, 0xf, 2, 0xf, 0x0120, 32},
289 {0x1f, 0xf, 2, 0xf, 0x0140, 32},
290 {0x1f, 0xf, 2, 0xf, 0x0160, 32},
291 {0x1f, 0xf, 2, 0xf, 0x0180, 32},
292 {0x1f, 0xf, 2, 0xf, 0x01a0, 32},
293 {0x1f, 0xf, 2, 0xf, 0x01c0, 32},
294 {0x1f, 0xf, 2, 0xf, 0x01e0, 32},
295 {0x1f, 0xf, 2, 0xf, 0x0200, 32},
296 {0x1f, 0xf, 2, 0xf, 0x0220, 32},
297 {0x1f, 0xf, 2, 0xf, 0x0240, 32},
298 {0x1f, 0xf, 2, 0xf, 0x0260, 32},
299 {0x1f, 0xf, 2, 0xf, 0x0280, 32},
300 {0x1f, 0xf, 2, 0xf, 0x02a0, 32},
301 {0x1f, 0xf, 2, 0xf, 0x02c0, 32},
302 {0x1f, 0xf, 2, 0xf, 0x02e0, 32},
303 {0x1f, 0xf, 2, 0xf, 0x0300, 32},
304 {0x1f, 0xf, 2, 0xf, 0x0320, 32},
305 {0x1f, 0xf, 2, 0xf, 0x0340, 32},
306 {0x1f, 0xf, 2, 0xf, 0x0360, 32},
307 {0x1f, 0xf, 2, 0xf, 0x0380, 32},
308 {0x1f, 0xf, 2, 0xf, 0x6280, 32},
309 {0x1f, 0xf, 2, 0xf, 0x6680, 32},
310 {0x1f, 0xf, 2, 0xf, 0x6A80, 32},
311 {0x1f, 0xf, 2, 0xf, 0x6E80, 32},
312 {0x1f, 0xf, 2, 0xf, 0x7280, 32},
313 {0x1f, 0xf, 2, 0xf, 0x7680, 32},
314 {0x1f, 0xf, 2, 0xf, 0x7A80, 32},
315 {0x1f, 0xf, 2, 0xf, 0x7E80, 32},
316 {0x1f, 0xf, 2, 0xf, 0x8280, 32},
317 {0x1f, 0xf, 2, 0xf, 0x8680, 32},
318 {0x1f, 0xf, 2, 0xf, 0x8A80, 32},
319 {0x1f, 0xf, 2, 0xf, 0x8E80, 32},
320 {0x1f, 0xf, 2, 0xf, 0x9280, 32},
321 {0x1f, 0xf, 2, 0xf, 0x9680, 32},
322 {0x1f, 0xf, 2, 0xf, 0x9A80, 32},
323 {0x1f, 0xf, 2, 0xf, 0x9E80, 32},
324 {0x1f, 0xf, 2, 0xf, 0xA280, 32},
325 {0x1f, 0xf, 2, 0xf, 0xA680, 32},
326 {0x1f, 0xf, 2, 0xf, 0xAA80, 32},
327 {0x1f, 0xf, 2, 0xf, 0xAE80, 32},
328 {0x1f, 0xf, 2, 0xf, 0xB280, 32},
329 {0x1f, 0xf, 2, 0xf, 0xB680, 32},
330 {0x1f, 0xf, 2, 0xf, 0xBA80, 32},
331 {0x1f, 0xf, 2, 0xf, 0xBE80, 32},
332 {0x1f, 0xf, 2, 0xf, 0xC280, 32},
333 {0x1f, 0xf, 2, 0xf, 0xC680, 32},
334 {0x1f, 0xf, 2, 0xf, 0xca80, 32},
335 {0x1f, 0xf, 2, 0xf, 0xce80, 32}
336
337};
338#else
339struct pattern_info pattern_table_16[] = {
340
341
342
343
344 {1, 1, 2, 1, 0x0080, 2},
345 {1, 1, 2, 1, 0x00c0, 2},
346 {1, 1, 2, 1, 0x0380, 2},
347 {1, 1, 2, 1, 0x0040, 2},
348 {1, 1, 2, 1, 0x0100, 2},
349 {1, 1, 2, 1, 0x0000, 2},
350 {0xf, 0x7, 2, 0x7, 0x0140, 16},
351 {0xf, 0x7, 2, 0x7, 0x0190, 16},
352 {0xf, 0x7, 2, 0x7, 0x01d0, 16},
353 {0xf, 0x7, 2, 0x7, 0x0210, 16},
354 {0xf, 0x7, 2, 0x7, 0x0250, 16},
355 {0xf, 0x7, 2, 0x7, 0x0290, 16},
356 {0xf, 0x7, 2, 0x7, 0x02d0, 16},
357 {0xf, 0x7, 2, 0x7, 0x0310, 16},
358 {0xf, 0x7, 2, 0x7, 0x0350, 16},
359 {0xf, 0x7, 2, 0x7, 0x04c0, 16},
360 {0xf, 0x7, 2, 0x7, 0x03c0, 16},
361 {0xf, 0x7, 2, 0x7, 0x0400, 16},
362 {0xf, 0x7, 2, 0x7, 0x0440, 16},
363 {0xf, 0x7, 2, 0x7, 0x0480, 16},
364 {0xf, 7, 2, 7, 0x6280, 16},
365 {0xf, 7, 2, 7, 0x6680, 16},
366 {0xf, 7, 2, 7, 0x6A80, 16},
367 {0xf, 7, 2, 7, 0x6E80, 16},
368 {0xf, 7, 2, 7, 0x7280, 16},
369 {0xf, 7, 2, 7, 0x7680, 16},
370 {0xf, 7, 2, 7, 0x7A80, 16},
371 {0xf, 7, 2, 7, 0x7E80, 16},
372 {0xf, 7, 2, 7, 0x8280, 16},
373 {0xf, 7, 2, 7, 0x8680, 16},
374 {0xf, 7, 2, 7, 0x8A80, 16},
375 {0xf, 7, 2, 7, 0x8E80, 16},
376 {0xf, 7, 2, 7, 0x9280, 16},
377 {0xf, 7, 2, 7, 0x9680, 16},
378 {0xf, 7, 2, 7, 0x9A80, 16},
379 {0xf, 7, 2, 7, 0x9E80, 16},
380 {0xf, 7, 2, 7, 0xA280, 16}
381
382};
383
384struct pattern_info pattern_table_32[] = {
385
386
387
388
389 {3, 3, 2, 3, 0x0080, 4},
390 {3, 3, 2, 3, 0x00c0, 4},
391 {3, 3, 2, 3, 0x0380, 4},
392 {3, 3, 2, 3, 0x0040, 4},
393 {3, 3, 2, 3, 0x0100, 4},
394 {3, 3, 2, 3, 0x0000, 4},
395 {0x1f, 0xf, 2, 0xf, 0x0140, 32},
396 {0x1f, 0xf, 2, 0xf, 0x0190, 32},
397 {0x1f, 0xf, 2, 0xf, 0x01d0, 32},
398 {0x1f, 0xf, 2, 0xf, 0x0210, 32},
399 {0x1f, 0xf, 2, 0xf, 0x0250, 32},
400 {0x1f, 0xf, 2, 0xf, 0x0290, 32},
401 {0x1f, 0xf, 2, 0xf, 0x02d0, 32},
402 {0x1f, 0xf, 2, 0xf, 0x0310, 32},
403 {0x1f, 0xf, 2, 0xf, 0x0350, 32},
404 {0x1f, 0xf, 2, 0xf, 0x04c0, 32},
405 {0x1f, 0xf, 2, 0xf, 0x03c0, 32},
406 {0x1f, 0xf, 2, 0xf, 0x0400, 32},
407 {0x1f, 0xf, 2, 0xf, 0x0440, 32},
408 {0x1f, 0xf, 2, 0xf, 0x0480, 32},
409 {0x1f, 0xF, 2, 0xf, 0x6280, 32},
410 {0x1f, 0xF, 2, 0xf, 0x6680, 32},
411 {0x1f, 0xF, 2, 0xf, 0x6A80, 32},
412 {0x1f, 0xF, 2, 0xf, 0x6E80, 32},
413 {0x1f, 0xF, 2, 0xf, 0x7280, 32},
414 {0x1f, 0xF, 2, 0xf, 0x7680, 32},
415 {0x1f, 0xF, 2, 0xf, 0x7A80, 32},
416 {0x1f, 0xF, 2, 0xf, 0x7E80, 32},
417 {0x1f, 0xF, 2, 0xf, 0x8280, 32},
418 {0x1f, 0xF, 2, 0xf, 0x8680, 32},
419 {0x1f, 0xF, 2, 0xf, 0x8A80, 32},
420 {0x1f, 0xF, 2, 0xf, 0x8E80, 32},
421 {0x1f, 0xF, 2, 0xf, 0x9280, 32},
422 {0x1f, 0xF, 2, 0xf, 0x9680, 32},
423 {0x1f, 0xF, 2, 0xf, 0x9A80, 32},
424 {0x1f, 0xF, 2, 0xf, 0x9E80, 32},
425 {0x1f, 0xF, 2, 0xf, 0xA280, 32}
426
427};
428#endif
429
430u32 train_dev_num;
431enum hws_ddr_cs traintrain_cs_type;
432u32 train_pup_num;
433enum hws_training_result train_result_type;
434enum hws_control_element train_control_element;
435enum hws_search_dir traine_search_dir;
436enum hws_dir train_direction;
437u32 train_if_select;
438u32 train_init_value;
439u32 train_number_iterations;
440enum hws_pattern train_pattern;
441enum hws_edge_compare train_edge_compare;
442u32 train_cs_num;
443u32 train_if_acess, train_if_id, train_pup_access;
444#if defined(CONFIG_DDR4)
445
446u32 max_polling_for_done = 100000000;
447#else
448u32 max_polling_for_done = 1000000;
449#endif
450
451u32 *ddr3_tip_get_buf_ptr(u32 dev_num, enum hws_search_dir search,
452 enum hws_training_result result_type,
453 u32 interface_num)
454{
455 u32 *buf_ptr = NULL;
456
457 buf_ptr = &training_res
458 [MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS * search +
459 interface_num * MAX_BUS_NUM * BUS_WIDTH_IN_BITS];
460
461 return buf_ptr;
462}
463
464enum {
465 PASS,
466 FAIL
467};
468
469
470
471
472
473int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
474 u32 interface_num,
475 enum hws_access_type pup_access_type,
476 u32 pup_num, enum hws_training_result result_type,
477 enum hws_control_element control_element,
478 enum hws_search_dir search_dir, enum hws_dir direction,
479 u32 interface_mask, u32 init_value, u32 num_iter,
480 enum hws_pattern pattern,
481 enum hws_edge_compare edge_comp,
482 enum hws_ddr_cs cs_type, u32 cs_num,
483 enum hws_training_ip_stat *train_status)
484{
485 u32 mask_dq_num_of_regs, mask_pup_num_of_regs, index_cnt,
486 reg_data, pup_id;
487 u32 tx_burst_size;
488 u32 delay_between_burst;
489 u32 rd_mode;
490 u32 data;
491 struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
492 u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
493 u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
494 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
495 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
496
497 if (pup_num >= octets_per_if_num) {
498 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
499 ("pup_num %d not valid\n", pup_num));
500 }
501 if (interface_num >= MAX_INTERFACE_NUM) {
502 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
503 ("if_id %d not valid\n",
504 interface_num));
505 }
506 if (train_status == NULL) {
507 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
508 ("error param 4\n"));
509 return MV_BAD_PARAM;
510 }
511
512
513 if (cs_type == CS_SINGLE) {
514
515 CHECK_STATUS(ddr3_tip_if_write
516 (dev_num, access_type, interface_num,
517 DUAL_DUNIT_CFG_REG, 1 << 3, 1 << 3));
518
519 CHECK_STATUS(ddr3_tip_if_write
520 (dev_num, access_type, interface_num,
521 ODPG_DATA_CTRL_REG,
522 (0x3 | (effective_cs << 26)), 0xc000003));
523 } else {
524 CHECK_STATUS(ddr3_tip_if_write
525 (dev_num, access_type, interface_num,
526 DUAL_DUNIT_CFG_REG, 0, 1 << 3));
527
528 CHECK_STATUS(ddr3_tip_if_write
529 (dev_num, access_type, interface_num,
530 ODPG_DATA_CTRL_REG, 0x3 | cs_num << 26,
531 0x3 | 3 << 26));
532 }
533
534
535 ddr3_tip_load_pattern_to_odpg(dev_num, access_type, interface_num,
536 pattern,
537 pattern_table[pattern].start_addr);
538 tx_burst_size = (direction == OPER_WRITE) ?
539 pattern_table[pattern].tx_burst_size : 0;
540 delay_between_burst = (direction == OPER_WRITE) ? 2 : 0;
541 rd_mode = (direction == OPER_WRITE) ? 1 : 0;
542 CHECK_STATUS(ddr3_tip_configure_odpg
543 (dev_num, access_type, interface_num, direction,
544 pattern_table[pattern].num_of_phases_tx, tx_burst_size,
545 pattern_table[pattern].num_of_phases_rx,
546 delay_between_burst, rd_mode, effective_cs, STRESS_NONE,
547 DURATION_SINGLE));
548 reg_data = (direction == OPER_READ) ? 0 : (0x3 << 30);
549 reg_data |= (direction == OPER_READ) ? 0x60 : 0xfa;
550 CHECK_STATUS(ddr3_tip_if_write
551 (dev_num, access_type, interface_num,
552 ODPG_WR_RD_MODE_ENA_REG, reg_data,
553 MASK_ALL_BITS));
554 reg_data = (edge_comp == EDGE_PF || edge_comp == EDGE_FP) ? 0 : 1 << 6;
555 reg_data |= (edge_comp == EDGE_PF || edge_comp == EDGE_PFP) ?
556 (1 << 7) : 0;
557
558
559 if (pup_access_type == ACCESS_TYPE_MULTICAST)
560 reg_data |= 0xe << 14;
561 else
562 reg_data |= pup_num << 14;
563
564 if (edge_comp == EDGE_FP) {
565
566 reg_data |= (0 << 20);
567 } else if (edge_comp == EDGE_FPF) {
568 reg_data |= (0 << 20);
569 } else {
570 reg_data |= (3 << 20);
571 }
572
573 CHECK_STATUS(ddr3_tip_if_write
574 (dev_num, access_type, interface_num,
575 GENERAL_TRAINING_OPCODE_REG,
576 reg_data | (0x7 << 8) | (0x7 << 11),
577 (0x3 | (0x3 << 2) | (0x3 << 6) | (1 << 5) | (0x7 << 8) |
578 (0x7 << 11) | (0xf << 14) | (0x3 << 18) | (3 << 20))));
579 reg_data = (search_dir == HWS_LOW2HIGH) ? 0 : (1 << 8);
580 CHECK_STATUS(ddr3_tip_if_write
581 (dev_num, access_type, interface_num, OPCODE_REG0_REG(1),
582 1 | reg_data | init_value << 9 | (1 << 25) | (1 << 26),
583 0xff | (1 << 8) | (0xffff << 9) | (1 << 25) | (1 << 26)));
584
585
586
587
588
589 CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
590 OPCODE_REG1_REG(1), num_iter,
591 0xffff));
592 if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
593 direction == OPER_READ) {
594
595
596
597
598 reg_data = PBS_RX_BCAST_PHY_REG(effective_cs);
599 } else if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
600 direction == OPER_WRITE) {
601 reg_data = PBS_TX_BCAST_PHY_REG(effective_cs);
602 } else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
603 direction == OPER_WRITE) {
604
605
606
607
608
609
610
611
612 reg_data = CTX_PHY_REG(effective_cs);
613 } else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
614 direction == OPER_READ) {
615
616 reg_data = CRX_PHY_REG(effective_cs);
617 } else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
618 direction == OPER_WRITE) {
619
620 } else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
621 direction == OPER_READ) {
622
623 }
624
625 reg_data |= (0x6 << 28);
626 CHECK_STATUS(ddr3_tip_if_write
627 (dev_num, access_type, interface_num, CAL_PHY_REG(1),
628 reg_data | (init_value << 8),
629 0xff | (0xffff << 8) | (0xf << 24) | (u32) (0xf << 28)));
630
631 mask_dq_num_of_regs = octets_per_if_num * BUS_WIDTH_IN_BITS;
632 mask_pup_num_of_regs = octets_per_if_num;
633
634 if (result_type == RESULT_PER_BIT) {
635 for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
636 index_cnt++) {
637 CHECK_STATUS(ddr3_tip_if_write
638 (dev_num, access_type, interface_num,
639 mask_results_dq_reg_map[index_cnt], 0,
640 1 << 24));
641 }
642
643
644 for (pup_id = 0; pup_id < octets_per_if_num;
645 pup_id++) {
646 if (IS_BUS_ACTIVE(tm->bus_act_mask, pup_id) == 1)
647 continue;
648
649 for (index_cnt = (pup_id * 8); index_cnt < (pup_id + 1) * 8; index_cnt++) {
650 CHECK_STATUS(ddr3_tip_if_write
651 (dev_num, access_type,
652 interface_num,
653 mask_results_dq_reg_map
654 [index_cnt], (1 << 24), 1 << 24));
655 }
656 }
657
658 for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
659 index_cnt++) {
660 CHECK_STATUS(ddr3_tip_if_write
661 (dev_num, access_type, interface_num,
662 mask_results_pup_reg_map[index_cnt],
663 (1 << 24), 1 << 24));
664 }
665 } else if (result_type == RESULT_PER_BYTE) {
666
667 for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
668 index_cnt++) {
669 CHECK_STATUS(ddr3_tip_if_write
670 (dev_num, access_type, interface_num,
671 mask_results_pup_reg_map[index_cnt], 0,
672 1 << 24));
673 }
674 for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
675 index_cnt++) {
676 CHECK_STATUS(ddr3_tip_if_write
677 (dev_num, access_type, interface_num,
678 mask_results_dq_reg_map[index_cnt],
679 (1 << 24), (1 << 24)));
680 }
681 }
682
683
684 mv_ddr_training_enable();
685
686
687 mdelay(1);
688
689
690 if (mv_ddr_is_training_done(MAX_POLLING_ITERATIONS, &data) != MV_OK) {
691 train_status[0] = HWS_TRAINING_IP_STATUS_TIMEOUT;
692 } else {
693 if (data == PASS)
694 train_status[0] = HWS_TRAINING_IP_STATUS_SUCCESS;
695 else
696 train_status[0] = HWS_TRAINING_IP_STATUS_FAIL;
697 }
698
699 ddr3_tip_if_write(0, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
700 ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS);
701#if defined(CONFIG_DDR4)
702 if (tm->debug_level != DEBUG_LEVEL_ERROR)
703 refresh();
704#endif
705
706 return MV_OK;
707}
708
709
710
711
712int ddr3_tip_load_pattern_to_odpg(u32 dev_num, enum hws_access_type access_type,
713 u32 if_id, enum hws_pattern pattern,
714 u32 load_addr)
715{
716 u32 pattern_length_cnt = 0;
717 struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
718 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
719
720 for (pattern_length_cnt = 0;
721 pattern_length_cnt < pattern_table[pattern].pattern_len;
722 pattern_length_cnt++) {
723 if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask)) {
724 CHECK_STATUS(ddr3_tip_if_write
725 (dev_num, access_type, if_id,
726 ODPG_DATA_WR_DATA_LOW_REG,
727 pattern_table_get_word(dev_num, pattern,
728 (u8) (pattern_length_cnt)),
729 MASK_ALL_BITS));
730 CHECK_STATUS(ddr3_tip_if_write
731 (dev_num, access_type, if_id,
732 ODPG_DATA_WR_DATA_HIGH_REG,
733 pattern_table_get_word(dev_num, pattern,
734 (u8) (pattern_length_cnt)),
735 MASK_ALL_BITS));
736 } else {
737 CHECK_STATUS(ddr3_tip_if_write
738 (dev_num, access_type, if_id,
739 ODPG_DATA_WR_DATA_LOW_REG,
740 pattern_table_get_word(dev_num, pattern,
741 (u8) (pattern_length_cnt * 2)),
742 MASK_ALL_BITS));
743 CHECK_STATUS(ddr3_tip_if_write
744 (dev_num, access_type, if_id,
745 ODPG_DATA_WR_DATA_HIGH_REG,
746 pattern_table_get_word(dev_num, pattern,
747 (u8) (pattern_length_cnt * 2 + 1)),
748 MASK_ALL_BITS));
749 }
750 CHECK_STATUS(ddr3_tip_if_write
751 (dev_num, access_type, if_id,
752 ODPG_DATA_WR_ADDR_REG, pattern_length_cnt,
753 MASK_ALL_BITS));
754 }
755
756 CHECK_STATUS(ddr3_tip_if_write
757 (dev_num, access_type, if_id,
758 ODPG_DATA_BUFFER_OFFS_REG, load_addr, MASK_ALL_BITS));
759
760 return MV_OK;
761}
762
763
764
765
766int ddr3_tip_configure_odpg(u32 dev_num, enum hws_access_type access_type,
767 u32 if_id, enum hws_dir direction, u32 tx_phases,
768 u32 tx_burst_size, u32 rx_phases,
769 u32 delay_between_burst, u32 rd_mode, u32 cs_num,
770 u32 addr_stress_jump, u32 single_pattern)
771{
772 u32 data_value = 0;
773 int ret;
774
775 data_value = ((single_pattern << 2) | (tx_phases << 5) |
776 (tx_burst_size << 11) | (delay_between_burst << 15) |
777 (rx_phases << 21) | (rd_mode << 25) | (cs_num << 26) |
778 (addr_stress_jump << 29));
779 ret = ddr3_tip_if_write(dev_num, access_type, if_id,
780 ODPG_DATA_CTRL_REG, data_value, 0xaffffffc);
781 if (ret != MV_OK)
782 return ret;
783
784 return MV_OK;
785}
786
787int ddr3_tip_process_result(u32 *ar_result, enum hws_edge e_edge,
788 enum hws_edge_search e_edge_search,
789 u32 *edge_result)
790{
791 u32 i, res;
792 int tap_val, max_val = -10000, min_val = 10000;
793 int lock_success = 1;
794
795 for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
796 res = GET_LOCK_RESULT(ar_result[i]);
797 if (res == 0) {
798 lock_success = 0;
799 break;
800 }
801 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
802 ("lock failed for bit %d\n", i));
803 }
804
805 if (lock_success == 1) {
806 for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
807 tap_val = GET_TAP_RESULT(ar_result[i], e_edge);
808 if (tap_val > max_val)
809 max_val = tap_val;
810 if (tap_val < min_val)
811 min_val = tap_val;
812 if (e_edge_search == TRAINING_EDGE_MAX)
813 *edge_result = (u32) max_val;
814 else
815 *edge_result = (u32) min_val;
816
817 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
818 ("i %d ar_result[i] 0x%x tap_val %d max_val %d min_val %d Edge_result %d\n",
819 i, ar_result[i], tap_val,
820 max_val, min_val,
821 *edge_result));
822 }
823 } else {
824 return MV_FAIL;
825 }
826
827 return MV_OK;
828}
829
830
831
832
833int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
834 enum hws_access_type pup_access_type,
835 u32 pup_num, u32 bit_num,
836 enum hws_search_dir search,
837 enum hws_dir direction,
838 enum hws_training_result result_type,
839 enum hws_training_load_op operation,
840 u32 cs_num_type, u32 **load_res,
841 int is_read_from_db, u8 cons_tap,
842 int is_check_result_validity)
843{
844 u32 reg_offset, pup_cnt, start_pup, end_pup, start_reg, end_reg;
845 u32 *interface_train_res = NULL;
846 u16 *reg_addr = NULL;
847 u32 read_data[MAX_INTERFACE_NUM];
848 u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
849 u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
850 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
851 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
852
853
854
855
856
857
858 CHECK_STATUS(ddr3_tip_if_write
859 (dev_num, ACCESS_TYPE_UNICAST, if_id, DUAL_DUNIT_CFG_REG,
860 (cs_num_type == 0) ? 1 << 3 : 0, (1 << 3)));
861 CHECK_STATUS(ddr3_tip_if_write
862 (dev_num, ACCESS_TYPE_UNICAST, if_id,
863 ODPG_DATA_CTRL_REG, (cs_num_type << 26), (3 << 26)));
864 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
865 ("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",
866 is_read_from_db, cs_num_type, operation,
867 result_type, direction, search, pup_num,
868 if_id, pup_access_type));
869
870 if ((load_res == NULL) && (is_read_from_db == 1)) {
871 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
872 ("ddr3_tip_read_training_result load_res = NULL"));
873 return MV_FAIL;
874 }
875 if (pup_num >= octets_per_if_num) {
876 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
877 ("pup_num %d not valid\n", pup_num));
878 }
879 if (if_id >= MAX_INTERFACE_NUM) {
880 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
881 ("if_id %d not valid\n", if_id));
882 }
883 if (result_type == RESULT_PER_BIT)
884 reg_addr = mask_results_dq_reg_map;
885 else
886 reg_addr = mask_results_pup_reg_map;
887 if (pup_access_type == ACCESS_TYPE_UNICAST) {
888 start_pup = pup_num;
889 end_pup = pup_num;
890 } else {
891
892 start_pup = 0;
893 end_pup = octets_per_if_num - 1;
894 }
895
896 for (pup_cnt = start_pup; pup_cnt <= end_pup; pup_cnt++) {
897 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup_cnt);
898 DEBUG_TRAINING_IP_ENGINE(
899 DEBUG_LEVEL_TRACE,
900 ("if_id %d start_pup %d end_pup %d pup_cnt %d\n",
901 if_id, start_pup, end_pup, pup_cnt));
902 if (result_type == RESULT_PER_BIT) {
903 if (bit_num == ALL_BITS_PER_PUP) {
904 start_reg = pup_cnt * BUS_WIDTH_IN_BITS;
905 end_reg = (pup_cnt + 1) * BUS_WIDTH_IN_BITS - 1;
906 } else {
907 start_reg =
908 pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
909 end_reg = pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
910 }
911 } else {
912 start_reg = pup_cnt;
913 end_reg = pup_cnt;
914 }
915
916 interface_train_res =
917 ddr3_tip_get_buf_ptr(dev_num, search, result_type,
918 if_id);
919 DEBUG_TRAINING_IP_ENGINE(
920 DEBUG_LEVEL_TRACE,
921 ("start_reg %d end_reg %d interface %p\n",
922 start_reg, end_reg, interface_train_res));
923 if (interface_train_res == NULL) {
924 DEBUG_TRAINING_IP_ENGINE(
925 DEBUG_LEVEL_ERROR,
926 ("interface_train_res is NULL\n"));
927 return MV_FAIL;
928 }
929
930 for (reg_offset = start_reg; reg_offset <= end_reg;
931 reg_offset++) {
932 if (operation == TRAINING_LOAD_OPERATION_UNLOAD) {
933 if (is_read_from_db == 0) {
934 CHECK_STATUS(ddr3_tip_if_read
935 (dev_num,
936 ACCESS_TYPE_UNICAST,
937 if_id,
938 reg_addr[reg_offset],
939 read_data,
940 MASK_ALL_BITS));
941 if (is_check_result_validity == 1) {
942 if ((read_data[if_id] &
943 TIP_ENG_LOCK) == 0) {
944 interface_train_res
945 [reg_offset] =
946 TIP_ENG_LOCK +
947 TIP_TX_DLL_RANGE_MAX;
948 } else {
949 interface_train_res
950 [reg_offset] =
951 read_data
952 [if_id] +
953 cons_tap;
954 }
955 } else {
956 interface_train_res[reg_offset]
957 = read_data[if_id] +
958 cons_tap;
959 }
960 DEBUG_TRAINING_IP_ENGINE
961 (DEBUG_LEVEL_TRACE,
962 ("reg_offset %d value 0x%x addr %p\n",
963 reg_offset,
964 interface_train_res
965 [reg_offset],
966 &interface_train_res
967 [reg_offset]));
968 } else {
969 *load_res =
970 &interface_train_res[start_reg];
971 DEBUG_TRAINING_IP_ENGINE
972 (DEBUG_LEVEL_TRACE,
973 ("*load_res %p\n", *load_res));
974 }
975 } else {
976 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
977 ("not supported\n"));
978 }
979 }
980 }
981#if defined(CONFIG_DDR4)
982 if (tm->debug_level != DEBUG_LEVEL_ERROR)
983 refresh();
984#endif
985
986 return MV_OK;
987}
988
989
990
991
992int ddr3_tip_load_all_pattern_to_mem(u32 dev_num)
993{
994 u32 pattern = 0, if_id;
995 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
996
997 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
998 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
999 training_result[training_stage][if_id] = TEST_SUCCESS;
1000 }
1001
1002 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1003 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1004
1005 CHECK_STATUS(ddr3_tip_if_write
1006 (dev_num, ACCESS_TYPE_UNICAST, if_id,
1007 DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3)));
1008 }
1009
1010 for (pattern = 0; pattern < PATTERN_LAST; pattern++) {
1011 if (pattern == PATTERN_TEST)
1012 continue;
1013 ddr3_tip_load_pattern_to_mem(dev_num, pattern);
1014 }
1015
1016 return MV_OK;
1017}
1018
1019
1020
1021
1022int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern pattern)
1023{
1024 u32 reg_data, if_id;
1025 struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
1026 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1027
1028
1029
1030
1031
1032
1033 reg_data =
1034 0x1 | (pattern_table[pattern].num_of_phases_tx << 5) |
1035 (pattern_table[pattern].tx_burst_size << 11) |
1036 (pattern_table[pattern].delay_between_bursts << 15) |
1037 (pattern_table[pattern].num_of_phases_rx << 21) | (0x1 << 25) |
1038 (effective_cs << 26);
1039 CHECK_STATUS(ddr3_tip_if_write
1040 (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1041 ODPG_DATA_CTRL_REG, reg_data, MASK_ALL_BITS));
1042
1043 CHECK_STATUS(ddr3_tip_if_write
1044 (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1045 ODPG_DATA_CTRL_REG, (0x1 | (effective_cs << 26)),
1046 0xc000003));
1047
1048 CHECK_STATUS(ddr3_tip_if_write
1049 (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1050 ODPG_DATA_WR_DATA_ERR_REG, 0, 0x1));
1051
1052 ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
1053 PARAM_NOT_CARE, pattern,
1054 pattern_table[pattern].start_addr);
1055
1056 if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) >= MV_TIP_REV_3) {
1057 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
1058 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1059
1060 CHECK_STATUS(ddr3_tip_if_write
1061 (dev_num, ACCESS_TYPE_UNICAST, if_id,
1062 SDRAM_ODT_CTRL_HIGH_REG,
1063 0x3, 0xf));
1064 }
1065
1066 mv_ddr_odpg_enable();
1067 } else {
1068 CHECK_STATUS(ddr3_tip_if_write
1069 (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1070 ODPG_DATA_CTRL_REG, (u32)(0x1 << 31),
1071 (u32)(0x1 << 31)));
1072 }
1073 mdelay(1);
1074
1075 if (mv_ddr_is_odpg_done(MAX_POLLING_ITERATIONS) != MV_OK)
1076 return MV_FAIL;
1077
1078
1079 CHECK_STATUS(ddr3_tip_if_write
1080 (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1081 ODPG_DATA_CTRL_REG, (0x1 << 30), (u32) (0x3 << 30)));
1082
1083
1084 CHECK_STATUS(ddr3_tip_if_write
1085 (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1086 ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS));
1087
1088 if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) >= MV_TIP_REV_3) {
1089
1090 CHECK_STATUS(ddr3_tip_if_write
1091 (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1092 SDRAM_ODT_CTRL_HIGH_REG, 0x0, 0xf));
1093 }
1094
1095 mdelay(1);
1096
1097 return MV_OK;
1098}
1099
1100
1101
1102
1103int ddr3_tip_ip_training_wrapper_int(u32 dev_num,
1104 enum hws_access_type access_type,
1105 u32 if_id,
1106 enum hws_access_type pup_access_type,
1107 u32 pup_num, u32 bit_num,
1108 enum hws_training_result result_type,
1109 enum hws_control_element control_element,
1110 enum hws_search_dir search_dir,
1111 enum hws_dir direction,
1112 u32 interface_mask, u32 init_value_l2h,
1113 u32 init_value_h2l, u32 num_iter,
1114 enum hws_pattern pattern,
1115 enum hws_edge_compare edge_comp,
1116 enum hws_ddr_cs train_cs_type, u32 cs_num,
1117 enum hws_training_ip_stat *train_status)
1118{
1119 u32 interface_num = 0, start_if, end_if, init_value_used;
1120 enum hws_search_dir search_dir_id, start_search, end_search;
1121 enum hws_edge_compare edge_comp_used;
1122 u8 cons_tap = 0;
1123 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
1124 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1125
1126 if (train_status == NULL) {
1127 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
1128 ("train_status is NULL\n"));
1129 return MV_FAIL;
1130 }
1131
1132 if ((train_cs_type > CS_NON_SINGLE) ||
1133 (edge_comp >= EDGE_PFP) ||
1134 (pattern >= PATTERN_LAST) ||
1135 (direction > OPER_WRITE_AND_READ) ||
1136 (search_dir > HWS_HIGH2LOW) ||
1137 (control_element > HWS_CONTROL_ELEMENT_DQS_SKEW) ||
1138 (result_type > RESULT_PER_BYTE) ||
1139 (pup_num >= octets_per_if_num) ||
1140 (pup_access_type > ACCESS_TYPE_MULTICAST) ||
1141 (if_id > 11) || (access_type > ACCESS_TYPE_MULTICAST)) {
1142 DEBUG_TRAINING_IP_ENGINE(
1143 DEBUG_LEVEL_ERROR,
1144 ("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",
1145 train_cs_type, edge_comp, pattern, direction,
1146 search_dir, control_element, result_type, pup_num,
1147 pup_access_type, if_id, access_type));
1148 return MV_FAIL;
1149 }
1150
1151 if (edge_comp == EDGE_FPF) {
1152 start_search = HWS_LOW2HIGH;
1153 end_search = HWS_HIGH2LOW;
1154 edge_comp_used = EDGE_FP;
1155 } else {
1156 start_search = search_dir;
1157 end_search = search_dir;
1158 edge_comp_used = edge_comp;
1159 }
1160
1161 for (search_dir_id = start_search; search_dir_id <= end_search;
1162 search_dir_id++) {
1163 init_value_used = (search_dir_id == HWS_LOW2HIGH) ?
1164 init_value_l2h : init_value_h2l;
1165 DEBUG_TRAINING_IP_ENGINE(
1166 DEBUG_LEVEL_TRACE,
1167 ("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",
1168 dev_num, access_type, if_id, pup_access_type, pup_num,
1169 result_type, control_element, search_dir_id,
1170 direction, interface_mask, init_value_used, num_iter,
1171 pattern, edge_comp_used, train_cs_type, cs_num));
1172
1173 ddr3_tip_ip_training(dev_num, access_type, if_id,
1174 pup_access_type, pup_num, result_type,
1175 control_element, search_dir_id, direction,
1176 interface_mask, init_value_used, num_iter,
1177 pattern, edge_comp_used, train_cs_type,
1178 cs_num, train_status);
1179 if (access_type == ACCESS_TYPE_MULTICAST) {
1180 start_if = 0;
1181 end_if = MAX_INTERFACE_NUM - 1;
1182 } else {
1183 start_if = if_id;
1184 end_if = if_id;
1185 }
1186
1187 for (interface_num = start_if; interface_num <= end_if;
1188 interface_num++) {
1189 VALIDATE_IF_ACTIVE(tm->if_act_mask, interface_num);
1190 cs_num = 0;
1191 CHECK_STATUS(ddr3_tip_read_training_result
1192 (dev_num, interface_num, pup_access_type,
1193 pup_num, bit_num, search_dir_id,
1194 direction, result_type,
1195 TRAINING_LOAD_OPERATION_UNLOAD,
1196 train_cs_type, NULL, 0, cons_tap,
1197 0));
1198 }
1199 }
1200
1201 return MV_OK;
1202}
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242int ddr3_tip_ip_training_wrapper(u32 dev_num, enum hws_access_type access_type,
1243 u32 if_id,
1244 enum hws_access_type pup_access_type,
1245 u32 pup_num,
1246 enum hws_training_result result_type,
1247 enum hws_control_element control_element,
1248 enum hws_search_dir search_dir,
1249 enum hws_dir direction, u32 interface_mask,
1250 u32 init_value_l2h, u32 init_value_h2l,
1251 u32 num_iter, enum hws_pattern pattern,
1252 enum hws_edge_compare edge_comp,
1253 enum hws_ddr_cs train_cs_type, u32 cs_num,
1254 enum hws_training_ip_stat *train_status)
1255{
1256 u8 e1, e2;
1257 u32 bit_id, start_if, end_if, bit_end = 0;
1258 u32 *result[HWS_SEARCH_DIR_LIMIT] = { 0 };
1259 u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
1260 u8 bit_bit_mask[MAX_BUS_NUM] = { 0 }, bit_bit_mask_active = 0;
1261 u8 bit_state[MAX_BUS_NUM * BUS_WIDTH_IN_BITS] = {0};
1262 u8 h2l_adll_value[MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
1263 u8 l2h_adll_value[MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
1264 u8 center_subphy_adll_window[MAX_BUS_NUM];
1265 u8 min_center_subphy_adll[MAX_BUS_NUM];
1266 u8 max_center_subphy_adll[MAX_BUS_NUM];
1267 u32 *l2h_if_train_res = NULL;
1268 u32 *h2l_if_train_res = NULL;
1269 enum hws_search_dir search_dir_id;
1270 int status;
1271 u32 bit_lock_result;
1272
1273 u8 sybphy_id;
1274 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
1275 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1276
1277 if (pup_num >= octets_per_if_num) {
1278 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
1279 ("pup_num %d not valid\n", pup_num));
1280 }
1281
1282 if (if_id >= MAX_INTERFACE_NUM) {
1283 DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
1284 ("if_id %d not valid\n", if_id));
1285 }
1286
1287 status = ddr3_tip_ip_training_wrapper_int
1288 (dev_num, access_type, if_id, pup_access_type, pup_num,
1289 ALL_BITS_PER_PUP, result_type, control_element,
1290 search_dir, direction, interface_mask, init_value_l2h,
1291 init_value_h2l, num_iter, pattern, edge_comp,
1292 train_cs_type, cs_num, train_status);
1293
1294 if (MV_OK != status)
1295 return status;
1296
1297 if (access_type == ACCESS_TYPE_MULTICAST) {
1298 start_if = 0;
1299 end_if = MAX_INTERFACE_NUM - 1;
1300 } else {
1301 start_if = if_id;
1302 end_if = if_id;
1303 }
1304
1305 for (if_id = start_if; if_id <= end_if; if_id++) {
1306 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1307
1308 bit_bit_mask_active = 0;
1309 memset(bit_state, 0, sizeof(bit_state));
1310
1311 for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1312 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1313 if (result_type == RESULT_PER_BIT)
1314 bit_end = BUS_WIDTH_IN_BITS;
1315 else
1316 bit_end = 0;
1317
1318
1319 bit_bit_mask[sybphy_id] = 0;
1320 byte_status[if_id][sybphy_id] = BYTE_NOT_DEFINED;
1321 for (bit_id = 0; bit_id < bit_end; bit_id++) {
1322 h2l_adll_value[sybphy_id][bit_id] = 64;
1323 l2h_adll_value[sybphy_id][bit_id] = 0;
1324 for (search_dir_id = HWS_LOW2HIGH; search_dir_id <= HWS_HIGH2LOW;
1325 search_dir_id++) {
1326 status = ddr3_tip_read_training_result
1327 (dev_num, if_id,
1328 ACCESS_TYPE_UNICAST, sybphy_id, bit_id,
1329 search_dir_id, direction, result_type,
1330 TRAINING_LOAD_OPERATION_UNLOAD, CS_SINGLE,
1331 &result[search_dir_id], 1, 0, 0);
1332
1333 if (MV_OK != status)
1334 return status;
1335 }
1336
1337 e1 = GET_TAP_RESULT(result[HWS_LOW2HIGH][0], EDGE_1);
1338 e2 = GET_TAP_RESULT(result[HWS_HIGH2LOW][0], EDGE_1);
1339 DEBUG_TRAINING_IP_ENGINE
1340 (DEBUG_LEVEL_INFO,
1341 ("if_id %d sybphy_id %d bit %d l2h 0x%x (e1 0x%x) h2l 0x%x (e2 0x%x)\n",
1342 if_id, sybphy_id, bit_id, result[HWS_LOW2HIGH][0], e1,
1343 result[HWS_HIGH2LOW][0], e2));
1344 bit_lock_result =
1345 (GET_LOCK_RESULT(result[HWS_LOW2HIGH][0]) &&
1346 GET_LOCK_RESULT(result[HWS_HIGH2LOW][0]));
1347
1348 if (bit_lock_result) {
1349
1350 if (direction == OPER_READ) {
1351 byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_LOW;
1352 } else if ((e2 - e1) > 32) {
1353
1354 bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
1355 BIT_SPLIT_OUT;
1356 byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_SPLIT_OUT;
1357
1358 bit_bit_mask[sybphy_id] |= (1 << bit_id);
1359 bit_bit_mask_active = 1;
1360 DEBUG_TRAINING_IP_ENGINE
1361 (DEBUG_LEVEL_TRACE,
1362 ("if_id %d sybphy_id %d bit %d BIT_SPLIT_OUT\n",
1363 if_id, sybphy_id, bit_id));
1364 } else {
1365
1366 if (e1 <= 31 && e2 <= 31) {
1367 bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
1368 BIT_LOW_UI;
1369 byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_LOW;
1370 l2h_adll_value[sybphy_id][bit_id] = e1;
1371 h2l_adll_value[sybphy_id][bit_id] = e2;
1372 DEBUG_TRAINING_IP_ENGINE
1373 (DEBUG_LEVEL_TRACE,
1374 ("if_id %d sybphy_id %d bit %d BIT_LOW_UI\n",
1375 if_id, sybphy_id, bit_id));
1376 }
1377
1378 if (e1 >= 32 && e2 >= 32) {
1379 bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
1380 BIT_HIGH_UI;
1381 byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_HIGH;
1382 l2h_adll_value[sybphy_id][bit_id] = e1;
1383 h2l_adll_value[sybphy_id][bit_id] = e2;
1384 DEBUG_TRAINING_IP_ENGINE
1385 (DEBUG_LEVEL_TRACE,
1386 ("if_id %d sybphy_id %d bit %d BIT_HIGH_UI\n",
1387 if_id, sybphy_id, bit_id));
1388 }
1389
1390 if (e1 <= 31 && e2 >= 32) {
1391 bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
1392 BIT_SPLIT_IN;
1393 byte_status[if_id][sybphy_id] |=
1394 BYTE_HOMOGENEOUS_SPLIT_IN;
1395 l2h_adll_value[sybphy_id][bit_id] = e1;
1396 h2l_adll_value[sybphy_id][bit_id] = e2;
1397 DEBUG_TRAINING_IP_ENGINE
1398 (DEBUG_LEVEL_TRACE,
1399 ("if_id %d sybphy_id %d bit %d BIT_SPLIT_IN\n",
1400 if_id, sybphy_id, bit_id));
1401 }
1402 }
1403 } else {
1404 DEBUG_TRAINING_IP_ENGINE
1405 (DEBUG_LEVEL_INFO,
1406 ("if_id %d sybphy_id %d bit %d l2h 0x%x (e1 0x%x)"
1407 "h2l 0x%x (e2 0x%x): bit cannot be categorized\n",
1408 if_id, sybphy_id, bit_id, result[HWS_LOW2HIGH][0], e1,
1409 result[HWS_HIGH2LOW][0], e2));
1410
1411 byte_status[if_id][sybphy_id] = BYTE_NOT_DEFINED;
1412 break;
1413 }
1414 }
1415 }
1416
1417
1418 if (bit_bit_mask_active != 0) {
1419 l2h_if_train_res = ddr3_tip_get_buf_ptr(dev_num, HWS_LOW2HIGH, result_type, if_id);
1420 h2l_if_train_res = ddr3_tip_get_buf_ptr(dev_num, HWS_HIGH2LOW, result_type, if_id);
1421
1422 ddr3_tip_ip_training
1423 (dev_num, ACCESS_TYPE_UNICAST,
1424 if_id, ACCESS_TYPE_MULTICAST,
1425 PARAM_NOT_CARE, result_type,
1426 control_element, HWS_LOW2HIGH,
1427 direction, interface_mask,
1428 num_iter / 2, num_iter / 2,
1429 pattern, EDGE_FP, train_cs_type,
1430 cs_num, train_status);
1431
1432 for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1433 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1434 if (byte_status[if_id][sybphy_id] != BYTE_NOT_DEFINED) {
1435 if (bit_bit_mask[sybphy_id] == 0)
1436 continue;
1437
1438 for (bit_id = 0; bit_id < bit_end; bit_id++) {
1439 if ((bit_bit_mask[sybphy_id] & (1 << bit_id)) == 0)
1440 continue;
1441
1442
1443 status = ddr3_tip_read_training_result
1444 (dev_num, if_id, ACCESS_TYPE_UNICAST, sybphy_id,
1445 bit_id, HWS_LOW2HIGH, direction, result_type,
1446 TRAINING_LOAD_OPERATION_UNLOAD, CS_SINGLE,
1447 &l2h_if_train_res, 0, 0, 1);
1448
1449 if (MV_OK != status)
1450 return status;
1451
1452 l2h_adll_value[sybphy_id][bit_id] =
1453 l2h_if_train_res[sybphy_id *
1454 BUS_WIDTH_IN_BITS + bit_id] & PUP_RESULT_EDGE_1_MASK;
1455 }
1456 }
1457 }
1458
1459 ddr3_tip_ip_training
1460 (dev_num, ACCESS_TYPE_UNICAST,
1461 if_id, ACCESS_TYPE_MULTICAST,
1462 PARAM_NOT_CARE, result_type,
1463 control_element, HWS_HIGH2LOW,
1464 direction, interface_mask,
1465 num_iter / 2, num_iter / 2,
1466 pattern, EDGE_FP, train_cs_type,
1467 cs_num, train_status);
1468
1469 for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1470 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1471 if (byte_status[if_id][sybphy_id] != BYTE_NOT_DEFINED) {
1472 if (bit_bit_mask[sybphy_id] == 0)
1473 continue;
1474
1475 for (bit_id = 0; bit_id < bit_end; bit_id++) {
1476 if ((bit_bit_mask[sybphy_id] & (1 << bit_id)) == 0)
1477 continue;
1478
1479 status = ddr3_tip_read_training_result
1480 (dev_num, if_id, ACCESS_TYPE_UNICAST, sybphy_id,
1481 bit_id, HWS_HIGH2LOW, direction, result_type,
1482 TRAINING_LOAD_OPERATION_UNLOAD, CS_SINGLE,
1483 &h2l_if_train_res, 0, cons_tap, 1);
1484
1485 if (MV_OK != status)
1486 return status;
1487
1488 h2l_adll_value[sybphy_id][bit_id] =
1489 h2l_if_train_res[sybphy_id *
1490 BUS_WIDTH_IN_BITS + bit_id] & PUP_RESULT_EDGE_1_MASK;
1491 }
1492 }
1493 }
1494 }
1495
1496
1497
1498
1499 for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1500 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1501
1502 if ((byte_status[if_id][sybphy_id] != BYTE_NOT_DEFINED) && (direction == OPER_WRITE)) {
1503
1504 center_subphy_adll_window[sybphy_id] = 0;
1505 max_center_subphy_adll[sybphy_id] = 0;
1506 min_center_subphy_adll[sybphy_id] = 64;
1507
1508 for (bit_id = 0; bit_id < bit_end; bit_id++) {
1509
1510 DEBUG_TRAINING_IP_ENGINE
1511 (DEBUG_LEVEL_TRACE,
1512 ("if_id %d sybphy_id %d bit %d l2h %d h2l %d\n",
1513 if_id, sybphy_id, bit_id, l2h_adll_value[sybphy_id][bit_id],
1514 h2l_adll_value[sybphy_id][bit_id]));
1515
1516 if (((l2h_adll_value[sybphy_id][bit_id] +
1517 h2l_adll_value[sybphy_id][bit_id]) / 2) >
1518 max_center_subphy_adll[sybphy_id])
1519 max_center_subphy_adll[sybphy_id] =
1520 (l2h_adll_value[sybphy_id][bit_id] +
1521 h2l_adll_value[sybphy_id][bit_id]) / 2;
1522 if (((l2h_adll_value[sybphy_id][bit_id] +
1523 h2l_adll_value[sybphy_id][bit_id]) / 2) <
1524 min_center_subphy_adll[sybphy_id])
1525 min_center_subphy_adll[sybphy_id] =
1526 (l2h_adll_value[sybphy_id][bit_id] +
1527 h2l_adll_value[sybphy_id][bit_id]) / 2;
1528 }
1529
1530
1531 center_subphy_adll_window[sybphy_id] =
1532 max_center_subphy_adll[sybphy_id] -
1533 min_center_subphy_adll[sybphy_id];
1534 DEBUG_TRAINING_IP_ENGINE
1535 (DEBUG_LEVEL_TRACE,
1536 ("if_id %d sybphy_id %d min center %d max center %d center %d\n",
1537 if_id, sybphy_id, min_center_subphy_adll[sybphy_id],
1538 max_center_subphy_adll[sybphy_id],
1539 center_subphy_adll_window[sybphy_id]));
1540 }
1541 }
1542
1543
1544
1545
1546
1547 for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1548 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1549 if ((byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_LOW) ||
1550 (byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_HIGH) ||
1551 (byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_SPLIT_IN) ||
1552 (byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_SPLIT_OUT) ||
1553 (byte_status[if_id][sybphy_id] == BYTE_NOT_DEFINED))
1554 continue;
1555
1556
1557
1558
1559
1560
1561 if (center_subphy_adll_window[sybphy_id] <= 31)
1562 byte_status[if_id][sybphy_id] = BYTE_HOMOGENEOUS_SPLIT_IN;
1563
1564
1565
1566
1567
1568
1569 if (center_subphy_adll_window[sybphy_id] >= 32) {
1570 byte_status[if_id][sybphy_id] = BYTE_SPLIT_OUT_MIX;
1571
1572 DEBUG_TRAINING_IP_ENGINE
1573 (DEBUG_LEVEL_TRACE,
1574 ("if_id %d sybphy_id %d byte state 0x%x\n",
1575 if_id, sybphy_id, byte_status[if_id][sybphy_id]));
1576 for (bit_id = 0; bit_id < bit_end; bit_id++) {
1577 if (bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] == BIT_LOW_UI) {
1578 l2h_if_train_res[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] += 64;
1579 h2l_if_train_res[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] += 64;
1580 }
1581 DEBUG_TRAINING_IP_ENGINE
1582 (DEBUG_LEVEL_TRACE,
1583 ("if_id %d sybphy_id %d bit_id %d added 64 adlls\n",
1584 if_id, sybphy_id, bit_id));
1585 }
1586 }
1587 }
1588 }
1589
1590 return MV_OK;
1591}
1592
1593u8 mv_ddr_tip_sub_phy_byte_status_get(u32 if_id, u32 subphy_id)
1594{
1595 return byte_status[if_id][subphy_id];
1596}
1597
1598void mv_ddr_tip_sub_phy_byte_status_set(u32 if_id, u32 subphy_id, u8 byte_status_data)
1599{
1600 byte_status[if_id][subphy_id] = byte_status_data;
1601}
1602
1603
1604
1605
1606int ddr3_tip_load_phy_values(int b_load)
1607{
1608 u32 bus_cnt = 0, if_id, dev_num = 0;
1609 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
1610 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1611
1612 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1613 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1614 for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
1615 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
1616 if (b_load == 1) {
1617 CHECK_STATUS(ddr3_tip_bus_read
1618 (dev_num, if_id,
1619 ACCESS_TYPE_UNICAST, bus_cnt,
1620 DDR_PHY_DATA,
1621 CTX_PHY_REG(effective_cs),
1622 &phy_reg_bk[if_id][bus_cnt]
1623 [0]));
1624 CHECK_STATUS(ddr3_tip_bus_read
1625 (dev_num, if_id,
1626 ACCESS_TYPE_UNICAST, bus_cnt,
1627 DDR_PHY_DATA,
1628 RL_PHY_REG(effective_cs),
1629 &phy_reg_bk[if_id][bus_cnt]
1630 [1]));
1631 CHECK_STATUS(ddr3_tip_bus_read
1632 (dev_num, if_id,
1633 ACCESS_TYPE_UNICAST, bus_cnt,
1634 DDR_PHY_DATA,
1635 CRX_PHY_REG(effective_cs),
1636 &phy_reg_bk[if_id][bus_cnt]
1637 [2]));
1638 } else {
1639 CHECK_STATUS(ddr3_tip_bus_write
1640 (dev_num, ACCESS_TYPE_UNICAST,
1641 if_id, ACCESS_TYPE_UNICAST,
1642 bus_cnt, DDR_PHY_DATA,
1643 CTX_PHY_REG(effective_cs),
1644 phy_reg_bk[if_id][bus_cnt]
1645 [0]));
1646 CHECK_STATUS(ddr3_tip_bus_write
1647 (dev_num, ACCESS_TYPE_UNICAST,
1648 if_id, ACCESS_TYPE_UNICAST,
1649 bus_cnt, DDR_PHY_DATA,
1650 RL_PHY_REG(effective_cs),
1651 phy_reg_bk[if_id][bus_cnt]
1652 [1]));
1653 CHECK_STATUS(ddr3_tip_bus_write
1654 (dev_num, ACCESS_TYPE_UNICAST,
1655 if_id, ACCESS_TYPE_UNICAST,
1656 bus_cnt, DDR_PHY_DATA,
1657 CRX_PHY_REG(effective_cs),
1658 phy_reg_bk[if_id][bus_cnt]
1659 [2]));
1660 }
1661 }
1662 }
1663
1664 return MV_OK;
1665}
1666
1667int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
1668 enum hws_search_dir search_dir,
1669 enum hws_dir direction,
1670 enum hws_edge_compare edge,
1671 u32 init_val1, u32 init_val2,
1672 u32 num_of_iterations,
1673 u32 start_pattern, u32 end_pattern)
1674{
1675 u32 pattern, if_id, pup_id;
1676 enum hws_training_ip_stat train_status[MAX_INTERFACE_NUM];
1677 u32 *res = NULL;
1678 u32 search_state = 0;
1679 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
1680 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1681
1682 ddr3_tip_load_phy_values(1);
1683
1684 for (pattern = start_pattern; pattern <= end_pattern; pattern++) {
1685 for (search_state = 0; search_state < HWS_SEARCH_DIR_LIMIT;
1686 search_state++) {
1687 ddr3_tip_ip_training_wrapper(dev_num,
1688 ACCESS_TYPE_MULTICAST, 0,
1689 ACCESS_TYPE_MULTICAST, 0,
1690 result_type,
1691 HWS_CONTROL_ELEMENT_ADLL,
1692 search_dir, direction,
1693 0xfff, init_val1,
1694 init_val2,
1695 num_of_iterations, pattern,
1696 edge, CS_SINGLE,
1697 PARAM_NOT_CARE,
1698 train_status);
1699
1700 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
1701 if_id++) {
1702 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1703 for (pup_id = 0; pup_id <
1704 octets_per_if_num;
1705 pup_id++) {
1706 VALIDATE_BUS_ACTIVE(tm->bus_act_mask,
1707 pup_id);
1708 CHECK_STATUS
1709 (ddr3_tip_read_training_result
1710 (dev_num, if_id,
1711 ACCESS_TYPE_UNICAST, pup_id,
1712 ALL_BITS_PER_PUP,
1713 search_state,
1714 direction, result_type,
1715 TRAINING_LOAD_OPERATION_UNLOAD,
1716 CS_SINGLE, &res, 1, 0,
1717 0));
1718 if (result_type == RESULT_PER_BYTE) {
1719 DEBUG_TRAINING_IP_ENGINE
1720 (DEBUG_LEVEL_INFO,
1721 ("search_state %d if_id %d pup_id %d 0x%x\n",
1722 search_state, if_id,
1723 pup_id, res[0]));
1724 } else {
1725 DEBUG_TRAINING_IP_ENGINE
1726 (DEBUG_LEVEL_INFO,
1727 ("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",
1728 search_state, if_id,
1729 pup_id, res[0],
1730 res[1], res[2],
1731 res[3], res[4],
1732 res[5], res[6],
1733 res[7]));
1734 }
1735 }
1736 }
1737 }
1738 }
1739
1740 ddr3_tip_load_phy_values(0);
1741
1742 return MV_OK;
1743}
1744
1745int mv_ddr_pattern_start_addr_set(struct pattern_info *pattern_tbl, enum hws_pattern pattern, u32 addr)
1746{
1747 pattern_tbl[pattern].start_addr = addr;
1748
1749 return 0;
1750}
1751
1752struct pattern_info *ddr3_tip_get_pattern_table()
1753{
1754 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1755
1756 if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask))
1757 return pattern_table_64;
1758 else if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0)
1759 return pattern_table_32;
1760 else
1761 return pattern_table_16;
1762}
1763
1764u16 *ddr3_tip_get_mask_results_dq_reg()
1765{
1766#if MAX_BUS_NUM == 5
1767 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1768
1769 if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
1770 return mask_results_dq_reg_map_pup3_ecc;
1771 else
1772#endif
1773 return mask_results_dq_reg_map;
1774}
1775
1776u16 *ddr3_tip_get_mask_results_pup_reg_map()
1777{
1778#if MAX_BUS_NUM == 5
1779 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1780
1781 if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
1782 return mask_results_pup_reg_map_pup3_ecc;
1783 else
1784#endif
1785 return mask_results_pup_reg_map;
1786}
1787
1788
1789#define LOW_NIBBLE_BYTE_MASK 0xf
1790#define HIGH_NIBBLE_BYTE_MASK 0xf0
1791int mv_ddr_load_dm_pattern_to_odpg(enum hws_access_type access_type, enum hws_pattern pattern,
1792 enum dm_direction dm_dir)
1793{
1794 struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
1795 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1796 u32 pattern_len = 0;
1797 u32 data_low, data_high;
1798 u8 dm_data;
1799
1800 for (pattern_len = 0;
1801 pattern_len < pattern_table[pattern].pattern_len;
1802 pattern_len++) {
1803 if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask)) {
1804 data_low = pattern_table_get_word(0, pattern, (u8)pattern_len);
1805 data_high = data_low;
1806 } else {
1807 data_low = pattern_table_get_word(0, pattern, (u8)(pattern_len * 2));
1808 data_high = pattern_table_get_word(0, pattern, (u8)(pattern_len * 2 + 1));
1809 }
1810
1811
1812 if (dm_dir == DM_DIR_INVERSE)
1813 dm_data = ~((data_low & LOW_NIBBLE_BYTE_MASK) | (data_high & HIGH_NIBBLE_BYTE_MASK));
1814 else
1815 dm_data = (data_low & LOW_NIBBLE_BYTE_MASK) | (data_high & HIGH_NIBBLE_BYTE_MASK);
1816
1817 ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_WR_DATA_LOW_REG, data_low, MASK_ALL_BITS);
1818 ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_WR_DATA_HIGH_REG, data_high, MASK_ALL_BITS);
1819 ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_WR_ADDR_REG,
1820 pattern_len | ((dm_data & ODPG_DATA_WR_DATA_MASK) << ODPG_DATA_WR_DATA_OFFS),
1821 MASK_ALL_BITS);
1822 }
1823
1824 return MV_OK;
1825}
1826