diff options
Diffstat (limited to 'firmware/target/arm/imx233')
-rw-r--r-- | firmware/target/arm/imx233/power-imx233.c | 15 | ||||
-rw-r--r-- | firmware/target/arm/imx233/power-imx233.h | 3 |
2 files changed, 18 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 |
diff --git a/firmware/target/arm/imx233/power-imx233.h b/firmware/target/arm/imx233/power-imx233.h index 6991fde7b2..786a450972 100644 --- a/firmware/target/arm/imx233/power-imx233.h +++ b/firmware/target/arm/imx233/power-imx233.h | |||
@@ -31,6 +31,8 @@ | |||
31 | #define HW_POWER_CTRL__ENIRQ_VBUS_VALID (1 << 3) | 31 | #define HW_POWER_CTRL__ENIRQ_VBUS_VALID (1 << 3) |
32 | #define HW_POWER_CTRL__VBUSVALID_IRQ (1 << 4) | 32 | #define HW_POWER_CTRL__VBUSVALID_IRQ (1 << 4) |
33 | #define HW_POWER_CTRL__POLARITY_VBUSVALID (1 << 5) | 33 | #define HW_POWER_CTRL__POLARITY_VBUSVALID (1 << 5) |
34 | #define HW_POWER_CTRL__ENIRQ_DC_OK (1 << 14) | ||
35 | #define HW_POWER_CTRL__DC_OK_IRQ (1 << 15) | ||
34 | 36 | ||
35 | #define HW_POWER_5VCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x10)) | 37 | #define HW_POWER_5VCTRL (*(volatile uint32_t *)(HW_POWER_BASE + 0x10)) |
36 | #define HW_POWER_5VCTRL__ENABLE_DCDC (1 << 0) | 38 | #define HW_POWER_5VCTRL__ENABLE_DCDC (1 << 0) |
@@ -191,6 +193,7 @@ enum imx233_regulator_t | |||
191 | void imx233_power_get_regulator(enum imx233_regulator_t reg, unsigned *target_mv, | 193 | void imx233_power_get_regulator(enum imx233_regulator_t reg, unsigned *target_mv, |
192 | unsigned *brownout_mv); | 194 | unsigned *brownout_mv); |
193 | 195 | ||
196 | // WARNING this call will block until voltage is stable | ||
194 | void imx233_power_set_regulator(enum imx233_regulator_t reg, unsigned target_mv, | 197 | void imx233_power_set_regulator(enum imx233_regulator_t reg, unsigned target_mv, |
195 | unsigned brownout_mv); | 198 | unsigned brownout_mv); |
196 | 199 | ||