1 /*
2  * Copyright (C) Marvell International Ltd. and its affiliates
3  *
4  * SPDX-License-Identifier:	GPL-2.0
5  */
6 
7 #include <common.h>
8 #include <spl.h>
9 #include <asm/io.h>
10 #include <asm/arch/cpu.h>
11 #include <asm/arch/soc.h>
12 
13 #include "ddr3_init.h"
14 
15 #define VREF_INITIAL_STEP		3
16 #define VREF_SECOND_STEP		1
17 #define VREF_MAX_INDEX			7
18 #define MAX_VALUE			(1024 - 1)
19 #define MIN_VALUE			(-MAX_VALUE)
20 #define GET_RD_SAMPLE_DELAY(data, cs)	((data >> rd_sample_mask[cs]) & 0xf)
21 
22 u32 ck_delay = (u32)-1, ck_delay_16 = (u32)-1;
23 u32 ca_delay;
24 int ddr3_tip_centr_skip_min_win_check = 0;
25 u8 current_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
26 u8 last_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
27 u16 current_valid_window[MAX_BUS_NUM][MAX_INTERFACE_NUM];
28 u16 last_valid_window[MAX_BUS_NUM][MAX_INTERFACE_NUM];
29 u8 lim_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
30 u8 interface_state[MAX_INTERFACE_NUM];
31 u8 vref_window_size[MAX_INTERFACE_NUM][MAX_BUS_NUM];
32 u8 vref_window_size_th = 12;
33 
34 static u8 pup_st[MAX_BUS_NUM][MAX_INTERFACE_NUM];
35 
36 static u32 rd_sample_mask[] = {
37 	0,
38 	8,
39 	16,
40 	24
41 };
42 
43 #define	VREF_STEP_1		0
44 #define	VREF_STEP_2		1
45 #define	VREF_CONVERGE		2
46 
47 /*
48  * ODT additional timing
49  */
50 int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id)
51 {
52 	u32 cs_num = 0, max_read_sample = 0, min_read_sample = 0;
53 	u32 data_read[MAX_INTERFACE_NUM] = { 0 };
54 	u32 read_sample[MAX_CS_NUM];
55 	u32 val;
56 	u32 pup_index;
57 	int max_phase = MIN_VALUE, current_phase;
58 	enum hws_access_type access_type = ACCESS_TYPE_UNICAST;
59 	struct hws_topology_map *tm = ddr3_get_topology_map();
60 
61 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
62 				       DUNIT_ODT_CONTROL_REG,
63 				       0 << 8, 0x3 << 8));
64 	CHECK_STATUS(ddr3_tip_if_read(dev_num, access_type, if_id,
65 				      READ_DATA_SAMPLE_DELAY,
66 				      data_read, MASK_ALL_BITS));
67 	val = data_read[if_id];
68 
69 	for (cs_num = 0; cs_num < MAX_CS_NUM; cs_num++) {
70 		read_sample[cs_num] = GET_RD_SAMPLE_DELAY(val, cs_num);
71 
72 		/* find maximum of read_samples */
73 		if (read_sample[cs_num] >= max_read_sample) {
74 			if (read_sample[cs_num] == max_read_sample)
75 				max_phase = MIN_VALUE;
76 			else
77 				max_read_sample = read_sample[cs_num];
78 
79 			for (pup_index = 0;
80 			     pup_index < tm->num_of_bus_per_interface;
81 			     pup_index++) {
82 				CHECK_STATUS(ddr3_tip_bus_read
83 					     (dev_num, if_id,
84 					      ACCESS_TYPE_UNICAST, pup_index,
85 					      DDR_PHY_DATA,
86 					      RL_PHY_REG + CS_REG_VALUE(cs_num),
87 					      &val));
88 
89 				current_phase = ((int)val & 0xe0) >> 6;
90 				if (current_phase >= max_phase)
91 					max_phase = current_phase;
92 			}
93 		}
94 
95 		/* find minimum */
96 		if (read_sample[cs_num] < min_read_sample)
97 			min_read_sample = read_sample[cs_num];
98 	}
99 
100 	min_read_sample = min_read_sample - 1;
101 	max_read_sample = max_read_sample + 4 + (max_phase + 1) / 2 + 1;
102 	if (min_read_sample >= 0xf)
103 		min_read_sample = 0xf;
104 	if (max_read_sample >= 0x1f)
105 		max_read_sample = 0x1f;
106 
107 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
108 				       ODT_TIMING_LOW,
109 				       ((min_read_sample - 1) << 12),
110 				       0xf << 12));
111 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
112 				       ODT_TIMING_LOW,
113 				       (max_read_sample << 16),
114 				       0x1f << 16));
115 
116 	return MV_OK;
117 }
118 
119 int get_valid_win_rx(u32 dev_num, u32 if_id, u8 res[4])
120 {
121 	u32 reg_pup = RESULT_DB_PHY_REG_ADDR;
122 	u32 reg_data;
123 	u32 cs_num;
124 	int i;
125 
126 	cs_num = 0;
127 
128 	/* TBD */
129 	reg_pup += cs_num;
130 
131 	for (i = 0; i < 4; i++) {
132 		CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id,
133 					       ACCESS_TYPE_UNICAST, i,
134 					       DDR_PHY_DATA, reg_pup,
135 					       &reg_data));
136 		res[i] = (reg_data >> RESULT_DB_PHY_REG_RX_OFFSET) & 0x1f;
137 	}
138 
139 	return 0;
140 }
141 
142 /*
143  * This algorithm deals with the vertical optimum from Voltage point of view
144  * of the sample signal.
145  * Voltage sample point can improve the Eye / window size of the bit and the
146  * pup.
147  * The problem is that it is tune for all DQ the same so there isn't any
148  * PBS like code.
149  * It is more like centralization.
150  * But because we don't have The training SM support we do it a bit more
151  * smart search to save time.
152  */
153 int ddr3_tip_vref(u32 dev_num)
154 {
155 	/*
156 	 * The Vref register have non linear order. Need to check what will be
157 	 * in future projects.
158 	 */
159 	u32 vref_map[8] = {
160 		1, 2, 3, 4, 5, 6, 7, 0
161 	};
162 	/* State and parameter definitions */
163 	u32 initial_step = VREF_INITIAL_STEP;
164 	/* need to be assign with minus ????? */
165 	u32 second_step = VREF_SECOND_STEP;
166 	u32 algo_run_flag = 0, currrent_vref = 0;
167 	u32 while_count = 0;
168 	u32 pup = 0, if_id = 0, num_pup = 0, rep = 0;
169 	u32 val = 0;
170 	u32 reg_addr = 0xa8;
171 	u32 copy_start_pattern, copy_end_pattern;
172 	enum hws_result *flow_result = ddr3_tip_get_result_ptr(training_stage);
173 	u8 res[4];
174 	struct hws_topology_map *tm = ddr3_get_topology_map();
175 
176 	CHECK_STATUS(ddr3_tip_special_rx(dev_num));
177 
178 	/* save start/end pattern */
179 	copy_start_pattern = start_pattern;
180 	copy_end_pattern = end_pattern;
181 
182 	/* set vref as centralization pattern */
183 	start_pattern = PATTERN_VREF;
184 	end_pattern = PATTERN_VREF;
185 
186 	/* init params */
187 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
188 		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
189 		for (pup = 0;
190 		     pup < tm->num_of_bus_per_interface; pup++) {
191 			current_vref[pup][if_id] = 0;
192 			last_vref[pup][if_id] = 0;
193 			lim_vref[pup][if_id] = 0;
194 			current_valid_window[pup][if_id] = 0;
195 			last_valid_window[pup][if_id] = 0;
196 			if (vref_window_size[if_id][pup] >
197 			    vref_window_size_th) {
198 				pup_st[pup][if_id] = VREF_CONVERGE;
199 				DEBUG_TRAINING_HW_ALG(
200 					DEBUG_LEVEL_INFO,
201 					("VREF config, IF[ %d ]pup[ %d ] - Vref tune not requered (%d)\n",
202 					 if_id, pup, __LINE__));
203 			} else {
204 				pup_st[pup][if_id] = VREF_STEP_1;
205 				CHECK_STATUS(ddr3_tip_bus_read
206 					     (dev_num, if_id,
207 					      ACCESS_TYPE_UNICAST, pup,
208 					      DDR_PHY_DATA, reg_addr, &val));
209 				CHECK_STATUS(ddr3_tip_bus_write
210 					     (dev_num, ACCESS_TYPE_UNICAST,
211 					      if_id, ACCESS_TYPE_UNICAST,
212 					      pup, DDR_PHY_DATA, reg_addr,
213 					      (val & (~0xf)) | vref_map[0]));
214 				DEBUG_TRAINING_HW_ALG(
215 					DEBUG_LEVEL_INFO,
216 					("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
217 					 if_id, pup,
218 					 (val & (~0xf)) | vref_map[0],
219 					 __LINE__));
220 			}
221 		}
222 		interface_state[if_id] = 0;
223 	}
224 
225 	/* TODO: Set number of active interfaces */
226 	num_pup = tm->num_of_bus_per_interface * MAX_INTERFACE_NUM;
227 
228 	while ((algo_run_flag <= num_pup) & (while_count < 10)) {
229 		while_count++;
230 		for (rep = 1; rep < 4; rep++) {
231 			ddr3_tip_centr_skip_min_win_check = 1;
232 			ddr3_tip_centralization_rx(dev_num);
233 			ddr3_tip_centr_skip_min_win_check = 0;
234 
235 			/* Read Valid window results only for non converge pups */
236 			for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
237 				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
238 				if (interface_state[if_id] != 4) {
239 					get_valid_win_rx(dev_num, if_id, res);
240 					for (pup = 0;
241 					     pup < tm->num_of_bus_per_interface;
242 					     pup++) {
243 						VALIDATE_ACTIVE
244 							(tm->bus_act_mask, pup);
245 						if (pup_st[pup]
246 						    [if_id] ==
247 						    VREF_CONVERGE)
248 							continue;
249 
250 						current_valid_window[pup]
251 							[if_id] =
252 							(current_valid_window[pup]
253 							 [if_id] * (rep - 1) +
254 							 1000 * res[pup]) / rep;
255 					}
256 				}
257 			}
258 		}
259 
260 		for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
261 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
262 			DEBUG_TRAINING_HW_ALG(
263 				DEBUG_LEVEL_TRACE,
264 				("current_valid_window: IF[ %d ] - ", if_id));
265 
266 			for (pup = 0;
267 			     pup < tm->num_of_bus_per_interface; pup++) {
268 				VALIDATE_ACTIVE(tm->bus_act_mask, pup);
269 				DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE,
270 						      ("%d ",
271 						       current_valid_window
272 						       [pup][if_id]));
273 			}
274 			DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE, ("\n"));
275 		}
276 
277 		/* Compare results and respond as function of state */
278 		for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
279 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
280 			for (pup = 0;
281 			     pup < tm->num_of_bus_per_interface; pup++) {
282 				VALIDATE_ACTIVE(tm->bus_act_mask, pup);
283 				DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE,
284 						      ("I/F[ %d ], pup[ %d ] STATE #%d (%d)\n",
285 						       if_id, pup,
286 						       pup_st[pup]
287 						       [if_id], __LINE__));
288 
289 				if (pup_st[pup][if_id] == VREF_CONVERGE)
290 					continue;
291 
292 				DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE,
293 						      ("I/F[ %d ], pup[ %d ] CHECK progress - Current %d Last %d, limit VREF %d (%d)\n",
294 						       if_id, pup,
295 						       current_valid_window[pup]
296 						       [if_id],
297 						       last_valid_window[pup]
298 						       [if_id], lim_vref[pup]
299 						       [if_id], __LINE__));
300 
301 				/*
302 				 * The -1 is for solution resolution +/- 1 tap
303 				 * of ADLL
304 				 */
305 				if (current_valid_window[pup][if_id] + 200 >=
306 				    (last_valid_window[pup][if_id])) {
307 					if (pup_st[pup][if_id] == VREF_STEP_1) {
308 						/*
309 						 * We stay in the same state and
310 						 * step just update the window
311 						 * size (take the max) and Vref
312 						 */
313 						if (current_vref[pup]
314 						    [if_id] == VREF_MAX_INDEX) {
315 							/*
316 							 * If we step to the end
317 							 * and didn't converge
318 							 * to some particular
319 							 * better Vref value
320 							 * define the pup as
321 							 * converge and step
322 							 * back to nominal
323 							 * Vref.
324 							 */
325 							pup_st[pup]
326 								[if_id] =
327 								VREF_CONVERGE;
328 							algo_run_flag++;
329 							interface_state
330 								[if_id]++;
331 							DEBUG_TRAINING_HW_ALG
332 								(DEBUG_LEVEL_TRACE,
333 								 ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n",
334 								  if_id, pup,
335 								  current_vref[pup]
336 								  [if_id],
337 								  __LINE__));
338 						} else {
339 							/* continue to update the Vref index */
340 							current_vref[pup]
341 								[if_id] =
342 								((current_vref[pup]
343 								  [if_id] +
344 								  initial_step) >
345 								 VREF_MAX_INDEX) ?
346 								VREF_MAX_INDEX
347 								: (current_vref[pup]
348 								   [if_id] +
349 								   initial_step);
350 							if (current_vref[pup]
351 							    [if_id] ==
352 							    VREF_MAX_INDEX) {
353 								pup_st[pup]
354 									[if_id]
355 									=
356 									VREF_STEP_2;
357 							}
358 							lim_vref[pup]
359 								[if_id] =
360 								last_vref[pup]
361 								[if_id] =
362 								current_vref[pup]
363 								[if_id];
364 						}
365 
366 						last_valid_window[pup]
367 							[if_id] =
368 							GET_MAX(current_valid_window
369 								[pup][if_id],
370 								last_valid_window
371 								[pup]
372 								[if_id]);
373 
374 						/* update the Vref for next stage */
375 						currrent_vref =
376 							current_vref[pup]
377 							[if_id];
378 						CHECK_STATUS
379 							(ddr3_tip_bus_read
380 							 (dev_num, if_id,
381 							  ACCESS_TYPE_UNICAST, pup,
382 							  DDR_PHY_DATA, reg_addr,
383 							  &val));
384 						CHECK_STATUS
385 							(ddr3_tip_bus_write
386 							 (dev_num,
387 							  ACCESS_TYPE_UNICAST,
388 							  if_id,
389 							  ACCESS_TYPE_UNICAST, pup,
390 							  DDR_PHY_DATA, reg_addr,
391 							  (val & (~0xf)) |
392 							  vref_map[currrent_vref]));
393 						DEBUG_TRAINING_HW_ALG
394 							(DEBUG_LEVEL_TRACE,
395 							 ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
396 							  if_id, pup,
397 							  (val & (~0xf)) |
398 							  vref_map[currrent_vref],
399 							  __LINE__));
400 					} else if (pup_st[pup][if_id]
401 						   == VREF_STEP_2) {
402 						/*
403 						 * We keep on search back with
404 						 * the same step size.
405 						 */
406 						last_valid_window[pup]
407 							[if_id] =
408 							GET_MAX(current_valid_window
409 								[pup][if_id],
410 								last_valid_window
411 								[pup]
412 								[if_id]);
413 						last_vref[pup][if_id] =
414 							current_vref[pup]
415 							[if_id];
416 
417 						/* we finish all search space */
418 						if ((current_vref[pup]
419 						     [if_id] - second_step) == lim_vref[pup][if_id]) {
420 							/*
421 							 * If we step to the end
422 							 * and didn't converge
423 							 * to some particular
424 							 * better Vref value
425 							 * define the pup as
426 							 * converge and step
427 							 * back to nominal
428 							 * Vref.
429 							 */
430 							pup_st[pup]
431 								[if_id] =
432 								VREF_CONVERGE;
433 							algo_run_flag++;
434 
435 							interface_state
436 								[if_id]++;
437 
438 							current_vref[pup]
439 								[if_id] =
440 								(current_vref[pup]
441 								 [if_id] -
442 								 second_step);
443 
444 							DEBUG_TRAINING_HW_ALG
445 								(DEBUG_LEVEL_TRACE,
446 								 ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n",
447 								  if_id, pup,
448 								  current_vref[pup]
449 								  [if_id],
450 								  __LINE__));
451 						} else
452 							/* we finish all search space */
453 							if (current_vref[pup]
454 							    [if_id] ==
455 							    lim_vref[pup]
456 							    [if_id]) {
457 								/*
458 								 * If we step to the end
459 								 * and didn't converge
460 								 * to some particular
461 								 * better Vref value
462 								 * define the pup as
463 								 * converge and step
464 								 * back to nominal
465 								 * Vref.
466 								 */
467 								pup_st[pup]
468 									[if_id] =
469 									VREF_CONVERGE;
470 
471 								algo_run_flag++;
472 								interface_state
473 									[if_id]++;
474 								DEBUG_TRAINING_HW_ALG
475 									(DEBUG_LEVEL_TRACE,
476 									 ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n",
477 									  if_id, pup,
478 									  current_vref[pup]
479 									  [if_id],
480 									  __LINE__));
481 							} else {
482 								current_vref[pup]
483 									[if_id] =
484 									current_vref[pup]
485 									[if_id] -
486 									second_step;
487 							}
488 
489 						/* Update the Vref for next stage */
490 						currrent_vref =
491 							current_vref[pup]
492 							[if_id];
493 						CHECK_STATUS
494 							(ddr3_tip_bus_read
495 							 (dev_num, if_id,
496 							  ACCESS_TYPE_UNICAST, pup,
497 							  DDR_PHY_DATA, reg_addr,
498 							  &val));
499 						CHECK_STATUS
500 							(ddr3_tip_bus_write
501 							 (dev_num,
502 							  ACCESS_TYPE_UNICAST,
503 							  if_id,
504 							  ACCESS_TYPE_UNICAST, pup,
505 							  DDR_PHY_DATA, reg_addr,
506 							  (val & (~0xf)) |
507 							  vref_map[currrent_vref]));
508 						DEBUG_TRAINING_HW_ALG
509 							(DEBUG_LEVEL_TRACE,
510 							 ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
511 							  if_id, pup,
512 							  (val & (~0xf)) |
513 							  vref_map[currrent_vref],
514 							  __LINE__));
515 					}
516 				} else {
517 					/* we change state and change step */
518 					if (pup_st[pup][if_id] == VREF_STEP_1) {
519 						pup_st[pup][if_id] =
520 							VREF_STEP_2;
521 						lim_vref[pup][if_id] =
522 							current_vref[pup]
523 							[if_id] - initial_step;
524 						last_valid_window[pup]
525 							[if_id] =
526 							current_valid_window[pup]
527 							[if_id];
528 						last_vref[pup][if_id] =
529 							current_vref[pup]
530 							[if_id];
531 						current_vref[pup][if_id] =
532 							last_vref[pup][if_id] -
533 							second_step;
534 
535 						/* Update the Vref for next stage */
536 						CHECK_STATUS
537 							(ddr3_tip_bus_read
538 							 (dev_num, if_id,
539 							  ACCESS_TYPE_UNICAST, pup,
540 							  DDR_PHY_DATA, reg_addr,
541 							  &val));
542 						CHECK_STATUS
543 							(ddr3_tip_bus_write
544 							 (dev_num,
545 							  ACCESS_TYPE_UNICAST,
546 							  if_id,
547 							  ACCESS_TYPE_UNICAST, pup,
548 							  DDR_PHY_DATA, reg_addr,
549 							  (val & (~0xf)) |
550 							  vref_map[current_vref[pup]
551 								   [if_id]]));
552 						DEBUG_TRAINING_HW_ALG
553 							(DEBUG_LEVEL_TRACE,
554 							 ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
555 							  if_id, pup,
556 							  (val & (~0xf)) |
557 							  vref_map[current_vref[pup]
558 								   [if_id]],
559 							  __LINE__));
560 
561 					} else if (pup_st[pup][if_id] == VREF_STEP_2) {
562 						/*
563 						 * The last search was the max
564 						 * point set value and exit
565 						 */
566 						CHECK_STATUS
567 							(ddr3_tip_bus_read
568 							 (dev_num, if_id,
569 							  ACCESS_TYPE_UNICAST, pup,
570 							  DDR_PHY_DATA, reg_addr,
571 							  &val));
572 						CHECK_STATUS
573 							(ddr3_tip_bus_write
574 							 (dev_num,
575 							  ACCESS_TYPE_UNICAST,
576 							  if_id,
577 							  ACCESS_TYPE_UNICAST, pup,
578 							  DDR_PHY_DATA, reg_addr,
579 							  (val & (~0xf)) |
580 							  vref_map[last_vref[pup]
581 								   [if_id]]));
582 						DEBUG_TRAINING_HW_ALG
583 							(DEBUG_LEVEL_TRACE,
584 							 ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
585 							  if_id, pup,
586 							  (val & (~0xf)) |
587 							  vref_map[last_vref[pup]
588 								   [if_id]],
589 							  __LINE__));
590 						pup_st[pup][if_id] =
591 							VREF_CONVERGE;
592 						algo_run_flag++;
593 						interface_state[if_id]++;
594 						DEBUG_TRAINING_HW_ALG
595 							(DEBUG_LEVEL_TRACE,
596 							 ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n",
597 							  if_id, pup,
598 							  current_vref[pup]
599 							  [if_id], __LINE__));
600 					}
601 				}
602 			}
603 		}
604 	}
605 
606 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
607 		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
608 		for (pup = 0;
609 		     pup < tm->num_of_bus_per_interface; pup++) {
610 			VALIDATE_ACTIVE(tm->bus_act_mask, pup);
611 			CHECK_STATUS(ddr3_tip_bus_read
612 				     (dev_num, if_id,
613 				      ACCESS_TYPE_UNICAST, pup,
614 				      DDR_PHY_DATA, reg_addr, &val));
615 			DEBUG_TRAINING_HW_ALG(
616 				DEBUG_LEVEL_INFO,
617 				("FINAL values: I/F[ %d ], pup[ %d ] - Vref = %X (%d)\n",
618 				 if_id, pup, val, __LINE__));
619 		}
620 	}
621 
622 	flow_result[if_id] = TEST_SUCCESS;
623 
624 	/* restore start/end pattern */
625 	start_pattern = copy_start_pattern;
626 	end_pattern = copy_end_pattern;
627 
628 	return 0;
629 }
630 
631 /*
632  * CK/CA Delay
633  */
634 int ddr3_tip_cmd_addr_init_delay(u32 dev_num, u32 adll_tap)
635 {
636 	u32 if_id = 0;
637 	u32 ck_num_adll_tap = 0, ca_num_adll_tap = 0, data = 0;
638 	struct hws_topology_map *tm = ddr3_get_topology_map();
639 
640 	/*
641 	 * ck_delay_table is delaying the of the clock signal only.
642 	 * (to overcome timing issues between_c_k & command/address signals)
643 	 */
644 	/*
645 	 * ca_delay is delaying the of the entire command & Address signals
646 	 * (include Clock signal to overcome DGL error on the Clock versus
647 	 * the DQS).
648 	 */
649 
650 	/* Calc ADLL Tap */
651 	if ((ck_delay == -1) || (ck_delay_16 == -1)) {
652 		DEBUG_TRAINING_HW_ALG(
653 			DEBUG_LEVEL_ERROR,
654 			("ERROR: One of ck_delay values not initialized!!!\n"));
655 	}
656 
657 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
658 		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
659 		/* Calc delay ps in ADLL tap */
660 		if (tm->interface_params[if_id].bus_width ==
661 		    BUS_WIDTH_16)
662 			ck_num_adll_tap = ck_delay_16 / adll_tap;
663 		else
664 			ck_num_adll_tap = ck_delay / adll_tap;
665 
666 		ca_num_adll_tap = ca_delay / adll_tap;
667 		data = (ck_num_adll_tap & 0x3f) +
668 			((ca_num_adll_tap & 0x3f) << 10);
669 
670 		/*
671 		 * Set the ADLL number to the CK ADLL for Interfaces for
672 		 * all Pup
673 		 */
674 		DEBUG_TRAINING_HW_ALG(
675 			DEBUG_LEVEL_TRACE,
676 			("ck_num_adll_tap %d ca_num_adll_tap %d adll_tap %d\n",
677 			 ck_num_adll_tap, ca_num_adll_tap, adll_tap));
678 
679 		CHECK_STATUS(ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST,
680 						if_id, ACCESS_TYPE_MULTICAST,
681 						PARAM_NOT_CARE, DDR_PHY_CONTROL,
682 						0x0, data));
683 	}
684 
685 	return MV_OK;
686 }
687