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);
12 typedef void (*pfun)(int);
13 static pfun calibrate_post = NULL;
15 static u16 ana_mixed_ctl;
17 #define REGU_CALI_DEBUG
19 #ifdef REGU_CALI_DEBUG
20 #define regu_debug(fmt, arg...) printf(fmt, ## arg)
22 #define regu_debug(fmt, arg...)
26 #define debug0(format, arg...)
27 #define debug(format, arg...) regu_debug(format, ## arg)
28 #define debug1(format, arg...) regu_debug("\t" format, ## arg)
29 #define debug2(format, arg...) regu_debug("\t\t" format, ## arg)
31 /* abs() handles unsigned and signed longs, ints, shorts and chars. For all input types abs()
32 * returns a signed long.
33 * abs() should not be used for 64-bit types (s64, u64, long long) - use abs64() for those.*/
36 if (sizeof(x) == sizeof(long)) { \
38 ret = (__x < 0) ? -__x : __x; \
41 ret = (__x < 0) ? -__x : __x; \
50 /* On ARMv5 and above those functions can be implemented around the clz instruction for
51 * much better code efficiency. */
53 static inline int fls(int x)
57 asm("clz\t%0, %1": "=r"(ret):"r"(x));
62 #define __fls(x) (fls(x) - 1)
63 #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
64 #define __ffs(x) (ffs(x) - 1)
65 #define ffz(x) __ffs( ~(x) )
67 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
69 #define MEASURE_TIMES (15)
71 #define ADC_DROP_CNT ( DIV_ROUND(MEASURE_TIMES, 5) )
72 static int __average(int a[], int N)
75 for (i = 0; i < N; i++)
77 return DIV_ROUND(sum, N);
80 static void bubble_sort(int a[], int N)
83 for (i = 0; i < N - 1; i++) {
84 for (j = i + 1; j < N; j++) {
94 //#define ADC_CALI_DEBUG
97 static short adc_data[4][2] = {
98 /* same as nv adc_t */
99 {4200, 3360}, /* 4.2@VBAT Reserved IdealA Value */
100 {3600, 2877}, /* 3.6@VBAT Reserved IdealB Value */
101 {900, 0}, /* 0.9@VBAT, Reserved IdealC Value */
102 {300, 0}, /* 0.3@VBAT, Reserved IdealD Value */
105 static int adc2vbat(int adc_res, int scale)
110 t = adc_data[0][0] - adc_data[1][0];
111 t *= (adc_res - adc_data[0][1]);
112 t /= (adc_data[0][1] - adc_data[1][1]);
115 t = adc_data[2][0] - adc_data[3][0];
116 t *= (adc_res - adc_data[2][1]);
117 t /= (adc_data[2][1] - adc_data[3][1]);
125 static int sci_adc_request(int channel, int scale)
127 int results[MEASURE_TIMES];
129 if (-1 == ADC_GetValues(channel, scale, MEASURE_TIMES, results)) {
133 bubble_sort(results, MEASURE_TIMES);
135 #if defined(ADC_CALI_DEBUG)
139 for (i = 0; i < MEASURE_TIMES; i++) {
140 debug("%d ", results[i]);
146 return __average(&results[ADC_DROP_CNT], MEASURE_TIMES - ADC_DROP_CNT * 2);
149 #define RATIO(_n_, _d_) (_n_ << 16 | _d_)
151 static int sci_adc_ratio(int channel, int scale, int mux)
159 return ((ADC_SCALE_3V == scale) ? RATIO(400, 1025) : RATIO(1, 1));
164 return RATIO(77, 1024);
165 case 0x0D: //dcdc core/arm/mem/gen/rf/con/wpa
170 return ((ADC_SCALE_3V == scale) ? RATIO(36, 55) : RATIO(9, 11));
173 return ((ADC_SCALE_3V == scale) ? RATIO(12, 25) : RATIO(3, 5));
175 return ((ADC_SCALE_3V == scale) ? RATIO(3, 10) : RATIO(3, 8));
177 return ((ADC_SCALE_3V == scale) ? RATIO(9, 20) : RATIO(9, 16));
179 return ((ADC_SCALE_3V == scale) ? RATIO(12, 55) : RATIO(3, 11));
184 return ((ADC_SCALE_3V == scale) ? RATIO(4, 5) : RATIO(1, 1));
188 case 0x15: //dcdc supply LDO, vdd18/vddcamd/vddcamio/vddrf0/vddgen1/vddgen0
191 case 0x16: //VbatD Domain LDO, vdd25/vddcama/vddsim2/vddsim1/vddsim0
192 case 0x17: //VbatA Domain LDO, vddwifipa/vddcammot/vddemmccore/vdddcxo/vddsdcore/vdd28
193 case 0x18: //kpled/vibr
194 case 0x1D://vddsdio/vddusb/vddfgu
195 case 0x1E: //DP from terminal
196 case 0x1F: //DM from terminal
206 static u32 bat_numerators, bat_denominators = 0;
207 extern uint16_t sprdbat_auxadc2vbatvol (uint16_t adcvalue);
208 extern u32 __adie_efuse_read(int blk_index);
210 static int sci_adc_vol_request(int channel, int scale, int mux, int* adc)
212 int chan_adc, chan_vol;
214 if(0 == bat_denominators) {
216 /* FIXME: Update CHGMNG_AdcvalueToVoltage table before setup vbat ratio. */
217 /*ADC_CHANNEL_VBAT is 5*/
218 res = (u32) sci_adc_ratio(5, ADC_SCALE_3V, 0);
219 bat_numerators = res >> 16;
220 bat_denominators = res & 0xffff;
223 chan_adc = sci_adc_request(channel, scale);
225 u32 res, chan_numerators, chan_denominators;
226 res = (u32) sci_adc_ratio(channel, scale, mux);
227 chan_numerators = res >> 16;
228 chan_denominators = res & 0xffff;
233 #ifdef ADC_CALI_DEBUG
234 chan_vol = adc2vbat(chan_adc, 1);
236 chan_vol = sprdbat_auxadc2vbatvol(chan_adc);
239 chan_vol *= (bat_numerators * chan_denominators);
240 chan_vol /= (bat_denominators * chan_numerators);
248 /* Simple shorthand for a section definition */
250 # define __section(S) __attribute__ ((__section__(#S)))
253 #define __init0 __section(.rodata.regu.init0)
254 #define __init1 __section(.rodata.regu.init1)
255 #define __init2 __section(.rodata.regu.init2)
257 static const u32 __init0 __init_begin = 0xeeeebbbb;
258 static const u32 __init2 __init_end = 0xddddeeee;
260 struct regulator_regs {
261 int typ; /* BIT4: default on/off(0: off, 1: on); BIT0~BIT3: dcdc/ldo type(0: ldo; 2: dcdc) */
262 unsigned long pd_set;
264 unsigned long vol_trm;
266 unsigned long cal_ctl;
268 //u32 min_mV, step_uV;
270 unsigned long vol_ctl;
272 u32 vol_sel_cnt, vol_sel[];
276 struct regulator_desc {
279 struct regulator_regs *regs;
282 #define REGU_VERIFY_DLY (1000) /*ms */
283 #define SCI_REGU_REG(VDD, TYP, PD_SET, SET_BIT, \
284 VOL_TRM, VOL_TRM_BITS, CAL_CTL, CAL_CTL_BITS, VOL_DEF, \
285 VOL_CTL, VOL_CTL_BITS, VOL_SEL_CNT, ...) \
286 static struct regulator_regs REGS_##VDD = { \
289 .pd_set_bit = SET_BIT, \
290 .vol_trm = VOL_TRM, \
291 .vol_trm_bits = VOL_TRM_BITS, \
292 .cal_ctl = CAL_CTL, \
293 .cal_ctl_bits = CAL_CTL_BITS, \
294 .vol_def = VOL_DEF, \
295 .vol_ctl = VOL_CTL, \
296 .vol_ctl_bits = VOL_CTL_BITS, \
297 .vol_sel_cnt = VOL_SEL_CNT, \
298 .vol_sel = {__VA_ARGS__}, \
300 struct regulator_desc __init1 DESC_##VDD = { \
303 .regs = ®S_##VDD, \
306 #include <asm/arch/__sc2723_regulator_map.h>
309 /* standard dcdc ops*/
311 static int dcdc_get_trimming_step(struct regulator_desc *desc, int to_vol)
314 if (0 == strcmp(desc->name, "vddmem")) {
315 /* FIXME: vddmem step 200/32mV */
316 return 1000 * 200 / 32; /*uV */
319 return 1000 * 100 / 32; /*uV */
322 static int __match_vol(struct regulator_desc *desc, u32 vol)
325 int ds, min_ds = 100; /* mV, the max range of small voltage */
326 struct regulator_regs *regs = desc->regs;
328 for (i = 0; i < regs->vol_sel_cnt; i++) {
329 ds = (int)(vol - regs->vol_sel[i]);
330 if (ds >= 0 && ds < min_ds) {
336 if ((2 == (regs->typ & (BIT(4) - 1))) && (j < 0)) {
337 for (i = 0; i < regs->vol_sel_cnt; i++) {
338 ds = abs(vol - regs->vol_sel[i]);
349 static int dcdc_get_voltage(struct regulator_desc *desc)
351 struct regulator_regs *regs = desc->regs;
353 int cal = 0; /* uV */
356 BUG_ON(regs->vol_sel_cnt > 8);
359 int shft_ctl = __ffs(regs->vol_ctl_bits);
360 int shft_trm = __ffs(regs->vol_trm_bits);
362 i = (ANA_REG_GET(regs->vol_ctl) & regs->vol_ctl_bits) >> shft_ctl;
363 mv = regs->vol_sel[i];
366 cal = (ANA_REG_GET(regs->vol_trm) & regs->vol_trm_bits) >> shft_trm;
367 cal *= dcdc_get_trimming_step(desc, 0); /*uV */
370 debug0("%s %d +%dmv(trim %#x)\n", desc->name, mv, cal / 1000, cal / dcdc_get_trimming_step(desc, 0));
372 } else if (regs->vol_trm && regs->vol_sel_cnt == 2) {
373 int shft_trm = __ffs(regs->vol_trm_bits);
375 (ANA_REG_GET(regs->vol_trm) & regs->vol_trm_bits) >> shft_trm;
376 mv = regs->vol_sel[0] + trim * regs->vol_sel[1] / 1000;
378 debug0("%s %d +%dmv(trim %#x)\n", desc->name, regs->vol_sel[0], (mv - regs->vol_sel[0]), trim);
381 return (mv + cal / 1000);
384 static int dcdc_set_voltage(struct regulator_desc *desc, int min_mV, int max_mV)
386 struct regulator_regs *regs = desc->regs;
387 int i = 0, mv = min_mV;
390 /* found the closely vol ctrl bits */
391 i = __match_vol(desc, mv);
393 debug2("%s: %s failed to match voltage: %d\n", __func__, desc->name, mv);
398 /* dcdc calibration control bits (default 0) small adjust voltage: 100/32mv ~= 3.125mv */
400 int shft_trm = __ffs(regs->vol_trm_bits);
406 shft_ctl = __ffs(regs->vol_ctl_bits);
407 step = dcdc_get_trimming_step(desc, mv);
409 j = (int)(mv - (int)regs->vol_sel[i]) * 1000 / step;
411 if(regs->vol_sel_cnt == 2) {
412 step = regs->vol_sel[1];
413 j = DIV_ROUND_UP((mv - regs->vol_sel[0]) * 1000, step);
417 debug2("regu_dcdc %p (%s) %d = %d %+dmv (trim=%d step=%duv);\n", regs, desc->name,
418 mv, regs->vol_sel[i], mv - regs->vol_sel[i], j, step);
420 if ((regs->vol_trm == regs->vol_ctl) && regs->vol_ctl) {
421 if (j >= 0 && j <= (regs->vol_trm_bits >> shft_trm)) {
422 ANA_REG_MSK_OR(regs->vol_ctl, (j << shft_trm) | (i << shft_ctl),
423 regs->vol_trm_bits | regs->vol_ctl_bits);
426 if (regs->vol_trm) { /* small adjust first */
427 if (j >= 0 && j <= (regs->vol_trm_bits >> shft_trm)) {
428 ANA_REG_MSK_OR(regs->vol_trm, j << shft_trm, regs->vol_trm_bits);
433 ANA_REG_MSK_OR(regs->vol_ctl, i << shft_ctl, regs->vol_ctl_bits);
440 static int dcdc_set_trimming(struct regulator_desc *desc, int def_vol, int to_vol, int adc_vol)
442 //int acc_vol = dcdc_get_trimming_step(desc, to_vol) / 1000;
443 int ctl_vol = (to_vol - (adc_vol - def_vol));
445 return dcdc_set_voltage(desc, ctl_vol, ctl_vol);
448 static int ldo_get_voltage(struct regulator_desc *desc)
450 struct regulator_regs *regs = desc->regs;
453 if (regs->vol_trm && regs->vol_sel_cnt == 2) {
454 int shft = __ffs(regs->vol_trm_bits);
456 (ANA_REG_GET(regs->vol_trm) & regs->vol_trm_bits) >> shft;
457 vol = regs->vol_sel[0] * 1000 + trim * regs->vol_sel[1];
460 debug0("%s get voltage %dmv(trim %#x)\n", desc->name, vol, trim);
468 static int ldo_set_trimming(struct regulator_desc *desc, int def_vol, int to_vol, int adc_vol)
470 struct regulator_regs *regs = desc->regs;
473 if (!regs->vol_ctl && regs->vol_sel_cnt == 2) {
474 /* ctl_vol = vol_base + reg[vol_trm] * vol_step */
475 int shft = __ffs(regs->vol_trm_bits);
476 int ctl_vol = (to_vol - (adc_vol - def_vol));
479 if(adc_vol > def_vol)
480 trim = DIV_ROUND_UP((ctl_vol - regs->vol_sel[0]) * 1000, regs->vol_sel[1]);
482 trim = ((ctl_vol - regs->vol_sel[0]) * 1000 / regs->vol_sel[1]);
484 debug2("regu_ldo %p (%s) %d = %d %+dmv (trim=%d step=%duv)\n", regs, desc->name,
485 ctl_vol, regs->vol_sel[0], ctl_vol - regs->vol_sel[0], trim, regs->vol_sel[1]);
487 if ((trim >= 0) && (trim <= (regs->vol_trm_bits >> shft))) {
488 ANA_REG_MSK_OR(regs->vol_trm,
498 static int reconfig_regulator(struct regulator_desc *desc)
500 struct regulator_regs *regs = desc->regs;
502 /* Fixme: Config DCDC linear/no linear control
503 * accoring to BIT14 of Reg(0x40038800 + 0x0118)
505 if (ana_mixed_ctl & BIT_DCDC_V_CTRL_MODE) {
506 /* dcdc linear control */
507 if ((0 == strcmp(desc->name, "vddcore"))
508 || (0 == strcmp(desc->name, "vddarm"))) {
509 regs->vol_trm_bits = (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4) \
510 |BIT(5)|BIT(6)|BIT(7)|BIT(8)|BIT(9));
512 regs->vol_ctl_bits = 0;
514 regs->vol_sel_cnt = 2;
515 regs->vol_sel[0] = 600;
516 regs->vol_sel[1] = 3125;
519 /* dcdc Non-linear control */
520 if ((0 == strcmp(desc->name, "vddcore"))
521 || (0 == strcmp(desc->name, "vddarm"))) {
522 regs->vol_ctl = regs->vol_trm;
523 regs->vol_trm_bits = (BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4));
524 regs->vol_ctl_bits = (BIT(5)|BIT(6)|BIT(7));
526 regs->vol_sel_cnt = 8;
527 regs->vol_sel[0] = 1100;
528 regs->vol_sel[1] = 700;
529 regs->vol_sel[2] = 800;
530 regs->vol_sel[3] = 900;
531 regs->vol_sel[4] = 1000;
532 regs->vol_sel[5] = 650;
533 regs->vol_sel[6] = 1200;
534 regs->vol_sel[7] = 1300;
540 static int DCDC_Cal_One(struct regulator_desc *desc, int is_cal)
542 struct regulator_regs *regs = desc->regs;
543 int def_vol = 0, to_vol = 0, ref_vol = 0;
544 int adc = 0, adc_vol = 0, cal_vol = 0;
545 int ret = -1, adc_chan = 0;
546 u16 ldo_cal_sel = 0, adc_scale = 0;
547 int vdd_type = desc->regs->typ & (BIT(4) - 1);
549 reconfig_regulator(desc);
551 if (!regs->cal_ctl_bits)
554 adc_chan = regs->cal_ctl_bits >> 16;
555 ldo_cal_sel = regs->cal_ctl_bits & 0xFFFF;
557 if (!adc_chan || !regs->vol_def)
560 /* only verify dcdc/ldo default on calibration */
561 if (!is_cal && !(regs->typ & BIT(4)))
565 debug("\nCalibrate %s ...\n", desc->name);
567 debug("\nVerify %s ...\n", desc->name);
569 adc_scale = (((adc_chan != 13) && (adc_chan != 14)) ? ADC_SCALE_3V : ADC_SCALE_1V2);
572 ANA_REG_OR(regs->cal_ctl, ldo_cal_sel);
575 * FIXME: force get dcdc&ldo voltage from ana global regs
576 * and get ideal voltage from vol para.
578 if (vdd_type == 2 /*DCDC*/) {
579 def_vol = dcdc_get_voltage(desc);
581 else if (vdd_type == 0 /*LDO*/) {
582 def_vol = ldo_get_voltage(desc);
585 to_vol = regulator_default_get(desc->name);
587 to_vol = regs->vol_def;
589 adc_vol = sci_adc_vol_request(adc_chan, adc_scale, ldo_cal_sel, &adc);
591 debug1("%s default %dmv, adc channel %d, maybe not enable\n", desc->name, def_vol, adc_chan);
595 ref_vol = (is_cal ? def_vol : to_vol);
596 cal_vol = abs(adc_vol - ref_vol);
598 debug1("%s chan[%d] adc %d, default %dmv, from %dmv to %dmv, bias %c%01d.%03d%%\n",
599 desc->name, adc_chan, adc, def_vol, adc_vol, to_vol,
600 (adc_vol > to_vol) ? '+' : '-',
601 cal_vol * 100 / ref_vol, cal_vol * 100 * 1000 / ref_vol % 1000);
603 if (!def_vol || !to_vol || adc_vol <= 0)
605 if (cal_vol >= ref_vol / 9) /* adjust limit 9% */
607 else if (cal_vol < ref_vol / 100) { /* bias 1% */
612 if (vdd_type == 2 /*VDD_TYP_DCDC*/)
613 ret = dcdc_set_trimming(desc, def_vol, to_vol, adc_vol);
614 else if (vdd_type == 0 /*VDD_TYP_LDO*/)
615 ret = ldo_set_trimming(desc, def_vol, to_vol, adc_vol);
618 regulator_default_set(desc->name, 0);
623 ANA_REG_BIC(regs->cal_ctl, ldo_cal_sel);
628 int DCDC_Cal_ArmCore(void)
630 u16 regval_dcdc_store, regval_ldo_store, otp_pwr_sel;
631 struct regulator_desc *desc = NULL;
632 struct regulator_desc *desc_end = NULL;
633 u32 cali_mask = regulator_get_calibration_mask();
634 u32 chip_id = ANA_GET_CHIP_ID();
636 int vbat_vol = sci_adc_vol_request(5, ADC_SCALE_3V, 0, &vbat_adc);
637 u16 otp_ana_flag = (u8)__adie_efuse_read(0) & BIT(7);
639 ana_mixed_ctl = ANA_REG_GET(ANA_REG_GLB_MIXED_CTRL0);
640 otp_pwr_sel = ANA_REG_GET(ANA_REG_GLB_PWR_SEL);
642 printf("%s; adie chipid:(0x%08x), mixed_ctl:(0x%08x), otp_sel:(0x%08x), cali_mask:(0x%08x), VBAT(vol %d, adc %d)\n",
643 __func__, chip_id, ana_mixed_ctl, otp_pwr_sel, cali_mask, vbat_vol, vbat_adc);
646 /* TODO: verify all DCDCs */
647 desc = (struct regulator_desc *)(&__init_begin + 1);
648 desc_end = (struct regulator_desc *)(&__init_end) - 1;
649 while (desc_end >= desc) { /* reverse order */
650 DCDC_Cal_One(desc_end, 0);
657 cali_mask &= 0x3FFFFFF1;
659 regval_dcdc_store = ANA_REG_GET(ANA_REG_GLB_LDO_DCDC_PD) & 0xFFFF;
660 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, BITS_PWR_WR_PROT_VALUE(0x6e7f), 0x7FFF);
661 ANA_REG_BIC(ANA_REG_GLB_LDO_DCDC_PD, (cali_mask >> 16));
662 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, 0, 0x7FFF);
664 regval_ldo_store = ANA_REG_GET(ANA_REG_GLB_LDO_PD_CTRL) & 0xFFFF;
665 ANA_REG_BIC(ANA_REG_GLB_LDO_PD_CTRL, cali_mask & 0xFFFF);
667 printf("REG_DCDC_PD(0x%08x): (0x%08x), REG_LDO_PD(0x%08x): (0x%08x), \n",
668 ANA_REG_GLB_LDO_DCDC_PD, regval_dcdc_store, ANA_REG_GLB_LDO_PD_CTRL, regval_ldo_store);
670 /* TODO: calibrate all DCDCs */
671 desc = (struct regulator_desc *)(&__init_begin + 1);
672 desc_end = (struct regulator_desc *)(&__init_end) - 1;
674 printf("%p (%x) -- %p -- %p (%x)\n", &__init_begin, __init_begin,
675 desc, &__init_end, __init_end);
677 while (desc_end >= desc) { /* reverse order */
678 DCDC_Cal_One(desc_end, 1);
682 #if defined(REGU_CALI_DEBUG)
683 /* wait a moment for LDOs ready */
684 udelay(10 * 1000); //wait 10ms
686 /* TODO: verify all DCDCs */
687 desc = (struct regulator_desc *)(&__init_begin + 1);
688 desc_end = (struct regulator_desc *)(&__init_end) - 1;
689 while (desc_end >= desc) { /* reverse order */
690 DCDC_Cal_One(desc_end, 0);
695 /* restore adie dcdc/ldo PD bits */
696 ANA_REG_SET(ANA_REG_GLB_LDO_PD_CTRL, regval_ldo_store);
697 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, BITS_PWR_WR_PROT_VALUE(0x6e7f), 0x7FFF);
698 ANA_REG_SET(ANA_REG_GLB_LDO_DCDC_PD, regval_dcdc_store);
699 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, 0, 0x7FFF);
709 int regulator_init(void)
712 * FIXME: turn on all DCDC/LDOs if need
717 struct regulator_desc *regulator_get(void/*struct device*/ *dev, const char *id)
719 struct regulator_desc *desc =
720 (struct regulator_desc *)(&__init_begin + 1);
721 while (desc < (struct regulator_desc *)&__init_end) {
722 if (0 == strcmp(desc->name, id))
729 int regulator_disable_all(void)
731 ANA_REG_OR(ANA_REG_GLB_LDO_PD_CTRL, 0x7fff);
732 ANA_REG_OR(ANA_REG_GLB_LDO_DCDC_PD, 0xbfff);
736 int regulator_enable_all(void)
738 ANA_REG_BIC(ANA_REG_GLB_LDO_DCDC_PD, 0xbfff);
739 ANA_REG_BIC(ANA_REG_GLB_LDO_PD_CTRL, 0x7fff);
743 int regulator_disable(const char con_id[])
745 struct regulator_desc *desc = regulator_get(0, con_id);
747 struct regulator_regs *regs = desc->regs;
748 ANA_REG_OR(regs->pd_set, regs->pd_set_bit);
753 int regulator_enable(const char con_id[])
755 struct regulator_desc *desc = regulator_get(0, con_id);
757 struct regulator_regs *regs = desc->regs;
758 ANA_REG_BIC(regs->pd_set, regs->pd_set_bit);
763 int regulator_set_voltage(const char con_id[], int to_vol)
766 struct regulator_desc *desc = regulator_get(0, con_id);
768 struct regulator_regs *regs = desc->regs;
769 int vdd_type = regs->typ & (BIT(4) - 1);
771 if (vdd_type == 2 /*VDD_TYP_DCDC*/)
772 ret = dcdc_set_voltage(desc, to_vol, 0);
773 else if (vdd_type == 0 /*VDD_TYP_LDO*/)
774 ret = ldo_set_trimming(desc, 0, to_vol, 0);
784 #if defined(CONFIG_FDL2_BUILD)
785 vol_para_t **ppvol_para = (vol_para_t **)0x50000020;
786 #elif defined(CONFIG_SPL_32K)
787 vol_para_t **ppvol_para = (vol_para_t **)0x50003C20;
789 vol_para_t **ppvol_para = (vol_para_t **)0x50003C20;
792 static int get_vol_para_num(void)
796 if (!(ppvol_para && *ppvol_para))
799 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
802 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end"))
808 static vol_para_t * match_vol_para(const char* vol_name)
812 BUG_ON(NULL == vol_name);
814 if (!(ppvol_para && *ppvol_para))
817 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
820 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end")) {
821 if (0 == strcmp((*ppvol_para)[i].name, vol_name)) {
822 debug0("%s name %s, ideal_vol %d\n", __func__, (*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
823 return (vol_para_t*)(&(*ppvol_para)[i]);
830 int regulator_default_get(const char con_id[])
832 vol_para_t * pvol_para = match_vol_para(con_id);
834 return (int)(pvol_para ? pvol_para->ideal_vol : 0);
837 void regulator_default_set(const char con_id[], int vol)
839 vol_para_t * pvol_para = match_vol_para(con_id);
842 pvol_para->ideal_vol = vol;
846 int regulator_default_set_all(void)
850 //dump & check all vol para
851 if (!(ppvol_para && *ppvol_para))
854 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
857 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end")) {
858 debug("regu: [%d] %s : %d\n", i, (*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
860 ret |= regulator_set_voltage((*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
866 /********************************************************************
868 * regulator_get_calibration_mask - get dcdc/ldo calibration flag
871 //High 16bit: dcdc ctrl calibration flag
874 * bit[14] : dcdctopclk6M
881 * bit[7] : vddemmccore
891 //Low 16bit: ldo ctrl calibration flag
897 * bit[11] : vddwifipa
898 * bit[10] : vddsdcore
909 ********************************************************************/
910 u32 regulator_get_calibration_mask(void)
912 int len = get_vol_para_num();
913 volatile vol_para_t *pvol_para = (volatile vol_para_t *)(*ppvol_para);
914 volatile u32* pdebug_flag = (u32*)(&pvol_para[len-1]);
917 printf("%s, vol_para_tbl_len %d, ldo_pd_mask 0x%08x; \n", __func__, len, *pdebug_flag);
918 return (*pdebug_flag);
924 /* register callback function after dcdc/ldo calibration */
925 int calibrate_register_callback(void* callback_fun)
928 calibrate_post = (pfun)callback_fun;