tizen 2.4 release
[kernel/u-boot-tm1.git] / arch / arm / cpu / armv7 / sc8830 / ldo.c
1 /******************************************************************************
2  ** File Name:      ldo_drv.c                                             *
3  ** Author:         Yi.Qiu                                                 *
4  ** DATE:           01/09/2009                                                *
5  ** Copyright:      2007 Spreatrum, Incoporated. All Rights Reserved.         *
6  ** Description:    This file defines the basic function for ldo management.  *
7  ******************************************************************************/
8
9 /******************************************************************************
10  **                        Edit History                                       *
11  ** ------------------------------------------------------------------------- *
12  ** DATE           NAME             DESCRIPTION                               *
13  ** 01/09/2009     Yi.Qiu        Create.                                   *
14  ******************************************************************************/
15
16 /**---------------------------------------------------------------------------*
17  **                         Dependencies                                      *
18  **---------------------------------------------------------------------------*/
19 #include <common.h>
20 #include <asm/io.h>
21
22 #include <asm/arch/ldo.h>
23 #include <asm/arch/chip_drv_common_io.h>
24 #include <asm/arch/sprd_reg.h>
25
26 #define LDO_INVALID_REG 0xFFFFFFFF
27 #define LDO_INVALID_BIT 0xFFFFFFFF
28
29
30 #define CURRENT_STATUS_INIT     0x00000001
31 #define CURRENT_STATUS_ON       0x00000002
32 #define CURRENT_STATUS_OFF      0x00000004
33
34 #define LDO_INVALID_REG_ADDR    0x1
35
36 #define SCI_PASSERT(condition, format...)  \
37         do {            \
38                 if(!(condition)) { \
39                         printf("function :%s\r\n", __FUNCTION__);\
40                 } \
41         }while(0)
42
43 struct ldo_ctl_info {
44 /**
45   need config area
46  */
47         LDO_ID_E id;
48         unsigned int bp_reg;
49         unsigned int bp_bits;
50         unsigned int bp_rst_reg;
51         unsigned int bp_rst;//bits
52                 
53         unsigned int level_reg_b0;
54         unsigned int b0;
55         unsigned int b0_rst;
56                 
57         unsigned int level_reg_b1;
58         unsigned int b1;
59         unsigned int b1_rst;
60
61         unsigned int init_level;
62 /**
63   not need config area
64  */
65         int ref;
66         int current_status;
67         int current_volt_level;
68 };
69
70 #if defined(CONFIG_SPX15) || defined(CONFIG_ADIE_SC2723) || defined(CONFIG_ADIE_SC2723S)
71 struct {
72         LDO_ID_E id;
73         const char *name;
74 }__ldo_names[] = {
75         {
76                 .id = LDO_LDO_USB, .name = "vddusb",
77         },
78         {
79                 .id = LDO_LDO_EMMCCORE, .name = "vddemmccore",
80         },
81 #if defined(CONFIG_ADIE_SC2723) || defined(CONFIG_ADIE_SC2723S)
82         {
83                 .id = LDO_LDO_SDIO0, .name = "vddsdcore",
84         },
85         {
86                 .id = LDO_LDO_SDIO1, .name = "vddsdio",
87         },
88         #if defined(CONFIG_SPX20)
89                 {
90                         .id = LDO_LDO_EMMCIO, .name = "vddgen0",
91                 },
92         #else
93                 {
94                         .id = LDO_LDO_EMMCIO, .name = "vddgen0",
95                 },
96         #endif
97 #else
98         {
99                 .id = LDO_LDO_EMMCIO, .name = "vddemmcio",
100         },
101         {
102                 .id = LDO_LDO_SDIO0, .name = "vddsd",
103         },
104 #endif
105         {
106                 .id = LDO_LDO_SIM0, .name = "vddsim0",
107         },
108         {
109                 .id = LDO_LDO_SIM1, .name = "vddsim1",
110         },
111         {
112                 .id = LDO_LDO_SIM2, .name = "vddsim2",
113         },
114 };
115
116 struct s_ldo_ctl_info {
117         SLP_LDO_E id;
118         unsigned int reg;
119         unsigned int bit;
120 };
121
122 static struct s_ldo_ctl_info s_ldo_ctl_data[] = {
123     {LDO_LDO_USB,        ANA_REG_GLB_LDO_PD_CTRL,    BIT(8)},
124     {LDO_LDO_EMMCCORE,   ANA_REG_GLB_LDO_DCDC_PD,    BIT(7)},
125     {LDO_LDO_EMMCIO,     ANA_REG_GLB_LDO_DCDC_PD,    BIT(6)},
126     {LDO_LDO_SDIO3,      ANA_REG_GLB_LDO_PD_CTRL,    BIT(0)},
127     {LDO_LDO_SIM0,       ANA_REG_GLB_LDO_PD_CTRL,    BIT(1)},
128     {LDO_LDO_SIM1,       ANA_REG_GLB_LDO_PD_CTRL,    BIT(2)},
129     {LDO_LDO_SIM2,       ANA_REG_GLB_LDO_PD_CTRL,    BIT(3)},
130     {LDO_LDO_CAMMOT,       ANA_REG_GLB_LDO_PD_CTRL,    BIT(7)},
131     {LDO_LDO_WIFIPA,       ANA_REG_GLB_LDO_PD_CTRL,    BIT(11)},
132 };
133
134 static int __LDO_IDX(LDO_ID_E ldo_id)
135 {
136    int i=0;
137    for(i=0; i< ARRAY_SIZE(s_ldo_ctl_data);i++)
138    {
139       if(ldo_id == s_ldo_ctl_data[i].id)
140                 return i;
141    }
142    return -1;
143 }
144
145 const char* __LDO_NAME(LDO_ID_E ldo_id)
146 {
147         int i = 0;
148         for(i = 0; i < ARRAY_SIZE(__ldo_names); i++) {
149                 if (ldo_id == __ldo_names[i].id)
150                         return __ldo_names[i].name;
151         }
152         return NULL;
153 }
154
155 int LDO_Init(void)
156 {
157         return regulator_init();
158 }
159
160 void LDO_TurnOffAllLDO(void)
161 {
162         unsigned int reg_val;
163
164         ANA_REG_SET(ANA_REG_GLB_PWR_WR_PROT_VALUE,BITS_PWR_WR_PROT_VALUE(0x6e7f));
165         
166         do{
167                 reg_val = (ANA_REG_GET(ANA_REG_GLB_PWR_WR_PROT_VALUE) & BIT_PWR_WR_PROT);
168         }while(reg_val == 0);
169
170         ANA_REG_SET(ANA_REG_GLB_LDO_PD_CTRL,0x0FFF);
171         ANA_REG_SET(ANA_REG_GLB_LDO_DCDC_PD,0x7FFF);
172         
173         ANA_REG_SET(ANA_REG_GLB_PWR_WR_PROT_VALUE,BITS_PWR_WR_PROT_VALUE(0x0000));
174         //never return here and wait power down action
175         while(1);
176 }
177
178 LDO_ERR_E LDO_TurnOffLDO(LDO_ID_E ldo_id)
179 {
180 #if defined(CONFIG_ADIE_SC2713S)
181         return regulator_disable(__LDO_NAME(ldo_id));
182 #else
183     int i = __LDO_IDX(ldo_id);
184
185         if (i < 0)
186                 return LDO_ERR_ERR;
187
188         ANA_REG_OR(s_ldo_ctl_data[i].reg, s_ldo_ctl_data[i].bit);
189
190         return 0;
191 #endif
192 }
193
194 LDO_ERR_E LDO_TurnOnLDO(LDO_ID_E ldo_id)
195 {
196 #if defined(CONFIG_ADIE_SC2713S)
197         return regulator_enable(__LDO_NAME(ldo_id));
198 #else
199     int i = __LDO_IDX(ldo_id);
200
201         if (i < 0)
202                 return LDO_ERR_ERR;
203
204         ANA_REG_BIC(s_ldo_ctl_data[i].reg, s_ldo_ctl_data[i].bit);
205
206         return 0;
207 #endif
208 }
209
210 static struct ldo_ctl_info* LDO_GetLdoCtl(LDO_ID_E ldo_id)
211 {
212         int i = 0;
213         struct ldo_ctl_info* ctl = NULL;
214
215         for ( i = 0; i < ARRAY_SIZE(s_ldo_ctl_data); ++i)
216         {
217                 if (s_ldo_ctl_data[i].id == ldo_id)
218                 {
219                         ctl = &s_ldo_ctl_data[i];
220                         break;
221                 }
222         }
223
224         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
225         return ctl;
226 }
227
228 LDO_ERR_E LDO_SetVoltLevel(LDO_ID_E ldo_id, LDO_VOLT_LEVEL_E volt_level)
229 {
230         unsigned short reg_data;
231         struct ldo_ctl_info* ctl = NULL;
232
233         ctl = LDO_GetLdoCtl(ldo_id);
234         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
235
236         if (ctl->level_reg_b0 == LDO_INVALID_REG_ADDR)
237         {
238                 goto Err_Exit;
239         }
240
241         if (ctl->level_reg_b0 != ctl->level_reg_b1)
242         {
243                 printf("ldo_id:%d, level_reg_b0:%08x, level_reg_b1:%08x\r\n", ldo_id, ctl->level_reg_b0, ctl->level_reg_b1);
244                 goto Err_Exit;
245         }
246
247         switch (volt_level)
248         {
249                 case LDO_VOLT_LEVEL0:
250                         ANA_REG_AND(ctl->level_reg_b0, (~(ctl->b0|ctl->b1)));
251                         break;
252
253                 case LDO_VOLT_LEVEL1:
254                         reg_data = ANA_REG_GET(ctl->level_reg_b0);
255                         reg_data &=~ctl->b1;
256                         reg_data |= ctl->b0;
257                         ANA_REG_SET(ctl->level_reg_b0, reg_data);
258                         break;
259
260                 case LDO_VOLT_LEVEL2:
261                         reg_data = ANA_REG_GET(ctl->level_reg_b0);
262                         reg_data &=~ctl->b0;
263                         reg_data |= ctl->b1;
264                         ANA_REG_SET(ctl->level_reg_b0, reg_data);
265                         break;
266
267                 case LDO_VOLT_LEVEL3:
268                         ANA_REG_OR (ctl->level_reg_b0, (ctl->b0|ctl->b1));
269                         break;
270
271                 default:
272                         goto Err_Exit;
273         }
274
275         ctl->current_volt_level = volt_level;
276         return LDO_ERR_OK;
277 Err_Exit:
278         return LDO_ERR_ERR;
279 }
280
281 #else
282
283 struct ldo_ctl_info {
284         /**
285           need config area
286          */
287         LDO_ID_E id;
288         unsigned int bp_reg;
289         unsigned int bp_bits;
290         unsigned int bp_rst_reg;
291         unsigned int bp_rst;//bits
292
293         unsigned int level_reg_b0;
294         unsigned int b0;
295         unsigned int b0_rst;
296
297         unsigned int level_reg_b1;
298         unsigned int b1;
299         unsigned int b1_rst;
300
301         unsigned int init_level;
302         /**
303           not need config area
304          */
305         int ref;
306         int current_status;
307         int current_volt_level;
308 };
309
310 static struct ldo_ctl_info ldo_ctl_data[] =
311 {
312         {
313                 .id           = LDO_LDO_EMMCCORE,
314                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
315                 .bp_bits      = BIT_8,
316                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
317                 .bp_rst       = BIT_8,
318                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL0,
319                 .b0           = BIT_14,
320                 .b0_rst       = BIT_14,
321                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL0,
322                 .b1           = BIT_15,
323                 .b1_rst       = BIT_15,
324                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
325         },
326         {
327                 .id           = LDO_LDO_EMMCIO,
328                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
329                 .bp_bits      = BIT_7,
330                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
331                 .bp_rst       = BIT_7,
332                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL2,
333                 .b0           = BIT_12,
334                 .b0_rst       = BIT_12,
335                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL2,
336                 .b1           = BIT_13,
337                 .b1_rst       = BIT_13,
338                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
339         },
340         {
341                 .id           = LDO_LDO_RF2,
342                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
343                 .bp_bits      = BIT_6,
344                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
345                 .bp_rst       = BIT_6,
346                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL0,
347                 .b0           = BIT_10,
348                 .b0_rst       = BIT_10,
349                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL0,
350                 .b1           = BIT_11,
351                 .b1_rst       = BIT_11,
352                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
353         },
354         {
355                 .id           = LDO_LDO_RF1,
356                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
357                 .bp_bits      = BIT_5,
358                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
359                 .bp_rst       = BIT_5,
360                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL0,
361                 .b0           = BIT_8,
362                 .b0_rst       = BIT_8,
363                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL0,
364                 .b1           = BIT_9,
365                 .b1_rst       = BIT_9,
366                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
367         },
368         {
369                 .id           = LDO_LDO_RF0,
370                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
371                 .bp_bits      = BIT_4,
372                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
373                 .bp_rst       = BIT_4,
374                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL0,
375                 .b0           = BIT_6,
376                 .b0_rst       = BIT_6,
377                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL0,
378                 .b1           = BIT_7,
379                 .b1_rst       = BIT_7,
380                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
381         },
382         {
383                 .id           = LDO_LDO_VDD25,
384                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
385                 .bp_bits      = BIT_3,
386                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
387                 .bp_rst       = BIT_3,
388                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL0,
389                 .b0           = BIT_4,
390                 .b0_rst       = BIT_4,
391                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL0,
392                 .b1           = BIT_5,
393                 .b1_rst       = BIT_5,
394                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
395         },
396         {
397                 .id           = LDO_LDO_VDD28,
398                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
399                 .bp_bits      = BIT_2,
400                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
401                 .bp_rst       = BIT_2,
402                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL0,
403                 .b0           = BIT_2,
404                 .b0_rst       = BIT_2,
405                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL0,
406                 .b1           = BIT_3,
407                 .b1_rst       = BIT_3,
408                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
409         },
410         {
411                 .id           = LDO_LDO_VDD18,
412                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
413                 .bp_bits      = BIT_1,
414                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
415                 .bp_rst       = BIT_1,
416                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL0,
417                 .b0           = BIT_0,
418                 .b0_rst       = BIT_0,
419                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL0,
420                 .b1           = BIT_1,
421                 .b1_rst       = BIT_1,
422                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
423         },
424         {
425                 .id           = LDO_LDO_SIM2,
426                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
427                 .bp_bits      = BIT_4,
428                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
429                 .bp_rst       = BIT_4,
430                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL1,
431                 .b0           = BIT_8,
432                 .b0_rst       = BIT_8,
433                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL1,
434                 .b1           = BIT_9,
435                 .b1_rst       = BIT_9,
436                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
437         },
438         {
439                 .id           = LDO_LDO_SIM1,
440                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
441                 .bp_bits      = BIT_3,
442                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
443                 .bp_rst       = BIT_3,
444                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL1,
445                 .b0           = BIT_6,
446                 .b0_rst       = BIT_6,
447                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL1,
448                 .b1           = BIT_7,
449                 .b1_rst       = BIT_7,
450                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
451         },
452         {
453                 .id           = LDO_LDO_SIM0,
454                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
455                 .bp_bits      = BIT_2,
456                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
457                 .bp_rst       = BIT_2,
458                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL1,
459                 .b0           = BIT_4,
460                 .b0_rst       = BIT_4,
461                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL1,
462                 .b1           = BIT_5,
463                 .b1_rst       = BIT_5,
464                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
465         },
466         {
467                 .id           = LDO_LDO_SDIO0,
468                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
469                 .bp_bits      = BIT_1,
470                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
471                 .bp_rst       = BIT_1,
472                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL1,
473                 .b0           = BIT_2,
474                 .b0_rst       = BIT_2,
475                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL1,
476                 .b1           = BIT_3,
477                 .b1_rst       = BIT_3,
478                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
479         },
480         {
481                 .id           = LDO_LDO_AVDD18,
482                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
483                 .bp_bits      = BIT_0,
484                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
485                 .bp_rst       = BIT_0,
486                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL1,
487                 .b0           = BIT_0,
488                 .b0_rst       = BIT_0,
489                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL1,
490                 .b1           = BIT_1,
491                 .b1_rst       = BIT_1,
492                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
493         },
494         {
495                 .id           = LDO_LDO_VBAT_RES,               //new
496                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
497                 .bp_bits      = BIT_0,
498                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
499                 .bp_rst       = BIT_0,
500                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL2,
501                 .b0           = BIT_14,
502                 .b0_rst       = BIT_14,
503                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL2,
504                 .b1           = BIT_15,
505                 .b1_rst       = BIT_15,
506                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
507         },
508         {
509                 .id           = LDO_LDO_VBAT_V,                 //new
510                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
511                 .bp_bits      = BIT_0,
512                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
513                 .bp_rst       = BIT_0,
514                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL2,
515                 .b0           = BIT_12,
516                 .b0_rst       = BIT_12,
517                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL2,
518                 .b1           = BIT_13,
519                 .b1_rst       = BIT_13,
520                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
521         },
522         {
523                 .id           = LDO_LDO_CLSG,
524                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
525                 .bp_bits      = BIT_10,
526                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
527                 .bp_rst       = BIT_10,
528                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL2,
529                 .b0           = BIT_10,
530                 .b0_rst       = BIT_10,
531                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL2,
532                 .b1           = BIT_11,
533                 .b1_rst       = BIT_11,
534                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
535         },
536         {
537                 .id           = LDO_LDO_USB,
538                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
539                 .bp_bits      = BIT_9,
540                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
541                 .bp_rst       = BIT_9,
542                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL2,
543                 .b0           = BIT_8,
544                 .b0_rst       = BIT_8,
545                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL2,
546                 .b1           = BIT_9,
547                 .b1_rst       = BIT_9,
548                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
549         },
550         {
551                 .id           = LDO_LDO_CAMM,  //LDO_LDO_CAMMOT
552                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
553                 .bp_bits      = BIT_8,
554                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
555                 .bp_rst       = BIT_8,
556                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL2,
557                 .b0           = BIT_6,
558                 .b0_rst       = BIT_6,
559                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL2,
560                 .b1           = BIT_7,
561                 .b1_rst       = BIT_7,
562                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
563         },
564         {
565                 .id           = LDO_LDO_CAMD1,  //LDO_LDO_CAMIO
566                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
567                 .bp_bits      = BIT_7,
568                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
569                 .bp_rst       = BIT_7,
570                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL2,
571                 .b0           = BIT_4,
572                 .b0_rst       = BIT_4,
573                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL2,
574                 .b1           = BIT_5,
575                 .b1_rst       = BIT_5,
576                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
577         },
578         {
579                 .id           = LDO_LDO_CAMD0,  //LDO_LDO_CAMCORE
580                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
581                 .bp_bits      = BIT_6,
582                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
583                 .bp_rst       = BIT_6,
584                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL2,
585                 .b0           = BIT_2,
586                 .b0_rst       = BIT_2,
587                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL2,
588                 .b1           = BIT_3,
589                 .b1_rst       = BIT_3,
590                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
591         },
592         {
593                 .id           = LDO_LDO_CAMA,  //LDO_LDO_CAMA
594                 .bp_reg       = ANA_REG_GLB_LDO_PD_CTRL,
595                 .bp_bits      = BIT_5,
596                 .bp_rst_reg   = ANA_REG_GLB_LDO_PD_CTRL,
597                 .bp_rst       = BIT_5,
598                 .level_reg_b0 = ANA_REG_GLB_LDO_V_CTRL2,
599                 .b0           = BIT_0,
600                 .b0_rst       = BIT_0,
601                 .level_reg_b1 = ANA_REG_GLB_LDO_V_CTRL2,
602                 .b1           = BIT_1,
603                 .b1_rst       = BIT_1,
604                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
605         },
606 /**                config it later               **/
607         {
608                 .id           = LDO_DCDCARM,
609                 .bp_reg       = LDO_INVALID_REG_ADDR,
610                 .bp_bits      = 0,
611                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
612                 .bp_rst       = 0,
613                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
614                 .b0           = BIT_14,
615                 .b0_rst       = BIT_14,
616                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
617                 .b1           = BIT_15,
618                 .b1_rst       = BIT_15,
619                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
620         },
621         {
622                 .id           = LDO_LDO_ABB,
623                 .bp_reg       = LDO_INVALID_REG_ADDR,
624                 .bp_bits      = 0,
625                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
626                 .bp_rst       = 0,
627                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
628                 .b0           = BIT_14,
629                 .b0_rst       = BIT_14,
630                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
631                 .b1           = BIT_15,
632                 .b1_rst       = BIT_15,
633                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
634         },
635         {
636                 .id           = LDO_LDO_MEM,
637                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
638                 .bp_bits      = BIT_11,
639                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
640                 .bp_rst       = BIT_11,
641                 .level_reg_b0 = ANA_REG_GLB_DCDC_MEM_ADI,
642                 .b0           = BIT_5,
643                 .b0_rst       = BIT_5,
644                 .level_reg_b1 = ANA_REG_GLB_DCDC_MEM_ADI,
645                 .b1           = BIT_6,
646                 .b1_rst       = BIT_6,
647                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
648         },
649         {
650                 .id           = LDO_DCDC,
651                 .bp_reg       = LDO_INVALID_REG_ADDR,
652                 .bp_bits      = 0,
653                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
654                 .bp_rst       = 0,
655                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
656                 .b0           = BIT_14,
657                 .b0_rst       = BIT_14,
658                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
659                 .b1           = BIT_15,
660                 .b1_rst       = BIT_15,
661                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
662         },
663         {
664                 .id           = LDO_LDO_BG,
665                 .bp_reg       = LDO_INVALID_REG_ADDR,
666                 .bp_bits      = 0,
667                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
668                 .bp_rst       = 0,
669                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
670                 .b0           = BIT_14,
671                 .b0_rst       = BIT_14,
672                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
673                 .b1           = BIT_15,
674                 .b1_rst       = BIT_15,
675                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
676         },
677         {
678                 .id           = LDO_LDO_AVB,
679                 .bp_reg       = LDO_INVALID_REG_ADDR,
680                 .bp_bits      = 0,
681                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
682                 .bp_rst       = 0,
683                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
684                 .b0           = BIT_14,
685                 .b0_rst       = BIT_14,
686                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
687                 .b1           = BIT_15,
688                 .b1_rst       = BIT_15,
689                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
690         },
691         {
692                 .id           = LDO_LDO_WIF1,
693                 .bp_reg       = LDO_INVALID_REG_ADDR,
694                 .bp_bits      = 0,
695                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
696                 .bp_rst       = 0,
697                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
698                 .b0           = BIT_14,
699                 .b0_rst       = BIT_14,
700                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
701                 .b1           = BIT_15,
702                 .b1_rst       = BIT_15,
703                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
704         },
705         {
706                 .id           = LDO_LDO_WIF0,
707                 .bp_reg       = LDO_INVALID_REG_ADDR,
708                 .bp_bits      = 0,
709                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
710                 .bp_rst       = 0,
711                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
712                 .b0           = BIT_14,
713                 .b0_rst       = BIT_14,
714                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
715                 .b1           = BIT_15,
716                 .b1_rst       = BIT_15,
717                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
718         },
719         {
720                 .id           = LDO_LDO_SDIO1,
721                 .bp_reg       = LDO_INVALID_REG_ADDR,
722                 .bp_bits      = 0,
723                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
724                 .bp_rst       = 0,
725                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
726                 .b0           = BIT_14,
727                 .b0_rst       = BIT_14,
728                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
729                 .b1           = BIT_15,
730                 .b1_rst       = BIT_15,
731                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
732         },
733         {
734                 .id           = LDO_LDO_RTC,
735                 .bp_reg       = ANA_REG_GLB_LDO_DCDC_PD_RTCSET,
736                 .bp_bits      = BIT_9,
737                 .bp_rst_reg   = ANA_REG_GLB_LDO_DCDC_PD_RTCCLR,
738                 .bp_rst       = BIT_9,
739                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
740                 .b0           = BIT_14,
741                 .b0_rst       = BIT_14,
742                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
743                 .b1           = BIT_15,
744                 .b1_rst       = BIT_15,
745                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
746         },
747         {
748                 .id           = LDO_LDO_USBD,
749                 .bp_reg       = LDO_INVALID_REG_ADDR,
750                 .bp_bits      = 0,
751                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
752                 .bp_rst       = 0,
753                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
754                 .b0           = BIT_14,
755                 .b0_rst       = BIT_14,
756                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
757                 .b1           = BIT_15,
758                 .b1_rst       = BIT_15,
759                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
760         },
761         {
762                 .id           = LDO_LDO_VDD30,
763                 .bp_reg       = LDO_INVALID_REG_ADDR,
764                 .bp_bits      = 0,
765                 .bp_rst_reg   = LDO_INVALID_REG_ADDR,
766                 .bp_rst       = 0,
767                 .level_reg_b0 = LDO_INVALID_REG_ADDR,
768                 .b0           = BIT_14,
769                 .b0_rst       = BIT_14,
770                 .level_reg_b1 = LDO_INVALID_REG_ADDR,
771                 .b1           = BIT_15,
772                 .b1_rst       = BIT_15,
773                 .init_level   = LDO_VOLT_LEVEL_FAULT_MAX,
774         },
775 };
776
777 /**---------------------------------------------------------------------------*
778  **                         Function Declaration                              *
779  **---------------------------------------------------------------------------*/
780 static struct ldo_ctl_info* LDO_GetLdoCtl(LDO_ID_E ldo_id)
781 {
782         int i = 0;
783         struct ldo_ctl_info* ctl = NULL;
784
785         for ( i = 0; i < ARRAY_SIZE(ldo_ctl_data); ++i)
786         {
787                 if (ldo_ctl_data[i].id == ldo_id)
788                 {
789                         ctl = &ldo_ctl_data[i];
790                         break;
791                 }
792         }
793
794         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
795         return ctl;
796 }
797
798 LDO_ERR_E LDO_TurnOnLDO(LDO_ID_E ldo_id)
799 {
800         struct ldo_ctl_info* ctl = NULL;
801
802         if (ldo_id == LDO_LDO_SDIO3)
803         {
804                 if (LDO_TurnOnLDO(LDO_LDO_EMMCCORE) != LDO_ERR_OK)
805                         return LDO_ERR_ERR;
806                 if (LDO_TurnOnLDO(LDO_LDO_EMMCIO)   != LDO_ERR_OK)
807                         return LDO_ERR_ERR;
808                 return LDO_ERR_OK;
809         }
810
811         ctl = LDO_GetLdoCtl(ldo_id);
812         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
813
814         //if ((ctl->ref++) == 0)
815         {
816                 if(ctl->bp_reg == LDO_INVALID_REG_ADDR)
817                 {
818                         //if (LDO_LDO_USBD == ldo_id)
819                         //      CHIP_REG_AND((~LDO_USB_PD), GR_CLK_GEN5);
820                         return LDO_ERR_ERR;
821                 }
822                 else
823                 {
824                         ANA_REG_OR (ctl->bp_rst_reg, ctl->bp_rst);
825                         ANA_REG_AND(ctl->bp_reg,     ~(ctl->bp_bits));
826                 }
827                 ctl->current_status = CURRENT_STATUS_ON;
828         }
829         return LDO_ERR_OK;
830 }
831
832 LDO_ERR_E LDO_TurnOffLDO(LDO_ID_E ldo_id)
833 {
834         struct ldo_ctl_info* ctl = NULL;
835
836         if (ldo_id == LDO_LDO_SDIO3)
837         {
838                 if (LDO_TurnOffLDO(LDO_LDO_EMMCCORE) != LDO_ERR_OK)
839                         return LDO_ERR_ERR;
840                 if (LDO_TurnOffLDO(LDO_LDO_EMMCIO)   != LDO_ERR_OK)
841                         return LDO_ERR_ERR;
842                 return LDO_ERR_OK;
843         }
844
845         ctl = LDO_GetLdoCtl(ldo_id);
846         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
847
848         //local_irq_save(flags);
849
850         //if ((--ctl->ref) == 0)
851         {
852                 if(ctl->bp_reg == LDO_INVALID_REG_ADDR)
853                 {
854                         //if (LDO_LDO_USBD == ldo_id)
855                         //      CHIP_REG_OR((LDO_USB_PD), GR_CLK_GEN5);
856                 }
857                 else
858                 {
859                         ANA_REG_AND(ctl->bp_rst_reg, (~(ctl->bp_rst)));
860                         ANA_REG_OR (ctl->bp_reg,     ctl->bp_bits);
861                 }
862                 ctl->current_status = CURRENT_STATUS_OFF;
863         }
864
865         //local_irq_restore(flags);
866
867         return LDO_ERR_OK;
868 }
869
870 int LDO_IsLDOOn(LDO_ID_E ldo_id)
871 {
872         unsigned int  masked_val = 0;
873         struct ldo_ctl_info* ctl = NULL;
874
875         ctl = LDO_GetLdoCtl(ldo_id);
876         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
877
878         if (ctl->current_status == CURRENT_STATUS_INIT)
879         {
880                 masked_val = (LDO_REG_GET(ctl->bp_reg) & ctl->bp_bits);
881         }
882         else
883         {
884                 return (ctl->current_status == CURRENT_STATUS_OFF ? 0 : 1);
885         }
886
887         return (masked_val ? 0 : 1);
888 }
889
890 LDO_ERR_E LDO_SetVoltLevel(LDO_ID_E ldo_id, LDO_VOLT_LEVEL_E volt_level)
891 {
892         unsigned short reg_data;
893         struct ldo_ctl_info* ctl = NULL;
894
895         ctl = LDO_GetLdoCtl(ldo_id);
896         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
897
898         if (ctl->level_reg_b0 == LDO_INVALID_REG_ADDR)
899         {
900                 goto Err_Exit;
901         }
902
903         if (ctl->level_reg_b0 != ctl->level_reg_b1)
904         {
905                 printf("ldo_id:%d, level_reg_b0:%08x, level_reg_b1:%08x\r\n", ldo_id, ctl->level_reg_b0, ctl->level_reg_b1);
906                 goto Err_Exit;
907         }
908
909         switch (volt_level)
910         {
911                 case LDO_VOLT_LEVEL0:
912                         ANA_REG_AND(ctl->level_reg_b0, (~(ctl->b0|ctl->b1)));
913                         break;
914
915                 case LDO_VOLT_LEVEL1:
916                         reg_data = ANA_REG_GET(ctl->level_reg_b0);
917                         reg_data &=~ctl->b1;
918                         reg_data |= ctl->b0;
919                         ANA_REG_SET(ctl->level_reg_b0, reg_data);
920                         break;
921
922                 case LDO_VOLT_LEVEL2:
923                         reg_data = ANA_REG_GET(ctl->level_reg_b0);
924                         reg_data &=~ctl->b0;
925                         reg_data |= ctl->b1;
926                         ANA_REG_SET(ctl->level_reg_b0, reg_data);
927                         break;
928
929                 case LDO_VOLT_LEVEL3:
930                         ANA_REG_OR (ctl->level_reg_b0, (ctl->b0|ctl->b1));
931                         break;
932
933                 default:
934                         goto Err_Exit;
935         }
936
937         ctl->current_volt_level = volt_level;
938         return LDO_ERR_OK;
939 Err_Exit:
940         return LDO_ERR_ERR;
941 }
942
943 LDO_VOLT_LEVEL_E LDO_GetVoltLevel(LDO_ID_E ldo_id)
944 {
945         unsigned int level_ret = 0;
946         struct ldo_ctl_info* ctl = NULL;
947
948         ctl = LDO_GetLdoCtl(ldo_id);
949         SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
950
951         if (ctl->current_volt_level == LDO_VOLT_LEVEL_FAULT_MAX)
952         {
953                 if(ctl->level_reg_b0 == ctl->level_reg_b1)
954                 {
955                         level_ret = 0;
956                 }
957                 else
958                 {
959                         level_ret = 0;
960                         SCI_PASSERT(0, ("shakr b0 must equal b1!"));
961                 }
962         }
963         else
964         {
965                 level_ret = ctl->current_volt_level;
966         }
967
968         return level_ret;
969 }
970
971 int LDO_Init(void)
972 {
973         int i;
974         for ( i = 0; i < ARRAY_SIZE(ldo_ctl_data); ++i)
975         {
976                 if( ldo_ctl_data[i].init_level != LDO_VOLT_LEVEL_FAULT_MAX)
977                 {
978                         LDO_SetVoltLevel(ldo_ctl_data[i].id, ldo_ctl_data[i].init_level);
979                 }
980                 ldo_ctl_data[i].ref = 0;
981                 ldo_ctl_data[i].current_status = CURRENT_STATUS_INIT;
982                 ldo_ctl_data[i].current_volt_level = ldo_ctl_data[i].init_level;
983         }
984         return LDO_ERR_OK;
985 }
986
987 static void LDO_TurnOffCoreLDO(void)
988 {
989         ANA_REG_SET(ANA_REG_GLB_LDO_DCDC_PD_RTCCLR, 0x0);
990         ANA_REG_SET(ANA_REG_GLB_LDO_DCDC_PD_RTCSET, 0x7FFF);
991 }
992
993 static void LDO_TurnOffAllModuleLDO(void)
994 {
995         ANA_REG_SET(ANA_REG_GLB_LDO_PD_CTRL, 0x1FFF);
996 }
997
998 void LDO_TurnOffAllLDO(void)
999 {
1000         LDO_TurnOffAllModuleLDO();
1001         LDO_TurnOffCoreLDO();
1002 }
1003
1004 #endif/*sc8830*/