1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) Marvell International Ltd. and its affiliates
4 */
5
6 #include "ddr_ml_wrapper.h"
7
8 #include "ddr3_training_ip_flow.h"
9 #include "mv_ddr_topology.h"
10 #include "mv_ddr_training_db.h"
11 #include "ddr3_training_ip_db.h"
12
13 /* Device attributes structures */
14 enum mv_ddr_dev_attribute ddr_dev_attributes[MV_ATTR_LAST];
15 int ddr_dev_attr_init_done = 0;
16
17 static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index);
18 static inline u32 pattern_table_get_sso_word(u8 sso, u8 index);
19 static inline u32 pattern_table_get_vref_word(u8 index);
20 static inline u32 pattern_table_get_vref_word16(u8 index);
21 static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index);
22 static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index);
23 static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index);
24 static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index);
25 static inline u32 pattern_table_get_isi_word(u8 index);
26 static inline u32 pattern_table_get_isi_word16(u8 index);
27
28 /* List of allowed frequency listed in order of enum mv_ddr_freq */
29 static unsigned int freq_val[MV_DDR_FREQ_LAST] = {
30 0, /*MV_DDR_FREQ_LOW_FREQ */
31 400, /*MV_DDR_FREQ_400, */
32 533, /*MV_DDR_FREQ_533, */
33 666, /*MV_DDR_FREQ_667, */
34 800, /*MV_DDR_FREQ_800, */
35 933, /*MV_DDR_FREQ_933, */
36 1066, /*MV_DDR_FREQ_1066, */
37 311, /*MV_DDR_FREQ_311, */
38 333, /*MV_DDR_FREQ_333, */
39 467, /*MV_DDR_FREQ_467, */
40 850, /*MV_DDR_FREQ_850, */
41 600, /*MV_DDR_FREQ_600 */
42 300, /*MV_DDR_FREQ_300 */
43 900, /*MV_DDR_FREQ_900 */
44 360, /*MV_DDR_FREQ_360 */
45 1000 /*MV_DDR_FREQ_1000 */
46 };
47
mv_ddr_freq_tbl_get(void)48 unsigned int *mv_ddr_freq_tbl_get(void)
49 {
50 return &freq_val[0];
51 }
52
mv_ddr_freq_get(enum mv_ddr_freq freq)53 u32 mv_ddr_freq_get(enum mv_ddr_freq freq)
54 {
55 return freq_val[freq];
56 }
57
58 /* cas latency values per frequency for each speed bin index */
59 static struct mv_ddr_cl_val_per_freq cl_table[] = {
60 /*
61 * 400M 667M 933M 311M 467M 600M 360
62 * 100M 533M 800M 1066M 333M 850M 900
63 * 1000 (the order is 100, 400, 533 etc.)
64 */
65 /* DDR3-800D */
66 { {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
67 /* DDR3-800E */
68 { {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} },
69 /* DDR3-1066E */
70 { {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} },
71 /* DDR3-1066F */
72 { {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} },
73 /* DDR3-1066G */
74 { {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} },
75 /* DDR3-1333F* */
76 { {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
77 /* DDR3-1333G */
78 { {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} },
79 /* DDR3-1333H */
80 { {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} },
81 /* DDR3-1333J* */
82 { {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0}
83 /* DDR3-1600G* */},
84 { {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
85 /* DDR3-1600H */
86 { {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} },
87 /* DDR3-1600J */
88 { {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} },
89 /* DDR3-1600K */
90 { {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } },
91 /* DDR3-1866J* */
92 { {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} },
93 /* DDR3-1866K */
94 { {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} },
95 /* DDR3-1866L */
96 { {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} },
97 /* DDR3-1866M* */
98 { {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} },
99 /* DDR3-2133K* */
100 { {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} },
101 /* DDR3-2133L */
102 { {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} },
103 /* DDR3-2133M */
104 { {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} },
105 /* DDR3-2133N* */
106 { {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14, 6, 14} },
107 /* DDR3-1333H-ext */
108 { {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
109 /* DDR3-1600K-ext */
110 { {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
111 /* DDR3-1866M-ext */
112 { {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} },
113 };
114
mv_ddr_cl_val_get(u32 index,u32 freq)115 u32 mv_ddr_cl_val_get(u32 index, u32 freq)
116 {
117 return cl_table[index].cl_val[freq];
118 }
119
120 /* cas write latency values per frequency for each speed bin index */
121 static struct mv_ddr_cl_val_per_freq cwl_table[] = {
122 /*
123 * 400M 667M 933M 311M 467M 600M 360
124 * 100M 533M 800M 1066M 333M 850M 900
125 * (the order is 100, 400, 533 etc.)
126 */
127 /* DDR3-800D */
128 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
129 /* DDR3-800E */
130 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
131 /* DDR3-1066E */
132 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
133 /* DDR3-1066F */
134 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
135 /* DDR3-1066G */
136 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
137 /* DDR3-1333F* */
138 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
139 /* DDR3-1333G */
140 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
141 /* DDR3-1333H */
142 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
143 /* DDR3-1333J* */
144 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
145 /* DDR3-1600G* */
146 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
147 /* DDR3-1600H */
148 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
149 /* DDR3-1600J */
150 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
151 /* DDR3-1600K */
152 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
153 /* DDR3-1866J* */
154 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
155 /* DDR3-1866K */
156 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
157 /* DDR3-1866L */
158 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
159 /* DDR3-1866M* */
160 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
161 /* DDR3-2133K* */
162 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
163 /* DDR3-2133L */
164 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
165 /* DDR3-2133M */
166 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
167 /* DDR3-2133N* */
168 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
169 /* DDR3-1333H-ext */
170 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
171 /* DDR3-1600K-ext */
172 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
173 /* DDR3-1866M-ext */
174 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
175 };
176
mv_ddr_cwl_val_get(u32 index,u32 freq)177 u32 mv_ddr_cwl_val_get(u32 index, u32 freq)
178 {
179 return cwl_table[index].cl_val[freq];
180 }
181
182 u8 twr_mask_table[] = {
183 10,
184 10,
185 10,
186 10,
187 10,
188 1, /* 5 */
189 2, /* 6 */
190 3, /* 7 */
191 4, /* 8 */
192 10,
193 5, /* 10 */
194 10,
195 6, /* 12 */
196 10,
197 7, /* 14 */
198 10,
199 0 /* 16 */
200 };
201
202 u8 cl_mask_table[] = {
203 0,
204 0,
205 0,
206 0,
207 0,
208 0x2,
209 0x4,
210 0x6,
211 0x8,
212 0xa,
213 0xc,
214 0xe,
215 0x1,
216 0x3,
217 0x5,
218 0x5
219 };
220
221 u8 cwl_mask_table[] = {
222 0,
223 0,
224 0,
225 0,
226 0,
227 0,
228 0x1,
229 0x2,
230 0x3,
231 0x4,
232 0x5,
233 0x6,
234 0x7,
235 0x8,
236 0x9,
237 0x9
238 };
239
240 /* RFC values (in ns) */
241 static unsigned int rfc_table[] = {
242 90, /* 512M */
243 110, /* 1G */
244 160, /* 2G */
245 260, /* 4G */
246 350, /* 8G */
247 0, /* TODO: placeholder for 16-Mbit dev width */
248 0, /* TODO: placeholder for 32-Mbit dev width */
249 0, /* TODO: placeholder for 12-Mbit dev width */
250 0 /* TODO: placeholder for 24-Mbit dev width */
251 };
252
mv_ddr_rfc_get(u32 mem)253 u32 mv_ddr_rfc_get(u32 mem)
254 {
255 return rfc_table[mem];
256 }
257
258 u32 speed_bin_table_t_rc[] = {
259 50000,
260 52500,
261 48750,
262 50625,
263 52500,
264 46500,
265 48000,
266 49500,
267 51000,
268 45000,
269 46250,
270 47500,
271 48750,
272 44700,
273 45770,
274 46840,
275 47910,
276 43285,
277 44220,
278 45155,
279 46090
280 };
281
282 u32 speed_bin_table_t_rcd_t_rp[] = {
283 12500,
284 15000,
285 11250,
286 13125,
287 15000,
288 10500,
289 12000,
290 13500,
291 15000,
292 10000,
293 11250,
294 12500,
295 13750,
296 10700,
297 11770,
298 12840,
299 13910,
300 10285,
301 11220,
302 12155,
303 13090,
304 };
305
306 enum {
307 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
308 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
309 };
310
311 static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = {
312 /*Aggressor / Victim */
313 {1, 0},
314 {0, 0},
315 {1, 0},
316 {1, 1},
317 {0, 1},
318 {0, 1},
319 {1, 0},
320 {0, 1},
321 {1, 0},
322 {0, 1},
323 {1, 0},
324 {1, 0},
325 {0, 1},
326 {1, 0},
327 {0, 1},
328 {0, 0},
329 {1, 1},
330 {0, 0},
331 {1, 1},
332 {0, 0},
333 {1, 1},
334 {0, 0},
335 {1, 1},
336 {1, 0},
337 {0, 0},
338 {1, 1},
339 {0, 0},
340 {1, 1},
341 {0, 0},
342 {0, 0},
343 {0, 0},
344 {0, 1},
345 {0, 1},
346 {1, 1},
347 {0, 0},
348 {0, 0},
349 {1, 1},
350 {1, 1},
351 {0, 0},
352 {1, 1},
353 {0, 0},
354 {1, 1},
355 {1, 1},
356 {0, 0},
357 {0, 0},
358 {1, 1},
359 {0, 0},
360 {1, 1},
361 {0, 1},
362 {0, 0},
363 {0, 1},
364 {0, 1},
365 {0, 0},
366 {1, 1},
367 {1, 1},
368 {1, 0},
369 {1, 0},
370 {1, 1},
371 {1, 1},
372 {1, 1},
373 {1, 1},
374 {1, 1},
375 {1, 1},
376 {1, 1}
377 };
378
379 static u8 pattern_vref_pattern_table_map[] = {
380 /* 1 means 0xffffffff, 0 is 0x0 */
381 0xb8,
382 0x52,
383 0x55,
384 0x8a,
385 0x33,
386 0xa6,
387 0x6d,
388 0xfe
389 };
390
391 static struct mv_ddr_page_element page_tbl[] = {
392 /* 8-bit, 16-bit page size */
393 {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 512M */
394 {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 1G */
395 {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 2G */
396 {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 4G */
397 {MV_DDR_PAGE_SIZE_2K, MV_DDR_PAGE_SIZE_2K}, /* 8G */
398 {0, 0}, /* TODO: placeholder for 16-Mbit die capacity */
399 {0, 0}, /* TODO: placeholder for 32-Mbit die capacity */
400 {0, 0}, /* TODO: placeholder for 12-Mbit die capacity */
401 {0, 0} /* TODO: placeholder for 24-Mbit die capacity */
402 };
403
mv_ddr_page_size_get(enum mv_ddr_dev_width bus_width,enum mv_ddr_die_capacity mem_size)404 u32 mv_ddr_page_size_get(enum mv_ddr_dev_width bus_width, enum mv_ddr_die_capacity mem_size)
405 {
406 if (bus_width == MV_DDR_DEV_WIDTH_8BIT)
407 return page_tbl[mem_size].page_size_8bit;
408 else
409 return page_tbl[mem_size].page_size_16bit;
410 }
411
412 /* Return speed Bin value for selected index and t* element */
mv_ddr_speed_bin_timing_get(enum mv_ddr_speed_bin index,enum mv_ddr_speed_bin_timing element)413 unsigned int mv_ddr_speed_bin_timing_get(enum mv_ddr_speed_bin index, enum mv_ddr_speed_bin_timing element)
414 {
415 u32 result = 0;
416
417 switch (element) {
418 case SPEED_BIN_TRCD:
419 case SPEED_BIN_TRP:
420 result = speed_bin_table_t_rcd_t_rp[index];
421 break;
422 case SPEED_BIN_TRAS:
423 if (index <= SPEED_BIN_DDR_1066G)
424 result = 37500;
425 else if (index <= SPEED_BIN_DDR_1333J)
426 result = 36000;
427 else if (index <= SPEED_BIN_DDR_1600K)
428 result = 35000;
429 else if (index <= SPEED_BIN_DDR_1866M)
430 result = 34000;
431 else
432 result = 33000;
433 break;
434 case SPEED_BIN_TRC:
435 result = speed_bin_table_t_rc[index];
436 break;
437 case SPEED_BIN_TRRD1K:
438 if (index <= SPEED_BIN_DDR_800E)
439 result = 10000;
440 else if (index <= SPEED_BIN_DDR_1066G)
441 result = 7500;
442 else if (index <= SPEED_BIN_DDR_1600K)
443 result = 6000;
444 else
445 result = 5000;
446 break;
447 case SPEED_BIN_TRRD2K:
448 if (index <= SPEED_BIN_DDR_1066G)
449 result = 10000;
450 else if (index <= SPEED_BIN_DDR_1600K)
451 result = 7500;
452 else
453 result = 6000;
454 break;
455 case SPEED_BIN_TPD:
456 if (index < SPEED_BIN_DDR_800E)
457 result = 7500;
458 else if (index < SPEED_BIN_DDR_1333J)
459 result = 5625;
460 else
461 result = 5000;
462 break;
463 case SPEED_BIN_TFAW1K:
464 if (index <= SPEED_BIN_DDR_800E)
465 result = 40000;
466 else if (index <= SPEED_BIN_DDR_1066G)
467 result = 37500;
468 else if (index <= SPEED_BIN_DDR_1600K)
469 result = 30000;
470 else if (index <= SPEED_BIN_DDR_1866M)
471 result = 27000;
472 else
473 result = 25000;
474 break;
475 case SPEED_BIN_TFAW2K:
476 if (index <= SPEED_BIN_DDR_1066G)
477 result = 50000;
478 else if (index <= SPEED_BIN_DDR_1333J)
479 result = 45000;
480 else if (index <= SPEED_BIN_DDR_1600K)
481 result = 40000;
482 else
483 result = 35000;
484 break;
485 case SPEED_BIN_TWTR:
486 result = 7500;
487 break;
488 case SPEED_BIN_TRTP:
489 result = 7500;
490 break;
491 case SPEED_BIN_TWR:
492 result = 15000;
493 break;
494 case SPEED_BIN_TMOD:
495 result = 15000;
496 break;
497 case SPEED_BIN_TXPDLL:
498 result = 24000;
499 break;
500 case SPEED_BIN_TXSDLL:
501 result = 512;
502 break;
503 default:
504 break;
505 }
506
507 return result;
508 }
509
pattern_table_get_killer_word(u8 dqs,u8 index)510 static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
511 {
512 u8 i, byte = 0;
513 u8 role;
514
515 for (i = 0; i < 8; i++) {
516 role = (i == dqs) ?
517 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
518 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
519 byte |= pattern_killer_pattern_table_map[index][role] << i;
520 }
521
522 return byte | (byte << 8) | (byte << 16) | (byte << 24);
523 }
524
pattern_table_get_killer_word16(u8 dqs,u8 index)525 static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
526 {
527 u8 i, byte0 = 0, byte1 = 0;
528 u8 role;
529
530 for (i = 0; i < 8; i++) {
531 role = (i == dqs) ?
532 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
533 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
534 byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i;
535 byte1 |= pattern_killer_pattern_table_map[index * 2 + 1][role] << i;
536 }
537
538 return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
539 }
540
pattern_table_get_sso_word(u8 sso,u8 index)541 static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
542 {
543 u8 step = sso + 1;
544
545 if (0 == ((index / step) & 1))
546 return 0x0;
547 else
548 return 0xffffffff;
549 }
550
pattern_table_get_sso_full_xtalk_word(u8 bit,u8 index)551 static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index)
552 {
553 u8 byte = (1 << bit);
554
555 if ((index & 1) == 1)
556 byte = ~byte;
557
558 return byte | (byte << 8) | (byte << 16) | (byte << 24);
559
560 }
561
pattern_table_get_sso_xtalk_free_word(u8 bit,u8 index)562 static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index)
563 {
564 u8 byte = (1 << bit);
565
566 if ((index & 1) == 1)
567 byte = 0;
568
569 return byte | (byte << 8) | (byte << 16) | (byte << 24);
570 }
571
pattern_table_get_isi_word(u8 index)572 static inline u32 pattern_table_get_isi_word(u8 index)
573 {
574 u8 i0 = index % 32;
575 u8 i1 = index % 8;
576 u32 word;
577
578 if (i0 > 15)
579 word = ((i1 == 5) | (i1 == 7)) ? 0xffffffff : 0x0;
580 else
581 word = (i1 == 6) ? 0xffffffff : 0x0;
582
583 word = ((i0 % 16) > 7) ? ~word : word;
584
585 return word;
586 }
587
pattern_table_get_sso_full_xtalk_word16(u8 bit,u8 index)588 static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index)
589 {
590 u8 byte = (1 << bit);
591
592 if ((index & 1) == 1)
593 byte = ~byte;
594
595 return byte | (byte << 8) | ((~byte) << 16) | ((~byte) << 24);
596 }
597
pattern_table_get_sso_xtalk_free_word16(u8 bit,u8 index)598 static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index)
599 {
600 u8 byte = (1 << bit);
601
602 if ((index & 1) == 0)
603 return (byte << 16) | (byte << 24);
604 else
605 return byte | (byte << 8);
606 }
607
pattern_table_get_isi_word16(u8 index)608 static inline u32 pattern_table_get_isi_word16(u8 index)
609 {
610 u8 i0 = index % 16;
611 u8 i1 = index % 4;
612 u32 word;
613
614 if (i0 > 7)
615 word = (i1 > 1) ? 0x0000ffff : 0x0;
616 else
617 word = (i1 == 3) ? 0xffff0000 : 0x0;
618
619 word = ((i0 % 8) > 3) ? ~word : word;
620
621 return word;
622 }
623
pattern_table_get_vref_word(u8 index)624 static inline u32 pattern_table_get_vref_word(u8 index)
625 {
626 if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
627 (index % 8)) & 1))
628 return 0x0;
629 else
630 return 0xffffffff;
631 }
632
pattern_table_get_vref_word16(u8 index)633 static inline u32 pattern_table_get_vref_word16(u8 index)
634 {
635 if (0 == pattern_killer_pattern_table_map
636 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
637 0 == pattern_killer_pattern_table_map
638 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
639 return 0x00000000;
640 else if (1 == pattern_killer_pattern_table_map
641 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
642 0 == pattern_killer_pattern_table_map
643 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
644 return 0xffff0000;
645 else if (0 == pattern_killer_pattern_table_map
646 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
647 1 == pattern_killer_pattern_table_map
648 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
649 return 0x0000ffff;
650 else
651 return 0xffffffff;
652 }
653
pattern_table_get_static_pbs_word(u8 index)654 static inline u32 pattern_table_get_static_pbs_word(u8 index)
655 {
656 u16 temp;
657
658 temp = ((0x00ff << (index / 3)) & 0xff00) >> 8;
659
660 return temp | (temp << 8) | (temp << 16) | (temp << 24);
661 }
662
pattern_table_get_word(u32 dev_num,enum hws_pattern type,u8 index)663 u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
664 {
665 u32 pattern = 0;
666 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
667
668 if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
669 /* 32/64-bit patterns */
670 switch (type) {
671 case PATTERN_PBS1:
672 case PATTERN_PBS2:
673 if (index == 0 || index == 2 || index == 5 ||
674 index == 7)
675 pattern = PATTERN_55;
676 else
677 pattern = PATTERN_AA;
678 break;
679 case PATTERN_PBS3:
680 if (0 == (index & 1))
681 pattern = PATTERN_55;
682 else
683 pattern = PATTERN_AA;
684 break;
685 case PATTERN_RL:
686 if (index < 6)
687 pattern = PATTERN_00;
688 else
689 pattern = PATTERN_80;
690 break;
691 case PATTERN_STATIC_PBS:
692 pattern = pattern_table_get_static_pbs_word(index);
693 break;
694 case PATTERN_KILLER_DQ0:
695 case PATTERN_KILLER_DQ1:
696 case PATTERN_KILLER_DQ2:
697 case PATTERN_KILLER_DQ3:
698 case PATTERN_KILLER_DQ4:
699 case PATTERN_KILLER_DQ5:
700 case PATTERN_KILLER_DQ6:
701 case PATTERN_KILLER_DQ7:
702 pattern = pattern_table_get_killer_word(
703 (u8)(type - PATTERN_KILLER_DQ0), index);
704 break;
705 case PATTERN_RL2:
706 if (index < 6)
707 pattern = PATTERN_00;
708 else
709 pattern = PATTERN_01;
710 break;
711 case PATTERN_TEST:
712 if (index > 1 && index < 6)
713 pattern = PATTERN_00;
714 else
715 pattern = PATTERN_FF;
716 break;
717 case PATTERN_FULL_SSO0:
718 case PATTERN_FULL_SSO1:
719 case PATTERN_FULL_SSO2:
720 case PATTERN_FULL_SSO3:
721 pattern = pattern_table_get_sso_word(
722 (u8)(type - PATTERN_FULL_SSO0), index);
723 break;
724 case PATTERN_VREF:
725 pattern = pattern_table_get_vref_word(index);
726 break;
727 case PATTERN_SSO_FULL_XTALK_DQ0:
728 case PATTERN_SSO_FULL_XTALK_DQ1:
729 case PATTERN_SSO_FULL_XTALK_DQ2:
730 case PATTERN_SSO_FULL_XTALK_DQ3:
731 case PATTERN_SSO_FULL_XTALK_DQ4:
732 case PATTERN_SSO_FULL_XTALK_DQ5:
733 case PATTERN_SSO_FULL_XTALK_DQ6:
734 case PATTERN_SSO_FULL_XTALK_DQ7:
735 pattern = pattern_table_get_sso_full_xtalk_word(
736 (u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
737 break;
738 case PATTERN_SSO_XTALK_FREE_DQ0:
739 case PATTERN_SSO_XTALK_FREE_DQ1:
740 case PATTERN_SSO_XTALK_FREE_DQ2:
741 case PATTERN_SSO_XTALK_FREE_DQ3:
742 case PATTERN_SSO_XTALK_FREE_DQ4:
743 case PATTERN_SSO_XTALK_FREE_DQ5:
744 case PATTERN_SSO_XTALK_FREE_DQ6:
745 case PATTERN_SSO_XTALK_FREE_DQ7:
746 pattern = pattern_table_get_sso_xtalk_free_word(
747 (u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
748 break;
749 case PATTERN_ISI_XTALK_FREE:
750 pattern = pattern_table_get_isi_word(index);
751 break;
752 default:
753 printf("error: %s: unsupported pattern type [%d] found\n",
754 __func__, (int)type);
755 pattern = 0;
756 break;
757 }
758 } else {
759 /* 16bit patterns */
760 switch (type) {
761 case PATTERN_PBS1:
762 case PATTERN_PBS2:
763 case PATTERN_PBS3:
764 pattern = PATTERN_55AA;
765 break;
766 case PATTERN_RL:
767 if (index < 3)
768 pattern = PATTERN_00;
769 else
770 pattern = PATTERN_80;
771 break;
772 case PATTERN_STATIC_PBS:
773 pattern = PATTERN_00FF;
774 break;
775 case PATTERN_KILLER_DQ0:
776 case PATTERN_KILLER_DQ1:
777 case PATTERN_KILLER_DQ2:
778 case PATTERN_KILLER_DQ3:
779 case PATTERN_KILLER_DQ4:
780 case PATTERN_KILLER_DQ5:
781 case PATTERN_KILLER_DQ6:
782 case PATTERN_KILLER_DQ7:
783 pattern = pattern_table_get_killer_word16(
784 (u8)(type - PATTERN_KILLER_DQ0), index);
785 break;
786 case PATTERN_RL2:
787 if (index < 3)
788 pattern = PATTERN_00;
789 else
790 pattern = PATTERN_01;
791 break;
792 case PATTERN_TEST:
793 if ((index == 0) || (index == 3))
794 pattern = 0x00000000;
795 else
796 pattern = 0xFFFFFFFF;
797 break;
798 case PATTERN_FULL_SSO0:
799 pattern = 0x0000ffff;
800 break;
801 case PATTERN_FULL_SSO1:
802 case PATTERN_FULL_SSO2:
803 case PATTERN_FULL_SSO3:
804 pattern = pattern_table_get_sso_word(
805 (u8)(type - PATTERN_FULL_SSO1), index);
806 break;
807 case PATTERN_VREF:
808 pattern = pattern_table_get_vref_word16(index);
809 break;
810 case PATTERN_SSO_FULL_XTALK_DQ0:
811 case PATTERN_SSO_FULL_XTALK_DQ1:
812 case PATTERN_SSO_FULL_XTALK_DQ2:
813 case PATTERN_SSO_FULL_XTALK_DQ3:
814 case PATTERN_SSO_FULL_XTALK_DQ4:
815 case PATTERN_SSO_FULL_XTALK_DQ5:
816 case PATTERN_SSO_FULL_XTALK_DQ6:
817 case PATTERN_SSO_FULL_XTALK_DQ7:
818 pattern = pattern_table_get_sso_full_xtalk_word16(
819 (u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
820 break;
821 case PATTERN_SSO_XTALK_FREE_DQ0:
822 case PATTERN_SSO_XTALK_FREE_DQ1:
823 case PATTERN_SSO_XTALK_FREE_DQ2:
824 case PATTERN_SSO_XTALK_FREE_DQ3:
825 case PATTERN_SSO_XTALK_FREE_DQ4:
826 case PATTERN_SSO_XTALK_FREE_DQ5:
827 case PATTERN_SSO_XTALK_FREE_DQ6:
828 case PATTERN_SSO_XTALK_FREE_DQ7:
829 pattern = pattern_table_get_sso_xtalk_free_word16(
830 (u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
831 break;
832 case PATTERN_ISI_XTALK_FREE:
833 pattern = pattern_table_get_isi_word16(index);
834 break;
835 default:
836 printf("error: %s: unsupported pattern type [%d] found\n",
837 __func__, (int)type);
838 pattern = 0;
839 break;
840 }
841 }
842
843 return pattern;
844 }
845
846 /* Device attribute functions */
ddr3_tip_dev_attr_init(u32 dev_num)847 void ddr3_tip_dev_attr_init(u32 dev_num)
848 {
849 u32 attr_id;
850
851 for (attr_id = 0; attr_id < MV_ATTR_LAST; attr_id++)
852 ddr_dev_attributes[attr_id] = 0xFF;
853
854 ddr_dev_attr_init_done = 1;
855 }
856
ddr3_tip_dev_attr_get(u32 dev_num,enum mv_ddr_dev_attribute attr_id)857 u32 ddr3_tip_dev_attr_get(u32 dev_num, enum mv_ddr_dev_attribute attr_id)
858 {
859 if (ddr_dev_attr_init_done == 0)
860 ddr3_tip_dev_attr_init(dev_num);
861
862 return ddr_dev_attributes[attr_id];
863 }
864
ddr3_tip_dev_attr_set(u32 dev_num,enum mv_ddr_dev_attribute attr_id,u32 value)865 void ddr3_tip_dev_attr_set(u32 dev_num, enum mv_ddr_dev_attribute attr_id, u32 value)
866 {
867 if (ddr_dev_attr_init_done == 0)
868 ddr3_tip_dev_attr_init(dev_num);
869
870 ddr_dev_attributes[attr_id] = value;
871 }
872