blob: c0089f67f271f561d8520c55e4fc14aa2a2987b0 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Stefan Roese5ffceb82015-03-26 15:36:56 +01002/*
3 * Copyright (C) Marvell International Ltd. and its affiliates
Stefan Roese5ffceb82015-03-26 15:36:56 +01004 */
5
Stefan Roese5ffceb82015-03-26 15:36:56 +01006#include "ddr3_init.h"
7
Chris Packham1a07d212018-05-10 13:28:29 +12008/* Device attributes structures */
9enum mv_ddr_dev_attribute ddr_dev_attributes[MAX_DEVICE_NUM][MV_ATTR_LAST];
10int ddr_dev_attr_init_done[MAX_DEVICE_NUM] = { 0 };
11
12static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index);
13static inline u32 pattern_table_get_sso_word(u8 sso, u8 index);
14static inline u32 pattern_table_get_vref_word(u8 index);
15static inline u32 pattern_table_get_vref_word16(u8 index);
16static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index);
17static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index);
18static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index);
19static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index);
20static inline u32 pattern_table_get_isi_word(u8 index);
21static inline u32 pattern_table_get_isi_word16(u8 index);
22
Stefan Roese5ffceb82015-03-26 15:36:56 +010023/* List of allowed frequency listed in order of enum hws_ddr_freq */
Chris Packham1a07d212018-05-10 13:28:29 +120024u32 freq_val[DDR_FREQ_LAST] = {
Stefan Roese5ffceb82015-03-26 15:36:56 +010025 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 */
44struct 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 */
101struct 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
157u8 twr_mask_table[] = {
158 10,
159 10,
160 10,
161 10,
162 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200163 1, /* 5 */
164 2, /* 6 */
165 3, /* 7 */
166 4, /* 8 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100167 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200168 5, /* 10 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100169 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200170 6, /* 12 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100171 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200172 7, /* 14 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100173 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200174 0 /* 16 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100175};
176
177u8 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
196u8 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) */
216u16 rfc_table[] = {
217 90, /* 512M */
218 110, /* 1G */
219 160, /* 2G */
220 260, /* 4G */
Chris Packham1a07d212018-05-10 13:28:29 +1200221 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 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100226};
227
228u32 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,
Chris Packham1a07d212018-05-10 13:28:29 +1200249 46090
Stefan Roese5ffceb82015-03-26 15:36:56 +0100250};
251
252u32 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,
Chris Packham1a07d212018-05-10 13:28:29 +1200271 11220,
Stefan Roese5ffceb82015-03-26 15:36:56 +0100272 12155,
273 13090,
274};
275
276enum {
277 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
278 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
279};
280
281static 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
349static 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 */
362u32 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:
Chris Packham1a07d212018-05-10 13:28:29 +1200372 if (index < SPEED_BIN_DDR_1066G)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100373 result = 37500;
Chris Packham1a07d212018-05-10 13:28:29 +1200374 else if (index < SPEED_BIN_DDR_1333J)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100375 result = 36000;
Chris Packham1a07d212018-05-10 13:28:29 +1200376 else if (index < SPEED_BIN_DDR_1600K)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100377 result = 35000;
Chris Packham1a07d212018-05-10 13:28:29 +1200378 else if (index < SPEED_BIN_DDR_1866M)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100379 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:
Chris Packham1a07d212018-05-10 13:28:29 +1200387 if (index < SPEED_BIN_DDR_800E)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100388 result = 10000;
Chris Packham1a07d212018-05-10 13:28:29 +1200389 else if (index < SPEED_BIN_DDR_1066G)
390 result = 7500;
391 else if (index < SPEED_BIN_DDR_1600K)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100392 result = 6000;
393 else
394 result = 5000;
395 break;
396 case SPEED_BIN_TRRD2K:
Chris Packham1a07d212018-05-10 13:28:29 +1200397 if (index < SPEED_BIN_DDR_1066G)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100398 result = 10000;
Chris Packham1a07d212018-05-10 13:28:29 +1200399 else if (index < SPEED_BIN_DDR_1600K)
400 result = 7500;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100401 else
402 result = 6000;
403 break;
404 case SPEED_BIN_TPD:
Chris Packham1a07d212018-05-10 13:28:29 +1200405 if (index < SPEED_BIN_DDR_800E)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100406 result = 7500;
Chris Packham1a07d212018-05-10 13:28:29 +1200407 else if (index < SPEED_BIN_DDR_1333J)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100408 result = 5625;
409 else
410 result = 5000;
411 break;
412 case SPEED_BIN_TFAW1K:
Chris Packham1a07d212018-05-10 13:28:29 +1200413 if (index < SPEED_BIN_DDR_800E)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100414 result = 40000;
Chris Packham1a07d212018-05-10 13:28:29 +1200415 else if (index < SPEED_BIN_DDR_1066G)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100416 result = 37500;
Chris Packham1a07d212018-05-10 13:28:29 +1200417 else if (index < SPEED_BIN_DDR_1600K)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100418 result = 30000;
Chris Packham1a07d212018-05-10 13:28:29 +1200419 else if (index < SPEED_BIN_DDR_1866M)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100420 result = 27000;
421 else
422 result = 25000;
423 break;
424 case SPEED_BIN_TFAW2K:
Chris Packham1a07d212018-05-10 13:28:29 +1200425 if (index < SPEED_BIN_DDR_1066G)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100426 result = 50000;
Chris Packham1a07d212018-05-10 13:28:29 +1200427 else if (index < SPEED_BIN_DDR_1333J)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100428 result = 45000;
Chris Packham1a07d212018-05-10 13:28:29 +1200429 else if (index < SPEED_BIN_DDR_1600K)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100430 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;
Chris Packham5450f0c2018-01-18 17:16:10 +1300446 case SPEED_BIN_TXPDLL:
447 result = 24000;
448 break;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100449 default:
450 break;
451 }
452
453 return result;
454}
455
456static 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
471static 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;
Chris Packham1a07d212018-05-10 13:28:29 +1200481 byte1 |= pattern_killer_pattern_table_map[index * 2 + 1][role] << i;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100482 }
483
484 return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
485}
486
487static 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
Chris Packham1a07d212018-05-10 13:28:29 +1200497static 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
508static 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
518static 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
534static 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
544static 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
554static 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
Stefan Roese5ffceb82015-03-26 15:36:56 +0100570static 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
579static 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
600static 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
Chris Packham1a07d212018-05-10 13:28:29 +1200609u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100610{
611 u32 pattern;
Chris Packham1a07d212018-05-10 13:28:29 +1200612 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100613
614 if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
Chris Packham1a07d212018-05-10 13:28:29 +1200615 /* 32/64-bit patterns */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100616 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)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100659 pattern = PATTERN_00;
Chris Packham1a07d212018-05-10 13:28:29 +1200660 else
661 pattern = PATTERN_FF;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100662 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;
Chris Packham1a07d212018-05-10 13:28:29 +1200673 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;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100698 default:
Chris Packham1a07d212018-05-10 13:28:29 +1200699 DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("Error: %s: pattern type [%d] not supported\n",
700 __func__, (int)type));
Stefan Roese5ffceb82015-03-26 15:36:56 +0100701 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:
Chris Packham1a07d212018-05-10 13:28:29 +1200739 if ((index == 0) || (index == 3))
740 pattern = 0x00000000;
741 else
742 pattern = 0xFFFFFFFF;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100743 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;
Chris Packham1a07d212018-05-10 13:28:29 +1200756 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;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100781 default:
Chris Packham1a07d212018-05-10 13:28:29 +1200782 DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("Error: %s: pattern type [%d] not supported\n",
783 __func__, (int)type));
Stefan Roese5ffceb82015-03-26 15:36:56 +0100784 pattern = 0;
785 break;
786 }
787 }
788
789 return pattern;
790}
Chris Packham1a07d212018-05-10 13:28:29 +1200791
792/* Device attribute functions */
793void 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
803u32 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
811void 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}