diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2010-04-23 15:32:50 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2010-04-23 15:32:50 +0000 |
commit | 11cca264ff57ad0b234bd1cd2c9a2366b967feb7 (patch) | |
tree | 7693e7150d5abc9687966cc248bfbd550d356964 /firmware/target/arm/imx31/gigabeat-s | |
parent | 6cee7579dbdc4d41c4df08c9395cf96c952ebab1 (diff) | |
download | rockbox-11cca264ff57ad0b234bd1cd2c9a2366b967feb7.tar.gz rockbox-11cca264ff57ad0b234bd1cd2c9a2366b967feb7.zip |
i.MX31/Gigabeat S: Implement frequency and voltage scaling-- 1.6V for 528MHz, and 1.35V for 264MHz and 132MHz. Keep DPTC overdrive ( > 400MHz) voltage scaling off for now because of uncertainties. Simplify the (working) mess later.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25699 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s')
5 files changed, 331 insertions, 21 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h b/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h new file mode 100644 index 0000000000..2356e23252 --- /dev/null +++ b/firmware/target/arm/imx31/gigabeat-s/dvfs_dptc_tables-target.h | |||
@@ -0,0 +1,279 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 by Michael Sevakis | ||
11 | * | ||
12 | * Target-specific i.MX31 DVFS and DPTC driver declarations | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
20 | * KIND, either express or implied. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | #ifndef _DVFS_DPTC_TARGET_H_ | ||
24 | #define _DVFS_DPTC_TARGET_H_ | ||
25 | |||
26 | #define DVFS_LEVEL_DEFAULT 1 /* 264 MHz - safe frequency for 1.35V */ | ||
27 | #define DVFS_NUM_LEVELS 3 /* 528 MHz, 264 MHz, 132 MHz */ | ||
28 | #define DVFS_NO_PWRRDY /* PWRRDY is connected to different SoC port */ | ||
29 | |||
30 | #define DPTC_WP_DEFAULT 1 /* 1.600, 1.350, 1.350 */ | ||
31 | #define DPTC_WP_PANIC 3 /* Up to minimum for > 400 MHz */ | ||
32 | #define DPTC_NUM_WP 17 | ||
33 | |||
34 | #define VOLTAGE_SETTING_MIN MC13783_SW_1_350 | ||
35 | #define VOLTAGE_SETTING_MAX MC13783_SW_1_625 | ||
36 | |||
37 | /* Frequency increase threshold. Increase frequency change request | ||
38 | * will be sent if DVFS counter value will be more than this value. */ | ||
39 | #define DVFS_UPTHR 30 | ||
40 | |||
41 | /* Frequency decrease threshold. Decrease frequency change request | ||
42 | * will be sent if DVFS counter value will be less than this value. */ | ||
43 | #define DVFS_DNTHR 18 | ||
44 | |||
45 | /* Panic threshold. Panic frequency change request | ||
46 | * will be sent if DVFS counter value will be more than this value. */ | ||
47 | #define DVFS_PNCTHR 63 | ||
48 | |||
49 | /* With the ARM clocked at 532, this setting yields a DIV_3_CLK of 2.03 kHz. | ||
50 | * | ||
51 | * Note: To get said clock, the divider would have to be 262144. The values | ||
52 | * and their meanings are not published in the reference manual for i.MX31 | ||
53 | * but show up in the i.MX35 reference manual. Either that chip is different | ||
54 | * and the values have an additional division or the comments in the BSP are | ||
55 | * incorrect. | ||
56 | */ | ||
57 | #define DVFS_DIV3CK CCM_LTR0_DIV3CK_131072 | ||
58 | |||
59 | /* UPCNT defines the amount of times the up threshold should be exceeded | ||
60 | * before DVFS will trigger frequency increase request. */ | ||
61 | |||
62 | #if 0 | ||
63 | /* Freescale BSP value: a bit too agressive IMHO */ | ||
64 | #define DVFS_UPCNT 0x33 | ||
65 | #endif | ||
66 | #define DVFS_UPCNT 0x48 | ||
67 | |||
68 | /* DNCNT defines the amount of times the down threshold should be undershot | ||
69 | * before DVFS will trigger frequency decrease request. */ | ||
70 | #define DVFS_DNCNT 0x33 | ||
71 | |||
72 | /* EMAC defines how many samples are included in EMA calculation */ | ||
73 | #define DVFS_EMAC 0x20 | ||
74 | |||
75 | /* Define mask of which reference circuits are employed for DPTC */ | ||
76 | #define DPTC_DRCE_MASK (CCM_PMCR0_DRCE1 | CCM_PMCR0_DRCE3) | ||
77 | |||
78 | /* When panicing, this working point is used */ | ||
79 | #define DPTC_PANIC_WP | ||
80 | |||
81 | /* Due to a hardware bug in chip revisions < 2.0, when switching between | ||
82 | * Serial and MCU PLLs, DVFS forces the target PLL to go into reset and | ||
83 | * relock, only post divider frequency scaling is possible. | ||
84 | */ | ||
85 | |||
86 | static const union dvfs_dptc_voltage_table_entry | ||
87 | dvfs_dptc_voltage_table[DPTC_NUM_WP] = | ||
88 | { | ||
89 | /* For each working point, there are four DVFS settings, chosen by the | ||
90 | * DVS pin states on the PMIC set by the DVFS routines. Pins are reversed | ||
91 | * and actual order as used by PMIC for DVSUP values of 00, 01, 10 and 11 | ||
92 | * is below. | ||
93 | * | ||
94 | * SW1A SW1ADVS SW1BDVS SW1BSTBY | ||
95 | * 0 2 1 3 */ | ||
96 | { { MC13783_SW_1_625, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
97 | { { MC13783_SW_1_600, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
98 | { { MC13783_SW_1_575, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
99 | { { MC13783_SW_1_550, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
100 | { { MC13783_SW_1_525, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
101 | { { MC13783_SW_1_500, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
102 | { { MC13783_SW_1_475, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
103 | { { MC13783_SW_1_450, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
104 | { { MC13783_SW_1_425, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
105 | { { MC13783_SW_1_400, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
106 | { { MC13783_SW_1_375, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
107 | { { MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
108 | { { MC13783_SW_1_325, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
109 | { { MC13783_SW_1_300, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
110 | { { MC13783_SW_1_275, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
111 | { { MC13783_SW_1_250, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
112 | { { MC13783_SW_1_225, MC13783_SW_1_350, MC13783_SW_1_350, MC13783_SW_1_350 } }, | ||
113 | }; | ||
114 | |||
115 | #if 1 | ||
116 | /* For 27 MHz PLL reference clock */ | ||
117 | static const struct dptc_dcvr_table_entry | ||
118 | dptc_dcvr_table[DVFS_NUM_LEVELS][DPTC_NUM_WP] = | ||
119 | { | ||
120 | /* DCVR0 DCVR1 DCVR2 DCVR3 */ | ||
121 | { /* 528 MHz */ | ||
122 | { 0xffc00000, 0x90400000, 0xffc00000, 0xdd000000 }, | ||
123 | { 0xffc00000, 0x90629890, 0xffc00000, 0xdd34ed20 }, | ||
124 | { 0xffc00000, 0x90629890, 0xffc00000, 0xdd34ed20 }, | ||
125 | { 0xffc00000, 0x90629894, 0xffc00000, 0xdd74fd24 }, | ||
126 | { 0xffc00000, 0x90a2a894, 0xffc00000, 0xddb50d28 }, | ||
127 | { 0xffc00000, 0x90e2b89c, 0xffc00000, 0xde352d30 }, | ||
128 | { 0xffc00000, 0x9162d8a0, 0xffc00000, 0xdef55d38 }, | ||
129 | { 0xffc00000, 0x91e2f8a8, 0xffc00000, 0xdfb58d44 }, | ||
130 | { 0xffc00000, 0x926308b0, 0xffc00000, 0xe0b5cd54 }, | ||
131 | { 0xffc00000, 0x92e328bc, 0xffc00000, 0xe1f60d64 }, | ||
132 | { 0xffc00000, 0x93a358c0, 0xffc00000, 0xe3365d74 }, | ||
133 | { 0xffc00000, 0xf66388cc, 0xffc00000, 0xf6768d84 }, | ||
134 | { 0xffc00000, 0xf663b8d4, 0xffc00000, 0xf676dd98 }, | ||
135 | { 0xffc00000, 0xf663e8e0, 0xffc00000, 0xf6773da4 }, | ||
136 | { 0xffc00000, 0xf66418ec, 0xffc00000, 0xf6778dbc }, | ||
137 | { 0xffc00000, 0xf66458fc, 0xffc00000, 0xf677edd0 }, | ||
138 | { 0xffc00000, 0xf6648908, 0xffc00000, 0xf6783de8 }, | ||
139 | |||
140 | }, | ||
141 | { /* 264 MHz */ | ||
142 | { 0xffc00000, 0x90400000, 0xffc00000, 0xdd000000 }, | ||
143 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, | ||
144 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, | ||
145 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd4d4348 }, | ||
146 | { 0xffc00000, 0x9088b228, 0xffc00000, 0xdd8d434c }, | ||
147 | { 0xffc00000, 0x90c8b228, 0xffc00000, 0xde0d534c }, | ||
148 | { 0xffc00000, 0x9148b228, 0xffc00000, 0xdecd5350 }, | ||
149 | { 0xffc00000, 0x91c8c22c, 0xffc00000, 0xdf8d6354 }, | ||
150 | { 0xffc00000, 0x9248d22c, 0xffc00000, 0xe08d7354 }, | ||
151 | { 0xffc00000, 0x92c8d230, 0xffc00000, 0xe1cd8358 }, | ||
152 | { 0xffc00000, 0x9388e234, 0xffc00000, 0xe30d935c }, | ||
153 | { 0xffc00000, 0xf648e234, 0xffc00000, 0xf64db364 }, | ||
154 | { 0xffc00000, 0xf648f238, 0xffc00000, 0xf64dc368 }, | ||
155 | { 0xffc00000, 0xf648f23c, 0xffc00000, 0xf64dd36c }, | ||
156 | { 0xffc00000, 0xf649023c, 0xffc00000, 0xf64de370 }, | ||
157 | { 0xffc00000, 0xf649123c, 0xffc00000, 0xf64df374 }, | ||
158 | { 0xffc00000, 0xf6492240, 0xffc00000, 0xf64e1378 }, | ||
159 | |||
160 | }, | ||
161 | { /* 132 MHz */ | ||
162 | { 0xffc00000, 0x90400000, 0xffc00000, 0xdd000000 }, | ||
163 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, | ||
164 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd0d4348 }, | ||
165 | { 0xffc00000, 0x9048a224, 0xffc00000, 0xdd4d4348 }, | ||
166 | { 0xffc00000, 0x9088b228, 0xffc00000, 0xdd8d434c }, | ||
167 | { 0xffc00000, 0x90c8b228, 0xffc00000, 0xde0d534c }, | ||
168 | { 0xffc00000, 0x9148b228, 0xffc00000, 0xdecd5350 }, | ||
169 | { 0xffc00000, 0x91c8c22c, 0xffc00000, 0xdf8d6354 }, | ||
170 | { 0xffc00000, 0x9248d22c, 0xffc00000, 0xe08d7354 }, | ||
171 | { 0xffc00000, 0x92c8d230, 0xffc00000, 0xe1cd8358 }, | ||
172 | { 0xffc00000, 0x9388e234, 0xffc00000, 0xe30d935c }, | ||
173 | { 0xffc00000, 0xf648e234, 0xffc00000, 0xf64db364 }, | ||
174 | { 0xffc00000, 0xf648f238, 0xffc00000, 0xf64dc368 }, | ||
175 | { 0xffc00000, 0xf648f23c, 0xffc00000, 0xf64dd36c }, | ||
176 | { 0xffc00000, 0xf649023c, 0xffc00000, 0xf64de370 }, | ||
177 | { 0xffc00000, 0xf649123c, 0xffc00000, 0xf64df374 }, | ||
178 | { 0xffc00000, 0xf6492240, 0xffc00000, 0xf64e1378 }, | ||
179 | }, | ||
180 | }; | ||
181 | #else/* For 26 MHz PLL reference clock */ | ||
182 | static const struct dptc_dcvr_table_entry | ||
183 | dptc_dcvr_table[DVFS_NUM_LEVELS][DPTC_NUM_WP] = | ||
184 | { | ||
185 | /* DCVR0 DCVR1 DCVR2 DCVR3 */ | ||
186 | { /* 528 MHz */ | ||
187 | { 0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000 }, | ||
188 | { 0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0 }, | ||
189 | { 0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0 }, | ||
190 | { 0xffc00000, 0x95e3e8e8, 0xffc00000, 0xe5f70da4 }, | ||
191 | { 0xffc00000, 0x9623f8e8, 0xffc00000, 0xe6371da8 }, | ||
192 | { 0xffc00000, 0x966408f0, 0xffc00000, 0xe6b73db0 }, | ||
193 | { 0xffc00000, 0x96e428f4, 0xffc00000, 0xe7776dbc }, | ||
194 | { 0xffc00000, 0x976448fc, 0xffc00000, 0xe8379dc8 }, | ||
195 | { 0xffc00000, 0x97e46904, 0xffc00000, 0xe977ddd8 }, | ||
196 | { 0xffc00000, 0x98a48910, 0xffc00000, 0xeab81de8 }, | ||
197 | { 0xffc00000, 0x9964b918, 0xffc00000, 0xebf86df8 }, | ||
198 | { 0xffc00000, 0xffe4e924, 0xffc00000, 0xfff8ae08 }, | ||
199 | { 0xffc00000, 0xffe5192c, 0xffc00000, 0xfff8fe1c }, | ||
200 | { 0xffc00000, 0xffe54938, 0xffc00000, 0xfff95e2c }, | ||
201 | { 0xffc00000, 0xffe57944, 0xffc00000, 0xfff9ae44 }, | ||
202 | { 0xffc00000, 0xffe5b954, 0xffc00000, 0xfffa0e58 }, | ||
203 | { 0xffc00000, 0xffe5e960, 0xffc00000, 0xfffa6e70 }, | ||
204 | }, | ||
205 | { /* 264 MHz */ | ||
206 | { 0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000 }, | ||
207 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, | ||
208 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, | ||
209 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe5cdc368 }, | ||
210 | { 0xffc00000, 0x9609023c, 0xffc00000, 0xe60dc36c }, | ||
211 | { 0xffc00000, 0x9649023c, 0xffc00000, 0xe68dd36c }, | ||
212 | { 0xffc00000, 0x96c9023c, 0xffc00000, 0xe74dd370 }, | ||
213 | { 0xffc00000, 0x97491240, 0xffc00000, 0xe80de374 }, | ||
214 | { 0xffc00000, 0x97c92240, 0xffc00000, 0xe94df374 }, | ||
215 | { 0xffc00000, 0x98892244, 0xffc00000, 0xea8e0378 }, | ||
216 | { 0xffc00000, 0x99493248, 0xffc00000, 0xebce137c }, | ||
217 | { 0xffc00000, 0xffc93248, 0xffc00000, 0xffce3384 }, | ||
218 | { 0xffc00000, 0xffc9424c, 0xffc00000, 0xffce4388 }, | ||
219 | { 0xffc00000, 0xffc95250, 0xffc00000, 0xffce538c }, | ||
220 | { 0xffc00000, 0xffc96250, 0xffc00000, 0xffce7390 }, | ||
221 | { 0xffc00000, 0xffc97254, 0xffc00000, 0xffce8394 }, | ||
222 | { 0xffc00000, 0xffc98258, 0xffc00000, 0xffcea39c }, | ||
223 | }, | ||
224 | { /* 132 MHz */ | ||
225 | { 0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000 }, | ||
226 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, | ||
227 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe58dc368 }, | ||
228 | { 0xffc00000, 0x95c8f238, 0xffc00000, 0xe5cdc368 }, | ||
229 | { 0xffc00000, 0x9609023c, 0xffc00000, 0xe60dc36c }, | ||
230 | { 0xffc00000, 0x9649023c, 0xffc00000, 0xe68dd36c }, | ||
231 | { 0xffc00000, 0x96c9023c, 0xffc00000, 0xe74dd370 }, | ||
232 | { 0xffc00000, 0x97491240, 0xffc00000, 0xe80de374 }, | ||
233 | { 0xffc00000, 0x97c92240, 0xffc00000, 0xe94df374 }, | ||
234 | { 0xffc00000, 0x98892244, 0xffc00000, 0xea8e0378 }, | ||
235 | { 0xffc00000, 0x99493248, 0xffc00000, 0xebce137c }, | ||
236 | { 0xffc00000, 0xffc93248, 0xffc00000, 0xffce3384 }, | ||
237 | { 0xffc00000, 0xffc9424c, 0xffc00000, 0xffce4388 }, | ||
238 | { 0xffc00000, 0xffc95250, 0xffc00000, 0xffce538c }, | ||
239 | { 0xffc00000, 0xffc96250, 0xffc00000, 0xffce7390 }, | ||
240 | { 0xffc00000, 0xffc97254, 0xffc00000, 0xffce8394 }, | ||
241 | { 0xffc00000, 0xffc98258, 0xffc00000, 0xffcea39c }, | ||
242 | }, | ||
243 | }; | ||
244 | #endif | ||
245 | |||
246 | |||
247 | /* For 27 MHz PLL reference clock */ | ||
248 | static const struct dvfs_clock_table_entry | ||
249 | dvfs_clock_table[DVFS_NUM_LEVELS] = | ||
250 | { | ||
251 | /* PLL val PDR0 val PLL VSCNT */ | ||
252 | { 0x00082407, 0xff841e58, 1, 7 }, /* MCUPLL, 528 MHz, /1 = 528 MHz */ | ||
253 | { 0x00082407, 0xff841e59, 1, 7 }, /* MCUPLL, 528 MHz, /2 = 264 MHz */ | ||
254 | { 0x00082407, 0xff841e5b, 1, 7 }, /* MCUPLL, 528 MHz, /4 = 132 MHz */ | ||
255 | }; | ||
256 | |||
257 | |||
258 | /* DVFS load-tracking signal weights and detect modes */ | ||
259 | static const struct dvfs_lt_signal_descriptor lt_signals[16] = | ||
260 | { | ||
261 | { 0, 0 }, /* DVFS_LT_SIG_M3IF_M0_BUF */ | ||
262 | { 0, 0 }, /* DVFS_LT_SIG_M3IF_M1 */ | ||
263 | { 0, 0 }, /* DVFS_LT_SIG_MBX_MBXCLKGATE */ | ||
264 | { 0, 0 }, /* DVFS_LT_SIG_M3IF_M3 */ | ||
265 | { 0, 0 }, /* DVFS_LT_SIG_M3IF_M4 */ | ||
266 | { 0, 0 }, /* DVFS_LT_SIG_M3IF_M5 */ | ||
267 | { 0, 0 }, /* DVFS_LT_SIG_M3IF_M6 */ | ||
268 | { 0, 0 }, /* DVFS_LT_SIG_M3IF_M7 */ | ||
269 | { 0, 0 }, /* DVFS_LT_SIG_ARM11_P_IRQ_B_RBT_GATE */ | ||
270 | { 0, 0 }, /* DVFS_LT_SIG_ARM11_P_FIQ_B_RBT_GATE */ | ||
271 | { 0, 0 }, /* DVFS_LT_SIG_IPI_GPIO1_INT0 */ | ||
272 | { 0, 0 }, /* DVFS_LT_SIG_IPI_INT_IPU_FUNC */ | ||
273 | { 7, 0 }, /* DVFS_LT_SIG_DVGP0 */ | ||
274 | { 7, 0 }, /* DVFS_LT_SIG_DVGP1 */ | ||
275 | { 7, 0 }, /* DVFS_LT_SIG_DVGP2 */ | ||
276 | { 7, 0 }, /* DVFS_LT_SIG_DVGP3 */ | ||
277 | }; | ||
278 | |||
279 | #endif /* _DVFS_DPTC_TARGET_H_ */ | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/kernel-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/kernel-gigabeat-s.c index 8e81447bd3..894aea4fd3 100644 --- a/firmware/target/arm/imx31/gigabeat-s/kernel-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/kernel-gigabeat-s.c | |||
@@ -70,10 +70,11 @@ void kernel_device_init(void) | |||
70 | sdma_init(); | 70 | sdma_init(); |
71 | spi_init(); | 71 | spi_init(); |
72 | mc13783_init(); | 72 | mc13783_init(); |
73 | dvfs_dptc_start(); | 73 | dvfs_dptc_init(); |
74 | dvfs_wfi_monitor(true); /* Monitor the WFI signal */ | ||
75 | dvfs_dptc_start(); /* Should be ok to start even so early */ | ||
74 | } | 76 | } |
75 | 77 | ||
76 | #ifdef BOOTLOADER | ||
77 | void tick_stop(void) | 78 | void tick_stop(void) |
78 | { | 79 | { |
79 | avic_disable_int(INT_EPIT1); /* Disable insterrupt */ | 80 | avic_disable_int(INT_EPIT1); /* Disable insterrupt */ |
@@ -81,4 +82,4 @@ void tick_stop(void) | |||
81 | EPITSR1 = EPITSR_OCIF; /* Clear pending */ | 82 | EPITSR1 = EPITSR_OCIF; /* Clear pending */ |
82 | ccm_module_clock_gating(CG_EPIT1, CGM_OFF); /* Turn off module clock */ | 83 | ccm_module_clock_gating(CG_EPIT1, CGM_OFF); /* Turn off module clock */ |
83 | } | 84 | } |
84 | #endif | 85 | |
diff --git a/firmware/target/arm/imx31/gigabeat-s/power-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/power-gigabeat-s.c index 7e3b39dba8..d7fe87f168 100644 --- a/firmware/target/arm/imx31/gigabeat-s/power-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/power-gigabeat-s.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "backlight-target.h" | 28 | #include "backlight-target.h" |
29 | #include "avic-imx31.h" | 29 | #include "avic-imx31.h" |
30 | #include "mc13783.h" | 30 | #include "mc13783.h" |
31 | #include "dvfs_dptc-imx31.h" | ||
31 | #if CONFIG_TUNER | 32 | #if CONFIG_TUNER |
32 | #include "fmradio_i2c.h" | 33 | #include "fmradio_i2c.h" |
33 | #endif | 34 | #endif |
@@ -121,6 +122,9 @@ bool tuner_powered(void) | |||
121 | 122 | ||
122 | void power_off(void) | 123 | void power_off(void) |
123 | { | 124 | { |
125 | /* Turn off voltage and frequency scaling */ | ||
126 | dvfs_dptc_stop(); | ||
127 | |||
124 | /* Cut backlight */ | 128 | /* Cut backlight */ |
125 | _backlight_off(); | 129 | _backlight_off(); |
126 | 130 | ||
@@ -131,9 +135,7 @@ void power_off(void) | |||
131 | mc13783_set(MC13783_POWER_CONTROL0, MC13783_USEROFFSPI); | 135 | mc13783_set(MC13783_POWER_CONTROL0, MC13783_USEROFFSPI); |
132 | 136 | ||
133 | /* Wait for power cut */ | 137 | /* Wait for power cut */ |
134 | disable_interrupt(IRQ_FIQ_STATUS); | 138 | system_halt(); |
135 | |||
136 | while (1); | ||
137 | } | 139 | } |
138 | 140 | ||
139 | void power_init(void) | 141 | void power_init(void) |
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c index cd684e77ac..7c0d30c783 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "gpio-imx31.h" | 26 | #include "gpio-imx31.h" |
27 | #include "mmu-imx31.h" | 27 | #include "mmu-imx31.h" |
28 | #include "system-target.h" | 28 | #include "system-target.h" |
29 | #include "powermgmt-target.h" | ||
29 | #include "lcd.h" | 30 | #include "lcd.h" |
30 | #include "serial-imx31.h" | 31 | #include "serial-imx31.h" |
31 | #include "debug.h" | 32 | #include "debug.h" |
@@ -115,18 +116,24 @@ int system_memory_guard(int newmode) | |||
115 | return 0; | 116 | return 0; |
116 | } | 117 | } |
117 | 118 | ||
119 | void system_halt(void) | ||
120 | { | ||
121 | disable_interrupt(IRQ_FIQ_STATUS); | ||
122 | avic_set_ni_level(AVIC_NIL_DISABLE); | ||
123 | while (1) | ||
124 | core_idle(); | ||
125 | } | ||
126 | |||
118 | void system_reboot(void) | 127 | void system_reboot(void) |
119 | { | 128 | { |
120 | /* Multi-context so no SPI available (WDT?) */ | 129 | /* Multi-context so no SPI available (WDT?) */ |
121 | while (1); | 130 | system_halt(); |
122 | } | 131 | } |
123 | 132 | ||
124 | void system_exception_wait(void) | 133 | void system_exception_wait(void) |
125 | { | 134 | { |
126 | /* Called in many contexts so button reading may be a chore */ | 135 | /* Called in many contexts so button reading may be a chore */ |
127 | avic_disable_int(INT_ALL); | 136 | system_halt(); |
128 | core_idle(); | ||
129 | while (1); | ||
130 | } | 137 | } |
131 | 138 | ||
132 | void system_init(void) | 139 | void system_init(void) |
@@ -175,6 +182,9 @@ void system_init(void) | |||
175 | 182 | ||
176 | unsigned int i; | 183 | unsigned int i; |
177 | 184 | ||
185 | /* Initialize frequency with current */ | ||
186 | cpu_frequency = ccm_get_mcu_clk(); | ||
187 | |||
178 | /* MCR WFI enables wait mode (CCM_CCMR_LPM_WAIT_MODE = 0) */ | 188 | /* MCR WFI enables wait mode (CCM_CCMR_LPM_WAIT_MODE = 0) */ |
179 | imx31_regclr32(&CCM_CCMR, CCM_CCMR_LPM); | 189 | imx31_regclr32(&CCM_CCMR, CCM_CCMR_LPM); |
180 | 190 | ||
@@ -239,16 +249,33 @@ void __attribute__((naked)) imx31_regclr32(volatile uint32_t *reg_p, | |||
239 | (void)reg_p; (void)mask; | 249 | (void)reg_p; (void)mask; |
240 | } | 250 | } |
241 | 251 | ||
242 | #ifdef BOOTLOADER | 252 | |
243 | void system_prepare_fw_start(void) | 253 | void system_prepare_fw_start(void) |
244 | { | 254 | { |
245 | dvfs_dptc_stop(); | 255 | dvfs_dptc_stop(); |
246 | disable_interrupt(IRQ_FIQ_STATUS); | ||
247 | avic_disable_int(INT_ALL); | ||
248 | mc13783_close(); | 256 | mc13783_close(); |
249 | tick_stop(); | 257 | tick_stop(); |
258 | disable_interrupt(IRQ_FIQ_STATUS); | ||
259 | avic_set_ni_level(AVIC_NIL_DISABLE); | ||
250 | } | 260 | } |
251 | #endif | 261 | |
262 | |||
263 | #ifndef BOOTLOADER | ||
264 | void rolo_restart_firmware(const unsigned char *source, unsigned char *dest, | ||
265 | int length) __attribute__((noreturn)); | ||
266 | |||
267 | void __attribute__((noreturn)) | ||
268 | rolo_restart(const unsigned char *source, unsigned char *dest, int length) | ||
269 | { | ||
270 | /* Some housekeeping tasks must be performed for a safe changeover */ | ||
271 | charging_algorithm_close(); | ||
272 | system_prepare_fw_start(); | ||
273 | |||
274 | /* Copying routine where new image is run */ | ||
275 | rolo_restart_firmware(source, dest, length); | ||
276 | } | ||
277 | #endif /* BOOTLOADER */ | ||
278 | |||
252 | 279 | ||
253 | inline void dumpregs(void) | 280 | inline void dumpregs(void) |
254 | { | 281 | { |
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h index b859093c58..af95471db6 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h | |||
@@ -24,12 +24,12 @@ | |||
24 | #include "system-arm.h" | 24 | #include "system-arm.h" |
25 | #include "mmu-arm.h" | 25 | #include "mmu-arm.h" |
26 | 26 | ||
27 | #ifndef HAVE_ADJUSTABLE_CPU_FREQ | 27 | /* High enough for most tasks but low enough for reduced voltage */ |
28 | /* TODO: implement CPU frequency scaling */ | 28 | #define CPUFREQ_DEFAULT 264000000 |
29 | #define CPUFREQ_DEFAULT CPU_FREQ | 29 | /* Still quite powerful, minimum possible frequency */ |
30 | #define CPUFREQ_NORMAL CPU_FREQ | 30 | #define CPUFREQ_NORMAL 132000000 |
31 | #define CPUFREQ_MAX CPU_FREQ | 31 | /* Overdrive mode */ |
32 | #endif | 32 | #define CPUFREQ_MAX 528000000 |
33 | 33 | ||
34 | static inline void udelay(unsigned int usecs) | 34 | static inline void udelay(unsigned int usecs) |
35 | { | 35 | { |
@@ -45,10 +45,11 @@ void gpt_stop(void); | |||
45 | 45 | ||
46 | unsigned int iim_system_rev(void); | 46 | unsigned int iim_system_rev(void); |
47 | 47 | ||
48 | /* Prepare for transition to firmware */ | 48 | /* Prepare for transition to (new) firmware */ |
49 | void system_prepare_fw_start(void); | 49 | void system_prepare_fw_start(void); |
50 | void tick_stop(void); | 50 | void tick_stop(void); |
51 | void kernel_device_init(void); | 51 | void kernel_device_init(void); |
52 | void system_halt(void); | ||
52 | 53 | ||
53 | void imx31_regmod32(volatile uint32_t *reg_p, uint32_t value, | 54 | void imx31_regmod32(volatile uint32_t *reg_p, uint32_t value, |
54 | uint32_t mask); | 55 | uint32_t mask); |