1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 #include <asm/arch/platform.h>
20 #include <config.h>
21 #include <compiler.h>
22 #include "ddr_training_impl.h"
23
24 #define HI_SYS_CTL_REG SYS_CTRL_REG_BASE
25
26 #define OK 0
27 #define ERROR -1
28 #define DDR_CA0_OFST 0x24
29 #define DDR_CA1_OFST 0x28
30 #define DDR_CA2_OFST 0x2c
31 #define REG_BASE_DDRC 0x11130000
32
33 #define DDRC_CTRL_SREF_OFST 0x8000 + 0x0
34 #define DDRC_CFG_DDRMODE_OFST 0x8000 + 0X50
35 #define DDRC_CURR_FUNC_OFST 0x8000 + 0x294
36
37 #define DDRC1_CTRL_SREF_OFST 0x9000 + 0x0
38 #define DDRC1_CFG_DDRMODE_OFST 0x9000 + 0X50
39 #define DDRC1_CURR_FUNC_OFST 0x9000 + 0x294
40
41 #define DDRC2_CTRL_SREF_OFST 0xa000 + 0x0
42 #define DDRC2_CFG_DDRMODE_OFST 0xa000 + 0X50
43 #define DDRC2_CURR_FUNC_OFST 0xa000 + 0x294
44
45 #define DDRC3_CTRL_SREF_OFST 0xb000 + 0x0
46 #define DDRC3_CFG_DDRMODE_OFST 0xb000 + 0X50
47 #define DDRC3_CURR_FUNC_OFST 0xb000 + 0x294
48
49 #define DDRC_SELF_REFURBISH_MASK (0x1)
50
delay(unsigned int num)51 static inline void delay(unsigned int num)
52 {
53 volatile unsigned int i;
54
55 for (i = 0; i < (100 * num); i++)
56 __asm__ __volatile__("nop");
57 }
58
59 extern void reset_cpu(unsigned long addr);
60
DWB(void)61 static inline void DWB(void) /* drain write buffer */
62 {
63 }
64
readl(unsigned addr)65 static inline unsigned int readl(unsigned addr)
66 {
67 unsigned int val;
68
69 val = (*(volatile unsigned int *)(uintptr_t)(addr));
70 return val;
71 }
72
writel(unsigned val,unsigned addr)73 static inline void writel(unsigned val, unsigned addr)
74 {
75 DWB();
76 (*(volatile unsigned *)(uintptr_t)(addr)) = val;
77 DWB();
78 }
79
80 #define REG_BASE_MISC 0x11024000
81
82 #ifdef DDR_SCRAMB_ENABLE
83
84 #undef reg_get
85 #define reg_get(addr) (*(volatile unsigned int *)((long)addr))
86
87 #undef reg_set
88 #define reg_set(addr, val) (*(volatile unsigned int *)((long)addr) = (val))
ddr_scramb_start(unsigned int random1,unsigned int random2)89 void ddr_scramb_start(unsigned int random1, unsigned int random2)
90 {
91
92 reg_set((unsigned int *)(REG_BASE_MISC + DDR_CA0_OFST), random1);
93 reg_set((unsigned int *)(REG_BASE_MISC + DDR_CA1_OFST), random2);
94 reg_set((unsigned int *)(REG_BASE_MISC + DDR_CA2_OFST), 0);
95 reg_set((unsigned int *)(REG_BASE_MISC + DDR_CA2_OFST), 0x10);
96 delay(0x100);
97 reg_set((unsigned int *)(REG_BASE_MISC + DDR_CA0_OFST), 0);
98 reg_set((unsigned int *)(REG_BASE_MISC + DDR_CA1_OFST), 0);
99 }
100
101 #define REG_BASE_RNG_GEN 0x10130000
102 #define TRNG_DSTA_FIFO_DATA_OFST 0x204
103 #define TRNG_DATA_ST_OFST 0x208
104 #define HISEC_COM_TRNG_CTRL_OFST 0x200
105
106 #define BIT_TRNG_FIFO_DATA_CNT 0x8
107 #define TRNG_FIFO_DATA_CNT_MASK 0xff
108 #define TRNG_CTRL_DEF_VAL 0xa
109
110 #define REG_PERI_CRG_TRNG 0x2d80
111 #define TRNG_CLK_ENABLE (0x1 << 4)
112 #define TRNG_DO_SRST (0x1 << 0)
113 #define TRNG_CLK_DISABLE ~(0x1 << 4)
114 #define TRNG_UNDO_SRST ~(0x1 << 0)
115
116 /* get random number */
get_random_num(void)117 int get_random_num(void)
118 {
119 unsigned int reg_val = 0;
120
121 do {
122 reg_val = reg_get(REG_BASE_RNG_GEN + TRNG_DATA_ST_OFST);
123
124 } while (!((reg_val >> BIT_TRNG_FIFO_DATA_CNT) &
125 TRNG_FIFO_DATA_CNT_MASK));
126
127 reg_val = reg_get(REG_BASE_RNG_GEN + TRNG_DSTA_FIFO_DATA_OFST);
128
129 return reg_val;
130 }
131
trng_init(void)132 void trng_init(void)
133 {
134 unsigned int reg_val = 0;
135
136 /* open trng clock */
137 reg_val = reg_get(CRG_REG_BASE + REG_PERI_CRG_TRNG);
138 reg_val |= TRNG_CLK_ENABLE;
139 reg_val &= TRNG_UNDO_SRST;
140 reg_set(CRG_REG_BASE + REG_PERI_CRG_TRNG, reg_val);
141
142 /* set trng ctrl register */
143 reg_set(REG_BASE_RNG_GEN + HISEC_COM_TRNG_CTRL_OFST,
144 TRNG_CTRL_DEF_VAL);
145 }
146
trng_deinit(void)147 void trng_deinit(void)
148 {
149 unsigned int reg_val = 0;
150
151 /* close trng clock */
152 reg_val = reg_get(CRG_REG_BASE + REG_PERI_CRG_TRNG);
153 reg_val &= TRNG_CLK_DISABLE;
154 reg_set(CRG_REG_BASE + REG_PERI_CRG_TRNG, reg_val);
155 }
156
ddr_scramb(void)157 int ddr_scramb(void)
158 {
159 unsigned int random_num1 = 0;
160 unsigned int random_num2 = 0;
161 unsigned int reg_val[4] = {0,0,0,0};
162 unsigned int ddrca_val[4] = {0, 0, 0, 0};
163 unsigned int ddrc_isvalid[4] = {0,0,0,0};
164
165 /* read ddrc_cfg_ddrmode register,
166 * if value[3:0] is not 0x0 ,the channel is valid.
167 */
168 ddrc_isvalid[0] = (reg_get(REG_BASE_DDRC + DDRC_CFG_DDRMODE_OFST) & 0xf)?1:0;
169 ddrc_isvalid[1] = (reg_get(REG_BASE_DDRC + DDRC1_CFG_DDRMODE_OFST)& 0xf)?1:0;
170 ddrc_isvalid[2] = (reg_get(REG_BASE_DDRC + DDRC2_CFG_DDRMODE_OFST)& 0xf)?1:0;
171 ddrc_isvalid[3] = (reg_get(REG_BASE_DDRC + DDRC3_CFG_DDRMODE_OFST)& 0xf)?1:0;
172
173 /* set ddrc to do self-refurbish */
174 if(ddrc_isvalid[0])
175 reg_set(REG_BASE_DDRC + DDRC_CTRL_SREF_OFST, 0x1);
176 if(ddrc_isvalid[1])
177 reg_set(REG_BASE_DDRC + DDRC1_CTRL_SREF_OFST, 0x1);
178 if(ddrc_isvalid[2])
179 reg_set(REG_BASE_DDRC + DDRC2_CTRL_SREF_OFST, 0x1);
180 if(ddrc_isvalid[3])
181 reg_set(REG_BASE_DDRC + DDRC3_CTRL_SREF_OFST, 0x1);
182
183 /* wait the status of ddrc to be sef-refurbish */
184 do {
185 reg_val[0] = ddrc_isvalid[0]?(reg_get(REG_BASE_DDRC + DDRC_CURR_FUNC_OFST) & 0x1):1;
186 reg_val[1] = ddrc_isvalid[1]?(reg_get(REG_BASE_DDRC + DDRC1_CURR_FUNC_OFST) & 0x1):1;
187 reg_val[2] = ddrc_isvalid[2]?(reg_get(REG_BASE_DDRC + DDRC2_CURR_FUNC_OFST) & 0x1):1;
188 reg_val[3] = ddrc_isvalid[3]?(reg_get(REG_BASE_DDRC + DDRC3_CURR_FUNC_OFST) & 0x1):1;
189
190 } while (!(reg_val[0] & reg_val[1] & reg_val[2] & reg_val[3]));
191
192
193 if (ddrc_isvalid[0]) {
194 ddrca_val[0] = reg_get(REG_BASE_DDRC + 0x8164);
195 reg_set(REG_BASE_DDRC + 0x8184, ddrca_val[0]);
196
197 ddrca_val[1] = reg_get(REG_BASE_DDRC + 0x8168);
198 reg_set(REG_BASE_DDRC + 0x8188, ddrca_val[1]);
199
200 ddrca_val[2] = reg_get(REG_BASE_DDRC + 0x816c);
201 reg_set(REG_BASE_DDRC + 0x8048, ddrca_val[2]);
202 }
203
204 if (ddrc_isvalid[1]) {
205 ddrca_val[0] = reg_get(REG_BASE_DDRC + 0x9164);
206 reg_set(REG_BASE_DDRC + 0x9184, ddrca_val[0]);
207
208 ddrca_val[1] = reg_get(REG_BASE_DDRC + 0x9168);
209 reg_set(REG_BASE_DDRC + 0x9188, ddrca_val[1]);
210
211 ddrca_val[2] = reg_get(REG_BASE_DDRC + 0x916c);
212 reg_set(REG_BASE_DDRC + 0x9048, ddrca_val[2]);
213 }
214
215 if (ddrc_isvalid[2]) {
216 ddrca_val[0] = reg_get(REG_BASE_DDRC + 0xa164);
217 reg_set(REG_BASE_DDRC + 0xa184, ddrca_val[0]);
218
219 ddrca_val[1] = reg_get(REG_BASE_DDRC + 0xa168);
220 reg_set(REG_BASE_DDRC + 0xa188, ddrca_val[1]);
221
222 ddrca_val[2] = reg_get(REG_BASE_DDRC + 0xa16c);
223 reg_set(REG_BASE_DDRC + 0xa048, ddrca_val[2]);
224 }
225
226 if (ddrc_isvalid[3]) {
227 ddrca_val[0] = reg_get(REG_BASE_DDRC + 0xb164);
228 reg_set(REG_BASE_DDRC + 0xb184, ddrca_val[0]);
229
230 ddrca_val[1] = reg_get(REG_BASE_DDRC + 0xb168);
231 reg_set(REG_BASE_DDRC + 0xb188, ddrca_val[1]);
232
233 ddrca_val[2] = reg_get(REG_BASE_DDRC + 0xb16c);
234 reg_set(REG_BASE_DDRC + 0xb048, ddrca_val[2]);
235 }
236
237 trng_init();
238 /* get random number */
239 random_num1 = get_random_num();
240 random_num2 = get_random_num();
241
242 /* start ddr scrambling */
243 ddr_scramb_start(random_num1, random_num2);
244
245 /* clear random number */
246 (void)get_random_num();
247 (void)get_random_num();
248 (void)get_random_num();
249 (void)get_random_num();
250 trng_deinit();
251
252 /* set ddrc to exit self-refurbish */
253 if(ddrc_isvalid[0])
254 reg_set(REG_BASE_DDRC + DDRC_CTRL_SREF_OFST, (0x1<<1));
255 if(ddrc_isvalid[1])
256 reg_set(REG_BASE_DDRC + DDRC1_CTRL_SREF_OFST, (0x1<<1));
257 if(ddrc_isvalid[2])
258 reg_set(REG_BASE_DDRC + DDRC2_CTRL_SREF_OFST, (0x1<<1));
259 if(ddrc_isvalid[3])
260 reg_set(REG_BASE_DDRC + DDRC3_CTRL_SREF_OFST, (0x1<<1));
261
262 /* wait the status of ddrc to be normal */
263 do {
264 reg_val[0] = ddrc_isvalid[0]?(reg_get(REG_BASE_DDRC + DDRC_CURR_FUNC_OFST) & 0x1):0;
265 reg_val[1] = ddrc_isvalid[1]?(reg_get(REG_BASE_DDRC + DDRC1_CURR_FUNC_OFST) & 0x1):0;
266 reg_val[2] = ddrc_isvalid[2]?(reg_get(REG_BASE_DDRC + DDRC2_CURR_FUNC_OFST) & 0x1):0;
267 reg_val[3] = ddrc_isvalid[3]?(reg_get(REG_BASE_DDRC + DDRC3_CURR_FUNC_OFST) & 0x1):0;
268 } while (reg_val[0] | reg_val[1] | reg_val[2] | reg_val[3]);
269
270 return OK;
271 }
272
273 #endif /* DDR_SCRAMB_ENABLE */
274
275 #define HPM_CORE_VOL_REG 0x11029000
276 #define HPM_CPU_VOL_REG 0x11029004
277
278 #define HMP_CLK_REG 0x11014A80
279 #define CPU_HPM_CTRL0_REG 0x1102B000
280 #define CORE_HPM_CTRL0_REG 0x1102B010
281 #define HPM_CPU_REG0 0x1102B008
282 #define HPM_CPU_REG1 0x1102B00c
283 #define HPM_CORE_REG0 0x1102B018
284 #define HPM_CORE_REG1 0x1102B01c
285 #define CYCLE_NUM 32
286 #define SVB_RECORD_REG0 0x11020340
287 #define SVB_RECORD_REG1 0x11020344
288
289 #define VOLTAGE_RECOED_REG 0x1102015C
290 #define SVB_VERSION_REG 0x11020168
291 #define SVB_VERSION 0x101
292 #define OTP_HPM_CORE_REG 0x11021504
293 #define OTP_HPM_CPU_REG 0x11021530
294 #define OTP_VOLTAGE_DELTA_CORE_REG 0x1102150C
295 #define OTP_VOLTAGE_DELTA_CPU_REG 0x11021518
296
297 #define TSENSOR_STATUS0 0X1102A008
298
hpm_value_avg(unsigned int * val,int num)299 static unsigned hpm_value_avg(unsigned int *val, int num)
300 {
301 unsigned int i;
302 unsigned tmp = 0;
303
304 for (i = 0; i < num; i++)
305 tmp += val[i] >> 2;
306
307 return tmp >> 5;
308 }
309
get_hpm_value(unsigned int * hpm_core,unsigned int * hpm_cpu)310 static void get_hpm_value(unsigned int *hpm_core, unsigned int *hpm_cpu)
311 {
312 int i;
313 unsigned int temp;
314 unsigned int core_value[4];
315 unsigned int cpu_value[4];
316
317 core_value[0] = 0;
318 core_value[1] = 0;
319 core_value[2] = 0;
320 core_value[3] = 0;
321
322 cpu_value[0] = 0;
323 cpu_value[1] = 0;
324 cpu_value[2] = 0;
325 cpu_value[3] = 0;
326
327 for (i = 0; i < CYCLE_NUM; i++) {
328 delay(24);
329
330 /* cpu */
331 temp = readl(HPM_CPU_REG0);
332 cpu_value[1] += (temp >> 16) & 0x3ff;
333 cpu_value[0] += temp & 0x3ff;
334 temp = readl(HPM_CPU_REG1);
335 cpu_value[3] += (temp >> 16) & 0x3ff;
336 cpu_value[2] += temp & 0x3ff;
337
338 /* core */
339 temp = readl(HPM_CORE_REG0);
340 core_value[1] += (temp >> 16) & 0x3ff;
341 core_value[0] += temp & 0x3ff;
342 temp = readl(HPM_CORE_REG1);
343 core_value[3] += (temp >> 16) & 0x3ff;
344 core_value[2] += temp & 0x3ff;
345 }
346
347 *hpm_core = hpm_value_avg(core_value, 4);
348 *hpm_cpu = hpm_value_avg(cpu_value, 4);
349 }
350
351
start_hpm(unsigned int * hpm_core,unsigned int * hpm_cpu)352 static void start_hpm(unsigned int *hpm_core, unsigned int *hpm_cpu)
353 {
354 /* core */
355 writel(0x60080001, CORE_HPM_CTRL0_REG);
356 /* cpu */
357 writel(0x60080001, CPU_HPM_CTRL0_REG);
358
359 delay(240); /*10ms*/
360
361 get_hpm_value(hpm_core, hpm_cpu);
362 }
363
hpm_check(unsigned int * hpm_core,unsigned int * hpm_cpu,int * temperature,unsigned int hpm_from_otp)364 static void hpm_check(unsigned int *hpm_core, unsigned int *hpm_cpu,
365 int *temperature, unsigned int hpm_from_otp)
366 {
367 union {
368 struct {
369 unsigned int sys_hpm_core : 9; /* [8..0]*/
370 unsigned int reserved_0 : 7; /* [15..9]*/
371 unsigned int sys_hpm_cpu : 9; /* [24..16]*/
372 unsigned int reserved_1 : 7; /* [31..25]*/
373 } bits;
374 unsigned int u32;
375 } hpm_reg0; /*SVB_RECORD_REG0 0x11020340*/
376
377 union {
378 struct {
379 signed char temperature : 8; /* [7..0]*/
380 unsigned int reserved_0 : 20; /* [27..8]*/
381 unsigned int temperature_err : 1; /* [28]*/
382 unsigned int hpm_cpu_err : 1; /* [29]*/
383 unsigned int hpm_core_err : 1; /* [30]*/
384 unsigned int from_otp : 1; /* [31]*/
385 } bits;
386 unsigned int u32;
387 } hpm_reg1; /*SVB_RECORD_REG1 0x11020344*/
388
389 hpm_reg0.u32 = 0;
390 hpm_reg1.u32 = 0;
391
392 if (*hpm_core < 200) {
393 *hpm_core = 200;
394 hpm_reg1.bits.hpm_core_err = 1;
395 }
396
397 if (*hpm_core > 300) {
398 *hpm_core = 300;
399 hpm_reg1.bits.hpm_core_err = 1;
400 }
401
402 if (*hpm_cpu < 240) {
403 *hpm_cpu = 240;
404 hpm_reg1.bits.hpm_cpu_err = 1;
405 }
406
407 if (*hpm_cpu > 330) {
408 *hpm_cpu = 330;
409 hpm_reg1.bits.hpm_cpu_err = 1;
410 }
411
412 if (*temperature < -40) {
413 *temperature = -40;
414 hpm_reg1.bits.temperature_err = 1;
415 }
416
417 if (*temperature > 110) {
418 *temperature = 110;
419 hpm_reg1.bits.temperature_err = 1;
420 }
421
422 hpm_reg0.bits.sys_hpm_core = *hpm_core;
423 hpm_reg0.bits.sys_hpm_cpu = *hpm_cpu;
424 hpm_reg1.bits.temperature = (signed char) *temperature;
425 hpm_reg1.bits.from_otp = hpm_from_otp;
426 writel(hpm_reg0.u32, SVB_RECORD_REG0);
427 writel(hpm_reg1.u32, SVB_RECORD_REG1);
428 }
429
voltage_check(double * pcore_mv,double * pcpu_mv,double core_delta_mv)430 static void voltage_check(double *pcore_mv, double *pcpu_mv, double core_delta_mv)
431 {
432 short otp_voltage_delta_core;
433 short otp_voltage_delta_cpu;
434
435 union {
436 struct {
437 unsigned int voltage_core : 12; /* [11..0]*/
438 unsigned int voltage_cpu : 12; /* [23..12]*/
439 unsigned int delta_core : 8; /* [31..24]*/
440 } bits;
441 unsigned int u32;
442 } voltage_reg;
443
444 otp_voltage_delta_core = (short)(readl(OTP_VOLTAGE_DELTA_CORE_REG) & 0xffff);
445 otp_voltage_delta_cpu = (short)(readl(OTP_VOLTAGE_DELTA_CPU_REG) & 0xffff);
446
447 *pcore_mv += (double)otp_voltage_delta_core;
448 *pcpu_mv += (double)otp_voltage_delta_cpu;
449
450 voltage_reg.u32 = 0;
451 voltage_reg.bits.voltage_core = (unsigned int)*pcore_mv;
452 voltage_reg.bits.voltage_cpu = (unsigned int)*pcpu_mv;
453 voltage_reg.bits.delta_core = (unsigned int)core_delta_mv;
454
455 writel(voltage_reg.u32, VOLTAGE_RECOED_REG);
456
457 }
458
set_hpm_core_volt(double mv)459 static void set_hpm_core_volt(double mv)
460 {
461 unsigned int svb_value;
462
463 svb_value = ((unsigned int)((1078000 - mv * 1000) * 84) & 0xffff0000) + 0x19f5;
464
465 writel(svb_value, HPM_CORE_VOL_REG);
466 }
467
set_hpm_cpu_volt(double mv)468 static void set_hpm_cpu_volt(double mv)
469 {
470 unsigned int svb_value;
471
472 svb_value = ((unsigned int)((1078000 - mv * 1000) * 84) & 0xffff0000) + 0x19f5;
473
474 writel(svb_value, HPM_CPU_VOL_REG);
475 }
476
477
get_temperature(int * temperature)478 static void get_temperature(int *temperature)
479 {
480 int value = 0;
481
482 value = (int)(readl(TSENSOR_STATUS0) & 0x3ff);
483 *temperature = (int)(((value - 127) * 165) / 784.0 ) - 40;
484 }
485
get_ate_hpm(unsigned int * pate_hpm_core,unsigned int * pate_hpm_cpu)486 static void get_ate_hpm(unsigned int *pate_hpm_core, unsigned int *pate_hpm_cpu)
487 {
488 *pate_hpm_core = (unsigned int)(readl(OTP_HPM_CORE_REG) & 0xffff);
489 *pate_hpm_cpu = (unsigned int)(readl(OTP_HPM_CPU_REG) & 0xffff);
490 }
491
start_svb(double * pcore_mv,double * pcpu_mv)492 static void start_svb(double *pcore_mv, double *pcpu_mv)
493 {
494 unsigned int ate_hpm_core;
495 unsigned int ate_hpm_cpu;
496 unsigned int hpm_core;
497 unsigned int hpm_cpu;
498 int temperature_delta;
499 double core_delta_mv;
500 int temperature;
501 unsigned int hpm_from_otp;
502 unsigned int version;
503
504 version = readl(SVB_VERSION_REG);
505 version = (version & 0x0000FFFF) | (SVB_VERSION << 16);
506 writel(version, SVB_VERSION_REG);
507
508 get_temperature(&temperature);
509 get_ate_hpm(&ate_hpm_core,&ate_hpm_cpu);
510
511 if ((!ate_hpm_core) || (!ate_hpm_cpu)) {
512 set_hpm_core_volt(900);
513 set_hpm_cpu_volt(1000);
514
515 /* open hmp clock */
516 writel(0x10, HMP_CLK_REG);
517 start_hpm(&hpm_core, &hpm_cpu);
518 hpm_from_otp = 0;
519 } else {
520 /*ATE SVB transfer to board SVB*/
521 hpm_core = ate_hpm_core - 5;
522 hpm_cpu = ate_hpm_cpu - 12;
523 hpm_from_otp = 1;
524 }
525
526 hpm_check(&hpm_core, &hpm_cpu, &temperature, hpm_from_otp);
527
528 /******************************** CORE ********************************/
529 *pcore_mv = 1330 - 1.533 * hpm_core;
530 temperature_delta = 110 - temperature;
531 if (temperature_delta > 85)
532 temperature_delta = 85;
533 core_delta_mv = ((((double)hpm_core - 200) / 3.3) + 30.0) * ((double)temperature_delta / 85.0);
534
535 /******************************** CPU *********************************/
536 *pcpu_mv = 1728.384 - 2.545 * hpm_cpu; /*svb001*/
537 if (*pcpu_mv > 1050)
538 *pcpu_mv = 1050;
539 if (*pcpu_mv < 910)
540 *pcpu_mv = 910;
541
542 voltage_check(pcore_mv, pcpu_mv, core_delta_mv);
543 set_hpm_core_volt(*pcore_mv - core_delta_mv);
544 set_hpm_cpu_volt(*pcpu_mv);
545
546 /* delay 10ms do not delete */
547 delay(240);
548 }
549
end_svb(const double * pcore_mv,const double * pcpu_mv)550 static void end_svb(const double *pcore_mv,const double *pcpu_mv)
551 {
552 set_hpm_core_volt(*pcore_mv);
553
554 /* delay 10ms do not delete */
555 delay(120);
556 }
557
start_ddr_training(unsigned int base)558 void start_ddr_training(unsigned int base)
559 {
560 double core_mv;
561 double cpu_mv;
562
563 start_svb(&core_mv, &cpu_mv);
564
565 /* ddr hw training */
566 ddr_hw_training_if();
567
568 /* ddr sw training */
569 ddr_sw_training_if();
570
571 /*the value should config after trainning, or
572 it will cause chip compatibility problems */
573 if ((readl(DDR_REG_BASE_PHY0 + DDR_PHY_DRAMCFG)
574 & PHY_DRAMCFG_TYPE_MASK) == PHY_DRAMCFG_TYPE_LPDDR4) {
575 writel(0x401, DDR_REG_BASE_DMC0 + 0x28);
576 writel(0x401, DDR_REG_BASE_DMC1 + 0x28);
577 } else
578 writel(0x401, DDR_REG_BASE_DMC0 + 0x28);
579
580 if ((readl(DDR_REG_BASE_PHY1 + DDR_PHY_DRAMCFG)
581 & PHY_DRAMCFG_TYPE_MASK) == PHY_DRAMCFG_TYPE_LPDDR4) {
582 writel(0x401, DDR_REG_BASE_DMC2 + 0x28);
583 writel(0x401, DDR_REG_BASE_DMC3 + 0x28);
584 } else
585 writel(0x401, DDR_REG_BASE_DMC1 + 0x28);
586
587 #ifdef DDR_SCRAMB_ENABLE
588 /* enable ddr scramb */
589 ddr_scramb();
590 #endif
591
592 end_svb(&core_mv, &cpu_mv);
593 }
594