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 */
14enum mv_ddr_dev_attribute ddr_dev_attributes[MV_ATTR_LAST];
15int ddr_dev_attr_init_done = 0;
16
17static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index);
18static inline u32 pattern_table_get_sso_word(u8 sso, u8 index);
19static inline u32 pattern_table_get_vref_word(u8 index);
20static inline u32 pattern_table_get_vref_word16(u8 index);
21static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index);
22static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index);
23static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index);
24static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index);
25static inline u32 pattern_table_get_isi_word(u8 index);
26static inline u32 pattern_table_get_isi_word16(u8 index);
27
28#if defined(CONFIG_DDR4)
29u8 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};
95static 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 */
121static 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
140unsigned int *mv_ddr_freq_tbl_get(void)
141{
142	return &freq_val[0];
143}
144
145u32 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 */
151static 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
207u32 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 */
213static 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
269u32 mv_ddr_cwl_val_get(u32 index, u32 freq)
270{
271	return cwl_table[index].cl_val[freq];
272}
273
274u8 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
294u8 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
313u8 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) */
333static 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
345u32 mv_ddr_rfc_get(u32 mem)
346{
347	return rfc_table[mem];
348}
349
350u32 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
374u32 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
399enum {
400	PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
401	PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
402};
403
404static 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
472static 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)
485static 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
498u32 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 */
507unsigned 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
604static 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
620static 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
636static 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
646static 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
657static 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
667static 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
683static 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
693static 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
703static 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
719static 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
728static 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)
750static 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
760u32 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 */
1062void 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
1072u32 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
1080void 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