summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/power-imx233.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx233/power-imx233.c')
-rw-r--r--firmware/target/arm/imx233/power-imx233.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/power-imx233.c b/firmware/target/arm/imx233/power-imx233.c
index c02d6ddb77..186256f7b8 100644
--- a/firmware/target/arm/imx233/power-imx233.c
+++ b/firmware/target/arm/imx233/power-imx233.c
@@ -102,6 +102,8 @@ void power_init(void)
102 __FIELD_SET(HW_POWER_VDDDCTRL, LINREG_OFFSET, 2); 102 __FIELD_SET(HW_POWER_VDDDCTRL, LINREG_OFFSET, 2);
103 __FIELD_SET(HW_POWER_VDDACTRL, LINREG_OFFSET, 2); 103 __FIELD_SET(HW_POWER_VDDACTRL, LINREG_OFFSET, 2);
104 __FIELD_SET(HW_POWER_VDDIOCTRL, LINREG_OFFSET, 2); 104 __FIELD_SET(HW_POWER_VDDIOCTRL, LINREG_OFFSET, 2);
105 /* enable DCDC (more efficient) */
106 __REG_SET(HW_POWER_5VCTRL) = HW_POWER_5VCTRL__ENABLE_DCDC;
105 /* enable a few bits controlling the DC-DC as recommended by Freescale */ 107 /* enable a few bits controlling the DC-DC as recommended by Freescale */
106 __REG_SET(HW_POWER_LOOPCTRL) = HW_POWER_LOOPCTRL__TOGGLE_DIF | 108 __REG_SET(HW_POWER_LOOPCTRL) = HW_POWER_LOOPCTRL__TOGGLE_DIF |
107 HW_POWER_LOOPCTRL__EN_CM_HYST; 109 HW_POWER_LOOPCTRL__EN_CM_HYST;
@@ -250,6 +252,8 @@ void imx233_power_set_regulator(enum imx233_regulator_t reg, unsigned value_mv,
250 // compute raw values 252 // compute raw values
251 unsigned raw_val = (value_mv - regulator_info[reg].min) / regulator_info[reg].step; 253 unsigned raw_val = (value_mv - regulator_info[reg].min) / regulator_info[reg].step;
252 unsigned raw_bo_offset = (value_mv - brownout_mv) / regulator_info[reg].step; 254 unsigned raw_bo_offset = (value_mv - brownout_mv) / regulator_info[reg].step;
255 // clear dc-dc ok flag
256 __REG_SET(HW_POWER_CTRL) = HW_POWER_CTRL__DC_OK_IRQ;
253 // update 257 // update
254 uint32_t reg_val = (*regulator_info[reg].reg) & ~regulator_info[reg].trg_bm; 258 uint32_t reg_val = (*regulator_info[reg].reg) & ~regulator_info[reg].trg_bm;
255 reg_val |= raw_val << regulator_info[reg].trg_bp; 259 reg_val |= raw_val << regulator_info[reg].trg_bp;
@@ -259,6 +263,17 @@ void imx233_power_set_regulator(enum imx233_regulator_t reg, unsigned value_mv,
259 reg_val |= raw_bo_offset << regulator_info[reg].bo_bp; 263 reg_val |= raw_bo_offset << regulator_info[reg].bo_bp;
260 } 264 }
261 *regulator_info[reg].reg = reg_val; 265 *regulator_info[reg].reg = reg_val;
266 /* Wait until regulator is stable (ie brownout condition is gone)
267 * If DC-DC is used, we can use the DCDC_OK irq
268 * Otherwise it is unreliable (doesn't work when lowering voltage on linregs)
269 * It usually takes between 0.5ms and 2.5ms */
270 if(!(HW_POWER_5VCTRL & HW_POWER_5VCTRL__ENABLE_DCDC))
271 panicf("regulator %d: wait for voltage stabilize in linreg mode !", reg);
272 unsigned timeout = current_tick + (HZ * 20) / 1000;
273 while(!(HW_POWER_CTRL & HW_POWER_CTRL__DC_OK_IRQ) || !TIME_AFTER(current_tick, timeout))
274 yield();
275 if(!(HW_POWER_CTRL & HW_POWER_CTRL__DC_OK_IRQ))
276 panicf("regulator %d: failed to stabilize", reg);
262} 277}
263 278
264// offset is -1,0 or 1 279// offset is -1,0 or 1