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