1
2
3
4
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
22u32 ck_delay = (u32)-1, ck_delay_16 = (u32)-1;
23u32 ca_delay;
24int ddr3_tip_centr_skip_min_win_check = 0;
25u8 current_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
26u8 last_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
27u16 current_valid_window[MAX_BUS_NUM][MAX_INTERFACE_NUM];
28u16 last_valid_window[MAX_BUS_NUM][MAX_INTERFACE_NUM];
29u8 lim_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
30u8 interface_state[MAX_INTERFACE_NUM];
31u8 vref_window_size[MAX_INTERFACE_NUM][MAX_BUS_NUM];
32u8 vref_window_size_th = 12;
33
34static u8 pup_st[MAX_BUS_NUM][MAX_INTERFACE_NUM];
35
36static 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
49
50int 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
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
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
119int 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
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 ®_data));
136 res[i] = (reg_data >> RESULT_DB_PHY_REG_RX_OFFSET) & 0x1f;
137 }
138
139 return 0;
140}
141
142
143
144
145
146
147
148
149
150
151
152
153int ddr3_tip_vref(u32 dev_num)
154{
155
156
157
158
159 u32 vref_map[8] = {
160 1, 2, 3, 4, 5, 6, 7, 0
161 };
162
163 u32 initial_step = VREF_INITIAL_STEP;
164
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
179 copy_start_pattern = start_pattern;
180 copy_end_pattern = end_pattern;
181
182
183 start_pattern = PATTERN_VREF;
184 end_pattern = PATTERN_VREF;
185
186
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
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
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
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
303
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
310
311
312
313 if (current_vref[pup]
314 [if_id] == VREF_MAX_INDEX) {
315
316
317
318
319
320
321
322
323
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
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
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
404
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
418 if ((current_vref[pup]
419 [if_id] - second_step) == lim_vref[pup][if_id]) {
420
421
422
423
424
425
426
427
428
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
453 if (current_vref[pup]
454 [if_id] ==
455 lim_vref[pup]
456 [if_id]) {
457
458
459
460
461
462
463
464
465
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
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
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
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
564
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
625 start_pattern = copy_start_pattern;
626 end_pattern = copy_end_pattern;
627
628 return 0;
629}
630
631
632
633
634int 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
642
643
644
645
646
647
648
649
650
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
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
672
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