• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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