1 /******************************************************************************
2 ** File Name: ldo_drv.c *
5 ** Copyright: 2007 Spreatrum, Incoporated. All Rights Reserved. *
6 ** Description: This file defines the basic function for ldo management. *
7 ******************************************************************************/
9 /******************************************************************************
11 ** ------------------------------------------------------------------------- *
12 ** DATE NAME DESCRIPTION *
13 ** 01/09/2009 Yi.Qiu Create. *
14 ******************************************************************************/
16 /**---------------------------------------------------------------------------*
18 **---------------------------------------------------------------------------*/
22 #include <asm/arch/regs_global.h>
23 #include <asm/arch/bits.h>
24 #include <asm/arch/ldo.h>
25 #include <asm/arch/regs_ana.h>
27 #define LDO_INVALID_REG 0xFFFFFFFF
28 #define LDO_INVALID_BIT 0xFFFFFFFF
33 #define CHIP_REG_OR(reg_addr, value) (*(volatile unsigned int *)(reg_addr) |= (unsigned int)(value))
34 #define CHIP_REG_AND(reg_addr, value) (*(volatile unsigned int *)(reg_addr) &= (unsigned int)(value))
35 #define CHIP_REG_GET(reg_addr) (*(volatile unsigned int *)(reg_addr))
36 #define CHIP_REG_SET(reg_addr, value) (*(volatile unsigned int *)(reg_addr) = (unsigned int)(value))
43 #define SCI_ASSERT(condition) BUG_ON(!(condition))
44 #define SCI_PASSERT(condition, format...) \
47 printf("function :%s\r\n", __FUNCTION__);\
64 unsigned int level_reg_b0;
67 unsigned int level_reg_b1;
70 unsigned int valid_time;
71 unsigned int init_level;
73 }LDO_CTL_T, * LDO_CTL_PTR;
82 unsigned int reserved;
83 }SLP_LDO_CTL_T, * SLP_LDO_CTL_PTR;
86 LDO_CTL_T ldo_ctl_data[] =
89 LDO_LDO_ABB, NULL, NULL, NULL, ANA_LDO_VCTL0, BIT_12, BIT_13,
90 ANA_LDO_VCTL0, BIT_14, BIT_15, NULL, LDO_VOLT_LEVEL_MAX, NULL
93 LDO_LDO_RF1, NULL, NULL, NULL, ANA_LDO_VCTL0, BIT_8, BIT_9,
94 ANA_LDO_VCTL0, BIT_10, BIT_11, NULL, LDO_VOLT_LEVEL_MAX, NULL
97 LDO_LDO_RF0, NULL, NULL, NULL, ANA_LDO_VCTL0, BIT_4, BIT_5,
98 ANA_LDO_VCTL0, BIT_6, BIT_7, NULL, LDO_VOLT_LEVEL_MAX, NULL
101 LDO_LDO_RTC, NULL, NULL, NULL, ANA_LDO_VCTL0, BIT_0, BIT_1,
102 ANA_LDO_VCTL0, BIT_2, BIT_3, NULL, LDO_VOLT_LEVEL_MAX, NULL
105 LDO_LDO_SDIO, ANA_LDO_PD_CTL, BIT_2, BIT_3, ANA_LDO_VCTL1, BIT_12,BIT_13,
106 ANA_LDO_VCTL1, BIT_14, BIT_15, NULL, LDO_VOLT_LEVEL_MAX, NULL
109 LDO_LDO_AVBO, ANA_LDO_PD_CTL, BIT_14, BIT_15, ANA_LDO_VCTL1, BIT_8, BIT_9,
110 ANA_LDO_VCTL1, BIT_10, BIT_11, NULL, LDO_VOLT_LEVEL_MAX, NULL
113 LDO_LDO_SIM1, ANA_LDO_PD_CTL, BIT_6, BIT_7, ANA_LDO_VCTL1, BIT_4, BIT_5,
114 ANA_LDO_VCTL1, BIT_6, BIT_7, NULL, LDO_VOLT_LEVEL_MAX, NULL
117 LDO_LDO_SIM0, ANA_LDO_PD_CTL, BIT_4, BIT_5, ANA_LDO_VCTL1, BIT_0, BIT_1,
118 ANA_LDO_VCTL1, BIT_2, BIT_3, NULL, LDO_VOLT_LEVEL_MAX, NULL
121 LDO_LDO_USB, ANA_LDO_PD_CTL, BIT_0, BIT_1, ANA_LDO_VCTL2, BIT_12, BIT_13,
122 ANA_LDO_VCTL2, BIT_14, BIT_15, NULL, LDO_VOLT_LEVEL_MAX, NULL
125 LDO_LDO_USBD, NULL, NULL, NULL, NULL, NULL, NULL,
126 NULL, NULL, NULL, NULL, LDO_VOLT_LEVEL_MAX, NULL
129 LDO_LDO_CAMA, ANA_LDO_PD_CTL, BIT_12, BIT_13, ANA_LDO_VCTL2, BIT_8, BIT_9,
130 ANA_LDO_VCTL2, BIT_10, BIT_11, NULL, LDO_VOLT_LEVEL_MAX, NULL
133 LDO_LDO_CAMD1, ANA_LDO_PD_CTL, BIT_10, BIT_11, ANA_LDO_VCTL2, BIT_4, BIT_5,
134 ANA_LDO_VCTL2, BIT_6, BIT_7, NULL, LDO_VOLT_LEVEL_MAX, NULL
137 LDO_LDO_CAMD0, ANA_LDO_PD_CTL, BIT_8, BIT_9, ANA_LDO_VCTL2, BIT_0, BIT_1,
138 ANA_LDO_VCTL2, BIT_2, BIT_3, NULL, LDO_VOLT_LEVEL_MAX, NULL
141 LDO_LDO_VDD25, NULL, NULL, NULL, ANA_LDO_VCTL3, BIT_8, BIT_9,
142 ANA_LDO_VCTL3, BIT_10, BIT_11, NULL, LDO_VOLT_LEVEL_MAX, NULL
145 LDO_LDO_VDD18, NULL, NULL, NULL, ANA_LDO_VCTL3, BIT_4, BIT_5,
146 ANA_LDO_VCTL3, BIT_6, BIT_7, NULL, LDO_VOLT_LEVEL_MAX, NULL
149 LDO_LDO_VDD28, NULL, NULL, NULL, ANA_LDO_VCTL3, BIT_0, BIT_1,
150 ANA_LDO_VCTL3, BIT_2, BIT_3, NULL, LDO_VOLT_LEVEL_MAX, NULL
153 LDO_LDO_MAX, NULL, NULL, NULL, NULL, NULL, NULL,
154 NULL, NULL, NULL, NULL, LDO_VOLT_LEVEL_MAX, NULL
158 SLP_LDO_CTL_T slp_ldo_ctl_data[] =
160 {SLP_LDO_PA, ANA_LDO_SLP, BIT_15, SLP_BIT_SET, TRUE, NULL},
161 {SLP_LDO_DVDD18, ANA_LDO_SLP, BIT_14, SLP_BIT_CLR, TRUE, NULL},
162 {SLP_LDO_VDD25, ANA_LDO_SLP, BIT_13, SLP_BIT_SET, TRUE, NULL},
163 {SLP_LDO_VDD18, ANA_LDO_SLP, BIT_12, SLP_BIT_CLR, TRUE, NULL},
164 {SLP_LDO_VDD28, ANA_LDO_SLP, BIT_11, SLP_BIT_CLR, TRUE, NULL},
165 {SLP_LDO_ABB, ANA_LDO_SLP, BIT_10, SLP_BIT_SET, TRUE, NULL},
166 {SLP_LDO_SDIO, ANA_LDO_SLP, BIT_9, SLP_BIT_SET, TRUE, NULL},
167 {SLP_LDO_VBO, ANA_LDO_SLP, BIT_8, SLP_BIT_CLR, TRUE, NULL},
168 {SLP_LDO_CAMA, ANA_LDO_SLP, BIT_7, SLP_BIT_SET, TRUE, NULL},
169 {SLP_LDO_CAMD1, ANA_LDO_SLP, BIT_6, SLP_BIT_SET, TRUE, NULL},
170 {SLP_LDO_CAMD0, ANA_LDO_SLP, BIT_5, SLP_BIT_SET, TRUE, NULL},
171 {SLP_LDO_USB, ANA_LDO_SLP, BIT_4, SLP_BIT_SET, TRUE, NULL},
172 {SLP_LDO_SIM1, ANA_LDO_SLP, BIT_3, SLP_BIT_SET, TRUE, NULL},
173 {SLP_LDO_SIM0, ANA_LDO_SLP, BIT_2, SLP_BIT_CLR, TRUE, NULL},
174 {SLP_LDO_RF1, ANA_LDO_SLP, BIT_1, SLP_BIT_SET, TRUE, NULL},
175 {SLP_LDO_RF0, ANA_LDO_SLP, BIT_0, SLP_BIT_SET, TRUE, NULL},
176 {SLP_LDO_MAX, NULL, NULL, SLP_BIT_SET, TRUE, NULL}
179 static LDO_CTL_PTR Ldo_Get_Cfg(void)
184 /**---------------------------------------------------------------------------*
185 ** Global variables *
186 **---------------------------------------------------------------------------*/
188 LDO_CTL_PTR g_ldo_ctl_tab = NULL;
191 /*****************************************************************************/
192 // Description: Slp_Ldo_Get_Cfg
193 // Global resource dependence: NONE
195 // Note: Slp_Ldo_Get_Cfg
196 /*****************************************************************************/
197 static SLP_LDO_CTL_PTR Slp_Ldo_Get_Cfg(void)
199 return slp_ldo_ctl_data;
202 /**---------------------------------------------------------------------------*
203 ** Function Declaration *
204 **---------------------------------------------------------------------------*/
206 /*****************************************************************************/
207 // Description: Turn on the LDO specified by input parameter ldo_id
208 // Global resource dependence: NONE
209 // Author: Tao.Feng && Yi.Qiu
210 // Note: return value = LDO_ERR_OK if operation is executed successfully
211 /*****************************************************************************/
212 static LDO_CTL_PTR LDO_GetLdoCtl(LDO_ID_E ldo_id)
215 LDO_CTL_PTR ctl = NULL;
217 SCI_ASSERT(NULL != g_ldo_ctl_tab);
219 for(i=0; g_ldo_ctl_tab[i].id != LDO_LDO_MAX; i++)
221 if( g_ldo_ctl_tab[i].id == ldo_id)
223 ctl = &g_ldo_ctl_tab[i];
228 SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
233 /*****************************************************************************/
234 // Description: Turn on the LDO specified by input parameter ldo_id
235 // Global resource dependence: NONE
236 // Author: Tao.Feng && Yi.Qiu
237 // Note: return value = LDO_ERR_OK if operation is executed successfully
238 /*****************************************************************************/
239 LDO_ERR_E LDO_TurnOnLDO(LDO_ID_E ldo_id)
241 unsigned int reg_val;
242 LDO_CTL_PTR ctl = NULL;
245 ctl = LDO_GetLdoCtl(ldo_id);
246 SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
248 if(ctl->bp_reg == NULL){
249 if (LDO_LDO_USBD == ldo_id){
250 local_irq_save(flags);
251 CHIP_REG_AND(GR_CLK_GEN5, (~LDO_USB_PD));
252 //__raw_bits_and((~LDO_USB_PD), GR_CLK_GEN5);
253 local_irq_restore(flags);
258 local_irq_save(flags);
260 SCI_PASSERT(ctl->ref >= 0, ("ctl->ref = %d", ctl->ref));
262 REG_SETCLRBIT(ctl->bp_reg, ctl->bp_rst, ctl->bp);
267 local_irq_restore(flags);
272 /*****************************************************************************/
273 // Description: Turo off the LDO specified by parameter ldo_id
274 // Global resource dependence: NONE
275 // Author: Tao.Feng && Yi.Qiu
277 /*****************************************************************************/
278 LDO_ERR_E LDO_TurnOffLDO(LDO_ID_E ldo_id)
280 unsigned int reg_val;
281 LDO_CTL_PTR ctl = NULL;
284 ctl = LDO_GetLdoCtl(ldo_id);
285 SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
287 if(ctl->bp_reg == NULL){
288 if (LDO_LDO_USBD == ldo_id){
289 local_irq_save(flags);
290 CHIP_REG_OR(GR_CLK_GEN5, (~LDO_USB_PD));
291 //__raw_bits_or((~LDO_USB_PD), GR_CLK_GEN5);
292 local_irq_restore(flags);
297 local_irq_save(flags);
303 REG_SETCLRBIT(ctl->bp_reg, ctl->bp, ctl->bp_rst);
306 local_irq_restore(flags);
311 /*****************************************************************************/
312 // Description: Find the LDO status -- ON or OFF
313 // Global resource dependence:
314 // Author: Tao.Feng && Yi.Qiu
315 // Note: return SCI_TRUE means LDO is ON, SCI_FALSE is OFF
316 /*****************************************************************************/
317 int LDO_IsLDOOn(LDO_ID_E ldo_id)
319 unsigned int masked_val = 0;
320 LDO_CTL_PTR ctl = NULL;
322 ctl = LDO_GetLdoCtl(ldo_id);
323 SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
325 masked_val = (LDO_REG_GET(ctl->bp_reg) & ctl->bp);
327 return (masked_val ? 0 : 1);
330 /*****************************************************************************/
331 // Description: change the LDO voltage level specified by parameter ldo_id
332 // Global resource dependence:
333 // Author: Tao.Feng && Yi.Qiu
335 /*****************************************************************************/
336 LDO_ERR_E LDO_SetVoltLevel(LDO_ID_E ldo_id, LDO_VOLT_LEVEL_E volt_level)
339 unsigned int b0_mask,b1_mask;
340 LDO_CTL_PTR ctl = NULL;
342 b0_mask = (volt_level & BIT_0)?~0:0;
343 b1_mask = (volt_level & BIT_1)?~0:0;
345 ctl = LDO_GetLdoCtl(ldo_id);
346 SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
348 if(ctl->level_reg_b0 == NULL)
353 if(ctl->level_reg_b0 == ctl->level_reg_b1)
355 SET_LEVEL(ctl->level_reg_b0, b0_mask, b1_mask, ctl->b0, ctl->b0_rst, ctl->b1, ctl->b1_rst);
359 SET_LEVELBIT(ctl->level_reg_b0, b0_mask, ctl->b0, ctl->b0_rst);
360 SET_LEVELBIT(ctl->level_reg_b1, b1_mask, ctl->b1, ctl->b1_rst);
366 /*****************************************************************************/
367 // Description: Get LDO voltage level
368 // Global resource dependence:
369 // Author: Tao.Feng && Yi.Qiu
371 /*****************************************************************************/
372 LDO_VOLT_LEVEL_E LDO_GetVoltLevel(LDO_ID_E ldo_id)
374 unsigned int level_ret = 0;
375 LDO_CTL_PTR ctl = NULL;
377 ctl = LDO_GetLdoCtl(ldo_id);
378 SCI_PASSERT(ctl != NULL, ("ldo_id = %d", ldo_id));
380 if(ctl->level_reg_b0 == ctl->level_reg_b1)
382 GET_LEVEL(ctl->level_reg_b0, ctl->b0, ctl->b1, level_ret);
386 GET_LEVELBIT(ctl->level_reg_b0, ctl->b0, BIT_0, level_ret);
387 GET_LEVELBIT(ctl->level_reg_b1, ctl->b1, BIT_1, level_ret);
394 /*****************************************************************************/
395 // Description: Shut down any LDO that do not used when system enters deepsleep
396 // Global resource dependence: s_ldo_reopen[]
397 // Author: Tao.Feng && Yi.Qiu
399 /*****************************************************************************/
400 void LDO_DeepSleepInit(void)
403 SLP_LDO_CTL_PTR slp_ldo_ctl_tab;
405 slp_ldo_ctl_tab = Slp_Ldo_Get_Cfg();
407 SCI_ASSERT(NULL != slp_ldo_ctl_tab);
409 for(i=0; slp_ldo_ctl_tab[i].id != SLP_LDO_MAX; i++)
411 if(slp_ldo_ctl_tab[i].value == SLP_BIT_SET)
412 ANA_REG_OR(slp_ldo_ctl_tab[i].ldo_reg, slp_ldo_ctl_tab[i].mask);
413 //__raw_bits_or(slp_ldo_ctl_tab[i].mask, slp_ldo_ctl_tab[i].ldo_reg);
415 ANA_REG_AND(slp_ldo_ctl_tab[i].ldo_reg, ~slp_ldo_ctl_tab[i].mask);
416 //__raw_bits_and(~slp_ldo_ctl_tab[i].mask, slp_ldo_ctl_tab[i].ldo_reg);
421 /*****************************************************************************/
422 // Description: this function is used to initialize LDO voltage level.
423 // Global resource dependence:
424 // Author: Tao.Feng && Yi.Qiu
426 /*****************************************************************************/
431 g_ldo_ctl_tab = Ldo_Get_Cfg();
433 SCI_ASSERT(NULL != g_ldo_ctl_tab);
435 for(i=0; g_ldo_ctl_tab[i].id != LDO_LDO_MAX; i++)
437 if( g_ldo_ctl_tab[i].init_level != LDO_VOLT_LEVEL_MAX)
438 LDO_SetVoltLevel(g_ldo_ctl_tab[i].id, g_ldo_ctl_tab[i].init_level);
440 g_ldo_ctl_tab[i].ref = 0;
443 //deepsleep init set for ldo
449 /*****************************************************************************/
450 // Description: turn off system core ldo
451 // Global resource dependence:
452 // Author: Mingwei.Zhang
454 /*****************************************************************************/
455 static void LDO_TurnOffCoreLDO (void)
457 ANA_REG_SET (ANA_LDO_PD_SET, ANA_LDO_PD_SET_MSK); /// turn off system core ldo
460 /*****************************************************************************/
461 // Description: turn off all module ldo befor system core ldo
462 // Global resource dependence:
463 // Author: Mingwei.Zhang
465 /*****************************************************************************/
467 static void LDO_TurnOffAllModuleLDO (void)
469 ANA_REG_SET (ANA_LDO_PD_CTL, ANA_LDO_PD_CTL_MSK); ///turn off all module ldo
470 ANA_REG_MSK_OR (ANA_PA_CTL, LDO_PA_SET, (LDO_PA_SET|LDO_PA_RST)); ///PA poweroff
472 /*****************************************************************************/
473 // Description: Shut down all LDO when system poweroff
474 // Global resource dependence:
475 // Author: Mingwei.Zhang
477 /*****************************************************************************/
478 void LDO_TurnOffAllLDO (void)
480 LDO_TurnOffAllModuleLDO();
481 LDO_TurnOffCoreLDO();