blob: b2f11a839961525c4a26b57a63e94f5719cf3d28 [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
Chris Packham4bf81db2018-12-03 14:26:49 +13006#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"
Stefan Roese5ffceb82015-03-26 15:36:56 +010012
Chris Packham1a07d212018-05-10 13:28:29 +120013/* Device attributes structures */
Chris Packham4bf81db2018-12-03 14:26:49 +130014enum mv_ddr_dev_attribute ddr_dev_attributes[MV_ATTR_LAST];
15int ddr_dev_attr_init_done = 0;
Chris Packham1a07d212018-05-10 13:28:29 +120016
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
Chris Packham4bf81db2018-12-03 14:26:49 +130028/* List of allowed frequency listed in order of enum mv_ddr_freq */
29static unsigned int freq_val[MV_DDR_FREQ_LAST] = {
30 0, /*MV_DDR_FREQ_LOW_FREQ */
31 400, /*MV_DDR_FREQ_400, */
32 533, /*MV_DDR_FREQ_533, */
33 666, /*MV_DDR_FREQ_667, */
34 800, /*MV_DDR_FREQ_800, */
35 933, /*MV_DDR_FREQ_933, */
36 1066, /*MV_DDR_FREQ_1066, */
37 311, /*MV_DDR_FREQ_311, */
38 333, /*MV_DDR_FREQ_333, */
39 467, /*MV_DDR_FREQ_467, */
40 850, /*MV_DDR_FREQ_850, */
41 600, /*MV_DDR_FREQ_600 */
42 300, /*MV_DDR_FREQ_300 */
43 900, /*MV_DDR_FREQ_900 */
44 360, /*MV_DDR_FREQ_360 */
45 1000 /*MV_DDR_FREQ_1000 */
Stefan Roese5ffceb82015-03-26 15:36:56 +010046};
47
Chris Packham4bf81db2018-12-03 14:26:49 +130048unsigned int *mv_ddr_freq_tbl_get(void)
49{
50 return &freq_val[0];
51}
52
53u32 mv_ddr_freq_get(enum mv_ddr_freq freq)
54{
55 return freq_val[freq];
56}
57
58/* cas latency values per frequency for each speed bin index */
59static struct mv_ddr_cl_val_per_freq cl_table[] = {
Stefan Roese5ffceb82015-03-26 15:36:56 +010060 /*
61 * 400M 667M 933M 311M 467M 600M 360
62 * 100M 533M 800M 1066M 333M 850M 900
63 * 1000 (the order is 100, 400, 533 etc.)
64 */
65 /* DDR3-800D */
66 { {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
67 /* DDR3-800E */
68 { {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} },
69 /* DDR3-1066E */
70 { {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} },
71 /* DDR3-1066F */
72 { {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} },
73 /* DDR3-1066G */
74 { {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} },
75 /* DDR3-1333F* */
76 { {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
77 /* DDR3-1333G */
78 { {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} },
79 /* DDR3-1333H */
80 { {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} },
81 /* DDR3-1333J* */
82 { {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0}
83 /* DDR3-1600G* */},
84 { {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
85 /* DDR3-1600H */
86 { {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} },
87 /* DDR3-1600J */
88 { {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} },
89 /* DDR3-1600K */
90 { {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } },
91 /* DDR3-1866J* */
92 { {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} },
93 /* DDR3-1866K */
94 { {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} },
95 /* DDR3-1866L */
96 { {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} },
97 /* DDR3-1866M* */
98 { {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} },
99 /* DDR3-2133K* */
100 { {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} },
101 /* DDR3-2133L */
102 { {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} },
103 /* DDR3-2133M */
104 { {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} },
105 /* DDR3-2133N* */
106 { {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14, 6, 14} },
107 /* DDR3-1333H-ext */
108 { {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
109 /* DDR3-1600K-ext */
110 { {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
111 /* DDR3-1866M-ext */
112 { {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} },
113};
114
Chris Packham4bf81db2018-12-03 14:26:49 +1300115u32 mv_ddr_cl_val_get(u32 index, u32 freq)
116{
117 return cl_table[index].cl_val[freq];
118}
119
120/* cas write latency values per frequency for each speed bin index */
121static struct mv_ddr_cl_val_per_freq cwl_table[] = {
Stefan Roese5ffceb82015-03-26 15:36:56 +0100122 /*
123 * 400M 667M 933M 311M 467M 600M 360
124 * 100M 533M 800M 1066M 333M 850M 900
125 * (the order is 100, 400, 533 etc.)
126 */
127 /* DDR3-800D */
128 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
129 /* DDR3-800E */
130 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
131 /* DDR3-1066E */
132 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
133 /* DDR3-1066F */
134 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
135 /* DDR3-1066G */
136 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
137 /* DDR3-1333F* */
138 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
139 /* DDR3-1333G */
140 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
141 /* DDR3-1333H */
142 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
143 /* DDR3-1333J* */
144 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
145 /* DDR3-1600G* */
146 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
147 /* DDR3-1600H */
148 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
149 /* DDR3-1600J */
150 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
151 /* DDR3-1600K */
152 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
153 /* DDR3-1866J* */
154 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
155 /* DDR3-1866K */
156 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
157 /* DDR3-1866L */
158 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
159 /* DDR3-1866M* */
160 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
161 /* DDR3-2133K* */
162 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
163 /* DDR3-2133L */
164 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
165 /* DDR3-2133M */
166 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
167 /* DDR3-2133N* */
168 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
169 /* DDR3-1333H-ext */
170 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
171 /* DDR3-1600K-ext */
172 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
173 /* DDR3-1866M-ext */
174 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
175};
176
Chris Packham4bf81db2018-12-03 14:26:49 +1300177u32 mv_ddr_cwl_val_get(u32 index, u32 freq)
178{
179 return cwl_table[index].cl_val[freq];
180}
181
Stefan Roese5ffceb82015-03-26 15:36:56 +0100182u8 twr_mask_table[] = {
183 10,
184 10,
185 10,
186 10,
187 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200188 1, /* 5 */
189 2, /* 6 */
190 3, /* 7 */
191 4, /* 8 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100192 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200193 5, /* 10 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100194 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200195 6, /* 12 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100196 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200197 7, /* 14 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100198 10,
Chris Packham1a07d212018-05-10 13:28:29 +1200199 0 /* 16 */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100200};
201
202u8 cl_mask_table[] = {
203 0,
204 0,
205 0,
206 0,
207 0,
208 0x2,
209 0x4,
210 0x6,
211 0x8,
212 0xa,
213 0xc,
214 0xe,
215 0x1,
216 0x3,
217 0x5,
218 0x5
219};
220
221u8 cwl_mask_table[] = {
222 0,
223 0,
224 0,
225 0,
226 0,
227 0,
228 0x1,
229 0x2,
230 0x3,
231 0x4,
232 0x5,
233 0x6,
234 0x7,
235 0x8,
236 0x9,
237 0x9
238};
239
240/* RFC values (in ns) */
Chris Packham4bf81db2018-12-03 14:26:49 +1300241static unsigned int rfc_table[] = {
242 90, /* 512M */
243 110, /* 1G */
244 160, /* 2G */
245 260, /* 4G */
246 350, /* 8G */
247 0, /* TODO: placeholder for 16-Mbit dev width */
248 0, /* TODO: placeholder for 32-Mbit dev width */
249 0, /* TODO: placeholder for 12-Mbit dev width */
250 0 /* TODO: placeholder for 24-Mbit dev width */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100251};
252
Chris Packham4bf81db2018-12-03 14:26:49 +1300253u32 mv_ddr_rfc_get(u32 mem)
254{
255 return rfc_table[mem];
256}
257
Stefan Roese5ffceb82015-03-26 15:36:56 +0100258u32 speed_bin_table_t_rc[] = {
259 50000,
260 52500,
261 48750,
262 50625,
263 52500,
264 46500,
265 48000,
266 49500,
267 51000,
268 45000,
269 46250,
270 47500,
271 48750,
272 44700,
273 45770,
274 46840,
275 47910,
276 43285,
277 44220,
278 45155,
Chris Packham1a07d212018-05-10 13:28:29 +1200279 46090
Stefan Roese5ffceb82015-03-26 15:36:56 +0100280};
281
282u32 speed_bin_table_t_rcd_t_rp[] = {
283 12500,
284 15000,
285 11250,
286 13125,
287 15000,
288 10500,
289 12000,
290 13500,
291 15000,
292 10000,
293 11250,
294 12500,
295 13750,
296 10700,
297 11770,
298 12840,
299 13910,
300 10285,
Chris Packham1a07d212018-05-10 13:28:29 +1200301 11220,
Stefan Roese5ffceb82015-03-26 15:36:56 +0100302 12155,
303 13090,
304};
305
306enum {
307 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
308 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
309};
310
311static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = {
312 /*Aggressor / Victim */
313 {1, 0},
314 {0, 0},
315 {1, 0},
316 {1, 1},
317 {0, 1},
318 {0, 1},
319 {1, 0},
320 {0, 1},
321 {1, 0},
322 {0, 1},
323 {1, 0},
324 {1, 0},
325 {0, 1},
326 {1, 0},
327 {0, 1},
328 {0, 0},
329 {1, 1},
330 {0, 0},
331 {1, 1},
332 {0, 0},
333 {1, 1},
334 {0, 0},
335 {1, 1},
336 {1, 0},
337 {0, 0},
338 {1, 1},
339 {0, 0},
340 {1, 1},
341 {0, 0},
342 {0, 0},
343 {0, 0},
344 {0, 1},
345 {0, 1},
346 {1, 1},
347 {0, 0},
348 {0, 0},
349 {1, 1},
350 {1, 1},
351 {0, 0},
352 {1, 1},
353 {0, 0},
354 {1, 1},
355 {1, 1},
356 {0, 0},
357 {0, 0},
358 {1, 1},
359 {0, 0},
360 {1, 1},
361 {0, 1},
362 {0, 0},
363 {0, 1},
364 {0, 1},
365 {0, 0},
366 {1, 1},
367 {1, 1},
368 {1, 0},
369 {1, 0},
370 {1, 1},
371 {1, 1},
372 {1, 1},
373 {1, 1},
374 {1, 1},
375 {1, 1},
376 {1, 1}
377};
378
379static u8 pattern_vref_pattern_table_map[] = {
380 /* 1 means 0xffffffff, 0 is 0x0 */
381 0xb8,
382 0x52,
383 0x55,
384 0x8a,
385 0x33,
386 0xa6,
387 0x6d,
388 0xfe
389};
390
Chris Packham4bf81db2018-12-03 14:26:49 +1300391static struct mv_ddr_page_element page_tbl[] = {
392 /* 8-bit, 16-bit page size */
393 {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 512M */
394 {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 1G */
395 {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 2G */
396 {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 4G */
397 {MV_DDR_PAGE_SIZE_2K, MV_DDR_PAGE_SIZE_2K}, /* 8G */
398 {0, 0}, /* TODO: placeholder for 16-Mbit die capacity */
399 {0, 0}, /* TODO: placeholder for 32-Mbit die capacity */
400 {0, 0}, /* TODO: placeholder for 12-Mbit die capacity */
401 {0, 0} /* TODO: placeholder for 24-Mbit die capacity */
402};
403
404u32 mv_ddr_page_size_get(enum mv_ddr_dev_width bus_width, enum mv_ddr_die_capacity mem_size)
405{
406 if (bus_width == MV_DDR_DEV_WIDTH_8BIT)
407 return page_tbl[mem_size].page_size_8bit;
408 else
409 return page_tbl[mem_size].page_size_16bit;
410}
411
Stefan Roese5ffceb82015-03-26 15:36:56 +0100412/* Return speed Bin value for selected index and t* element */
Chris Packham4bf81db2018-12-03 14:26:49 +1300413unsigned int mv_ddr_speed_bin_timing_get(enum mv_ddr_speed_bin index, enum mv_ddr_speed_bin_timing element)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100414{
415 u32 result = 0;
416
417 switch (element) {
418 case SPEED_BIN_TRCD:
419 case SPEED_BIN_TRP:
420 result = speed_bin_table_t_rcd_t_rp[index];
421 break;
422 case SPEED_BIN_TRAS:
Chris Packhamac8bfb12019-03-01 10:11:13 +1300423 if (index <= SPEED_BIN_DDR_1066G)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100424 result = 37500;
Chris Packhamac8bfb12019-03-01 10:11:13 +1300425 else if (index <= SPEED_BIN_DDR_1333J)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100426 result = 36000;
Chris Packhamac8bfb12019-03-01 10:11:13 +1300427 else if (index <= SPEED_BIN_DDR_1600K)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100428 result = 35000;
Chris Packhamac8bfb12019-03-01 10:11:13 +1300429 else if (index <= SPEED_BIN_DDR_1866M)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100430 result = 34000;
431 else
432 result = 33000;
433 break;
434 case SPEED_BIN_TRC:
435 result = speed_bin_table_t_rc[index];
436 break;
437 case SPEED_BIN_TRRD1K:
Chris Packham4bf81db2018-12-03 14:26:49 +1300438 if (index <= SPEED_BIN_DDR_800E)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100439 result = 10000;
Chris Packham4bf81db2018-12-03 14:26:49 +1300440 else if (index <= SPEED_BIN_DDR_1066G)
Chris Packham1a07d212018-05-10 13:28:29 +1200441 result = 7500;
Chris Packham4bf81db2018-12-03 14:26:49 +1300442 else if (index <= SPEED_BIN_DDR_1600K)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100443 result = 6000;
444 else
445 result = 5000;
446 break;
447 case SPEED_BIN_TRRD2K:
Chris Packham4bf81db2018-12-03 14:26:49 +1300448 if (index <= SPEED_BIN_DDR_1066G)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100449 result = 10000;
Chris Packham4bf81db2018-12-03 14:26:49 +1300450 else if (index <= SPEED_BIN_DDR_1600K)
Chris Packham1a07d212018-05-10 13:28:29 +1200451 result = 7500;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100452 else
453 result = 6000;
454 break;
455 case SPEED_BIN_TPD:
Chris Packham1a07d212018-05-10 13:28:29 +1200456 if (index < SPEED_BIN_DDR_800E)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100457 result = 7500;
Chris Packham1a07d212018-05-10 13:28:29 +1200458 else if (index < SPEED_BIN_DDR_1333J)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100459 result = 5625;
460 else
461 result = 5000;
462 break;
463 case SPEED_BIN_TFAW1K:
Chris Packham4bf81db2018-12-03 14:26:49 +1300464 if (index <= SPEED_BIN_DDR_800E)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100465 result = 40000;
Chris Packham4bf81db2018-12-03 14:26:49 +1300466 else if (index <= SPEED_BIN_DDR_1066G)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100467 result = 37500;
Chris Packham4bf81db2018-12-03 14:26:49 +1300468 else if (index <= SPEED_BIN_DDR_1600K)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100469 result = 30000;
Chris Packham4bf81db2018-12-03 14:26:49 +1300470 else if (index <= SPEED_BIN_DDR_1866M)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100471 result = 27000;
472 else
473 result = 25000;
474 break;
475 case SPEED_BIN_TFAW2K:
Chris Packham4bf81db2018-12-03 14:26:49 +1300476 if (index <= SPEED_BIN_DDR_1066G)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100477 result = 50000;
Chris Packham4bf81db2018-12-03 14:26:49 +1300478 else if (index <= SPEED_BIN_DDR_1333J)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100479 result = 45000;
Chris Packham4bf81db2018-12-03 14:26:49 +1300480 else if (index <= SPEED_BIN_DDR_1600K)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100481 result = 40000;
482 else
483 result = 35000;
484 break;
485 case SPEED_BIN_TWTR:
486 result = 7500;
487 break;
488 case SPEED_BIN_TRTP:
489 result = 7500;
490 break;
491 case SPEED_BIN_TWR:
492 result = 15000;
493 break;
494 case SPEED_BIN_TMOD:
495 result = 15000;
496 break;
Chris Packham5450f0c2018-01-18 17:16:10 +1300497 case SPEED_BIN_TXPDLL:
498 result = 24000;
499 break;
Chris Packham4bf81db2018-12-03 14:26:49 +1300500 case SPEED_BIN_TXSDLL:
501 result = 512;
502 break;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100503 default:
504 break;
505 }
506
507 return result;
508}
509
510static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
511{
512 u8 i, byte = 0;
513 u8 role;
514
515 for (i = 0; i < 8; i++) {
516 role = (i == dqs) ?
517 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
518 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
519 byte |= pattern_killer_pattern_table_map[index][role] << i;
520 }
521
522 return byte | (byte << 8) | (byte << 16) | (byte << 24);
523}
524
525static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
526{
527 u8 i, byte0 = 0, byte1 = 0;
528 u8 role;
529
530 for (i = 0; i < 8; i++) {
531 role = (i == dqs) ?
532 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
533 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
534 byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i;
Chris Packham1a07d212018-05-10 13:28:29 +1200535 byte1 |= pattern_killer_pattern_table_map[index * 2 + 1][role] << i;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100536 }
537
538 return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
539}
540
541static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
542{
543 u8 step = sso + 1;
544
545 if (0 == ((index / step) & 1))
546 return 0x0;
547 else
548 return 0xffffffff;
549}
550
Chris Packham1a07d212018-05-10 13:28:29 +1200551static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index)
552{
553 u8 byte = (1 << bit);
554
555 if ((index & 1) == 1)
556 byte = ~byte;
557
558 return byte | (byte << 8) | (byte << 16) | (byte << 24);
559
560}
561
562static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index)
563{
564 u8 byte = (1 << bit);
565
566 if ((index & 1) == 1)
567 byte = 0;
568
569 return byte | (byte << 8) | (byte << 16) | (byte << 24);
570}
571
572static inline u32 pattern_table_get_isi_word(u8 index)
573{
574 u8 i0 = index % 32;
575 u8 i1 = index % 8;
576 u32 word;
577
578 if (i0 > 15)
579 word = ((i1 == 5) | (i1 == 7)) ? 0xffffffff : 0x0;
580 else
581 word = (i1 == 6) ? 0xffffffff : 0x0;
582
583 word = ((i0 % 16) > 7) ? ~word : word;
584
585 return word;
586}
587
588static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index)
589{
590 u8 byte = (1 << bit);
591
592 if ((index & 1) == 1)
593 byte = ~byte;
594
595 return byte | (byte << 8) | ((~byte) << 16) | ((~byte) << 24);
596}
597
598static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index)
599{
600 u8 byte = (1 << bit);
601
602 if ((index & 1) == 0)
603 return (byte << 16) | (byte << 24);
604 else
605 return byte | (byte << 8);
606}
607
608static inline u32 pattern_table_get_isi_word16(u8 index)
609{
610 u8 i0 = index % 16;
611 u8 i1 = index % 4;
612 u32 word;
613
614 if (i0 > 7)
615 word = (i1 > 1) ? 0x0000ffff : 0x0;
616 else
617 word = (i1 == 3) ? 0xffff0000 : 0x0;
618
619 word = ((i0 % 8) > 3) ? ~word : word;
620
621 return word;
622}
623
Stefan Roese5ffceb82015-03-26 15:36:56 +0100624static inline u32 pattern_table_get_vref_word(u8 index)
625{
626 if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
627 (index % 8)) & 1))
628 return 0x0;
629 else
630 return 0xffffffff;
631}
632
633static inline u32 pattern_table_get_vref_word16(u8 index)
634{
635 if (0 == pattern_killer_pattern_table_map
636 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
637 0 == pattern_killer_pattern_table_map
638 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
639 return 0x00000000;
640 else if (1 == pattern_killer_pattern_table_map
641 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
642 0 == pattern_killer_pattern_table_map
643 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
644 return 0xffff0000;
645 else if (0 == pattern_killer_pattern_table_map
646 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
647 1 == pattern_killer_pattern_table_map
648 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
649 return 0x0000ffff;
650 else
651 return 0xffffffff;
652}
653
654static inline u32 pattern_table_get_static_pbs_word(u8 index)
655{
656 u16 temp;
657
658 temp = ((0x00ff << (index / 3)) & 0xff00) >> 8;
659
660 return temp | (temp << 8) | (temp << 16) | (temp << 24);
661}
662
Chris Packham1a07d212018-05-10 13:28:29 +1200663u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100664{
Chris Packham4bf81db2018-12-03 14:26:49 +1300665 u32 pattern = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200666 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100667
668 if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
Chris Packham1a07d212018-05-10 13:28:29 +1200669 /* 32/64-bit patterns */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100670 switch (type) {
671 case PATTERN_PBS1:
672 case PATTERN_PBS2:
673 if (index == 0 || index == 2 || index == 5 ||
674 index == 7)
675 pattern = PATTERN_55;
676 else
677 pattern = PATTERN_AA;
678 break;
679 case PATTERN_PBS3:
680 if (0 == (index & 1))
681 pattern = PATTERN_55;
682 else
683 pattern = PATTERN_AA;
684 break;
685 case PATTERN_RL:
686 if (index < 6)
687 pattern = PATTERN_00;
688 else
689 pattern = PATTERN_80;
690 break;
691 case PATTERN_STATIC_PBS:
692 pattern = pattern_table_get_static_pbs_word(index);
693 break;
694 case PATTERN_KILLER_DQ0:
695 case PATTERN_KILLER_DQ1:
696 case PATTERN_KILLER_DQ2:
697 case PATTERN_KILLER_DQ3:
698 case PATTERN_KILLER_DQ4:
699 case PATTERN_KILLER_DQ5:
700 case PATTERN_KILLER_DQ6:
701 case PATTERN_KILLER_DQ7:
702 pattern = pattern_table_get_killer_word(
703 (u8)(type - PATTERN_KILLER_DQ0), index);
704 break;
705 case PATTERN_RL2:
706 if (index < 6)
707 pattern = PATTERN_00;
708 else
709 pattern = PATTERN_01;
710 break;
711 case PATTERN_TEST:
712 if (index > 1 && index < 6)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100713 pattern = PATTERN_00;
Chris Packham1a07d212018-05-10 13:28:29 +1200714 else
715 pattern = PATTERN_FF;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100716 break;
717 case PATTERN_FULL_SSO0:
718 case PATTERN_FULL_SSO1:
719 case PATTERN_FULL_SSO2:
720 case PATTERN_FULL_SSO3:
721 pattern = pattern_table_get_sso_word(
722 (u8)(type - PATTERN_FULL_SSO0), index);
723 break;
724 case PATTERN_VREF:
725 pattern = pattern_table_get_vref_word(index);
726 break;
Chris Packham1a07d212018-05-10 13:28:29 +1200727 case PATTERN_SSO_FULL_XTALK_DQ0:
728 case PATTERN_SSO_FULL_XTALK_DQ1:
729 case PATTERN_SSO_FULL_XTALK_DQ2:
730 case PATTERN_SSO_FULL_XTALK_DQ3:
731 case PATTERN_SSO_FULL_XTALK_DQ4:
732 case PATTERN_SSO_FULL_XTALK_DQ5:
733 case PATTERN_SSO_FULL_XTALK_DQ6:
734 case PATTERN_SSO_FULL_XTALK_DQ7:
735 pattern = pattern_table_get_sso_full_xtalk_word(
736 (u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
737 break;
738 case PATTERN_SSO_XTALK_FREE_DQ0:
739 case PATTERN_SSO_XTALK_FREE_DQ1:
740 case PATTERN_SSO_XTALK_FREE_DQ2:
741 case PATTERN_SSO_XTALK_FREE_DQ3:
742 case PATTERN_SSO_XTALK_FREE_DQ4:
743 case PATTERN_SSO_XTALK_FREE_DQ5:
744 case PATTERN_SSO_XTALK_FREE_DQ6:
745 case PATTERN_SSO_XTALK_FREE_DQ7:
746 pattern = pattern_table_get_sso_xtalk_free_word(
747 (u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
748 break;
749 case PATTERN_ISI_XTALK_FREE:
750 pattern = pattern_table_get_isi_word(index);
751 break;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100752 default:
Chris Packham4bf81db2018-12-03 14:26:49 +1300753 printf("error: %s: unsupported pattern type [%d] found\n",
754 __func__, (int)type);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100755 pattern = 0;
756 break;
757 }
758 } else {
759 /* 16bit patterns */
760 switch (type) {
761 case PATTERN_PBS1:
762 case PATTERN_PBS2:
763 case PATTERN_PBS3:
764 pattern = PATTERN_55AA;
765 break;
766 case PATTERN_RL:
767 if (index < 3)
768 pattern = PATTERN_00;
769 else
770 pattern = PATTERN_80;
771 break;
772 case PATTERN_STATIC_PBS:
773 pattern = PATTERN_00FF;
774 break;
775 case PATTERN_KILLER_DQ0:
776 case PATTERN_KILLER_DQ1:
777 case PATTERN_KILLER_DQ2:
778 case PATTERN_KILLER_DQ3:
779 case PATTERN_KILLER_DQ4:
780 case PATTERN_KILLER_DQ5:
781 case PATTERN_KILLER_DQ6:
782 case PATTERN_KILLER_DQ7:
783 pattern = pattern_table_get_killer_word16(
784 (u8)(type - PATTERN_KILLER_DQ0), index);
785 break;
786 case PATTERN_RL2:
787 if (index < 3)
788 pattern = PATTERN_00;
789 else
790 pattern = PATTERN_01;
791 break;
792 case PATTERN_TEST:
Chris Packham1a07d212018-05-10 13:28:29 +1200793 if ((index == 0) || (index == 3))
794 pattern = 0x00000000;
795 else
796 pattern = 0xFFFFFFFF;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100797 break;
798 case PATTERN_FULL_SSO0:
799 pattern = 0x0000ffff;
800 break;
801 case PATTERN_FULL_SSO1:
802 case PATTERN_FULL_SSO2:
803 case PATTERN_FULL_SSO3:
804 pattern = pattern_table_get_sso_word(
805 (u8)(type - PATTERN_FULL_SSO1), index);
806 break;
807 case PATTERN_VREF:
808 pattern = pattern_table_get_vref_word16(index);
809 break;
Chris Packham1a07d212018-05-10 13:28:29 +1200810 case PATTERN_SSO_FULL_XTALK_DQ0:
811 case PATTERN_SSO_FULL_XTALK_DQ1:
812 case PATTERN_SSO_FULL_XTALK_DQ2:
813 case PATTERN_SSO_FULL_XTALK_DQ3:
814 case PATTERN_SSO_FULL_XTALK_DQ4:
815 case PATTERN_SSO_FULL_XTALK_DQ5:
816 case PATTERN_SSO_FULL_XTALK_DQ6:
817 case PATTERN_SSO_FULL_XTALK_DQ7:
818 pattern = pattern_table_get_sso_full_xtalk_word16(
819 (u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
820 break;
821 case PATTERN_SSO_XTALK_FREE_DQ0:
822 case PATTERN_SSO_XTALK_FREE_DQ1:
823 case PATTERN_SSO_XTALK_FREE_DQ2:
824 case PATTERN_SSO_XTALK_FREE_DQ3:
825 case PATTERN_SSO_XTALK_FREE_DQ4:
826 case PATTERN_SSO_XTALK_FREE_DQ5:
827 case PATTERN_SSO_XTALK_FREE_DQ6:
828 case PATTERN_SSO_XTALK_FREE_DQ7:
829 pattern = pattern_table_get_sso_xtalk_free_word16(
830 (u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
831 break;
832 case PATTERN_ISI_XTALK_FREE:
833 pattern = pattern_table_get_isi_word16(index);
834 break;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100835 default:
Chris Packham4bf81db2018-12-03 14:26:49 +1300836 printf("error: %s: unsupported pattern type [%d] found\n",
837 __func__, (int)type);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100838 pattern = 0;
839 break;
840 }
841 }
842
843 return pattern;
844}
Chris Packham1a07d212018-05-10 13:28:29 +1200845
846/* Device attribute functions */
847void ddr3_tip_dev_attr_init(u32 dev_num)
848{
849 u32 attr_id;
850
851 for (attr_id = 0; attr_id < MV_ATTR_LAST; attr_id++)
Chris Packham4bf81db2018-12-03 14:26:49 +1300852 ddr_dev_attributes[attr_id] = 0xFF;
Chris Packham1a07d212018-05-10 13:28:29 +1200853
Chris Packham4bf81db2018-12-03 14:26:49 +1300854 ddr_dev_attr_init_done = 1;
Chris Packham1a07d212018-05-10 13:28:29 +1200855}
856
857u32 ddr3_tip_dev_attr_get(u32 dev_num, enum mv_ddr_dev_attribute attr_id)
858{
Chris Packham4bf81db2018-12-03 14:26:49 +1300859 if (ddr_dev_attr_init_done == 0)
Chris Packham1a07d212018-05-10 13:28:29 +1200860 ddr3_tip_dev_attr_init(dev_num);
861
Chris Packham4bf81db2018-12-03 14:26:49 +1300862 return ddr_dev_attributes[attr_id];
Chris Packham1a07d212018-05-10 13:28:29 +1200863}
864
865void ddr3_tip_dev_attr_set(u32 dev_num, enum mv_ddr_dev_attribute attr_id, u32 value)
866{
Chris Packham4bf81db2018-12-03 14:26:49 +1300867 if (ddr_dev_attr_init_done == 0)
Chris Packham1a07d212018-05-10 13:28:29 +1200868 ddr3_tip_dev_attr_init(dev_num);
869
Chris Packham4bf81db2018-12-03 14:26:49 +1300870 ddr_dev_attributes[attr_id] = value;
Chris Packham1a07d212018-05-10 13:28:29 +1200871}