summaryrefslogtreecommitdiff
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2013-07-07 17:29:41 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2013-07-07 17:36:21 +0200
commit3afcb53fb94b7bb937147236f338dd89afb781d0 (patch)
treefca31ca98a49047e49a0f317abdc00ede26599f3 /firmware/target/arm
parent659febc749627a92c59f2d765da59eb9c995c50d (diff)
downloadrockbox-3afcb53fb94b7bb937147236f338dd89afb781d0.tar.gz
rockbox-3afcb53fb94b7bb937147236f338dd89afb781d0.zip
imx233: rework power management
The current code was spreaded over power and powermgmt which made it behave strangely, especially since there are relationships between power management and frequency scaling. The new code makes sure power management is initialised before frequency scaling starts. It also makes sure to start from a known state, thus fixing potential issue when the bootloader stops in a trickle state where DCDC is improperly configured. Change-Id: Ibded2e590e108f6c98daa52d2cf1bd28763c8923
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/imx233/kernel-imx233.c1
-rw-r--r--firmware/target/arm/imx233/power-imx233.c21
-rw-r--r--firmware/target/arm/imx233/powermgmt-imx233.c34
-rw-r--r--firmware/target/arm/imx233/powermgmt-imx233.h1
-rw-r--r--firmware/target/arm/imx233/system-imx233.c2
5 files changed, 32 insertions, 27 deletions
diff --git a/firmware/target/arm/imx233/kernel-imx233.c b/firmware/target/arm/imx233/kernel-imx233.c
index b3760a4782..c3ee2e8bd3 100644
--- a/firmware/target/arm/imx233/kernel-imx233.c
+++ b/firmware/target/arm/imx233/kernel-imx233.c
@@ -37,7 +37,6 @@ void tick_start(unsigned int interval_in_ms)
37 false, &tick_timer); 37 false, &tick_timer);
38} 38}
39 39
40
41void arbiter_init(struct channel_arbiter_t *a, unsigned count) 40void arbiter_init(struct channel_arbiter_t *a, unsigned count)
42{ 41{
43 mutex_init(&a->mutex); 42 mutex_init(&a->mutex);
diff --git a/firmware/target/arm/imx233/power-imx233.c b/firmware/target/arm/imx233/power-imx233.c
index 5041c3b7fc..ccbd12b4ef 100644
--- a/firmware/target/arm/imx233/power-imx233.c
+++ b/firmware/target/arm/imx233/power-imx233.c
@@ -146,27 +146,6 @@ void imx233_power_init(void)
146 BF_SET(POWER_CTRL, ENIRQ_VDD5V_GT_VDDIO); 146 BF_SET(POWER_CTRL, ENIRQ_VDD5V_GT_VDDIO);
147#endif 147#endif
148 imx233_icoll_enable_interrupt(INT_SRC_VDD5V, true); 148 imx233_icoll_enable_interrupt(INT_SRC_VDD5V, true);
149 /* setup linear regulator offsets to 25 mV below to prevent contention between
150 * linear regulators and DCDC */
151#if IMX233_SUBTARGET >= 3700
152 BF_WR(POWER_VDDDCTRL, LINREG_OFFSET, 2);
153 BF_WR(POWER_VDDACTRL, LINREG_OFFSET, 2);
154 BF_WR(POWER_VDDIOCTRL, LINREG_OFFSET, 2);
155 /* enable DCDC (more efficient) */
156 BF_SET(POWER_5VCTRL, ENABLE_DCDC);
157#else
158 BF_SET(POWER_5VCTRL, LINREG_OFFSET);
159 BF_SET(POWER_5VCTRL, EN_DCDC1);
160 BF_SET(POWER_5VCTRL, EN_DCDC2);
161#endif
162
163#if IMX233_SUBTARGET >= 3780
164 /* enable a few bits controlling the DC-DC as recommended by Freescale */
165 BF_SET(POWER_LOOPCTRL, TOGGLE_DIF);
166 BF_SET(POWER_LOOPCTRL, EN_CM_HYST);
167 BF_CLR(POWER_LOOPCTRL, EN_RCSCALE);
168 BF_SETV(POWER_LOOPCTRL, EN_RCSCALE, 1);
169#endif
170} 149}
171 150
172void power_init(void) 151void power_init(void)
diff --git a/firmware/target/arm/imx233/powermgmt-imx233.c b/firmware/target/arm/imx233/powermgmt-imx233.c
index 8980124b33..9819406974 100644
--- a/firmware/target/arm/imx233/powermgmt-imx233.c
+++ b/firmware/target/arm/imx233/powermgmt-imx233.c
@@ -44,19 +44,46 @@ int _battery_voltage(void)
44 return BF_RD(POWER_BATTMONITOR, BATT_VAL) * 8; 44 return BF_RD(POWER_BATTMONITOR, BATT_VAL) * 8;
45} 45}
46 46
47void powermgmt_init_target(void) 47void imx233_powermgmt_init(void)
48{ 48{
49 imx233_power_set_charge_current(IMX233_CHARGE_CURRENT); 49 imx233_power_set_charge_current(IMX233_CHARGE_CURRENT);
50 imx233_power_set_stop_current(IMX233_STOP_CURRENT); 50 imx233_power_set_stop_current(IMX233_STOP_CURRENT);
51#if IMX233_SUBTARGET >= 3780
52 /* assume that adc_init was called and battery monitoring via LRADC setup */ 51 /* assume that adc_init was called and battery monitoring via LRADC setup */
53 BF_WR(POWER_BATTMONITOR, EN_BATADJ, 1); 52 BF_WR(POWER_BATTMONITOR, EN_BATADJ, 1);
53#if IMX233_SUBTARGET >= 3700
54 /* setup linear regulator offsets to 25 mV below to prevent contention between
55 * linear regulators and DCDC */
56 BF_WR(POWER_VDDDCTRL, LINREG_OFFSET, 2);
57 BF_WR(POWER_VDDACTRL, LINREG_OFFSET, 2);
58 BF_WR(POWER_VDDIOCTRL, LINREG_OFFSET, 2);
59 /* enable DCDC (more efficient) */
60 BF_SET(POWER_5VCTRL, ENABLE_DCDC);
61 BF_CLR(POWER_5VCTRL, DCDC_XFER);
62#else
63 BF_SET(POWER_5VCTRL, LINREG_OFFSET);
64 BF_SET(POWER_5VCTRL, EN_DCDC1);
65 BF_SET(POWER_5VCTRL, EN_DCDC2);
66#endif
67
68#if IMX233_SUBTARGET >= 3780
69 /* enable a few bits controlling the DC-DC as recommended by Freescale */
70 BF_SET(POWER_LOOPCTRL, TOGGLE_DIF);
71 BF_SET(POWER_LOOPCTRL, EN_CM_HYST);
72 BF_CLR(POWER_LOOPCTRL, EN_RCSCALE);
73 BF_SETV(POWER_LOOPCTRL, EN_RCSCALE, 1);
74 /* adjust arbitration between 4.2 and battery */
75 BF_WR(POWER_DCDC4P2, CMPTRIP, 0); /* 85% */
76 BF_WR(POWER_DCDC4P2, DROPOUT_CTRL, 0xe); /* select greater, 200 mV drop */
54 /* make sure we are in a known state: disable charger and 4p2 */ 77 /* make sure we are in a known state: disable charger and 4p2 */
55 BF_SET(POWER_CHARGE, PWD_BATTCHRG); 78 BF_SET(POWER_CHARGE, PWD_BATTCHRG);
56 BF_WR(POWER_DCDC4P2, ENABLE_DCDC, 0); 79 BF_WR(POWER_DCDC4P2, ENABLE_DCDC, 0);
57 BF_WR(POWER_DCDC4P2, ENABLE_4P2, 0); 80 BF_WR(POWER_DCDC4P2, ENABLE_4P2, 0);
58 BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2); 81 BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2);
59#endif 82#endif
83}
84
85void powermgmt_init_target(void)
86{
60 charge_state = DISCHARGING; 87 charge_state = DISCHARGING;
61} 88}
62 89
@@ -106,9 +133,6 @@ void charging_algorithm_step(void)
106 { 133 {
107 logf("pwrmgmt: enable dcdc and charger"); 134 logf("pwrmgmt: enable dcdc and charger");
108 logf("pwrmgmt: trickle -> charging"); 135 logf("pwrmgmt: trickle -> charging");
109 /* adjust arbitration between 4.2 and battery */
110 BF_WR(POWER_DCDC4P2, CMPTRIP, 0); /* 85% */
111 BF_WR(POWER_DCDC4P2, DROPOUT_CTRL, 0xe); /* select greater, 200 mV drop */
112 BF_CLR(POWER_5VCTRL, DCDC_XFER); 136 BF_CLR(POWER_5VCTRL, DCDC_XFER);
113 BF_SET(POWER_5VCTRL, ENABLE_DCDC); 137 BF_SET(POWER_5VCTRL, ENABLE_DCDC);
114 /* enable battery charging */ 138 /* enable battery charging */
diff --git a/firmware/target/arm/imx233/powermgmt-imx233.h b/firmware/target/arm/imx233/powermgmt-imx233.h
index 8876a2d62e..07634ec12e 100644
--- a/firmware/target/arm/imx233/powermgmt-imx233.h
+++ b/firmware/target/arm/imx233/powermgmt-imx233.h
@@ -24,6 +24,7 @@
24#include "config.h" 24#include "config.h"
25#include "powermgmt.h" 25#include "powermgmt.h"
26 26
27void imx233_powermgmt_init(void);
27void powermgmt_init_target(void); 28void powermgmt_init_target(void);
28void charging_algorithm_step(void); 29void charging_algorithm_step(void);
29void charging_algorithm_close(void); 30void charging_algorithm_close(void);
diff --git a/firmware/target/arm/imx233/system-imx233.c b/firmware/target/arm/imx233/system-imx233.c
index aa1c216e46..d1f2cfbf15 100644
--- a/firmware/target/arm/imx233/system-imx233.c
+++ b/firmware/target/arm/imx233/system-imx233.c
@@ -43,6 +43,7 @@
43#include "backlight-target.h" 43#include "backlight-target.h"
44#include "button.h" 44#include "button.h"
45#include "fmradio_i2c.h" 45#include "fmradio_i2c.h"
46#include "powermgmt.h"
46 47
47void imx233_chip_reset(void) 48void imx233_chip_reset(void)
48{ 49{
@@ -132,6 +133,7 @@ void system_init(void)
132 imx233_lradc_init(); 133 imx233_lradc_init();
133 imx233_power_init(); 134 imx233_power_init();
134 imx233_i2c_init(); 135 imx233_i2c_init();
136 imx233_powermgmt_init();
135 137
136 /* make sure auto-slow is disable now, we don't know at which frequency we 138 /* make sure auto-slow is disable now, we don't know at which frequency we
137 * are running and auto-slow could violate constraints on {xbus,hbus} */ 139 * are running and auto-slow could violate constraints on {xbus,hbus} */