3 #include <asm/arch/adc_drvapi.h>
4 #include <asm/arch/adi_hal_internal.h>
5 #include <asm/arch/sprd_reg.h>
7 int regulator_default_get(const char con_id[]);
8 void regulator_default_set(const char con_id[], int vol);
9 int regulator_default_set_all(void);
10 u32 regulator_get_calibration_mask(void);
14 #define debug0(format, arg...)
15 #define debug(format, arg...) printf("\t" format, ## arg)
16 #define debug2(format, arg...) printf("\t\t" format, ## arg)
18 /* abs() handles unsigned and signed longs, ints, shorts and chars. For all input types abs()
19 * returns a signed long.
20 * abs() should not be used for 64-bit types (s64, u64, long long) - use abs64() for those.*/
23 if (sizeof(x) == sizeof(long)) { \
25 ret = (__x < 0) ? -__x : __x; \
28 ret = (__x < 0) ? -__x : __x; \
37 /* On ARMv5 and above those functions can be implemented around the clz instruction for
38 * much better code efficiency. */
40 static inline int fls(int x)
44 asm("clz\t%0, %1": "=r"(ret):"r"(x));
49 #define __fls(x) (fls(x) - 1)
50 #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
51 #define __ffs(x) (ffs(x) - 1)
52 #define ffz(x) __ffs( ~(x) )
54 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
56 #define MEASURE_TIMES (15)
58 #define ADC_DROP_CNT ( DIV_ROUND(MEASURE_TIMES, 5) )
59 static int __average(int a[], int N)
62 for (i = 0; i < N; i++)
64 return DIV_ROUND(sum, N);
67 static void bubble_sort(int a[], int N)
70 for (i = 0; i < N - 1; i++) {
71 for (j = i + 1; j < N; j++) {
81 int sci_adc_request(int channel)
84 int results[MEASURE_TIMES];
86 if (-1 == ADC_GetValues(channel, ADC_SCALE_3V, MEASURE_TIMES, results)) {
90 bubble_sort(results, MEASURE_TIMES);
93 for (i = 0; i < MEASURE_TIMES; i++) {
94 printf("%d ", results[i]);
98 return __average(&results[ADC_DROP_CNT], MEASURE_TIMES - ADC_DROP_CNT * 2);
101 #define RATIO(_n_, _d_) (_n_ << 16 | _d_)
103 static int sci_adc_ratio(int channel, int mux)
108 case 0x0D: //dcdccore
115 case 0x15: //DCDC Supply LDO
117 case 0x13: //DCDCVBATBK
118 case 0x14: //DCDCHEADMIC
119 case 0x16: //VBATD Domain LDO
120 case 0x17: //VBATA Domain LDO
121 case 0x1E: //DP from terminal
122 case 0x1F: //DM from terminal
131 static u32 bat_numerators, bat_denominators = 0;
132 extern uint16_t sprdbat_auxadc2vbatvol (uint16_t adcvalue);
134 int sci_adc_vol_request(int channel, int mux)
137 adc_res = sci_adc_request(channel);
139 u32 res, chan_numerators, chan_denominators;
140 res = (u32) sci_adc_ratio(channel, mux);
141 chan_numerators = res >> 16;
142 chan_denominators = res & 0xffff;
143 return sprdbat_auxadc2vbatvol(adc_res)
144 * (bat_numerators * chan_denominators)
145 / (bat_denominators * chan_numerators);
150 /* Simple shorthand for a section definition */
152 # define __section(S) __attribute__ ((__section__(#S)))
155 #define __init0 __section(.rodata.regu.init0)
156 #define __init1 __section(.rodata.regu.init1)
157 #define __init2 __section(.rodata.regu.init2)
159 const u32 __init0 __init_begin = 0xeeeebbbb;
160 const u32 __init2 __init_end = 0xddddeeee;
162 struct regulator_regs {
164 u32 pd_set, pd_set_bit;
165 /* at new feature, some LDOs had only set, no rst bits.
166 * and DCDCs voltage and trimming controller is the same register */
167 u32 pd_rst, pd_rst_bit;
168 u32 slp_ctl, slp_ctl_bit;
169 u32 vol_trm, vol_trm_bits;
170 u32 cal_ctl, cal_ctl_bits;
172 u32 vol_ctl, vol_ctl_bits;
173 u32 vol_sel_cnt, vol_sel[];
176 struct regulator_desc {
179 struct regulator_regs *regs;
182 #define REGU_VERIFY_DLY (1000) /*ms */
183 #define SCI_REGU_REG(VDD, TYP, PD_SET, SET_BIT, PD_RST, RST_BIT, SLP_CTL, SLP_CTL_BIT, \
184 VOL_TRM, VOL_TRM_BITS, CAL_CTL, CAL_CTL_BITS, VOL_DEF, \
185 VOL_CTL, VOL_CTL_BITS, VOL_SEL_CNT, ...) \
186 static struct regulator_regs REGS_##VDD = { \
189 .pd_set_bit = SET_BIT, \
191 .pd_rst_bit = RST_BIT, \
192 .slp_ctl = SLP_CTL, \
193 .slp_ctl_bit = SLP_CTL_BIT, \
194 .vol_trm = VOL_TRM, \
195 .vol_trm_bits = VOL_TRM_BITS, \
196 .cal_ctl = CAL_CTL, \
197 .cal_ctl_bits = CAL_CTL_BITS, \
198 .vol_def = VOL_DEF, \
199 .vol_ctl = VOL_CTL, \
200 .vol_ctl_bits = VOL_CTL_BITS, \
201 .vol_sel_cnt = VOL_SEL_CNT, \
202 .vol_sel = {__VA_ARGS__}, \
204 struct regulator_desc __init1 DESC_##VDD = { \
207 .regs = ®S_##VDD, \
210 #include <asm/arch/chip_x15/__regs_regulator_map.h>
213 /* standard dcdc ops*/
214 static int adjust_ldo_vol_base(struct regulator_desc *desc)
216 struct regulator_regs *regs = desc->regs;
218 if (regs->vol_sel_cnt == 2) {
219 if ((0 == strcmp(desc->name, "vdd18"))
220 || (0 == strcmp(desc->name, "vddemmcio"))
221 || (0 == strcmp(desc->name, "vddcamd"))
222 || (0 == strcmp(desc->name, "vddcamio"))) {
224 regs->vol_sel[0] = 1400;
227 debug0("%s vol base %dmv\n", desc->name, regs->vol_sel[0]);
228 return regs->vol_sel[0];
231 static int __dcdc_is_up_down_adjust(struct regulator_desc *desc)
233 return ((0 == strcmp(desc->name, "dcdcmem")) ? 1 : 0);
236 static int dcdc_get_trimming_step(struct regulator_desc *desc, int to_vol)
238 /* FIXME: vddmem step 200/32mV */
239 return (!strcmp(desc->name, "dcdcmem") ) ? (1000 * 200 / 32) : (1000 * 100 / 32) /*uV */;
242 static int __match_dcdc_vol(struct regulator_desc *desc, u32 vol)
245 int ds, min_ds = 100; /* mV, the max range of small voltage */
246 const struct regulator_regs *regs = desc->regs;
248 for (i = 0; i < regs->vol_sel_cnt; i++) {
249 ds = vol - regs->vol_sel[i];
250 if (ds >= 0 && ds < min_ds) {
257 for (i = 0; i < regs->vol_sel_cnt; i++) {
258 ds = abs(vol - regs->vol_sel[i]);
269 static int dcdc_get_voltage(struct regulator_desc *desc)
271 const struct regulator_regs *regs = desc->regs;
273 int cal = 0; /* uV */
274 int i, shft = __ffs(regs->vol_ctl_bits);
276 i = (ANA_REG_GET(regs->vol_ctl) & regs->vol_ctl_bits) >> shft;
277 mv = regs->vol_sel[i];
279 cal = (ANA_REG_GET(regs->vol_trm) & regs->vol_trm_bits) >> __ffs(regs->vol_trm_bits);
280 if (__dcdc_is_up_down_adjust(desc)) {
283 cal *= dcdc_get_trimming_step(desc, 0); /*uV */
285 debug0("%s %d +%dmv\n", desc->name, mv, cal / 1000);
286 return mv + cal / 1000;
289 static int dcdc_set_voltage(struct regulator_desc *desc, int min_mV, int max_mV)
291 const struct regulator_regs *regs = desc->regs;
294 /* found the closely vol ctrl bits */
295 i = __match_dcdc_vol(desc, mv);
297 debug2("%s: %s failed to match voltage: %d\n",__func__,desc->name,mv);
301 /* dcdc calibration control bits (default 0) small adjust voltage: 100/32mv ~= 3.125mv */
303 int shft_ctl = __ffs(regs->vol_ctl_bits);
304 int shft_trm = __ffs(regs->vol_trm_bits);
305 int step = dcdc_get_trimming_step(desc, mv);
306 int j = (int)(mv - (int)regs->vol_sel[i]) * 1000 / step;
308 if (__dcdc_is_up_down_adjust(desc))
311 debug2("regu_dcdc %p (%s) %d = %d %+dmv (trim=%d step=%duv);\n", regs, desc->name,
312 mv, regs->vol_sel[i], mv - regs->vol_sel[i], j, step);
314 if (j >= 0 && j <= (regs->vol_trm_bits >> shft_trm))
315 ANA_REG_MSK_OR(regs->vol_ctl, (j << shft_trm) | (i << shft_ctl),
316 regs->vol_trm_bits | regs->vol_ctl_bits);
321 static int dcdc_set_trimming(struct regulator_desc *desc, int def_vol, int to_vol, int adc_vol)
323 //int acc_vol = dcdc_get_trimming_step(desc, to_vol) / 1000;
324 int ctl_vol = (def_vol - (adc_vol - to_vol));
326 return dcdc_set_voltage(desc, ctl_vol, ctl_vol);
329 static int ldo_get_voltage(struct regulator_desc *desc)
331 const struct regulator_regs *regs = desc->regs;
334 if (regs->vol_trm && regs->vol_sel_cnt == 2) {
335 int shft = __ffs(regs->vol_trm_bits);
337 (ANA_REG_GET(regs->vol_trm) & regs->vol_trm_bits) >> shft;
338 vol = regs->vol_sel[0] * 1000 + trim * regs->vol_sel[1];
340 debug0("%s voltage %dmv\n", desc->name, vol);
347 static int ldo_set_trimming(struct regulator_desc *desc, int def_vol, int to_vol, int adc_vol)
349 const struct regulator_regs *regs = desc->regs;
352 if (!regs->vol_ctl && regs->vol_sel_cnt == 2) {
353 /* ctl_vol = vol_base + reg[vol_trm] * vol_step */
354 int shft = __ffs(regs->vol_trm_bits);
355 int ctl_vol = (def_vol - (adc_vol - to_vol)); //same as dcdc?
358 trim = DIV_ROUND_UP((ctl_vol - regs->vol_sel[0]) * 1000, regs->vol_sel[1]);
360 trim = ((ctl_vol - regs->vol_sel[0]) * 1000 / regs->vol_sel[1]);
362 debug2("regu_ldo %p (%s) %d = %d %+dmv (trim=%d step=%duv vol_base=%dmv)\n", regs, desc->name,
363 ctl_vol, regs->vol_sel[0], ctl_vol - regs->vol_sel[0], trim, regs->vol_sel[1], regs->vol_sel[0]);
365 if ((trim >= 0) && (trim <= (regs->vol_trm_bits >> shft))) {
366 ANA_REG_MSK_OR(regs->vol_trm,
376 static int DCDC_Cal_One(struct regulator_desc *desc, int is_cal)
378 struct regulator_regs *regs = desc->regs;
379 int def_vol = 0, to_vol = 0;
380 int adc_vol = 0, cal_vol = 0;
381 int ret = -1, adc_chan = regs->cal_ctl_bits >> 16;
382 u16 ldo_cal_sel = regs->cal_ctl_bits & 0xFFFF;
384 if (!adc_chan || !regs->vol_def)
387 if(0x2711A000 == ANA_GET_CHIP_ID()) {
388 if (desc->regs->typ == 0) {
389 adjust_ldo_vol_base(desc);
394 ANA_REG_OR(regs->cal_ctl, ldo_cal_sel);
397 * FIXME: force get dcdc&ldo voltage from ana global regs
398 * and get ideal voltage from vol para.
400 if (desc->regs->typ == 2 /*DCDC*/) {
401 def_vol = dcdc_get_voltage(desc);
403 else if (desc->regs->typ == 0 /*LDO*/) {
404 def_vol = ldo_get_voltage(desc);
407 to_vol = regulator_default_get(desc->name);
409 to_vol = regs->vol_def;
411 adc_vol = sci_adc_vol_request(adc_chan, ldo_cal_sel);
413 debug("%s default %dmv, adc channel %d, maybe not enable\n", desc->name, def_vol, adc_chan);
417 cal_vol = abs(adc_vol - to_vol);
418 debug("%s default %dmv, from %dmv to %dmv, bias %c%d.%03d%%\n",
419 desc->name, def_vol, adc_vol, to_vol,
420 (adc_vol > to_vol) ? '+' : '-',
421 cal_vol * 100 / to_vol, cal_vol * 100 * 1000 / to_vol % 1000);
423 if (!def_vol || !to_vol || adc_vol <= 0)
425 if (abs(adc_vol - def_vol) >= def_vol / 9) /* adjust limit 9% */
427 else if (cal_vol < to_vol / 100) { /* bias 1% */
432 if (regs->typ == 2/*VDD_TYP_DCDC*/)
433 ret = dcdc_set_trimming(desc, def_vol, to_vol, adc_vol);
434 else if (regs->typ == 0/*VDD_TYP_LDO*/)
435 ret = ldo_set_trimming(desc, def_vol, to_vol, adc_vol);
438 regulator_default_set(desc->name, 0);
443 ANA_REG_BIC(regs->cal_ctl, ldo_cal_sel);
448 int DCDC_Cal_ArmCore(void)
450 u16 regval_dcdc_store, regval_ldo_store;
452 struct regulator_desc *desc = NULL;
453 struct regulator_desc *desc_end = NULL;
454 u32 cali_mask = regulator_get_calibration_mask();
455 u32 chip_id = ANA_GET_CHIP_ID();
457 printf("%s; adie chip id 0x%08x\n", __FUNCTION__, chip_id);
459 regval_dcdc_store = ANA_REG_GET(ANA_REG_GLB_LDO_DCDC_PD) & 0xFFFF;
460 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, BITS_PWR_WR_PROT_VALUE(0x6e7f), 0x7FFF);
461 ANA_REG_BIC(ANA_REG_GLB_LDO_DCDC_PD, (cali_mask >> 16));
462 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, 0, 0x7FFF);
464 regval_ldo_store = ANA_REG_GET(ANA_REG_GLB_LDO_PD_CTRL) & 0xFFFF;
465 ANA_REG_BIC(ANA_REG_GLB_LDO_PD_CTRL, cali_mask & 0xFFFF);
467 if(0x2711A000 == chip_id) {
468 //FIXME: vddcamio/vddcamd/vddemmcio/vdd18 real voltage value is greater than design value
469 ANA_REG_MSK_OR(ANA_REG_GLB_LDO_V_CTRL9, BITS_LDO_VDD18_V(0x40),
470 BITS_LDO_VDD18_V(-1)); //0x68D2 -->0x40D2
471 ANA_REG_MSK_OR(ANA_REG_GLB_LDO_V_CTRL2, BITS_LDO_EMMCIO_V(0x40),
472 BITS_LDO_EMMCIO_V(-1)); //0x3C68 -->0x3C40
473 ANA_REG_MSK_OR(ANA_REG_GLB_LDO_V_CTRL1, BITS_LDO_CAMIO_V(0x40) | BITS_LDO_CAMD_V(0x10),
474 BITS_LDO_CAMIO_V(-1) | BITS_LDO_CAMD_V(-1)); //0x6838 -->0x4010
475 udelay(200 * 1000); //wait 200ms
478 /* FIXME: Update CHGMNG_AdcvalueToVoltage table before setup vbat ratio. */
479 /*ADC_CHANNEL_VBAT is 5*/
480 res = (u32) sci_adc_ratio(5, 0);
481 bat_numerators = res >> 16;
482 bat_denominators = res & 0xffff;
485 /* TODO: calibrate all DCDCs */
486 desc = (struct regulator_desc *)(&__init_begin + 1);
488 printf("%p (%x) -- %p -- %p (%x)\n", &__init_begin, __init_begin,
489 desc, &__init_end, __init_end);
491 desc_end = (struct regulator_desc *)&__init_end;
492 while (--desc_end >= desc) { /* reverse order */
493 printf("\nCalibrate %s ...\n", desc_end->name);
494 DCDC_Cal_One(desc_end, 1);
497 /* wait a moment for LDOs ready */
500 /* TODO: verify all DCDCs */
501 desc = (struct regulator_desc *)(&__init_begin + 1);
502 desc_end = (struct regulator_desc *)&__init_end;
503 while (--desc_end >= desc) { /* reverse order */
504 printf("\nVerify %s ...\n", desc_end->name);
505 DCDC_Cal_One(desc_end, 0);
508 /* restore adie dcdc/ldo PD bits */
509 ANA_REG_SET(ANA_REG_GLB_LDO_PD_CTRL, regval_ldo_store);
510 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, BITS_PWR_WR_PROT_VALUE(0x6e7f), 0x7FFF);
511 ANA_REG_SET(ANA_REG_GLB_LDO_DCDC_PD, regval_dcdc_store);
512 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, 0, 0x7FFF);
518 int regulator_init(void)
521 * FIXME: turn on all DCDC/LDOs if need
526 struct regulator_desc *regulator_get(void/*struct device*/ *dev, const char *id)
528 struct regulator_desc *desc =
529 (struct regulator_desc *)(&__init_begin + 1);
530 while (desc < (struct regulator_desc *)&__init_end) {
531 if (0 == strcmp(desc->name, id))
538 int regulator_disable_all(void)
540 ANA_REG_OR(ANA_REG_GLB_LDO_PD_CTRL, 0x7ff);
541 ANA_REG_OR(ANA_REG_GLB_LDO_DCDC_PD, 0x1fff);
544 int regulator_enable_all(void)
546 ANA_REG_BIC(ANA_REG_GLB_LDO_DCDC_PD, 0x1fff);
547 ANA_REG_BIC(ANA_REG_GLB_LDO_PD_CTRL, 0x7ff);
550 int regulator_disable(const char con_id[])
552 struct regulator_desc *desc = regulator_get(0, con_id);
554 struct regulator_regs *regs = desc->regs;
555 ANA_REG_OR(regs->pd_set, regs->pd_set_bit);
560 int regulator_enable(const char con_id[])
562 struct regulator_desc *desc = regulator_get(0, con_id);
564 struct regulator_regs *regs = desc->regs;
565 ANA_REG_BIC(regs->pd_set, regs->pd_set_bit);
570 int regulator_set_voltage(const char con_id[], int to_vol)
573 struct regulator_desc *desc = regulator_get(0, con_id);
575 struct regulator_regs *regs = desc->regs;
576 if (regs->typ == 2/*VDD_TYP_DCDC*/)
577 ret = dcdc_set_voltage(desc, to_vol, 0);
578 else if (regs->typ == 0/*VDD_TYP_LDO*/)
579 ret = ldo_set_trimming(desc, 0, to_vol, 0);
589 vol_para_t **ppvol_para = 0x50005c20;
591 static int get_vol_para_num(void)
595 if (!(ppvol_para && *ppvol_para))
598 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
601 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end"))
607 static vol_para_t * match_vol_para(const char* vol_name)
611 BUG_ON(NULL == vol_name);
613 if (!(ppvol_para && *ppvol_para))
616 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
619 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end")) {
620 if (0 == strcmp((*ppvol_para)[i].name, vol_name)) {
621 debug("%s name %s, ideal_vol %d\n", __func__, (*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
622 return (vol_para_t*)(&(*ppvol_para)[i]);
629 int regulator_default_get(const char con_id[])
631 vol_para_t * pvol_para = match_vol_para(con_id);
633 return (int)(pvol_para ? pvol_para->ideal_vol : 0);
636 void regulator_default_set(const char con_id[], int vol)
638 vol_para_t * pvol_para = match_vol_para(con_id);
641 pvol_para->ideal_vol = vol;
645 int regulator_default_set_all(void)
649 //dump & check all vol para
650 if (!(ppvol_para && *ppvol_para))
653 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
656 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end")) {
657 debug("regu: [%d] %s : %d\n", i, (*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
659 ret |= regulator_set_voltage((*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
665 /********************************************************************
667 * regulator_get_calibration_mask - get dcdc/ldo calibration flag
670 //High 16bit: dcdc ctrl calibration flag
672 * bit[13] ~ bit[15] : reserved
678 * bit[7] : vddemmccore
688 //Low 16bit: ldo ctrl calibration flag
690 * bit[12] ~ bit[15] : reserved
703 ********************************************************************/
704 u32 regulator_get_calibration_mask(void)
706 int len = get_vol_para_num();
707 volatile vol_para_t *pvol_para = (volatile vol_para_t *)(*ppvol_para);
708 volatile u32* pdebug_flag = (u32*)(&pvol_para[len-1]);
711 printf("%s, vol_para_tbl_len %d, ldo_pd_mask 0x%08x; \n", __func__, len, *pdebug_flag);
712 return (*pdebug_flag);