diff options
Diffstat (limited to 'firmware/target/arm/imx233/power-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/power-imx233.c | 15 |
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 |