1f1df9364SStefan Roese /*
2f1df9364SStefan Roese  * Copyright (C) Marvell International Ltd. and its affiliates
3f1df9364SStefan Roese  *
4f1df9364SStefan Roese  * SPDX-License-Identifier:	GPL-2.0
5f1df9364SStefan Roese  */
6f1df9364SStefan Roese 
7f1df9364SStefan Roese #include <common.h>
8f1df9364SStefan Roese #include <spl.h>
9f1df9364SStefan Roese #include <asm/io.h>
10f1df9364SStefan Roese #include <asm/arch/cpu.h>
11f1df9364SStefan Roese #include <asm/arch/soc.h>
12f1df9364SStefan Roese 
13f1df9364SStefan Roese #include "ddr3_init.h"
14f1df9364SStefan Roese 
15f1df9364SStefan Roese /* List of allowed frequency listed in order of enum hws_ddr_freq */
16f1df9364SStefan Roese u32 freq_val[DDR_FREQ_LIMIT] = {
17f1df9364SStefan Roese 	0,			/*DDR_FREQ_LOW_FREQ */
18f1df9364SStefan Roese 	400,			/*DDR_FREQ_400, */
19f1df9364SStefan Roese 	533,			/*DDR_FREQ_533, */
20f1df9364SStefan Roese 	666,			/*DDR_FREQ_667, */
21f1df9364SStefan Roese 	800,			/*DDR_FREQ_800, */
22f1df9364SStefan Roese 	933,			/*DDR_FREQ_933, */
23f1df9364SStefan Roese 	1066,			/*DDR_FREQ_1066, */
24f1df9364SStefan Roese 	311,			/*DDR_FREQ_311, */
25f1df9364SStefan Roese 	333,			/*DDR_FREQ_333, */
26f1df9364SStefan Roese 	467,			/*DDR_FREQ_467, */
27f1df9364SStefan Roese 	850,			/*DDR_FREQ_850, */
28f1df9364SStefan Roese 	600,			/*DDR_FREQ_600 */
29f1df9364SStefan Roese 	300,			/*DDR_FREQ_300 */
30f1df9364SStefan Roese 	900,			/*DDR_FREQ_900 */
31f1df9364SStefan Roese 	360,			/*DDR_FREQ_360 */
32f1df9364SStefan Roese 	1000			/*DDR_FREQ_1000 */
33f1df9364SStefan Roese };
34f1df9364SStefan Roese 
35f1df9364SStefan Roese /* Table for CL values per frequency for each speed bin index */
36f1df9364SStefan Roese struct cl_val_per_freq cas_latency_table[] = {
37f1df9364SStefan Roese 	/*
38f1df9364SStefan Roese 	 * 400M   667M     933M   311M     467M  600M    360
39f1df9364SStefan Roese 	 * 100M    533M    800M    1066M   333M    850M      900
40f1df9364SStefan Roese 	 * 1000 (the order is 100, 400, 533 etc.)
41f1df9364SStefan Roese 	 */
42f1df9364SStefan Roese 	/* DDR3-800D */
43f1df9364SStefan Roese 	{ {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
44f1df9364SStefan Roese 	/* DDR3-800E */
45f1df9364SStefan Roese 	{ {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} },
46f1df9364SStefan Roese 	/* DDR3-1066E */
47f1df9364SStefan Roese 	{ {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} },
48f1df9364SStefan Roese 	/* DDR3-1066F */
49f1df9364SStefan Roese 	{ {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} },
50f1df9364SStefan Roese 	/* DDR3-1066G */
51f1df9364SStefan Roese 	{ {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} },
52f1df9364SStefan Roese 	/* DDR3-1333F* */
53f1df9364SStefan Roese 	{ {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
54f1df9364SStefan Roese 	/* DDR3-1333G */
55f1df9364SStefan Roese 	{ {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} },
56f1df9364SStefan Roese 	/* DDR3-1333H */
57f1df9364SStefan Roese 	{ {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} },
58f1df9364SStefan Roese 	/* DDR3-1333J* */
59f1df9364SStefan Roese 	{ {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6,  0}
60f1df9364SStefan Roese 	 /* DDR3-1600G* */},
61f1df9364SStefan Roese 	{ {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
62f1df9364SStefan Roese 	/* DDR3-1600H */
63f1df9364SStefan Roese 	{ {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} },
64f1df9364SStefan Roese 	/* DDR3-1600J */
65f1df9364SStefan Roese 	{ {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} },
66f1df9364SStefan Roese 	/* DDR3-1600K */
67f1df9364SStefan Roese 	{ {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } },
68f1df9364SStefan Roese 	/* DDR3-1866J* */
69f1df9364SStefan Roese 	{ {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} },
70f1df9364SStefan Roese 	/* DDR3-1866K */
71f1df9364SStefan Roese 	{ {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} },
72f1df9364SStefan Roese 	/* DDR3-1866L */
73f1df9364SStefan Roese 	{ {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} },
74f1df9364SStefan Roese 	/* DDR3-1866M* */
75f1df9364SStefan Roese 	{ {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} },
76f1df9364SStefan Roese 	/* DDR3-2133K* */
77f1df9364SStefan Roese 	{ {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} },
78f1df9364SStefan Roese 	/* DDR3-2133L */
79f1df9364SStefan Roese 	{ {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} },
80f1df9364SStefan Roese 	/* DDR3-2133M */
81f1df9364SStefan Roese 	{ {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} },
82f1df9364SStefan Roese 	/* DDR3-2133N* */
83f1df9364SStefan Roese 	{ {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14,  6, 14} },
84f1df9364SStefan Roese 	/* DDR3-1333H-ext */
85f1df9364SStefan Roese 	{ {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
86f1df9364SStefan Roese 	/* DDR3-1600K-ext */
87f1df9364SStefan Roese 	{ {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
88f1df9364SStefan Roese 	/* DDR3-1866M-ext */
89f1df9364SStefan Roese 	{ {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} },
90f1df9364SStefan Roese };
91f1df9364SStefan Roese 
92f1df9364SStefan Roese /* Table for CWL values per speedbin index */
93f1df9364SStefan Roese struct cl_val_per_freq cas_write_latency_table[] = {
94f1df9364SStefan Roese 	/*
95f1df9364SStefan Roese 	 * 400M   667M     933M   311M     467M  600M    360
96f1df9364SStefan Roese 	 * 100M    533M    800M    1066M   333M    850M      900
97f1df9364SStefan Roese 	 * (the order is 100, 400, 533 etc.)
98f1df9364SStefan Roese 	 */
99f1df9364SStefan Roese 	/* DDR3-800D  */
100f1df9364SStefan Roese 	{ {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
101f1df9364SStefan Roese 	/* DDR3-800E  */
102f1df9364SStefan Roese 	{ {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
103f1df9364SStefan Roese 	/* DDR3-1066E  */
104f1df9364SStefan Roese 	{ {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
105f1df9364SStefan Roese 	/* DDR3-1066F  */
106f1df9364SStefan Roese 	{ {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
107f1df9364SStefan Roese 	/* DDR3-1066G  */
108f1df9364SStefan Roese 	{ {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
109f1df9364SStefan Roese 	/* DDR3-1333F*  */
110f1df9364SStefan Roese 	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
111f1df9364SStefan Roese 	/* DDR3-1333G  */
112f1df9364SStefan Roese 	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
113f1df9364SStefan Roese 	/* DDR3-1333H  */
114f1df9364SStefan Roese 	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
115f1df9364SStefan Roese 	/* DDR3-1333J*  */
116f1df9364SStefan Roese 	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
117f1df9364SStefan Roese 	/* DDR3-1600G*  */
118f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
119f1df9364SStefan Roese 	/* DDR3-1600H  */
120f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
121f1df9364SStefan Roese 	/* DDR3-1600J  */
122f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
123f1df9364SStefan Roese 	/* DDR3-1600K  */
124f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
125f1df9364SStefan Roese 	/* DDR3-1866J*  */
126f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
127f1df9364SStefan Roese 	/* DDR3-1866K  */
128f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
129f1df9364SStefan Roese 	/* DDR3-1866L  */
130f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
131f1df9364SStefan Roese 	/* DDR3-1866M*   */
132f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
133f1df9364SStefan Roese 	/* DDR3-2133K*  */
134f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
135f1df9364SStefan Roese 	/* DDR3-2133L  */
136f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
137f1df9364SStefan Roese 	/* DDR3-2133M  */
138f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
139f1df9364SStefan Roese 	/* DDR3-2133N*  */
140f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
141f1df9364SStefan Roese 	/* DDR3-1333H-ext  */
142f1df9364SStefan Roese 	{ {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
143f1df9364SStefan Roese 	/* DDR3-1600K-ext  */
144f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
145f1df9364SStefan Roese 	/* DDR3-1866M-ext  */
146f1df9364SStefan Roese 	{ {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
147f1df9364SStefan Roese };
148f1df9364SStefan Roese 
149f1df9364SStefan Roese u8 twr_mask_table[] = {
150f1df9364SStefan Roese 	10,
151f1df9364SStefan Roese 	10,
152f1df9364SStefan Roese 	10,
153f1df9364SStefan Roese 	10,
154f1df9364SStefan Roese 	10,
155f1df9364SStefan Roese 	1,			/*5*/
156f1df9364SStefan Roese 	2,			/*6*/
157f1df9364SStefan Roese 	3,			/*7*/
158*672e5598SChris Packham 	4,			/*8*/
159f1df9364SStefan Roese 	10,
160f1df9364SStefan Roese 	5,			/*10*/
161f1df9364SStefan Roese 	10,
162f1df9364SStefan Roese 	6,			/*12*/
163f1df9364SStefan Roese 	10,
164f1df9364SStefan Roese 	7,			/*14*/
165f1df9364SStefan Roese 	10,
166f1df9364SStefan Roese 	0			/*16*/
167f1df9364SStefan Roese };
168f1df9364SStefan Roese 
169f1df9364SStefan Roese u8 cl_mask_table[] = {
170f1df9364SStefan Roese 	0,
171f1df9364SStefan Roese 	0,
172f1df9364SStefan Roese 	0,
173f1df9364SStefan Roese 	0,
174f1df9364SStefan Roese 	0,
175f1df9364SStefan Roese 	0x2,
176f1df9364SStefan Roese 	0x4,
177f1df9364SStefan Roese 	0x6,
178f1df9364SStefan Roese 	0x8,
179f1df9364SStefan Roese 	0xa,
180f1df9364SStefan Roese 	0xc,
181f1df9364SStefan Roese 	0xe,
182f1df9364SStefan Roese 	0x1,
183f1df9364SStefan Roese 	0x3,
184f1df9364SStefan Roese 	0x5,
185f1df9364SStefan Roese 	0x5
186f1df9364SStefan Roese };
187f1df9364SStefan Roese 
188f1df9364SStefan Roese u8 cwl_mask_table[] = {
189f1df9364SStefan Roese 	0,
190f1df9364SStefan Roese 	0,
191f1df9364SStefan Roese 	0,
192f1df9364SStefan Roese 	0,
193f1df9364SStefan Roese 	0,
194f1df9364SStefan Roese 	0,
195f1df9364SStefan Roese 	0x1,
196f1df9364SStefan Roese 	0x2,
197f1df9364SStefan Roese 	0x3,
198f1df9364SStefan Roese 	0x4,
199f1df9364SStefan Roese 	0x5,
200f1df9364SStefan Roese 	0x6,
201f1df9364SStefan Roese 	0x7,
202f1df9364SStefan Roese 	0x8,
203f1df9364SStefan Roese 	0x9,
204f1df9364SStefan Roese 	0x9
205f1df9364SStefan Roese };
206f1df9364SStefan Roese 
207f1df9364SStefan Roese /* RFC values (in ns) */
208f1df9364SStefan Roese u16 rfc_table[] = {
209f1df9364SStefan Roese 	90,			/* 512M */
210f1df9364SStefan Roese 	110,			/* 1G */
211f1df9364SStefan Roese 	160,			/* 2G */
212f1df9364SStefan Roese 	260,			/* 4G */
213f1df9364SStefan Roese 	350			/* 8G */
214f1df9364SStefan Roese };
215f1df9364SStefan Roese 
216f1df9364SStefan Roese u32 speed_bin_table_t_rc[] = {
217f1df9364SStefan Roese 	50000,
218f1df9364SStefan Roese 	52500,
219f1df9364SStefan Roese 	48750,
220f1df9364SStefan Roese 	50625,
221f1df9364SStefan Roese 	52500,
222f1df9364SStefan Roese 	46500,
223f1df9364SStefan Roese 	48000,
224f1df9364SStefan Roese 	49500,
225f1df9364SStefan Roese 	51000,
226f1df9364SStefan Roese 	45000,
227f1df9364SStefan Roese 	46250,
228f1df9364SStefan Roese 	47500,
229f1df9364SStefan Roese 	48750,
230f1df9364SStefan Roese 	44700,
231f1df9364SStefan Roese 	45770,
232f1df9364SStefan Roese 	46840,
233f1df9364SStefan Roese 	47910,
234f1df9364SStefan Roese 	43285,
235f1df9364SStefan Roese 	44220,
236f1df9364SStefan Roese 	45155,
237f1df9364SStefan Roese 	46900
238f1df9364SStefan Roese };
239f1df9364SStefan Roese 
240f1df9364SStefan Roese u32 speed_bin_table_t_rcd_t_rp[] = {
241f1df9364SStefan Roese 	12500,
242f1df9364SStefan Roese 	15000,
243f1df9364SStefan Roese 	11250,
244f1df9364SStefan Roese 	13125,
245f1df9364SStefan Roese 	15000,
246f1df9364SStefan Roese 	10500,
247f1df9364SStefan Roese 	12000,
248f1df9364SStefan Roese 	13500,
249f1df9364SStefan Roese 	15000,
250f1df9364SStefan Roese 	10000,
251f1df9364SStefan Roese 	11250,
252f1df9364SStefan Roese 	12500,
253f1df9364SStefan Roese 	13750,
254f1df9364SStefan Roese 	10700,
255f1df9364SStefan Roese 	11770,
256f1df9364SStefan Roese 	12840,
257f1df9364SStefan Roese 	13910,
258f1df9364SStefan Roese 	10285,
259f1df9364SStefan Roese 	11022,
260f1df9364SStefan Roese 	12155,
261f1df9364SStefan Roese 	13090,
262f1df9364SStefan Roese };
263f1df9364SStefan Roese 
264f1df9364SStefan Roese enum {
265f1df9364SStefan Roese 	PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
266f1df9364SStefan Roese 	PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
267f1df9364SStefan Roese };
268f1df9364SStefan Roese 
269f1df9364SStefan Roese static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = {
270f1df9364SStefan Roese 	/*Aggressor / Victim */
271f1df9364SStefan Roese 	{1, 0},
272f1df9364SStefan Roese 	{0, 0},
273f1df9364SStefan Roese 	{1, 0},
274f1df9364SStefan Roese 	{1, 1},
275f1df9364SStefan Roese 	{0, 1},
276f1df9364SStefan Roese 	{0, 1},
277f1df9364SStefan Roese 	{1, 0},
278f1df9364SStefan Roese 	{0, 1},
279f1df9364SStefan Roese 	{1, 0},
280f1df9364SStefan Roese 	{0, 1},
281f1df9364SStefan Roese 	{1, 0},
282f1df9364SStefan Roese 	{1, 0},
283f1df9364SStefan Roese 	{0, 1},
284f1df9364SStefan Roese 	{1, 0},
285f1df9364SStefan Roese 	{0, 1},
286f1df9364SStefan Roese 	{0, 0},
287f1df9364SStefan Roese 	{1, 1},
288f1df9364SStefan Roese 	{0, 0},
289f1df9364SStefan Roese 	{1, 1},
290f1df9364SStefan Roese 	{0, 0},
291f1df9364SStefan Roese 	{1, 1},
292f1df9364SStefan Roese 	{0, 0},
293f1df9364SStefan Roese 	{1, 1},
294f1df9364SStefan Roese 	{1, 0},
295f1df9364SStefan Roese 	{0, 0},
296f1df9364SStefan Roese 	{1, 1},
297f1df9364SStefan Roese 	{0, 0},
298f1df9364SStefan Roese 	{1, 1},
299f1df9364SStefan Roese 	{0, 0},
300f1df9364SStefan Roese 	{0, 0},
301f1df9364SStefan Roese 	{0, 0},
302f1df9364SStefan Roese 	{0, 1},
303f1df9364SStefan Roese 	{0, 1},
304f1df9364SStefan Roese 	{1, 1},
305f1df9364SStefan Roese 	{0, 0},
306f1df9364SStefan Roese 	{0, 0},
307f1df9364SStefan Roese 	{1, 1},
308f1df9364SStefan Roese 	{1, 1},
309f1df9364SStefan Roese 	{0, 0},
310f1df9364SStefan Roese 	{1, 1},
311f1df9364SStefan Roese 	{0, 0},
312f1df9364SStefan Roese 	{1, 1},
313f1df9364SStefan Roese 	{1, 1},
314f1df9364SStefan Roese 	{0, 0},
315f1df9364SStefan Roese 	{0, 0},
316f1df9364SStefan Roese 	{1, 1},
317f1df9364SStefan Roese 	{0, 0},
318f1df9364SStefan Roese 	{1, 1},
319f1df9364SStefan Roese 	{0, 1},
320f1df9364SStefan Roese 	{0, 0},
321f1df9364SStefan Roese 	{0, 1},
322f1df9364SStefan Roese 	{0, 1},
323f1df9364SStefan Roese 	{0, 0},
324f1df9364SStefan Roese 	{1, 1},
325f1df9364SStefan Roese 	{1, 1},
326f1df9364SStefan Roese 	{1, 0},
327f1df9364SStefan Roese 	{1, 0},
328f1df9364SStefan Roese 	{1, 1},
329f1df9364SStefan Roese 	{1, 1},
330f1df9364SStefan Roese 	{1, 1},
331f1df9364SStefan Roese 	{1, 1},
332f1df9364SStefan Roese 	{1, 1},
333f1df9364SStefan Roese 	{1, 1},
334f1df9364SStefan Roese 	{1, 1}
335f1df9364SStefan Roese };
336f1df9364SStefan Roese 
337f1df9364SStefan Roese static u8 pattern_vref_pattern_table_map[] = {
338f1df9364SStefan Roese 	/* 1 means 0xffffffff, 0 is 0x0 */
339f1df9364SStefan Roese 	0xb8,
340f1df9364SStefan Roese 	0x52,
341f1df9364SStefan Roese 	0x55,
342f1df9364SStefan Roese 	0x8a,
343f1df9364SStefan Roese 	0x33,
344f1df9364SStefan Roese 	0xa6,
345f1df9364SStefan Roese 	0x6d,
346f1df9364SStefan Roese 	0xfe
347f1df9364SStefan Roese };
348f1df9364SStefan Roese 
349f1df9364SStefan Roese /* Return speed Bin value for selected index and t* element */
350f1df9364SStefan Roese u32 speed_bin_table(u8 index, enum speed_bin_table_elements element)
351f1df9364SStefan Roese {
352f1df9364SStefan Roese 	u32 result = 0;
353f1df9364SStefan Roese 
354f1df9364SStefan Roese 	switch (element) {
355f1df9364SStefan Roese 	case SPEED_BIN_TRCD:
356f1df9364SStefan Roese 	case SPEED_BIN_TRP:
357f1df9364SStefan Roese 		result = speed_bin_table_t_rcd_t_rp[index];
358f1df9364SStefan Roese 		break;
359f1df9364SStefan Roese 	case SPEED_BIN_TRAS:
360f1df9364SStefan Roese 		if (index < 6)
361f1df9364SStefan Roese 			result = 37500;
362f1df9364SStefan Roese 		else if (index < 10)
363f1df9364SStefan Roese 			result = 36000;
364f1df9364SStefan Roese 		else if (index < 14)
365f1df9364SStefan Roese 			result = 35000;
366f1df9364SStefan Roese 		else if (index < 18)
367f1df9364SStefan Roese 			result = 34000;
368f1df9364SStefan Roese 		else
369f1df9364SStefan Roese 			result = 33000;
370f1df9364SStefan Roese 		break;
371f1df9364SStefan Roese 	case SPEED_BIN_TRC:
372f1df9364SStefan Roese 		result = speed_bin_table_t_rc[index];
373f1df9364SStefan Roese 		break;
374f1df9364SStefan Roese 	case SPEED_BIN_TRRD1K:
375f1df9364SStefan Roese 		if (index < 3)
376f1df9364SStefan Roese 			result = 10000;
377f1df9364SStefan Roese 		else if (index < 6)
378f1df9364SStefan Roese 			result = 7005;
379f1df9364SStefan Roese 		else if (index < 14)
380f1df9364SStefan Roese 			result = 6000;
381f1df9364SStefan Roese 		else
382f1df9364SStefan Roese 			result = 5000;
383f1df9364SStefan Roese 		break;
384f1df9364SStefan Roese 	case SPEED_BIN_TRRD2K:
385f1df9364SStefan Roese 		if (index < 6)
386f1df9364SStefan Roese 			result = 10000;
387f1df9364SStefan Roese 		else if (index < 14)
388f1df9364SStefan Roese 			result = 7005;
389f1df9364SStefan Roese 		else
390f1df9364SStefan Roese 			result = 6000;
391f1df9364SStefan Roese 		break;
392f1df9364SStefan Roese 	case SPEED_BIN_TPD:
393f1df9364SStefan Roese 		if (index < 3)
394f1df9364SStefan Roese 			result = 7500;
395f1df9364SStefan Roese 		else if (index < 10)
396f1df9364SStefan Roese 			result = 5625;
397f1df9364SStefan Roese 		else
398f1df9364SStefan Roese 			result = 5000;
399f1df9364SStefan Roese 		break;
400f1df9364SStefan Roese 	case SPEED_BIN_TFAW1K:
401f1df9364SStefan Roese 		if (index < 3)
402f1df9364SStefan Roese 			result = 40000;
403f1df9364SStefan Roese 		else if (index < 6)
404f1df9364SStefan Roese 			result = 37500;
405f1df9364SStefan Roese 		else if (index < 14)
406f1df9364SStefan Roese 			result = 30000;
407f1df9364SStefan Roese 		else if (index < 18)
408f1df9364SStefan Roese 			result = 27000;
409f1df9364SStefan Roese 		else
410f1df9364SStefan Roese 			result = 25000;
411f1df9364SStefan Roese 		break;
412f1df9364SStefan Roese 	case SPEED_BIN_TFAW2K:
413f1df9364SStefan Roese 		if (index < 6)
414f1df9364SStefan Roese 			result = 50000;
415f1df9364SStefan Roese 		else if (index < 10)
416f1df9364SStefan Roese 			result = 45000;
417f1df9364SStefan Roese 		else if (index < 14)
418f1df9364SStefan Roese 			result = 40000;
419f1df9364SStefan Roese 		else
420f1df9364SStefan Roese 			result = 35000;
421f1df9364SStefan Roese 		break;
422f1df9364SStefan Roese 	case SPEED_BIN_TWTR:
423f1df9364SStefan Roese 		result = 7500;
424f1df9364SStefan Roese 		break;
425f1df9364SStefan Roese 	case SPEED_BIN_TRTP:
426f1df9364SStefan Roese 		result = 7500;
427f1df9364SStefan Roese 		break;
428f1df9364SStefan Roese 	case SPEED_BIN_TWR:
429f1df9364SStefan Roese 		result = 15000;
430f1df9364SStefan Roese 		break;
431f1df9364SStefan Roese 	case SPEED_BIN_TMOD:
432f1df9364SStefan Roese 		result = 15000;
433f1df9364SStefan Roese 		break;
434*672e5598SChris Packham 	case SPEED_BIN_TXPDLL:
435*672e5598SChris Packham 		result = 24000;
436*672e5598SChris Packham 		break;
437f1df9364SStefan Roese 	default:
438f1df9364SStefan Roese 		break;
439f1df9364SStefan Roese 	}
440f1df9364SStefan Roese 
441f1df9364SStefan Roese 	return result;
442f1df9364SStefan Roese }
443f1df9364SStefan Roese 
444f1df9364SStefan Roese static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
445f1df9364SStefan Roese {
446f1df9364SStefan Roese 	u8 i, byte = 0;
447f1df9364SStefan Roese 	u8 role;
448f1df9364SStefan Roese 
449f1df9364SStefan Roese 	for (i = 0; i < 8; i++) {
450f1df9364SStefan Roese 		role = (i == dqs) ?
451f1df9364SStefan Roese 			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
452f1df9364SStefan Roese 			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
453f1df9364SStefan Roese 		byte |= pattern_killer_pattern_table_map[index][role] << i;
454f1df9364SStefan Roese 	}
455f1df9364SStefan Roese 
456f1df9364SStefan Roese 	return byte | (byte << 8) | (byte << 16) | (byte << 24);
457f1df9364SStefan Roese }
458f1df9364SStefan Roese 
459f1df9364SStefan Roese static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
460f1df9364SStefan Roese {
461f1df9364SStefan Roese 	u8 i, byte0 = 0, byte1 = 0;
462f1df9364SStefan Roese 	u8 role;
463f1df9364SStefan Roese 
464f1df9364SStefan Roese 	for (i = 0; i < 8; i++) {
465f1df9364SStefan Roese 		role = (i == dqs) ?
466f1df9364SStefan Roese 			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
467f1df9364SStefan Roese 			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
468f1df9364SStefan Roese 		byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i;
469f1df9364SStefan Roese 	}
470f1df9364SStefan Roese 
471f1df9364SStefan Roese 	for (i = 0; i < 8; i++) {
472f1df9364SStefan Roese 		role = (i == dqs) ?
473f1df9364SStefan Roese 			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
474f1df9364SStefan Roese 			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
475f1df9364SStefan Roese 		byte1 |= pattern_killer_pattern_table_map
476f1df9364SStefan Roese 			[index * 2 + 1][role] << i;
477f1df9364SStefan Roese 	}
478f1df9364SStefan Roese 
479f1df9364SStefan Roese 	return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
480f1df9364SStefan Roese }
481f1df9364SStefan Roese 
482f1df9364SStefan Roese static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
483f1df9364SStefan Roese {
484f1df9364SStefan Roese 	u8 step = sso + 1;
485f1df9364SStefan Roese 
486f1df9364SStefan Roese 	if (0 == ((index / step) & 1))
487f1df9364SStefan Roese 		return 0x0;
488f1df9364SStefan Roese 	else
489f1df9364SStefan Roese 		return 0xffffffff;
490f1df9364SStefan Roese }
491f1df9364SStefan Roese 
492f1df9364SStefan Roese static inline u32 pattern_table_get_vref_word(u8 index)
493f1df9364SStefan Roese {
494f1df9364SStefan Roese 	if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
495f1df9364SStefan Roese 		   (index % 8)) & 1))
496f1df9364SStefan Roese 		return 0x0;
497f1df9364SStefan Roese 	else
498f1df9364SStefan Roese 		return 0xffffffff;
499f1df9364SStefan Roese }
500f1df9364SStefan Roese 
501f1df9364SStefan Roese static inline u32 pattern_table_get_vref_word16(u8 index)
502f1df9364SStefan Roese {
503f1df9364SStefan Roese 	if (0 == pattern_killer_pattern_table_map
504f1df9364SStefan Roese 	    [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
505f1df9364SStefan Roese 	    0 == pattern_killer_pattern_table_map
506f1df9364SStefan Roese 	    [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
507f1df9364SStefan Roese 		return 0x00000000;
508f1df9364SStefan Roese 	else if (1 == pattern_killer_pattern_table_map
509f1df9364SStefan Roese 		 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
510f1df9364SStefan Roese 		 0 == pattern_killer_pattern_table_map
511f1df9364SStefan Roese 		 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
512f1df9364SStefan Roese 		return 0xffff0000;
513f1df9364SStefan Roese 	else if (0 == pattern_killer_pattern_table_map
514f1df9364SStefan Roese 		 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
515f1df9364SStefan Roese 		 1 == pattern_killer_pattern_table_map
516f1df9364SStefan Roese 		 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
517f1df9364SStefan Roese 		return 0x0000ffff;
518f1df9364SStefan Roese 	else
519f1df9364SStefan Roese 		return 0xffffffff;
520f1df9364SStefan Roese }
521f1df9364SStefan Roese 
522f1df9364SStefan Roese static inline u32 pattern_table_get_static_pbs_word(u8 index)
523f1df9364SStefan Roese {
524f1df9364SStefan Roese 	u16 temp;
525f1df9364SStefan Roese 
526f1df9364SStefan Roese 	temp = ((0x00ff << (index / 3)) & 0xff00) >> 8;
527f1df9364SStefan Roese 
528f1df9364SStefan Roese 	return temp | (temp << 8) | (temp << 16) | (temp << 24);
529f1df9364SStefan Roese }
530f1df9364SStefan Roese 
531f1df9364SStefan Roese inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
532f1df9364SStefan Roese {
533f1df9364SStefan Roese 	u32 pattern;
534f1df9364SStefan Roese 	struct hws_topology_map *tm = ddr3_get_topology_map();
535f1df9364SStefan Roese 
536f1df9364SStefan Roese 	if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
537f1df9364SStefan Roese 		/* 32bit patterns */
538f1df9364SStefan Roese 		switch (type) {
539f1df9364SStefan Roese 		case PATTERN_PBS1:
540f1df9364SStefan Roese 		case PATTERN_PBS2:
541f1df9364SStefan Roese 			if (index == 0 || index == 2 || index == 5 ||
542f1df9364SStefan Roese 			    index == 7)
543f1df9364SStefan Roese 				pattern = PATTERN_55;
544f1df9364SStefan Roese 			else
545f1df9364SStefan Roese 				pattern = PATTERN_AA;
546f1df9364SStefan Roese 			break;
547f1df9364SStefan Roese 		case PATTERN_PBS3:
548f1df9364SStefan Roese 			if (0 == (index & 1))
549f1df9364SStefan Roese 				pattern = PATTERN_55;
550f1df9364SStefan Roese 			else
551f1df9364SStefan Roese 				pattern = PATTERN_AA;
552f1df9364SStefan Roese 			break;
553f1df9364SStefan Roese 		case PATTERN_RL:
554f1df9364SStefan Roese 			if (index < 6)
555f1df9364SStefan Roese 				pattern = PATTERN_00;
556f1df9364SStefan Roese 			else
557f1df9364SStefan Roese 				pattern = PATTERN_80;
558f1df9364SStefan Roese 			break;
559f1df9364SStefan Roese 		case PATTERN_STATIC_PBS:
560f1df9364SStefan Roese 			pattern = pattern_table_get_static_pbs_word(index);
561f1df9364SStefan Roese 			break;
562f1df9364SStefan Roese 		case PATTERN_KILLER_DQ0:
563f1df9364SStefan Roese 		case PATTERN_KILLER_DQ1:
564f1df9364SStefan Roese 		case PATTERN_KILLER_DQ2:
565f1df9364SStefan Roese 		case PATTERN_KILLER_DQ3:
566f1df9364SStefan Roese 		case PATTERN_KILLER_DQ4:
567f1df9364SStefan Roese 		case PATTERN_KILLER_DQ5:
568f1df9364SStefan Roese 		case PATTERN_KILLER_DQ6:
569f1df9364SStefan Roese 		case PATTERN_KILLER_DQ7:
570f1df9364SStefan Roese 			pattern = pattern_table_get_killer_word(
571f1df9364SStefan Roese 				(u8)(type - PATTERN_KILLER_DQ0), index);
572f1df9364SStefan Roese 			break;
573f1df9364SStefan Roese 		case PATTERN_RL2:
574f1df9364SStefan Roese 			if (index < 6)
575f1df9364SStefan Roese 				pattern = PATTERN_00;
576f1df9364SStefan Roese 			else
577f1df9364SStefan Roese 				pattern = PATTERN_01;
578f1df9364SStefan Roese 			break;
579f1df9364SStefan Roese 		case PATTERN_TEST:
580f1df9364SStefan Roese 			if (index > 1 && index < 6)
581f1df9364SStefan Roese 				pattern = PATTERN_20;
582f1df9364SStefan Roese 			else
583f1df9364SStefan Roese 				pattern = PATTERN_00;
584f1df9364SStefan Roese 			break;
585f1df9364SStefan Roese 		case PATTERN_FULL_SSO0:
586f1df9364SStefan Roese 		case PATTERN_FULL_SSO1:
587f1df9364SStefan Roese 		case PATTERN_FULL_SSO2:
588f1df9364SStefan Roese 		case PATTERN_FULL_SSO3:
589f1df9364SStefan Roese 			pattern = pattern_table_get_sso_word(
590f1df9364SStefan Roese 				(u8)(type - PATTERN_FULL_SSO0), index);
591f1df9364SStefan Roese 			break;
592f1df9364SStefan Roese 		case PATTERN_VREF:
593f1df9364SStefan Roese 			pattern = pattern_table_get_vref_word(index);
594f1df9364SStefan Roese 			break;
595f1df9364SStefan Roese 		default:
596f1df9364SStefan Roese 			pattern = 0;
597f1df9364SStefan Roese 			break;
598f1df9364SStefan Roese 		}
599f1df9364SStefan Roese 	} else {
600f1df9364SStefan Roese 		/* 16bit patterns */
601f1df9364SStefan Roese 		switch (type) {
602f1df9364SStefan Roese 		case PATTERN_PBS1:
603f1df9364SStefan Roese 		case PATTERN_PBS2:
604f1df9364SStefan Roese 		case PATTERN_PBS3:
605f1df9364SStefan Roese 			pattern = PATTERN_55AA;
606f1df9364SStefan Roese 			break;
607f1df9364SStefan Roese 		case PATTERN_RL:
608f1df9364SStefan Roese 			if (index < 3)
609f1df9364SStefan Roese 				pattern = PATTERN_00;
610f1df9364SStefan Roese 			else
611f1df9364SStefan Roese 				pattern = PATTERN_80;
612f1df9364SStefan Roese 			break;
613f1df9364SStefan Roese 		case PATTERN_STATIC_PBS:
614f1df9364SStefan Roese 			pattern = PATTERN_00FF;
615f1df9364SStefan Roese 			break;
616f1df9364SStefan Roese 		case PATTERN_KILLER_DQ0:
617f1df9364SStefan Roese 		case PATTERN_KILLER_DQ1:
618f1df9364SStefan Roese 		case PATTERN_KILLER_DQ2:
619f1df9364SStefan Roese 		case PATTERN_KILLER_DQ3:
620f1df9364SStefan Roese 		case PATTERN_KILLER_DQ4:
621f1df9364SStefan Roese 		case PATTERN_KILLER_DQ5:
622f1df9364SStefan Roese 		case PATTERN_KILLER_DQ6:
623f1df9364SStefan Roese 		case PATTERN_KILLER_DQ7:
624f1df9364SStefan Roese 			pattern = pattern_table_get_killer_word16(
625f1df9364SStefan Roese 				(u8)(type - PATTERN_KILLER_DQ0), index);
626f1df9364SStefan Roese 			break;
627f1df9364SStefan Roese 		case PATTERN_RL2:
628f1df9364SStefan Roese 			if (index < 3)
629f1df9364SStefan Roese 				pattern = PATTERN_00;
630f1df9364SStefan Roese 			else
631f1df9364SStefan Roese 				pattern = PATTERN_01;
632f1df9364SStefan Roese 			break;
633f1df9364SStefan Roese 		case PATTERN_TEST:
634f1df9364SStefan Roese 			pattern = PATTERN_0080;
635f1df9364SStefan Roese 			break;
636f1df9364SStefan Roese 		case PATTERN_FULL_SSO0:
637f1df9364SStefan Roese 			pattern = 0x0000ffff;
638f1df9364SStefan Roese 			break;
639f1df9364SStefan Roese 		case PATTERN_FULL_SSO1:
640f1df9364SStefan Roese 		case PATTERN_FULL_SSO2:
641f1df9364SStefan Roese 		case PATTERN_FULL_SSO3:
642f1df9364SStefan Roese 			pattern = pattern_table_get_sso_word(
643f1df9364SStefan Roese 				(u8)(type - PATTERN_FULL_SSO1), index);
644f1df9364SStefan Roese 			break;
645f1df9364SStefan Roese 		case PATTERN_VREF:
646f1df9364SStefan Roese 			pattern = pattern_table_get_vref_word16(index);
647f1df9364SStefan Roese 			break;
648f1df9364SStefan Roese 		default:
649f1df9364SStefan Roese 			pattern = 0;
650f1df9364SStefan Roese 			break;
651f1df9364SStefan Roese 		}
652f1df9364SStefan Roese 	}
653f1df9364SStefan Roese 
654f1df9364SStefan Roese 	return pattern;
655f1df9364SStefan Roese }
656