summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8700/system-s5l8700.c
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2010-11-14 15:20:06 +0000
committerMichael Sparmann <theseven@rockbox.org>2010-11-14 15:20:06 +0000
commitbbebaa406f74970709bf2105413bd696f5466041 (patch)
tree15b99fab1d6f6efb4772707a03be59d6300628d5 /firmware/target/arm/s5l8700/system-s5l8700.c
parent81381a36b4e5e8fd963f630fdf59c6c947c54de4 (diff)
downloadrockbox-bbebaa406f74970709bf2105413bd696f5466041.tar.gz
rockbox-bbebaa406f74970709bf2105413bd696f5466041.zip
iPod Nano 2G: Dynamic Vcore scaling, based on current CPU clock. Adds 1-2 hours of battery life.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28590 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/s5l8700/system-s5l8700.c')
-rw-r--r--firmware/target/arm/s5l8700/system-s5l8700.c41
1 files changed, 8 insertions, 33 deletions
diff --git a/firmware/target/arm/s5l8700/system-s5l8700.c b/firmware/target/arm/s5l8700/system-s5l8700.c
index a0f671e298..e35da90617 100644
--- a/firmware/target/arm/s5l8700/system-s5l8700.c
+++ b/firmware/target/arm/s5l8700/system-s5l8700.c
@@ -203,16 +203,17 @@ void set_cpu_frequency(long frequency)
203 if (cpu_frequency == frequency) 203 if (cpu_frequency == frequency)
204 return; 204 return;
205 205
206 int oldlevel = disable_irq_save();
207
208#if 1
209 if (frequency == CPUFREQ_MAX) 206 if (frequency == CPUFREQ_MAX)
210 { 207 {
208 /* Vcore = 1.000V */
209 pmu_write(0x1e, 0xf);
210 /* Allow for voltage to stabilize */
211 sleep(HZ / 100);
211 /* FCLK_CPU = PLL0, HCLK = PLL0 / 2 */ 212 /* FCLK_CPU = PLL0, HCLK = PLL0 / 2 */
212 CLKCON = (CLKCON & ~0xFF00FF00) | 0x20003100; 213 CLKCON = (CLKCON & ~0xFF00FF00) | 0x20003100;
213 /* PCLK = HCLK / 2 */ 214 /* PCLK = HCLK / 2 */
214 CLKCON2 |= 0x200; 215 CLKCON2 |= 0x200;
215 /* Switch to ASYNCHRONOUS mode */ 216 /* Switch to ASYNCHRONOUS mode => GCLK = FCLK_CPU */
216 asm volatile( 217 asm volatile(
217 "mrc p15, 0, r0,c1,c0 \n\t" 218 "mrc p15, 0, r0,c1,c0 \n\t"
218 "orr r0, r0, #0xc0000000 \n\t" 219 "orr r0, r0, #0xc0000000 \n\t"
@@ -222,7 +223,7 @@ void set_cpu_frequency(long frequency)
222 } 223 }
223 else 224 else
224 { 225 {
225 /* Switch to FASTBUS mode */ 226 /* Switch to FASTBUS mode => GCLK = HCLK */
226 asm volatile( 227 asm volatile(
227 "mrc p15, 0, r0,c1,c0 \n\t" 228 "mrc p15, 0, r0,c1,c0 \n\t"
228 "bic r0, r0, #0xc0000000 \n\t" 229 "bic r0, r0, #0xc0000000 \n\t"
@@ -233,37 +234,11 @@ void set_cpu_frequency(long frequency)
233 CLKCON2 &= ~0x200; 234 CLKCON2 &= ~0x200;
234 /* FCLK_CPU = OFF, HCLK = PLL0 / 4 */ 235 /* FCLK_CPU = OFF, HCLK = PLL0 / 4 */
235 CLKCON = (CLKCON & ~0xFF00FF00) | 0x80003300; 236 CLKCON = (CLKCON & ~0xFF00FF00) | 0x80003300;
237 /* Vcore = 0.900V */
238 pmu_write(0x1e, 0xb);
236 } 239 }
237 240
238#else /* Alternative: Also clock down the PLL. Doesn't seem to save much
239 current, but results in high switching latency. */
240
241 if (frequency == CPUFREQ_MAX)
242 {
243 CLKCON &= ~0xFF00FF00; /* Everything back to the OSC */
244 PLLCON &= ~1; /* Power down PLL0 */
245 PLL0PMS = 0x021200; /* 192 MHz */
246 PLL0LCNT = 8100;
247 PLLCON |= 1; /* Power up PLL0 */
248 while (!(PLLLOCK & 1)); /* Wait for PLL to lock */
249 CLKCON2 |= 0x200; /* PCLK = HCLK / 2 */
250 CLKCON |= 0x20003100; /* FCLK_CPU = PLL0, PCLK = PLL0 / 2 */
251 }
252 else
253 {
254 CLKCON &= ~0xFF00FF00; /* Everything back to the OSC */
255 CLKCON2 &= ~0x200; /* PCLK = HCLK */
256 PLLCON &= ~1; /* Power down PLL0 */
257 PLL0PMS = 0x000500; /* 48 MHz */
258 PLL0LCNT = 8100;
259 PLLCON |= 1; /* Power up PLL0 */
260 while (!(PLLLOCK & 1)); /* Wait for PLL to lock */
261 CLKCON |= 0x20002000; /* FCLK_CPU = PLL0, PCLK = PLL0 */
262 }
263#endif
264
265 cpu_frequency = frequency; 241 cpu_frequency = frequency;
266 restore_irq(oldlevel);
267} 242}
268 243
269#endif 244#endif