blob: 22e0cc4d9176068cbda2667964c5e407c71cb75c [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"
Chris Packham4bf81db2018-12-03 14:26:49 +13007#include "mv_ddr_training_db.h"
8#include "mv_ddr_regs.h"
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Stefan Roese5ffceb82015-03-26 15:36:56 +010010
11u8 is_reg_dump = 0;
12u8 debug_pbs = DEBUG_LEVEL_ERROR;
13
14/*
15 * API to change flags outside of the lib
16 */
Chris Packham1a07d212018-05-10 13:28:29 +120017#if defined(SILENT_LIB)
18void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level)
19{
20 /* do nothing */
21}
22#else /* SILENT_LIB */
Stefan Roese5ffceb82015-03-26 15:36:56 +010023/* Debug flags for other Training modules */
24u8 debug_training_static = DEBUG_LEVEL_ERROR;
25u8 debug_training = DEBUG_LEVEL_ERROR;
26u8 debug_leveling = DEBUG_LEVEL_ERROR;
27u8 debug_centralization = DEBUG_LEVEL_ERROR;
28u8 debug_training_ip = DEBUG_LEVEL_ERROR;
29u8 debug_training_bist = DEBUG_LEVEL_ERROR;
30u8 debug_training_hw_alg = DEBUG_LEVEL_ERROR;
31u8 debug_training_access = DEBUG_LEVEL_ERROR;
Chris Packham1a07d212018-05-10 13:28:29 +120032u8 debug_training_device = DEBUG_LEVEL_ERROR;
33
34
35void mv_ddr_user_log_level_set(enum ddr_lib_debug_block block)
36{
37 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
38 ddr3_hws_set_log_level(block, tm->debug_level);
39};
Stefan Roese5ffceb82015-03-26 15:36:56 +010040
41void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level)
42{
43 switch (block) {
44 case DEBUG_BLOCK_STATIC:
45 debug_training_static = level;
46 break;
47 case DEBUG_BLOCK_TRAINING_MAIN:
48 debug_training = level;
49 break;
50 case DEBUG_BLOCK_LEVELING:
51 debug_leveling = level;
52 break;
53 case DEBUG_BLOCK_CENTRALIZATION:
54 debug_centralization = level;
55 break;
56 case DEBUG_BLOCK_PBS:
57 debug_pbs = level;
58 break;
59 case DEBUG_BLOCK_ALG:
60 debug_training_hw_alg = level;
61 break;
62 case DEBUG_BLOCK_DEVICE:
Chris Packham1a07d212018-05-10 13:28:29 +120063 debug_training_device = level;
Stefan Roese5ffceb82015-03-26 15:36:56 +010064 break;
65 case DEBUG_BLOCK_ACCESS:
66 debug_training_access = level;
67 break;
68 case DEBUG_STAGES_REG_DUMP:
69 if (level == DEBUG_LEVEL_TRACE)
70 is_reg_dump = 1;
71 else
72 is_reg_dump = 0;
73 break;
74 case DEBUG_BLOCK_ALL:
75 default:
76 debug_training_static = level;
77 debug_training = level;
78 debug_leveling = level;
79 debug_centralization = level;
80 debug_pbs = level;
81 debug_training_hw_alg = level;
82 debug_training_access = level;
Chris Packham1a07d212018-05-10 13:28:29 +120083 debug_training_device = level;
Stefan Roese5ffceb82015-03-26 15:36:56 +010084 }
85}
Chris Packham1a07d212018-05-10 13:28:29 +120086#endif /* SILENT_LIB */
Stefan Roese5ffceb82015-03-26 15:36:56 +010087
Chris Packham1a07d212018-05-10 13:28:29 +120088#if defined(DDR_VIEWER_TOOL)
Chris Packham4bf81db2018-12-03 14:26:49 +130089static char *convert_freq(enum mv_ddr_freq freq);
Chris Packham1a07d212018-05-10 13:28:29 +120090#if defined(EXCLUDE_SWITCH_DEBUG)
91u32 ctrl_sweepres[ADLL_LENGTH][MAX_INTERFACE_NUM][MAX_BUS_NUM];
92u32 ctrl_adll[MAX_CS_NUM * MAX_INTERFACE_NUM * MAX_BUS_NUM];
93u32 ctrl_adll1[MAX_CS_NUM * MAX_INTERFACE_NUM * MAX_BUS_NUM];
94u32 ctrl_level_phase[MAX_CS_NUM * MAX_INTERFACE_NUM * MAX_BUS_NUM];
95#endif /* EXCLUDE_SWITCH_DEBUG */
96#endif /* DDR_VIEWER_TOOL */
97
98struct hws_tip_config_func_db config_func_info[MAX_DEVICE_NUM];
Stefan Roese5ffceb82015-03-26 15:36:56 +010099u8 is_default_centralization = 0;
100u8 is_tune_result = 0;
101u8 is_validate_window_per_if = 0;
102u8 is_validate_window_per_pup = 0;
103u8 sweep_cnt = 1;
104u32 is_bist_reset_bit = 1;
Chris Packham1a07d212018-05-10 13:28:29 +1200105u8 is_run_leveling_sweep_tests;
106
107static struct hws_xsb_info xsb_info[MAX_DEVICE_NUM];
Stefan Roese5ffceb82015-03-26 15:36:56 +0100108
109/*
110 * Dump Dunit & Phy registers
111 */
112int ddr3_tip_reg_dump(u32 dev_num)
113{
114 u32 if_id, reg_addr, data_value, bus_id;
115 u32 read_data[MAX_INTERFACE_NUM];
Chris Packham1a07d212018-05-10 13:28:29 +1200116 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
117 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100118
119 printf("-- dunit registers --\n");
120 for (reg_addr = 0x1400; reg_addr < 0x19f0; reg_addr += 4) {
121 printf("0x%x ", reg_addr);
122 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200123 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100124 CHECK_STATUS(ddr3_tip_if_read
125 (dev_num, ACCESS_TYPE_UNICAST,
126 if_id, reg_addr, read_data,
127 MASK_ALL_BITS));
128 printf("0x%x ", read_data[if_id]);
129 }
130 printf("\n");
131 }
132
133 printf("-- Phy registers --\n");
134 for (reg_addr = 0; reg_addr <= 0xff; reg_addr++) {
135 printf("0x%x ", reg_addr);
136 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200137 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100138 for (bus_id = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200139 bus_id < octets_per_if_num;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100140 bus_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200141 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100142 CHECK_STATUS(ddr3_tip_bus_read
143 (dev_num, if_id,
144 ACCESS_TYPE_UNICAST, bus_id,
145 DDR_PHY_DATA, reg_addr,
146 &data_value));
147 printf("0x%x ", data_value);
148 }
149 for (bus_id = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200150 bus_id < octets_per_if_num;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100151 bus_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200152 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100153 CHECK_STATUS(ddr3_tip_bus_read
154 (dev_num, if_id,
155 ACCESS_TYPE_UNICAST, bus_id,
156 DDR_PHY_CONTROL, reg_addr,
157 &data_value));
158 printf("0x%x ", data_value);
159 }
160 }
161 printf("\n");
162 }
163
164 return MV_OK;
165}
166
167/*
168 * Register access func registration
169 */
170int ddr3_tip_init_config_func(u32 dev_num,
171 struct hws_tip_config_func_db *config_func)
172{
173 if (config_func == NULL)
174 return MV_BAD_PARAM;
175
176 memcpy(&config_func_info[dev_num], config_func,
177 sizeof(struct hws_tip_config_func_db));
178
179 return MV_OK;
180}
181
182/*
Stefan Roese5ffceb82015-03-26 15:36:56 +0100183 * Get training result info pointer
184 */
185enum hws_result *ddr3_tip_get_result_ptr(u32 stage)
186{
187 return training_result[stage];
188}
189
190/*
191 * Device info read
192 */
193int ddr3_tip_get_device_info(u32 dev_num, struct ddr3_device_info *info_ptr)
194{
195 if (config_func_info[dev_num].tip_get_device_info_func != NULL) {
196 return config_func_info[dev_num].
197 tip_get_device_info_func((u8) dev_num, info_ptr);
198 }
199
200 return MV_FAIL;
201}
202
Chris Packham1a07d212018-05-10 13:28:29 +1200203#if defined(DDR_VIEWER_TOOL)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100204/*
205 * Convert freq to character string
206 */
Chris Packham4bf81db2018-12-03 14:26:49 +1300207static char *convert_freq(enum mv_ddr_freq freq)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100208{
209 switch (freq) {
Chris Packham4bf81db2018-12-03 14:26:49 +1300210 case MV_DDR_FREQ_LOW_FREQ:
211 return "MV_DDR_FREQ_LOW_FREQ";
Chris Packham1a07d212018-05-10 13:28:29 +1200212
Chris Packham4bf81db2018-12-03 14:26:49 +1300213 case MV_DDR_FREQ_400:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100214 return "400";
215
Chris Packham4bf81db2018-12-03 14:26:49 +1300216 case MV_DDR_FREQ_533:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100217 return "533";
Chris Packham1a07d212018-05-10 13:28:29 +1200218
Chris Packham4bf81db2018-12-03 14:26:49 +1300219 case MV_DDR_FREQ_667:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100220 return "667";
221
Chris Packham4bf81db2018-12-03 14:26:49 +1300222 case MV_DDR_FREQ_800:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100223 return "800";
224
Chris Packham4bf81db2018-12-03 14:26:49 +1300225 case MV_DDR_FREQ_933:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100226 return "933";
227
Chris Packham4bf81db2018-12-03 14:26:49 +1300228 case MV_DDR_FREQ_1066:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100229 return "1066";
Chris Packham1a07d212018-05-10 13:28:29 +1200230
Chris Packham4bf81db2018-12-03 14:26:49 +1300231 case MV_DDR_FREQ_311:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100232 return "311";
233
Chris Packham4bf81db2018-12-03 14:26:49 +1300234 case MV_DDR_FREQ_333:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100235 return "333";
236
Chris Packham4bf81db2018-12-03 14:26:49 +1300237 case MV_DDR_FREQ_467:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100238 return "467";
239
Chris Packham4bf81db2018-12-03 14:26:49 +1300240 case MV_DDR_FREQ_850:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100241 return "850";
242
Chris Packham4bf81db2018-12-03 14:26:49 +1300243 case MV_DDR_FREQ_900:
Stefan Roese5ffceb82015-03-26 15:36:56 +0100244 return "900";
245
Chris Packham4bf81db2018-12-03 14:26:49 +1300246 case MV_DDR_FREQ_360:
247 return "MV_DDR_FREQ_360";
Stefan Roese5ffceb82015-03-26 15:36:56 +0100248
Chris Packham4bf81db2018-12-03 14:26:49 +1300249 case MV_DDR_FREQ_1000:
250 return "MV_DDR_FREQ_1000";
Chris Packham1a07d212018-05-10 13:28:29 +1200251
Stefan Roese5ffceb82015-03-26 15:36:56 +0100252 default:
253 return "Unknown Frequency";
254 }
255}
256
257/*
258 * Convert device ID to character string
259 */
260static char *convert_dev_id(u32 dev_id)
261{
262 switch (dev_id) {
263 case 0x6800:
264 return "A38xx";
265 case 0x6900:
266 return "A39XX";
267 case 0xf400:
268 return "AC3";
269 case 0xfc00:
270 return "BC2";
271
272 default:
273 return "Unknown Device";
274 }
275}
276
277/*
278 * Convert device ID to character string
279 */
280static char *convert_mem_size(u32 dev_id)
281{
282 switch (dev_id) {
283 case 0:
284 return "512 MB";
285 case 1:
286 return "1 GB";
287 case 2:
288 return "2 GB";
289 case 3:
290 return "4 GB";
291 case 4:
292 return "8 GB";
293
294 default:
295 return "wrong mem size";
296 }
297}
298
299int print_device_info(u8 dev_num)
300{
301 struct ddr3_device_info info_ptr;
Chris Packham1a07d212018-05-10 13:28:29 +1200302 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100303
304 CHECK_STATUS(ddr3_tip_get_device_info(dev_num, &info_ptr));
305 printf("=== DDR setup START===\n");
306 printf("\tDevice ID: %s\n", convert_dev_id(info_ptr.device_id));
307 printf("\tDDR3 CK delay: %d\n", info_ptr.ck_delay);
308 print_topology(tm);
309 printf("=== DDR setup END===\n");
310
311 return MV_OK;
312}
313
314void hws_ddr3_tip_sweep_test(int enable)
315{
316 if (enable) {
317 is_validate_window_per_if = 1;
318 is_validate_window_per_pup = 1;
319 debug_training = DEBUG_LEVEL_TRACE;
320 } else {
321 is_validate_window_per_if = 0;
322 is_validate_window_per_pup = 0;
323 }
324}
Chris Packham1a07d212018-05-10 13:28:29 +1200325#endif /* DDR_VIEWER_TOOL */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100326
327char *ddr3_tip_convert_tune_result(enum hws_result tune_result)
328{
329 switch (tune_result) {
330 case TEST_FAILED:
331 return "FAILED";
332 case TEST_SUCCESS:
333 return "PASS";
334 case NO_TEST_DONE:
335 return "NOT COMPLETED";
336 default:
337 return "Un-KNOWN";
338 }
339}
340
341/*
342 * Print log info
343 */
344int ddr3_tip_print_log(u32 dev_num, u32 mem_addr)
345{
346 u32 if_id = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200347 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100348
Chris Packham1a07d212018-05-10 13:28:29 +1200349#if defined(DDR_VIEWER_TOOL)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100350 if ((is_validate_window_per_if != 0) ||
351 (is_validate_window_per_pup != 0)) {
352 u32 is_pup_log = 0;
Chris Packham4bf81db2018-12-03 14:26:49 +1300353 enum mv_ddr_freq freq;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100354
355 freq = tm->interface_params[first_active_if].memory_freq;
356
357 is_pup_log = (is_validate_window_per_pup != 0) ? 1 : 0;
358 printf("===VALIDATE WINDOW LOG START===\n");
359 printf("DDR Frequency: %s ======\n", convert_freq(freq));
360 /* print sweep windows */
361 ddr3_tip_run_sweep_test(dev_num, sweep_cnt, 1, is_pup_log);
362 ddr3_tip_run_sweep_test(dev_num, sweep_cnt, 0, is_pup_log);
Chris Packham1a07d212018-05-10 13:28:29 +1200363#if defined(EXCLUDE_SWITCH_DEBUG)
364 if (is_run_leveling_sweep_tests == 1) {
365 ddr3_tip_run_leveling_sweep_test(dev_num, sweep_cnt, 0, is_pup_log);
366 ddr3_tip_run_leveling_sweep_test(dev_num, sweep_cnt, 1, is_pup_log);
367 }
368#endif /* EXCLUDE_SWITCH_DEBUG */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100369 ddr3_tip_print_all_pbs_result(dev_num);
370 ddr3_tip_print_wl_supp_result(dev_num);
371 printf("===VALIDATE WINDOW LOG END ===\n");
372 CHECK_STATUS(ddr3_tip_restore_dunit_regs(dev_num));
373 ddr3_tip_reg_dump(dev_num);
374 }
Chris Packham1a07d212018-05-10 13:28:29 +1200375#endif /* DDR_VIEWER_TOOL */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100376
377 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200378 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100379
380 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
381 ("IF %d Status:\n", if_id));
382
383 if (mask_tune_func & INIT_CONTROLLER_MASK_BIT) {
384 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
385 ("\tInit Controller: %s\n",
386 ddr3_tip_convert_tune_result
387 (training_result[INIT_CONTROLLER]
388 [if_id])));
389 }
390 if (mask_tune_func & SET_LOW_FREQ_MASK_BIT) {
391 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
392 ("\tLow freq Config: %s\n",
393 ddr3_tip_convert_tune_result
394 (training_result[SET_LOW_FREQ]
395 [if_id])));
396 }
397 if (mask_tune_func & LOAD_PATTERN_MASK_BIT) {
398 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
399 ("\tLoad Pattern: %s\n",
400 ddr3_tip_convert_tune_result
401 (training_result[LOAD_PATTERN]
402 [if_id])));
403 }
404 if (mask_tune_func & SET_MEDIUM_FREQ_MASK_BIT) {
405 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
406 ("\tMedium freq Config: %s\n",
407 ddr3_tip_convert_tune_result
408 (training_result[SET_MEDIUM_FREQ]
409 [if_id])));
410 }
411 if (mask_tune_func & WRITE_LEVELING_MASK_BIT) {
412 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
413 ("\tWL: %s\n",
414 ddr3_tip_convert_tune_result
415 (training_result[WRITE_LEVELING]
416 [if_id])));
417 }
418 if (mask_tune_func & LOAD_PATTERN_2_MASK_BIT) {
419 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
420 ("\tLoad Pattern: %s\n",
421 ddr3_tip_convert_tune_result
422 (training_result[LOAD_PATTERN_2]
423 [if_id])));
424 }
425 if (mask_tune_func & READ_LEVELING_MASK_BIT) {
426 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
427 ("\tRL: %s\n",
428 ddr3_tip_convert_tune_result
429 (training_result[READ_LEVELING]
430 [if_id])));
431 }
432 if (mask_tune_func & WRITE_LEVELING_SUPP_MASK_BIT) {
433 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
434 ("\tWL Supp: %s\n",
435 ddr3_tip_convert_tune_result
436 (training_result[WRITE_LEVELING_SUPP]
437 [if_id])));
438 }
439 if (mask_tune_func & PBS_RX_MASK_BIT) {
440 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
441 ("\tPBS RX: %s\n",
442 ddr3_tip_convert_tune_result
443 (training_result[PBS_RX]
444 [if_id])));
445 }
446 if (mask_tune_func & PBS_TX_MASK_BIT) {
447 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
448 ("\tPBS TX: %s\n",
449 ddr3_tip_convert_tune_result
450 (training_result[PBS_TX]
451 [if_id])));
452 }
453 if (mask_tune_func & SET_TARGET_FREQ_MASK_BIT) {
454 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
455 ("\tTarget freq Config: %s\n",
456 ddr3_tip_convert_tune_result
457 (training_result[SET_TARGET_FREQ]
458 [if_id])));
459 }
460 if (mask_tune_func & WRITE_LEVELING_TF_MASK_BIT) {
461 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
462 ("\tWL TF: %s\n",
463 ddr3_tip_convert_tune_result
464 (training_result[WRITE_LEVELING_TF]
465 [if_id])));
466 }
467 if (mask_tune_func & READ_LEVELING_TF_MASK_BIT) {
468 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
469 ("\tRL TF: %s\n",
470 ddr3_tip_convert_tune_result
471 (training_result[READ_LEVELING_TF]
472 [if_id])));
473 }
474 if (mask_tune_func & WRITE_LEVELING_SUPP_TF_MASK_BIT) {
475 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
476 ("\tWL TF Supp: %s\n",
477 ddr3_tip_convert_tune_result
478 (training_result
479 [WRITE_LEVELING_SUPP_TF]
480 [if_id])));
481 }
482 if (mask_tune_func & CENTRALIZATION_RX_MASK_BIT) {
483 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
484 ("\tCentr RX: %s\n",
485 ddr3_tip_convert_tune_result
486 (training_result[CENTRALIZATION_RX]
487 [if_id])));
488 }
489 if (mask_tune_func & VREF_CALIBRATION_MASK_BIT) {
490 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
491 ("\tVREF_CALIBRATION: %s\n",
492 ddr3_tip_convert_tune_result
493 (training_result[VREF_CALIBRATION]
494 [if_id])));
495 }
496 if (mask_tune_func & CENTRALIZATION_TX_MASK_BIT) {
497 DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
498 ("\tCentr TX: %s\n",
499 ddr3_tip_convert_tune_result
500 (training_result[CENTRALIZATION_TX]
501 [if_id])));
502 }
503 }
504
505 return MV_OK;
506}
507
Chris Packham1a07d212018-05-10 13:28:29 +1200508#if !defined(EXCLUDE_DEBUG_PRINTS)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100509/*
510 * Print stability log info
511 */
512int ddr3_tip_print_stability_log(u32 dev_num)
513{
514 u8 if_id = 0, csindex = 0, bus_id = 0, idx = 0;
515 u32 reg_data;
516 u32 read_data[MAX_INTERFACE_NUM];
Chris Packham4bf81db2018-12-03 14:26:49 +1300517 unsigned int max_cs = mv_ddr_cs_num_get();
Chris Packham1a07d212018-05-10 13:28:29 +1200518 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100519
520 /* Title print */
521 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200522 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100523 printf("Title: I/F# , Tj, Calibration_n0, Calibration_p0, Calibration_n1, Calibration_p1, Calibration_n2, Calibration_p2,");
524 for (csindex = 0; csindex < max_cs; csindex++) {
525 printf("CS%d , ", csindex);
526 printf("\n");
Chris Packham1a07d212018-05-10 13:28:29 +1200527 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100528 printf("VWTx, VWRx, WL_tot, WL_ADLL, WL_PH, RL_Tot, RL_ADLL, RL_PH, RL_Smp, Cen_tx, Cen_rx, Vref, DQVref,");
529 printf("\t\t");
530 for (idx = 0; idx < 11; idx++)
531 printf("PBSTx-Pad%d,", idx);
532 printf("\t\t");
533 for (idx = 0; idx < 11; idx++)
534 printf("PBSRx-Pad%d,", idx);
535 }
536 }
537 printf("\n");
538
539 /* Data print */
540 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200541 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100542
543 printf("Data: %d,%d,", if_id,
544 (config_func_info[dev_num].tip_get_temperature != NULL)
545 ? (config_func_info[dev_num].
546 tip_get_temperature(dev_num)) : (0));
547
548 CHECK_STATUS(ddr3_tip_if_read
549 (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x14c8,
550 read_data, MASK_ALL_BITS));
551 printf("%d,%d,", ((read_data[if_id] & 0x3f0) >> 4),
552 ((read_data[if_id] & 0xfc00) >> 10));
553 CHECK_STATUS(ddr3_tip_if_read
554 (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x17c8,
555 read_data, MASK_ALL_BITS));
556 printf("%d,%d,", ((read_data[if_id] & 0x3f0) >> 4),
557 ((read_data[if_id] & 0xfc00) >> 10));
558 CHECK_STATUS(ddr3_tip_if_read
559 (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1dc8,
560 read_data, MASK_ALL_BITS));
561 printf("%d,%d,", ((read_data[if_id] & 0x3f0000) >> 16),
562 ((read_data[if_id] & 0xfc00000) >> 22));
563
564 for (csindex = 0; csindex < max_cs; csindex++) {
565 printf("CS%d , ", csindex);
566 for (bus_id = 0; bus_id < MAX_BUS_NUM; bus_id++) {
567 printf("\n");
Chris Packham1a07d212018-05-10 13:28:29 +1200568 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100569 ddr3_tip_bus_read(dev_num, if_id,
570 ACCESS_TYPE_UNICAST,
571 bus_id, DDR_PHY_DATA,
Chris Packham1a07d212018-05-10 13:28:29 +1200572 RESULT_PHY_REG +
Stefan Roese5ffceb82015-03-26 15:36:56 +0100573 csindex, &reg_data);
574 printf("%d,%d,", (reg_data & 0x1f),
575 ((reg_data & 0x3e0) >> 5));
576 /* WL */
577 ddr3_tip_bus_read(dev_num, if_id,
578 ACCESS_TYPE_UNICAST,
579 bus_id, DDR_PHY_DATA,
Chris Packham1a07d212018-05-10 13:28:29 +1200580 WL_PHY_REG(csindex),
581 &reg_data);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100582 printf("%d,%d,%d,",
583 (reg_data & 0x1f) +
584 ((reg_data & 0x1c0) >> 6) * 32,
585 (reg_data & 0x1f),
586 (reg_data & 0x1c0) >> 6);
587 /* RL */
588 CHECK_STATUS(ddr3_tip_if_read
589 (dev_num, ACCESS_TYPE_UNICAST,
590 if_id,
Chris Packham1a07d212018-05-10 13:28:29 +1200591 RD_DATA_SMPL_DLYS_REG,
Stefan Roese5ffceb82015-03-26 15:36:56 +0100592 read_data, MASK_ALL_BITS));
593 read_data[if_id] =
594 (read_data[if_id] &
Chris Packham1a07d212018-05-10 13:28:29 +1200595 (0x1f << (8 * csindex))) >>
596 (8 * csindex);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100597 ddr3_tip_bus_read(dev_num, if_id,
598 ACCESS_TYPE_UNICAST, bus_id,
599 DDR_PHY_DATA,
Chris Packham1a07d212018-05-10 13:28:29 +1200600 RL_PHY_REG(csindex),
Stefan Roese5ffceb82015-03-26 15:36:56 +0100601 &reg_data);
602 printf("%d,%d,%d,%d,",
603 (reg_data & 0x1f) +
604 ((reg_data & 0x1c0) >> 6) * 32 +
605 read_data[if_id] * 64,
606 (reg_data & 0x1f),
607 ((reg_data & 0x1c0) >> 6),
608 read_data[if_id]);
609 /* Centralization */
610 ddr3_tip_bus_read(dev_num, if_id,
611 ACCESS_TYPE_UNICAST, bus_id,
612 DDR_PHY_DATA,
Chris Packham1a07d212018-05-10 13:28:29 +1200613 CTX_PHY_REG(csindex),
614 &reg_data);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100615 printf("%d,", (reg_data & 0x3f));
616 ddr3_tip_bus_read(dev_num, if_id,
617 ACCESS_TYPE_UNICAST, bus_id,
618 DDR_PHY_DATA,
Chris Packham1a07d212018-05-10 13:28:29 +1200619 CRX_PHY_REG(csindex),
620 &reg_data);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100621 printf("%d,", (reg_data & 0x1f));
622 /* Vref */
623 ddr3_tip_bus_read(dev_num, if_id,
624 ACCESS_TYPE_UNICAST, bus_id,
625 DDR_PHY_DATA,
Chris Packham1a07d212018-05-10 13:28:29 +1200626 PAD_CFG_PHY_REG,
Stefan Roese5ffceb82015-03-26 15:36:56 +0100627 &reg_data);
628 printf("%d,", (reg_data & 0x7));
629 /* DQVref */
630 /* Need to add the Read Function from device */
631 printf("%d,", 0);
632 printf("\t\t");
633 for (idx = 0; idx < 11; idx++) {
634 ddr3_tip_bus_read(dev_num, if_id,
635 ACCESS_TYPE_UNICAST,
636 bus_id, DDR_PHY_DATA,
Stefan Roese5ffceb82015-03-26 15:36:56 +0100637 0x10 +
638 16 * csindex +
639 idx, &reg_data);
640 printf("%d,", (reg_data & 0x3f));
641 }
642 printf("\t\t");
643 for (idx = 0; idx < 11; idx++) {
644 ddr3_tip_bus_read(dev_num, if_id,
645 ACCESS_TYPE_UNICAST,
646 bus_id, DDR_PHY_DATA,
647 0x50 +
648 16 * csindex +
649 idx, &reg_data);
650 printf("%d,", (reg_data & 0x3f));
651 }
652 }
653 }
654 }
655 printf("\n");
656
657 return MV_OK;
658}
Chris Packham1a07d212018-05-10 13:28:29 +1200659#endif /* EXCLUDE_DEBUG_PRINTS */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100660
661/*
662 * Register XSB information
663 */
664int ddr3_tip_register_xsb_info(u32 dev_num, struct hws_xsb_info *xsb_info_table)
665{
666 memcpy(&xsb_info[dev_num], xsb_info_table, sizeof(struct hws_xsb_info));
667 return MV_OK;
668}
669
670/*
671 * Read ADLL Value
672 */
Chris Packham1a07d212018-05-10 13:28:29 +1200673int ddr3_tip_read_adll_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
674 u32 reg_addr, u32 mask)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100675{
676 u32 data_value;
677 u32 if_id = 0, bus_id = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200678 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
679 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100680
681 /*
682 * multi CS support - reg_addr is calucalated in calling function
683 * with CS offset
684 */
685 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200686 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
687 for (bus_id = 0; bus_id < octets_per_if_num;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100688 bus_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200689 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100690 CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id,
691 ACCESS_TYPE_UNICAST,
692 bus_id,
693 DDR_PHY_DATA, reg_addr,
694 &data_value));
695 pup_values[if_id *
Chris Packham1a07d212018-05-10 13:28:29 +1200696 octets_per_if_num + bus_id] =
Stefan Roese5ffceb82015-03-26 15:36:56 +0100697 data_value & mask;
698 }
699 }
700
701 return 0;
702}
703
704/*
705 * Write ADLL Value
706 */
Chris Packham1a07d212018-05-10 13:28:29 +1200707int ddr3_tip_write_adll_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
708 u32 reg_addr)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100709{
710 u32 if_id = 0, bus_id = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200711 u32 data;
712 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
713 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100714
715 /*
716 * multi CS support - reg_addr is calucalated in calling function
717 * with CS offset
718 */
719 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200720 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
721 for (bus_id = 0; bus_id < octets_per_if_num;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100722 bus_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200723 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100724 data = pup_values[if_id *
Chris Packham1a07d212018-05-10 13:28:29 +1200725 octets_per_if_num +
Stefan Roese5ffceb82015-03-26 15:36:56 +0100726 bus_id];
727 CHECK_STATUS(ddr3_tip_bus_write(dev_num,
728 ACCESS_TYPE_UNICAST,
729 if_id,
730 ACCESS_TYPE_UNICAST,
731 bus_id, DDR_PHY_DATA,
732 reg_addr, data));
733 }
734 }
735
736 return 0;
737}
738
Chris Packham1a07d212018-05-10 13:28:29 +1200739/**
740 * Read Phase Value
741 */
742int read_phase_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
743 int reg_addr, u32 mask)
744{
745 u32 data_value;
746 u32 if_id = 0, bus_id = 0;
747 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
748 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
749
750 /* multi CS support - reg_addr is calucalated in calling function with CS offset */
751 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
752 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
753 for (bus_id = 0; bus_id < octets_per_if_num; bus_id++) {
754 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
755 CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id,
756 ACCESS_TYPE_UNICAST,
757 bus_id,
758 DDR_PHY_DATA, reg_addr,
759 &data_value));
760 pup_values[if_id * octets_per_if_num + bus_id] = data_value & mask;
761 }
762 }
763
764 return 0;
765}
766
767/**
768 * Write Leveling Value
769 */
770int write_leveling_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
771 u32 pup_ph_values[MAX_INTERFACE_NUM * MAX_BUS_NUM], int reg_addr)
772{
773 u32 if_id = 0, bus_id = 0;
774 u32 data;
775 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
776 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
777
778 /* multi CS support - reg_addr is calucalated in calling function with CS offset */
779 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
780 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
781 for (bus_id = 0 ; bus_id < octets_per_if_num ; bus_id++) {
782 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
783 data = pup_values[if_id * octets_per_if_num + bus_id] +
784 pup_ph_values[if_id * octets_per_if_num + bus_id];
785 CHECK_STATUS(ddr3_tip_bus_write(dev_num,
786 ACCESS_TYPE_UNICAST,
787 if_id,
788 ACCESS_TYPE_UNICAST,
789 bus_id,
790 DDR_PHY_DATA,
791 reg_addr,
792 data));
793 }
794 }
795
796 return 0;
797}
798
799#if !defined(EXCLUDE_SWITCH_DEBUG)
800struct hws_tip_config_func_db config_func_info[MAX_DEVICE_NUM];
Stefan Roese5ffceb82015-03-26 15:36:56 +0100801u32 start_xsb_offset = 0;
802u8 is_rl_old = 0;
803u8 is_freq_old = 0;
804u8 is_dfs_disabled = 0;
805u32 default_centrlization_value = 0x12;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100806u32 activate_select_before_run_alg = 1, activate_deselect_after_run_alg = 1,
807 rl_test = 0, reset_read_fifo = 0;
808int debug_acc = 0;
809u32 ctrl_sweepres[ADLL_LENGTH][MAX_INTERFACE_NUM][MAX_BUS_NUM];
810u32 ctrl_adll[MAX_CS_NUM * MAX_INTERFACE_NUM * MAX_BUS_NUM];
Stefan Roese5ffceb82015-03-26 15:36:56 +0100811
812u32 xsb_test_table[][8] = {
813 {0x00000000, 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555,
814 0x66666666, 0x77777777},
815 {0x88888888, 0x99999999, 0xaaaaaaaa, 0xbbbbbbbb, 0xcccccccc, 0xdddddddd,
816 0xeeeeeeee, 0xffffffff},
817 {0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
818 0x00000000, 0xffffffff},
819 {0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
820 0x00000000, 0xffffffff},
821 {0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
822 0x00000000, 0xffffffff},
823 {0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
824 0x00000000, 0xffffffff},
825 {0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
826 0xffffffff, 0xffffffff},
827 {0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000,
828 0x00000000, 0x00000000},
829 {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
830 0xffffffff, 0xffffffff}
831};
832
Stefan Roese5ffceb82015-03-26 15:36:56 +0100833int ddr3_tip_print_adll(void)
834{
835 u32 bus_cnt = 0, if_id, data_p1, data_p2, ui_data3, dev_num = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200836 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
837 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100838
839 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200840 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
841 for (bus_cnt = 0; bus_cnt < octets_per_if_num;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100842 bus_cnt++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200843 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100844 CHECK_STATUS(ddr3_tip_bus_read
845 (dev_num, if_id,
846 ACCESS_TYPE_UNICAST, bus_cnt,
847 DDR_PHY_DATA, 0x1, &data_p1));
848 CHECK_STATUS(ddr3_tip_bus_read
849 (dev_num, if_id, ACCESS_TYPE_UNICAST,
850 bus_cnt, DDR_PHY_DATA, 0x2, &data_p2));
851 CHECK_STATUS(ddr3_tip_bus_read
852 (dev_num, if_id, ACCESS_TYPE_UNICAST,
853 bus_cnt, DDR_PHY_DATA, 0x3, &ui_data3));
854 DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
855 (" IF %d bus_cnt %d phy_reg_1_data 0x%x phy_reg_2_data 0x%x phy_reg_3_data 0x%x\n",
856 if_id, bus_cnt, data_p1, data_p2,
857 ui_data3));
858 }
859 }
860
861 return MV_OK;
862}
863
Chris Packham1a07d212018-05-10 13:28:29 +1200864#endif /* EXCLUDE_SWITCH_DEBUG */
865
866#if defined(DDR_VIEWER_TOOL)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100867/*
868 * Print ADLL
869 */
870int print_adll(u32 dev_num, u32 adll[MAX_INTERFACE_NUM * MAX_BUS_NUM])
871{
872 u32 i, j;
Chris Packham1a07d212018-05-10 13:28:29 +1200873 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
874 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +0100875
Chris Packham1a07d212018-05-10 13:28:29 +1200876 for (j = 0; j < octets_per_if_num; j++) {
877 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, j);
878 for (i = 0; i < MAX_INTERFACE_NUM; i++)
879 printf("%d ,", adll[i * octets_per_if_num + j]);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100880 }
881 printf("\n");
882
883 return MV_OK;
884}
Stefan Roese5ffceb82015-03-26 15:36:56 +0100885
Chris Packham1a07d212018-05-10 13:28:29 +1200886int print_ph(u32 dev_num, u32 adll[MAX_INTERFACE_NUM * MAX_BUS_NUM])
887{
888 u32 i, j;
889 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
890 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
891
892 for (j = 0; j < octets_per_if_num; j++) {
893 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, j);
894 for (i = 0; i < MAX_INTERFACE_NUM; i++)
895 printf("%d ,", adll[i * octets_per_if_num + j] >> 6);
896 }
897 printf("\n");
898
899 return MV_OK;
900}
901#endif /* DDR_VIEWER_TOOL */
902
903#if !defined(EXCLUDE_SWITCH_DEBUG)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100904/* byte_index - only byte 0, 1, 2, or 3, oxff - test all bytes */
905static u32 ddr3_tip_compare(u32 if_id, u32 *p_src, u32 *p_dst,
906 u32 byte_index)
907{
908 u32 burst_cnt = 0, addr_offset, i_id;
909 int b_is_fail = 0;
910
911 addr_offset =
912 (byte_index ==
913 0xff) ? (u32) 0xffffffff : (u32) (0xff << (byte_index * 8));
914 for (burst_cnt = 0; burst_cnt < EXT_ACCESS_BURST_LENGTH; burst_cnt++) {
915 if ((p_src[burst_cnt] & addr_offset) !=
Chris Packham1a07d212018-05-10 13:28:29 +1200916 (p_dst[if_id] & addr_offset))
Stefan Roese5ffceb82015-03-26 15:36:56 +0100917 b_is_fail = 1;
918 }
919
920 if (b_is_fail == 1) {
921 DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
922 ("IF %d exp: ", if_id));
923 for (i_id = 0; i_id <= MAX_INTERFACE_NUM - 1; i_id++) {
924 DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
925 ("0x%8x ", p_src[i_id]));
926 }
927 DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
928 ("\n_i_f %d rcv: ", if_id));
929 for (i_id = 0; i_id <= MAX_INTERFACE_NUM - 1; i_id++) {
930 DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
931 ("(0x%8x ", p_dst[i_id]));
932 }
933 DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("\n "));
934 }
935
936 return b_is_fail;
937}
Chris Packham1a07d212018-05-10 13:28:29 +1200938#endif /* EXCLUDE_SWITCH_DEBUG */
Stefan Roese5ffceb82015-03-26 15:36:56 +0100939
Chris Packham1a07d212018-05-10 13:28:29 +1200940#if defined(DDR_VIEWER_TOOL)
Stefan Roese5ffceb82015-03-26 15:36:56 +0100941/*
942 * Sweep validation
943 */
944int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
945 u32 mode)
946{
947 u32 pup = 0, start_pup = 0, end_pup = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200948 u32 adll = 0, rep = 0, pattern_idx = 0;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100949 u32 res[MAX_INTERFACE_NUM] = { 0 };
950 int if_id = 0;
951 u32 adll_value = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200952 u32 reg;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100953 enum hws_access_type pup_access;
954 u32 cs;
Chris Packham4bf81db2018-12-03 14:26:49 +1300955 unsigned int max_cs = mv_ddr_cs_num_get();
Chris Packham1a07d212018-05-10 13:28:29 +1200956 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
957 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
958
959 repeat_num = 2;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100960
Stefan Roese5ffceb82015-03-26 15:36:56 +0100961 if (mode == 1) {
962 /* per pup */
963 start_pup = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200964 end_pup = octets_per_if_num - 1;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100965 pup_access = ACCESS_TYPE_UNICAST;
966 } else {
967 start_pup = 0;
968 end_pup = 0;
969 pup_access = ACCESS_TYPE_MULTICAST;
970 }
971
972 for (cs = 0; cs < max_cs; cs++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200973 reg = (direction == 0) ? CTX_PHY_REG(cs) : CRX_PHY_REG(cs);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100974 for (adll = 0; adll < ADLL_LENGTH; adll++) {
975 for (if_id = 0;
976 if_id <= MAX_INTERFACE_NUM - 1;
977 if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +1200978 VALIDATE_IF_ACTIVE
Stefan Roese5ffceb82015-03-26 15:36:56 +0100979 (tm->if_act_mask,
980 if_id);
981 for (pup = start_pup; pup <= end_pup; pup++) {
982 ctrl_sweepres[adll][if_id][pup] =
983 0;
984 }
985 }
986 }
987
988 for (adll = 0; adll < (MAX_INTERFACE_NUM * MAX_BUS_NUM); adll++)
989 ctrl_adll[adll] = 0;
Chris Packham1a07d212018-05-10 13:28:29 +1200990 /* Save DQS value(after algorithm run) */
991 ddr3_tip_read_adll_value(dev_num, ctrl_adll,
992 reg, MASK_ALL_BITS);
Stefan Roese5ffceb82015-03-26 15:36:56 +0100993
994 /*
995 * Sweep ADLL from 0:31 on all I/F on all Pup and perform
996 * BIST on each stage.
997 */
998 for (pup = start_pup; pup <= end_pup; pup++) {
999 for (adll = 0; adll < ADLL_LENGTH; adll++) {
Chris Packham1a07d212018-05-10 13:28:29 +12001000 for (rep = 0; rep < repeat_num; rep++) {
1001 for (pattern_idx = PATTERN_KILLER_DQ0;
1002 pattern_idx < PATTERN_LAST;
1003 pattern_idx++) {
1004 adll_value =
1005 (direction == 0) ? (adll * 2) : adll;
1006 CHECK_STATUS(ddr3_tip_bus_write
1007 (dev_num, ACCESS_TYPE_MULTICAST, 0,
1008 pup_access, pup, DDR_PHY_DATA,
1009 reg, adll_value));
1010 hws_ddr3_run_bist(dev_num, sweep_pattern, res,
1011 cs);
1012 /* ddr3_tip_reset_fifo_ptr(dev_num); */
1013 for (if_id = 0;
1014 if_id < MAX_INTERFACE_NUM;
1015 if_id++) {
1016 VALIDATE_IF_ACTIVE
1017 (tm->if_act_mask,
1018 if_id);
1019 ctrl_sweepres[adll][if_id][pup]
1020 += res[if_id];
1021 if (mode == 1) {
1022 CHECK_STATUS
1023 (ddr3_tip_bus_write
1024 (dev_num,
1025 ACCESS_TYPE_UNICAST,
1026 if_id,
1027 ACCESS_TYPE_UNICAST,
1028 pup,
1029 DDR_PHY_DATA,
1030 reg,
1031 ctrl_adll[if_id *
1032 cs *
1033 octets_per_if_num
1034 + pup]));
1035 }
1036 }
Stefan Roese5ffceb82015-03-26 15:36:56 +01001037 }
1038 }
1039 }
1040 }
1041 printf("Final, CS %d,%s, Sweep, Result, Adll,", cs,
1042 ((direction == 0) ? "TX" : "RX"));
1043 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +12001044 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +01001045 if (mode == 1) {
1046 for (pup = start_pup; pup <= end_pup; pup++) {
Chris Packham1a07d212018-05-10 13:28:29 +12001047 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
Stefan Roese5ffceb82015-03-26 15:36:56 +01001048 printf("I/F%d-PHY%d , ", if_id, pup);
1049 }
1050 } else {
1051 printf("I/F%d , ", if_id);
1052 }
1053 }
1054 printf("\n");
1055
1056 for (adll = 0; adll < ADLL_LENGTH; adll++) {
1057 adll_value = (direction == 0) ? (adll * 2) : adll;
1058 printf("Final,%s, Sweep, Result, %d ,",
1059 ((direction == 0) ? "TX" : "RX"), adll_value);
1060
1061 for (if_id = 0;
1062 if_id <= MAX_INTERFACE_NUM - 1;
1063 if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +12001064 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +01001065 for (pup = start_pup; pup <= end_pup; pup++) {
Chris Packham1a07d212018-05-10 13:28:29 +12001066 printf("%8d , ",
Stefan Roese5ffceb82015-03-26 15:36:56 +01001067 ctrl_sweepres[adll][if_id]
1068 [pup]);
1069 }
1070 }
1071 printf("\n");
1072 }
1073
1074 /*
1075 * Write back to the phy the Rx DQS value, we store in
1076 * the beginning.
1077 */
Chris Packham1a07d212018-05-10 13:28:29 +12001078 ddr3_tip_write_adll_value(dev_num, ctrl_adll, reg);
Stefan Roese5ffceb82015-03-26 15:36:56 +01001079 /* print adll results */
Chris Packham1a07d212018-05-10 13:28:29 +12001080 ddr3_tip_read_adll_value(dev_num, ctrl_adll, reg, MASK_ALL_BITS);
Stefan Roese5ffceb82015-03-26 15:36:56 +01001081 printf("%s, DQS, ADLL,,,", (direction == 0) ? "Tx" : "Rx");
1082 print_adll(dev_num, ctrl_adll);
Chris Packham1a07d212018-05-10 13:28:29 +12001083 }
1084 ddr3_tip_reset_fifo_ptr(dev_num);
1085
1086 return 0;
1087}
1088
1089#if defined(EXCLUDE_SWITCH_DEBUG)
1090int ddr3_tip_run_leveling_sweep_test(int dev_num, u32 repeat_num,
1091 u32 direction, u32 mode)
1092{
1093 u32 pup = 0, start_pup = 0, end_pup = 0, start_adll = 0;
1094 u32 adll = 0, rep = 0, pattern_idx = 0;
1095 u32 read_data[MAX_INTERFACE_NUM];
1096 u32 res[MAX_INTERFACE_NUM] = { 0 };
1097 int if_id = 0, gap = 0;
1098 u32 adll_value = 0;
1099 u32 reg;
1100 enum hws_access_type pup_access;
1101 u32 cs;
Chris Packham4bf81db2018-12-03 14:26:49 +13001102 unsigned int max_cs = mv_ddr_cs_num_get();
Chris Packham1a07d212018-05-10 13:28:29 +12001103 u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
1104 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1105
1106 if (mode == 1) { /* per pup */
1107 start_pup = 0;
1108 end_pup = octets_per_if_num - 1;
1109 pup_access = ACCESS_TYPE_UNICAST;
1110 } else {
1111 start_pup = 0;
1112 end_pup = 0;
1113 pup_access = ACCESS_TYPE_MULTICAST;
1114 }
1115
1116 for (cs = 0; cs < max_cs; cs++) {
1117 reg = (direction == 0) ? WL_PHY_REG(cs) : RL_PHY_REG(cs);
1118 for (adll = 0; adll < ADLL_LENGTH; adll++) {
1119 for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
1120 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1121 for (pup = start_pup; pup <= end_pup; pup++)
1122 ctrl_sweepres[adll][if_id][pup] = 0;
1123 }
1124 }
1125
1126 for (adll = 0; adll < MAX_INTERFACE_NUM * MAX_BUS_NUM; adll++) {
1127 ctrl_adll[adll] = 0;
1128 ctrl_level_phase[adll] = 0;
1129 ctrl_adll1[adll] = 0;
1130 }
1131
1132 /* save leveling value after running algorithm */
1133 ddr3_tip_read_adll_value(dev_num, ctrl_adll, reg, 0x1f);
1134 read_phase_value(dev_num, ctrl_level_phase, reg, 0x7 << 6);
1135
1136 if (direction == 0)
1137 ddr3_tip_read_adll_value(dev_num, ctrl_adll1,
1138 CTX_PHY_REG(cs), MASK_ALL_BITS);
1139
1140 /* Sweep ADLL from 0 to 31 on all interfaces, all pups,
1141 * and perform BIST on each stage
1142 */
1143 for (pup = start_pup; pup <= end_pup; pup++) {
1144 for (adll = 0; adll < ADLL_LENGTH; adll++) {
1145 for (rep = 0; rep < repeat_num; rep++) {
1146 adll_value = (direction == 0) ? (adll * 2) : (adll * 3);
1147 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1148 start_adll = ctrl_adll[if_id * cs * octets_per_if_num + pup] +
1149 (ctrl_level_phase[if_id * cs *
1150 octets_per_if_num +
1151 pup] >> 6) * 32;
1152
1153 if (direction == 0)
1154 start_adll = (start_adll > 32) ? (start_adll - 32) : 0;
1155 else
1156 start_adll = (start_adll > 48) ? (start_adll - 48) : 0;
1157
1158 adll_value += start_adll;
1159
1160 gap = ctrl_adll1[if_id * cs * octets_per_if_num + pup] -
1161 ctrl_adll[if_id * cs * octets_per_if_num + pup];
1162 gap = (((adll_value % 32) + gap) % 64);
1163
1164 adll_value = ((adll_value % 32) +
1165 (((adll_value - (adll_value % 32)) / 32) << 6));
1166
1167 CHECK_STATUS(ddr3_tip_bus_write(dev_num,
1168 ACCESS_TYPE_UNICAST,
1169 if_id,
1170 pup_access,
1171 pup,
1172 DDR_PHY_DATA,
1173 reg,
1174 adll_value));
1175 if (direction == 0)
1176 CHECK_STATUS(ddr3_tip_bus_write(dev_num,
1177 ACCESS_TYPE_UNICAST,
1178 if_id,
1179 pup_access,
1180 pup,
1181 DDR_PHY_DATA,
1182 CTX_PHY_REG(cs),
1183 gap));
1184 }
1185
1186 for (pattern_idx = PATTERN_KILLER_DQ0;
1187 pattern_idx < PATTERN_LAST;
1188 pattern_idx++) {
1189 hws_ddr3_run_bist(dev_num, sweep_pattern, res, cs);
1190 ddr3_tip_reset_fifo_ptr(dev_num);
1191 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1192 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1193 if (pup != 4) { /* TODO: remove literal */
1194 ctrl_sweepres[adll][if_id][pup] += res[if_id];
1195 } else {
1196 CHECK_STATUS(ddr3_tip_if_read(dev_num,
1197 ACCESS_TYPE_UNICAST,
1198 if_id,
1199 0x1458,
1200 read_data,
1201 MASK_ALL_BITS));
1202 ctrl_sweepres[adll][if_id][pup] += read_data[if_id];
1203 CHECK_STATUS(ddr3_tip_if_write(dev_num,
1204 ACCESS_TYPE_UNICAST,
1205 if_id,
1206 0x1458,
1207 0x0,
1208 0xFFFFFFFF));
1209 CHECK_STATUS(ddr3_tip_if_write(dev_num,
1210 ACCESS_TYPE_UNICAST,
1211 if_id,
1212 0x145C,
1213 0x0,
1214 0xFFFFFFFF));
1215 }
1216 }
1217 }
1218 }
1219 }
1220
1221 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1222 start_adll = ctrl_adll[if_id * cs * octets_per_if_num + pup] +
1223 ctrl_level_phase[if_id * cs * octets_per_if_num + pup];
1224 CHECK_STATUS(ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST, if_id, pup_access, pup,
1225 DDR_PHY_DATA, reg, start_adll));
1226 if (direction == 0)
1227 CHECK_STATUS(ddr3_tip_bus_write(dev_num,
1228 ACCESS_TYPE_UNICAST,
1229 if_id,
1230 pup_access,
1231 pup,
1232 DDR_PHY_DATA,
1233 CTX_PHY_REG(cs),
1234 ctrl_adll1[if_id *
1235 cs *
1236 octets_per_if_num +
1237 pup]));
1238 }
1239 }
1240
1241 printf("Final,CS %d,%s,Leveling,Result,Adll,", cs, ((direction == 0) ? "TX" : "RX"));
1242
1243 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1244 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1245 if (mode == 1) {
1246 for (pup = start_pup; pup <= end_pup; pup++) {
1247 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
1248 printf("I/F%d-PHY%d , ", if_id, pup);
1249 }
1250 } else {
1251 printf("I/F%d , ", if_id);
1252 }
1253 }
1254 printf("\n");
1255
1256 for (adll = 0; adll < ADLL_LENGTH; adll++) {
1257 adll_value = (direction == 0) ? ((adll * 2) - 32) : ((adll * 3) - 48);
1258 printf("Final,%s,LevelingSweep,Result, %d ,", ((direction == 0) ? "TX" : "RX"), adll_value);
1259
1260 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1261 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1262 for (pup = start_pup; pup <= end_pup; pup++)
1263 printf("%8d , ", ctrl_sweepres[adll][if_id][pup]);
1264 }
1265 printf("\n");
1266 }
1267
1268 /* write back to the phy the Rx DQS value, we store in the beginning */
1269 write_leveling_value(dev_num, ctrl_adll, ctrl_level_phase, reg);
1270 if (direction == 0)
1271 ddr3_tip_write_adll_value(dev_num, ctrl_adll1, CTX_PHY_REG(cs));
1272
1273 /* print adll results */
1274 ddr3_tip_read_adll_value(dev_num, ctrl_adll, reg, MASK_ALL_BITS);
1275 printf("%s,DQS,Leveling,,,", (direction == 0) ? "Tx" : "Rx");
1276 print_adll(dev_num, ctrl_adll);
1277 print_ph(dev_num, ctrl_level_phase);
Stefan Roese5ffceb82015-03-26 15:36:56 +01001278 }
1279 ddr3_tip_reset_fifo_ptr(dev_num);
1280
1281 return 0;
1282}
Chris Packham1a07d212018-05-10 13:28:29 +12001283#endif /* EXCLUDE_SWITCH_DEBUG */
Stefan Roese5ffceb82015-03-26 15:36:56 +01001284
Chris Packham1a07d212018-05-10 13:28:29 +12001285void print_topology(struct mv_ddr_topology_map *topology_db)
Stefan Roese5ffceb82015-03-26 15:36:56 +01001286{
1287 u32 ui, uj;
Chris Packham1a07d212018-05-10 13:28:29 +12001288 u32 dev_num = 0;
Stefan Roese5ffceb82015-03-26 15:36:56 +01001289
1290 printf("\tinterface_mask: 0x%x\n", topology_db->if_act_mask);
Chris Packham1a07d212018-05-10 13:28:29 +12001291 printf("\tNumber of buses: 0x%x\n",
1292 ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE));
Stefan Roese5ffceb82015-03-26 15:36:56 +01001293 printf("\tbus_act_mask: 0x%x\n", topology_db->bus_act_mask);
1294
1295 for (ui = 0; ui < MAX_INTERFACE_NUM; ui++) {
Chris Packham1a07d212018-05-10 13:28:29 +12001296 VALIDATE_IF_ACTIVE(topology_db->if_act_mask, ui);
Stefan Roese5ffceb82015-03-26 15:36:56 +01001297 printf("\n\tInterface ID: %d\n", ui);
1298 printf("\t\tDDR Frequency: %s\n",
1299 convert_freq(topology_db->
1300 interface_params[ui].memory_freq));
1301 printf("\t\tSpeed_bin: %d\n",
1302 topology_db->interface_params[ui].speed_bin_index);
1303 printf("\t\tBus_width: %d\n",
1304 (4 << topology_db->interface_params[ui].bus_width));
1305 printf("\t\tMem_size: %s\n",
1306 convert_mem_size(topology_db->
1307 interface_params[ui].memory_size));
1308 printf("\t\tCAS-WL: %d\n",
1309 topology_db->interface_params[ui].cas_wl);
1310 printf("\t\tCAS-L: %d\n",
1311 topology_db->interface_params[ui].cas_l);
1312 printf("\t\tTemperature: %d\n",
1313 topology_db->interface_params[ui].interface_temp);
1314 printf("\n");
1315 for (uj = 0; uj < 4; uj++) {
1316 printf("\t\tBus %d parameters- CS Mask: 0x%x\t", uj,
1317 topology_db->interface_params[ui].
1318 as_bus_params[uj].cs_bitmask);
1319 printf("Mirror: 0x%x\t",
1320 topology_db->interface_params[ui].
1321 as_bus_params[uj].mirror_enable_bitmask);
1322 printf("DQS Swap is %s \t",
1323 (topology_db->
1324 interface_params[ui].as_bus_params[uj].
1325 is_dqs_swap == 1) ? "enabled" : "disabled");
1326 printf("Ck Swap:%s\t",
1327 (topology_db->
1328 interface_params[ui].as_bus_params[uj].
1329 is_ck_swap == 1) ? "enabled" : "disabled");
1330 printf("\n");
1331 }
1332 }
1333}
Chris Packham1a07d212018-05-10 13:28:29 +12001334#endif /* DDR_VIEWER_TOOL */
Stefan Roese5ffceb82015-03-26 15:36:56 +01001335
Chris Packham1a07d212018-05-10 13:28:29 +12001336#if !defined(EXCLUDE_SWITCH_DEBUG)
Stefan Roese5ffceb82015-03-26 15:36:56 +01001337/*
1338 * Execute XSB Test transaction (rd/wr/both)
1339 */
1340int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type,
1341 u32 read_type, u32 burst_length)
1342{
1343 u32 seq = 0, if_id = 0, addr, cnt;
1344 int ret = MV_OK, ret_tmp;
1345 u32 data_read[MAX_INTERFACE_NUM];
Chris Packham1a07d212018-05-10 13:28:29 +12001346 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
Stefan Roese5ffceb82015-03-26 15:36:56 +01001347
1348 for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
Chris Packham1a07d212018-05-10 13:28:29 +12001349 VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
Stefan Roese5ffceb82015-03-26 15:36:56 +01001350 addr = mem_addr;
1351 for (cnt = 0; cnt <= burst_length; cnt++) {
1352 seq = (seq + 1) % 8;
1353 if (write_type != 0) {
1354 CHECK_STATUS(ddr3_tip_ext_write
1355 (dev_num, if_id, addr, 1,
1356 xsb_test_table[seq]));
1357 }
1358 if (read_type != 0) {
1359 CHECK_STATUS(ddr3_tip_ext_read
1360 (dev_num, if_id, addr, 1,
1361 data_read));
1362 }
1363 if ((read_type != 0) && (write_type != 0)) {
1364 ret_tmp =
1365 ddr3_tip_compare(if_id,
1366 xsb_test_table[seq],
1367 data_read,
1368 0xff);
1369 addr += (EXT_ACCESS_BURST_LENGTH * 4);
1370 ret = (ret != MV_OK) ? ret : ret_tmp;
1371 }
1372 }
1373 }
1374
1375 return ret;
1376}
1377
1378#else /*EXCLUDE_SWITCH_DEBUG */
Stefan Roese5ffceb82015-03-26 15:36:56 +01001379u32 start_xsb_offset = 0;
Stefan Roese5ffceb82015-03-26 15:36:56 +01001380
1381int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type,
1382 u32 read_type, u32 burst_length)
1383{
1384 return MV_OK;
1385}
1386
Chris Packham1a07d212018-05-10 13:28:29 +12001387#endif /* EXCLUDE_SWITCH_DEBUG */