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 #define REGU_CALI_DEBUG
14 #ifdef REGU_CALI_DEBUG
15 #define regu_debug(fmt, arg...) printf(fmt, ## arg)
17 #define regu_debug(fmt, arg...)
21 #define debug0(format, arg...)
22 #define debug(format, arg...) regu_debug(format, ## arg)
23 #define debug1(format, arg...) regu_debug("\t" format, ## arg)
24 #define debug2(format, arg...) regu_debug("\t\t" format, ## arg)
26 /* abs() handles unsigned and signed longs, ints, shorts and chars. For all input types abs()
27 * returns a signed long.
28 * abs() should not be used for 64-bit types (s64, u64, long long) - use abs64() for those.*/
31 if (sizeof(x) == sizeof(long)) { \
33 ret = (__x < 0) ? -__x : __x; \
36 ret = (__x < 0) ? -__x : __x; \
45 /* On ARMv5 and above those functions can be implemented around the clz instruction for
46 * much better code efficiency. */
48 static inline int fls(int x)
52 asm("clz\t%0, %1": "=r"(ret):"r"(x));
57 #define __fls(x) (fls(x) - 1)
58 #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
59 #define __ffs(x) (ffs(x) - 1)
60 #define ffz(x) __ffs( ~(x) )
62 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
64 #define MEASURE_TIMES (15)
66 #define ADC_DROP_CNT ( DIV_ROUND(MEASURE_TIMES, 5) )
67 static int __average(int a[], int N)
70 for (i = 0; i < N; i++)
72 return DIV_ROUND(sum, N);
75 static void bubble_sort(int a[], int N)
78 for (i = 0; i < N - 1; i++) {
79 for (j = i + 1; j < N; j++) {
89 static int sci_adc_request(int channel, int scale)
91 int results[MEASURE_TIMES];
93 if (-1 == ADC_GetValues(channel, scale, MEASURE_TIMES, results)) {
97 bubble_sort(results, MEASURE_TIMES);
104 for (i = 0; i < MEASURE_TIMES; i++) {
105 printf("%d ", results[i]);
111 return __average(&results[ADC_DROP_CNT], MEASURE_TIMES - ADC_DROP_CNT * 2);
114 #define RATIO(_n_, _d_) (_n_ << 16 | _d_)
116 static int sci_adc_ratio(int channel, int scale, int mux)
123 return ((ADC_SCALE_3V == scale) ? RATIO(400, 1025) : RATIO(1, 1));
126 case 0x0D: //dcdccore
128 return ((ADC_SCALE_3V == scale) ? RATIO(4, 5) : RATIO(1, 1));
130 return ((ADC_SCALE_3V == scale) ? RATIO(3, 5) : RATIO(4, 5));
133 case 0x15: //DCDC Supply LDO
135 case 0x13: //DCDCVBATBK
136 case 0x16: //VBATD Domain LDO
137 case 0x17: //VBATA Domain LDO
138 case 0x1E: //DP from terminal
139 case 0x1F: //DM from terminal
141 case 0x14: //DCDCHEADMIC
142 return ((ADC_SCALE_3V == scale) ? RATIO(1, 3) : RATIO(1, 1));
150 static u32 bat_numerators, bat_denominators = 0;
151 extern uint16_t sprdbat_auxadc2vbatvol (uint16_t adcvalue);
153 static int sci_adc_vol_request(int channel, int scale, int mux, int* adc)
155 int chan_adc, chan_vol;
157 if(0 == bat_denominators) {
159 /* FIXME: Update CHGMNG_AdcvalueToVoltage table before setup vbat ratio. */
160 /*ADC_CHANNEL_VBAT is 5*/
161 res = (u32) sci_adc_ratio(5, ADC_SCALE_3V, 0);
162 bat_numerators = res >> 16;
163 bat_denominators = res & 0xffff;
166 chan_adc = sci_adc_request(channel, scale);
171 chan_vol = sprdbat_auxadc2vbatvol(chan_adc);
172 if(ADC_SCALE_3V == scale) {
173 u32 res, chan_numerators, chan_denominators;
174 res = (u32) sci_adc_ratio(channel, scale, mux);
175 chan_numerators = res >> 16;
176 chan_denominators = res & 0xffff;
178 chan_vol *= (bat_numerators * chan_denominators);
179 chan_vol /= (bat_denominators * chan_numerators);
186 /* Simple shorthand for a section definition */
188 # define __section(S) __attribute__ ((__section__(#S)))
191 #define __init0 __section(.rodata.regu.init0)
192 #define __init1 __section(.rodata.regu.init1)
193 #define __init2 __section(.rodata.regu.init2)
195 static const u32 __init0 __init_begin = 0xeeeebbbb;
196 static const u32 __init2 __init_end = 0xddddeeee;
198 struct regulator_regs {
200 u32 pd_set, pd_set_bit;
201 /* at new feature, some LDOs had only set, no rst bits.
202 * and DCDCs voltage and trimming controller is the same register */
203 u32 pd_rst, pd_rst_bit;
204 u32 slp_ctl, slp_ctl_bit;
205 u32 vol_trm, vol_trm_bits;
206 u32 cal_ctl, cal_ctl_bits;
208 u32 vol_ctl, vol_ctl_bits;
209 u32 vol_sel_cnt, vol_sel[];
212 struct regulator_desc {
215 struct regulator_regs *regs;
218 #define REGU_VERIFY_DLY (1000) /*ms */
219 #define SCI_REGU_REG(VDD, TYP, PD_SET, SET_BIT, PD_RST, RST_BIT, SLP_CTL, SLP_CTL_BIT, \
220 VOL_TRM, VOL_TRM_BITS, CAL_CTL, CAL_CTL_BITS, VOL_DEF, \
221 VOL_CTL, VOL_CTL_BITS, VOL_SEL_CNT, ...) \
222 static struct regulator_regs REGS_##VDD = { \
225 .pd_set_bit = SET_BIT, \
227 .pd_rst_bit = RST_BIT, \
228 .slp_ctl = SLP_CTL, \
229 .slp_ctl_bit = SLP_CTL_BIT, \
230 .vol_trm = VOL_TRM, \
231 .vol_trm_bits = VOL_TRM_BITS, \
232 .cal_ctl = CAL_CTL, \
233 .cal_ctl_bits = CAL_CTL_BITS, \
234 .vol_def = VOL_DEF, \
235 .vol_ctl = VOL_CTL, \
236 .vol_ctl_bits = VOL_CTL_BITS, \
237 .vol_sel_cnt = VOL_SEL_CNT, \
238 .vol_sel = {__VA_ARGS__}, \
240 struct regulator_desc __init1 DESC_##VDD = { \
243 .regs = ®S_##VDD, \
246 #include <asm/arch/__sc2711_regulator_map.h>
249 /* standard dcdc ops*/
250 static int adjust_ldo_vol_base(struct regulator_desc *desc)
252 struct regulator_regs *regs = desc->regs;
254 if (regs->vol_sel_cnt == 2) {
255 if ((0 == strcmp(desc->name, "vdd18"))
256 || (0 == strcmp(desc->name, "vddemmcio"))
257 || (0 == strcmp(desc->name, "vddcamd"))
258 || (0 == strcmp(desc->name, "vddcamio"))) {
260 regs->vol_sel[0] = 1400;
263 debug0("%s vol base %dmv\n", desc->name, regs->vol_sel[0]);
264 return regs->vol_sel[0];
267 static int __dcdc_is_up_down_adjust(struct regulator_desc *desc)
269 return ((0 == strcmp(desc->name, "vddmem")) ? 1 : 0);
272 static int dcdc_get_trimming_step(struct regulator_desc *desc, int to_vol)
274 /* FIXME: vddmem step 200/32mV */
275 return (!strcmp(desc->name, "vddmem") ) ? (1000 * 200 / 32) : (1000 * 100 / 32) /*uV */;
278 static int __match_dcdc_vol(struct regulator_desc *desc, u32 vol)
281 int ds, min_ds = 100; /* mV, the max range of small voltage */
282 const struct regulator_regs *regs = desc->regs;
284 for (i = 0; i < regs->vol_sel_cnt; i++) {
285 ds = vol - regs->vol_sel[i];
286 if (ds >= 0 && ds < min_ds) {
293 for (i = 0; i < regs->vol_sel_cnt; i++) {
294 ds = abs(vol - regs->vol_sel[i]);
305 static int dcdc_get_voltage(struct regulator_desc *desc)
307 const struct regulator_regs *regs = desc->regs;
309 int cal = 0; /* uV */
310 int i, shft = __ffs(regs->vol_ctl_bits);
312 i = (ANA_REG_GET(regs->vol_ctl) & regs->vol_ctl_bits) >> shft;
313 mv = regs->vol_sel[i];
315 cal = (ANA_REG_GET(regs->vol_trm) & regs->vol_trm_bits) >> __ffs(regs->vol_trm_bits);
316 if (__dcdc_is_up_down_adjust(desc)) {
319 cal *= dcdc_get_trimming_step(desc, 0); /*uV */
321 debug0("%s %d +%dmv\n", desc->name, mv, cal / 1000);
322 return mv + cal / 1000;
325 static int dcdc_set_voltage(struct regulator_desc *desc, int min_mV, int max_mV)
327 const struct regulator_regs *regs = desc->regs;
330 /* found the closely vol ctrl bits */
331 i = __match_dcdc_vol(desc, mv);
333 debug2("%s: %s failed to match voltage: %d\n",__func__,desc->name,mv);
337 /* dcdc calibration control bits (default 0) small adjust voltage: 100/32mv ~= 3.125mv */
339 int shft_ctl = __ffs(regs->vol_ctl_bits);
340 int shft_trm = __ffs(regs->vol_trm_bits);
341 int step = dcdc_get_trimming_step(desc, mv);
342 int j = (int)(mv - (int)regs->vol_sel[i]) * 1000 / step;
344 if (__dcdc_is_up_down_adjust(desc))
347 debug2("regu_dcdc %d = %d %+dmv (trim=%d step=%duv);\n",
348 mv, regs->vol_sel[i], mv - regs->vol_sel[i], j, step);
350 if (j >= 0 && j <= (regs->vol_trm_bits >> shft_trm))
351 ANA_REG_MSK_OR(regs->vol_ctl, (j << shft_trm) | (i << shft_ctl),
352 regs->vol_trm_bits | regs->vol_ctl_bits);
357 static int dcdc_set_trimming(struct regulator_desc *desc, int def_vol, int to_vol, int adc_vol)
359 //int acc_vol = dcdc_get_trimming_step(desc, to_vol) / 1000;
360 int ctl_vol = (def_vol - (adc_vol - to_vol));
362 return dcdc_set_voltage(desc, ctl_vol, ctl_vol);
365 static int ldo_get_voltage(struct regulator_desc *desc)
367 const struct regulator_regs *regs = desc->regs;
370 if (regs->vol_trm && regs->vol_sel_cnt == 2) {
371 int shft = __ffs(regs->vol_trm_bits);
373 (ANA_REG_GET(regs->vol_trm) & regs->vol_trm_bits) >> shft;
374 vol = regs->vol_sel[0] * 1000 + trim * regs->vol_sel[1];
376 debug0("%s voltage %dmv\n", desc->name, vol);
383 static int ldo_set_trimming(struct regulator_desc *desc, int def_vol, int to_vol, int adc_vol)
385 const struct regulator_regs *regs = desc->regs;
388 if (!regs->vol_ctl && regs->vol_sel_cnt == 2) {
389 /* ctl_vol = vol_base + reg[vol_trm] * vol_step */
390 int shft = __ffs(regs->vol_trm_bits);
391 int ctl_vol = (def_vol - (adc_vol - to_vol)); //same as dcdc?
394 trim = DIV_ROUND_UP((ctl_vol - regs->vol_sel[0]) * 1000, regs->vol_sel[1]);
396 trim = ((ctl_vol - regs->vol_sel[0]) * 1000 / regs->vol_sel[1]);
398 debug2("regu_ldo %d = %d %+dmv (trim=%d step=%duv vol_base=%dmv)\n",
399 ctl_vol, regs->vol_sel[0], ctl_vol - regs->vol_sel[0], trim, regs->vol_sel[1], regs->vol_sel[0]);
401 if ((trim >= 0) && (trim <= (regs->vol_trm_bits >> shft))) {
402 ANA_REG_MSK_OR(regs->vol_trm,
412 static int DCDC_Cal_One(struct regulator_desc *desc, int is_cal)
414 struct regulator_regs *regs = desc->regs;
415 int def_vol = 0, to_vol = 0;
416 int adc = 0, adc_vol = 0, cal_vol = 0;
417 int ret = -1, adc_chan = regs->cal_ctl_bits >> 16;
418 u16 ldo_cal_sel = regs->cal_ctl_bits & 0xFFFF;
420 if (!adc_chan || !regs->vol_def)
423 /* only verify dcdc calibration */
424 if (!is_cal && (2 != desc->regs->typ))
428 debug("\nCalibrate %s ...\n", desc->name);
430 debug("\nVerify %s ...\n", desc->name);
433 if(0x2711A000 == ANA_GET_CHIP_ID()) {
434 if (desc->regs->typ == 0) {
435 adjust_ldo_vol_base(desc);
439 if (0 == strcmp(desc->name, "vddrf0")) {
440 if ((ANA_REG_GET(ANA_REG_GLB_LDO_V_CTRL9) & BIT(15)) >> 15) { /* BONDOPT4 */
441 regs->vol_def = 2800;
443 regs->vol_def = 1800;
448 ANA_REG_OR(regs->cal_ctl, ldo_cal_sel);
451 * FIXME: force get dcdc&ldo voltage from ana global regs
452 * and get ideal voltage from vol para.
454 if (desc->regs->typ == 2 /*DCDC*/) {
455 def_vol = dcdc_get_voltage(desc);
457 else if (desc->regs->typ == 0 /*LDO*/) {
458 def_vol = ldo_get_voltage(desc);
461 to_vol = regulator_default_get(desc->name);
463 to_vol = regs->vol_def;
465 adc_vol = sci_adc_vol_request(adc_chan, ADC_SCALE_3V, ldo_cal_sel, &adc);
467 debug1("%s default %dmv, adc channel %d, maybe not enable\n", desc->name, def_vol, adc_chan);
471 cal_vol = abs(adc_vol - to_vol);
472 debug1("%s chan[%d] adc %d, default %dmv, from %dmv to %dmv, bias %c%d.%03d%%\n",
473 desc->name, adc_chan, adc, def_vol, adc_vol, to_vol,
474 (adc_vol > to_vol) ? '+' : '-',
475 cal_vol * 100 / to_vol, cal_vol * 100 * 1000 / to_vol % 1000);
477 if (!def_vol || !to_vol || adc_vol <= 0)
479 if (abs(adc_vol - def_vol) >= def_vol / 9) /* adjust limit 9% */
481 else if (cal_vol < to_vol / 100) { /* bias 1% */
486 if (regs->typ == 2/*VDD_TYP_DCDC*/)
487 ret = dcdc_set_trimming(desc, def_vol, to_vol, adc_vol);
488 else if (regs->typ == 0/*VDD_TYP_LDO*/)
489 ret = ldo_set_trimming(desc, def_vol, to_vol, adc_vol);
492 regulator_default_set(desc->name, 0);
497 ANA_REG_BIC(regs->cal_ctl, ldo_cal_sel);
502 int DCDC_Cal_ArmCore(void)
504 u16 regval_dcdc_store, regval_ldo_store;
505 struct regulator_desc *desc = NULL;
506 struct regulator_desc *desc_end = NULL;
507 u32 cali_mask = regulator_get_calibration_mask();
508 u32 chip_id = ANA_GET_CHIP_ID();
510 int vbat_vol = sci_adc_vol_request(5, ADC_SCALE_3V, 0, &vbat_adc);
512 printf("%s; adie chip id: (0x%08x), cali_mask: (0x%08x), VBAT(vol %d, adc %d)\n",
513 __FUNCTION__, chip_id, cali_mask, vbat_vol, vbat_adc);
515 cali_mask &= 0x01F00FFF;
517 regval_dcdc_store = ANA_REG_GET(ANA_REG_GLB_LDO_DCDC_PD) & 0xFFFF;
518 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, BITS_PWR_WR_PROT_VALUE(0x6e7f), 0x7FFF);
519 ANA_REG_BIC(ANA_REG_GLB_LDO_DCDC_PD, (cali_mask >> 16));
520 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, 0, 0x7FFF);
522 regval_ldo_store = ANA_REG_GET(ANA_REG_GLB_LDO_PD_CTRL) & 0xFFFF;
523 ANA_REG_BIC(ANA_REG_GLB_LDO_PD_CTRL, cali_mask & 0xFFFF);
525 if(0x2711A000 == chip_id) {
526 //FIXME: vddcamio/vddcamd/vddemmcio/vdd18 real voltage value is greater than design value
527 ANA_REG_MSK_OR(ANA_REG_GLB_LDO_V_CTRL9, BITS_LDO_VDD18_V(0x40),
528 BITS_LDO_VDD18_V(-1)); //0x68D2 -->0x40D2
529 ANA_REG_MSK_OR(ANA_REG_GLB_LDO_V_CTRL2, BITS_LDO_EMMCIO_V(0x40),
530 BITS_LDO_EMMCIO_V(-1)); //0x3C68 -->0x3C40
531 ANA_REG_MSK_OR(ANA_REG_GLB_LDO_V_CTRL1, BITS_LDO_CAMIO_V(0x40) | BITS_LDO_CAMD_V(0x10),
532 BITS_LDO_CAMIO_V(-1) | BITS_LDO_CAMD_V(-1)); //0x6838 -->0x4010
533 udelay(10 * 1000); //wait 10ms
536 /* TODO: calibrate all DCDCs */
537 desc = (struct regulator_desc *)(&__init_begin + 1);
539 printf("%p (%x) -- %p -- %p (%x)\n", &__init_begin, __init_begin,
540 desc, &__init_end, __init_end);
542 desc_end = (struct regulator_desc *)(&__init_end) - 1;
543 while (desc_end >= desc) { /* reverse order */
544 DCDC_Cal_One(desc_end, 1);
548 #if defined(REGU_CALI_DEBUG)
549 /* wait a moment for LDOs ready */
550 udelay(10 * 1000); //wait 10ms
552 /* TODO: verify all DCDCs */
553 desc = (struct regulator_desc *)(&__init_begin + 1);
554 desc_end = (struct regulator_desc *)(&__init_end) - 1;
555 while (desc_end >= desc) { /* reverse order */
556 DCDC_Cal_One(desc_end, 0);
561 /* restore adie dcdc/ldo PD bits */
562 ANA_REG_SET(ANA_REG_GLB_LDO_PD_CTRL, regval_ldo_store);
563 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, BITS_PWR_WR_PROT_VALUE(0x6e7f), 0x7FFF);
564 ANA_REG_SET(ANA_REG_GLB_LDO_DCDC_PD, regval_dcdc_store);
565 ANA_REG_MSK_OR(ANA_REG_GLB_PWR_WR_PROT_VALUE, 0, 0x7FFF);
571 int regulator_init(void)
574 * FIXME: turn on all DCDC/LDOs if need
579 struct regulator_desc *regulator_get(void/*struct device*/ *dev, const char *id)
581 struct regulator_desc *desc =
582 (struct regulator_desc *)(&__init_begin + 1);
583 while (desc < (struct regulator_desc *)&__init_end) {
584 if (0 == strcmp(desc->name, id))
591 int regulator_disable_all(void)
593 ANA_REG_OR(ANA_REG_GLB_LDO_PD_CTRL, 0x7ff);
594 ANA_REG_OR(ANA_REG_GLB_LDO_DCDC_PD, 0x1fff);
598 int regulator_enable_all(void)
600 ANA_REG_BIC(ANA_REG_GLB_LDO_DCDC_PD, 0x1fff);
601 ANA_REG_BIC(ANA_REG_GLB_LDO_PD_CTRL, 0x7ff);
605 int regulator_disable(const char con_id[])
607 struct regulator_desc *desc = regulator_get(0, con_id);
609 struct regulator_regs *regs = desc->regs;
610 ANA_REG_OR(regs->pd_set, regs->pd_set_bit);
615 int regulator_enable(const char con_id[])
617 struct regulator_desc *desc = regulator_get(0, con_id);
619 struct regulator_regs *regs = desc->regs;
620 ANA_REG_BIC(regs->pd_set, regs->pd_set_bit);
625 int regulator_set_voltage(const char con_id[], int to_vol)
628 struct regulator_desc *desc = regulator_get(0, con_id);
630 struct regulator_regs *regs = desc->regs;
631 if (regs->typ == 2/*VDD_TYP_DCDC*/)
632 ret = dcdc_set_voltage(desc, to_vol, 0);
633 else if (regs->typ == 0/*VDD_TYP_LDO*/)
634 ret = ldo_set_trimming(desc, 0, to_vol, 0);
644 #if defined(CONFIG_FDL2_BUILD)
645 vol_para_t **ppvol_para = 0x50000020;
647 vol_para_t **ppvol_para = 0x50005c20;
650 static int get_vol_para_num(void)
654 if (!(ppvol_para && *ppvol_para))
657 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
660 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end"))
666 static vol_para_t * match_vol_para(const char* vol_name)
670 BUG_ON(NULL == vol_name);
672 if (!(ppvol_para && *ppvol_para))
675 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
678 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end")) {
679 if (0 == strcmp((*ppvol_para)[i].name, vol_name)) {
680 debug0("%s name %s, ideal_vol %d\n", __func__, (*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
681 return (vol_para_t*)(&(*ppvol_para)[i]);
688 int regulator_default_get(const char con_id[])
690 vol_para_t * pvol_para = match_vol_para(con_id);
692 return (int)(pvol_para ? pvol_para->ideal_vol : 0);
695 void regulator_default_set(const char con_id[], int vol)
697 vol_para_t * pvol_para = match_vol_para(con_id);
700 pvol_para->ideal_vol = vol;
704 int regulator_default_set_all(void)
708 //dump & check all vol para
709 if (!(ppvol_para && *ppvol_para))
712 if(strcmp((*ppvol_para)[0].name, "volpara_begin") || (0xfaed != (*ppvol_para)[0].ideal_vol))
715 while(0 != strcmp((*ppvol_para)[i++].name, "volpara_end")) {
716 debug("regu: [%d] %s : %d\n", i, (*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
718 ret |= regulator_set_voltage((*ppvol_para)[i].name, (*ppvol_para)[i].ideal_vol);
724 /********************************************************************
726 * regulator_get_calibration_mask - get dcdc/ldo calibration flag
729 //High 16bit: dcdc ctrl calibration flag
731 * bit[13] ~ bit[15] : reserved
737 * bit[7] : vddemmccore
747 //Low 16bit: ldo ctrl calibration flag
749 * bit[12] ~ bit[15] : reserved
762 ********************************************************************/
763 u32 regulator_get_calibration_mask(void)
765 int len = get_vol_para_num();
766 volatile vol_para_t *pvol_para = (volatile vol_para_t *)(*ppvol_para);
767 volatile u32* pdebug_flag = (u32*)(&pvol_para[len-1]);
770 printf("%s, vol_para_tbl_len %d, ldo_pd_mask 0x%08x; \n", __func__, len, *pdebug_flag);
771 return (*pdebug_flag);