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