summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2012-12-26 01:08:56 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2012-12-26 01:17:28 +0100
commite2da3f47d335dad87362354c36ea7e27bc26676b (patch)
tree9582166e73d0cb05eaff08c2b0208acb157139e0
parentca83b558dffbdc91e7ada0e1c48c208b945e1385 (diff)
downloadrockbox-e2da3f47d335dad87362354c36ea7e27bc26676b.tar.gz
rockbox-e2da3f47d335dad87362354c36ea7e27bc26676b.zip
imx233: fix regulator voltage setting + always enable DCDC mode
Make sure DCDC is running at boot (it is disabled by default when 5V is present and we don't want to rely on the bootloader to change this). When changing the voltage on a regulator, it usually takes 2ms for the voltage to stabilize. In DCDC mode, there is an irq to notify about the event so use it ! This is especially important when changing cpu frequency because increasing the cpu freq while the voltage is rising is unreliable. Change-Id: Icfe9ef3ee90156d1e17da0820d9041859f7f3bca
-rw-r--r--firmware/target/arm/imx233/power-imx233.c15
-rw-r--r--firmware/target/arm/imx233/power-imx233.h3
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
191void imx233_power_get_regulator(enum imx233_regulator_t reg, unsigned *target_mv, 193void 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
194void imx233_power_set_regulator(enum imx233_regulator_t reg, unsigned target_mv, 197void imx233_power_set_regulator(enum imx233_regulator_t reg, unsigned target_mv,
195 unsigned brownout_mv); 198 unsigned brownout_mv);
196 199