summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/config/ipodnano2g.h2
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/pmu-nano2g.c16
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/pmu-target.h6
-rw-r--r--firmware/target/arm/s5l8700/system-s5l8700.c67
4 files changed, 65 insertions, 26 deletions
diff --git a/firmware/export/config/ipodnano2g.h b/firmware/export/config/ipodnano2g.h
index be7129b690..851c59f529 100644
--- a/firmware/export/config/ipodnano2g.h
+++ b/firmware/export/config/ipodnano2g.h
@@ -171,7 +171,7 @@
171#define HAVE_WHEEL_POSITION 171#define HAVE_WHEEL_POSITION
172 172
173/* Define this if you have adjustable CPU frequency */ 173/* Define this if you have adjustable CPU frequency */
174/* #define HAVE_ADJUSTABLE_CPU_FREQ - not yet */ 174#define HAVE_ADJUSTABLE_CPU_FREQ
175 175
176#define BOOTFILE_EXT "ipod" 176#define BOOTFILE_EXT "ipod"
177#define BOOTFILE "rockbox." BOOTFILE_EXT 177#define BOOTFILE "rockbox." BOOTFILE_EXT
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/pmu-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/pmu-nano2g.c
index be026a8cf4..aea9b79b55 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/pmu-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/pmu-nano2g.c
@@ -24,16 +24,15 @@
24#include "i2c-s5l8700.h" 24#include "i2c-s5l8700.h"
25 25
26static struct mutex pmu_adc_mutex; 26static struct mutex pmu_adc_mutex;
27int pmu_initialized = 0;
28 27
29void pmu_read_multiple(int address, int count, unsigned char* buffer) 28int pmu_read_multiple(int address, int count, unsigned char* buffer)
30{ 29{
31 i2c_read(0xe6, address, count, buffer); 30 return i2c_read(0xe6, address, count, buffer);
32} 31}
33 32
34void pmu_write_multiple(int address, int count, unsigned char* buffer) 33int pmu_write_multiple(int address, int count, unsigned char* buffer)
35{ 34{
36 i2c_write(0xe6, address, count, buffer); 35 return i2c_write(0xe6, address, count, buffer);
37} 36}
38 37
39unsigned char pmu_read(int address) 38unsigned char pmu_read(int address)
@@ -45,22 +44,19 @@ unsigned char pmu_read(int address)
45 return tmp; 44 return tmp;
46} 45}
47 46
48void pmu_write(int address, unsigned char val) 47int pmu_write(int address, unsigned char val)
49{ 48{
50 pmu_write_multiple(address, 1, &val); 49 return pmu_write_multiple(address, 1, &val);
51} 50}
52 51
53void pmu_init(void) 52void pmu_init(void)
54{ 53{
55 if (pmu_initialized) return;
56 mutex_init(&pmu_adc_mutex); 54 mutex_init(&pmu_adc_mutex);
57 pmu_initialized = 1;
58} 55}
59 56
60int pmu_read_adc(unsigned int adc) 57int pmu_read_adc(unsigned int adc)
61{ 58{
62 int data = 0; 59 int data = 0;
63 if (!pmu_initialized) pmu_init();
64 mutex_lock(&pmu_adc_mutex); 60 mutex_lock(&pmu_adc_mutex);
65 pmu_write(0x54, 5 | (adc << 4)); 61 pmu_write(0x54, 5 | (adc << 4));
66 while ((data & 0x80) == 0) 62 while ((data & 0x80) == 0)
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/pmu-target.h b/firmware/target/arm/s5l8700/ipodnano2g/pmu-target.h
index 53f4dacc1b..40618c4447 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/pmu-target.h
+++ b/firmware/target/arm/s5l8700/ipodnano2g/pmu-target.h
@@ -25,9 +25,9 @@
25#include "config.h" 25#include "config.h"
26 26
27unsigned char pmu_read(int address); 27unsigned char pmu_read(int address);
28void pmu_write(int address, unsigned char val); 28int pmu_write(int address, unsigned char val);
29void pmu_read_multiple(int address, int count, unsigned char* buffer); 29int pmu_read_multiple(int address, int count, unsigned char* buffer);
30void pmu_write_multiple(int address, int count, unsigned char* buffer); 30int pmu_write_multiple(int address, int count, unsigned char* buffer);
31int pmu_read_adc(unsigned int adc); 31int pmu_read_adc(unsigned int adc);
32int pmu_read_battery_voltage(void); 32int pmu_read_battery_voltage(void);
33int pmu_read_battery_current(void); 33int pmu_read_battery_current(void);
diff --git a/firmware/target/arm/s5l8700/system-s5l8700.c b/firmware/target/arm/s5l8700/system-s5l8700.c
index fe0fb9ff7c..68ec3826a8 100644
--- a/firmware/target/arm/s5l8700/system-s5l8700.c
+++ b/firmware/target/arm/s5l8700/system-s5l8700.c
@@ -24,6 +24,7 @@
24#include "panic.h" 24#include "panic.h"
25#ifdef IPOD_NANO2G 25#ifdef IPOD_NANO2G
26#include "storage.h" 26#include "storage.h"
27#include "pmu-target.h"
27#endif 28#endif
28 29
29#define default_interrupt(name) \ 30#define default_interrupt(name) \
@@ -153,6 +154,7 @@ void fiq_dummy(void)
153 154
154void system_init(void) 155void system_init(void)
155{ 156{
157 pmu_init();
156} 158}
157 159
158void system_reboot(void) 160void system_reboot(void)
@@ -180,7 +182,7 @@ void system_reboot(void)
180 182
181void system_exception_wait(void) 183void system_exception_wait(void)
182{ 184{
183 while (1); 185 while(1);
184} 186}
185 187
186int system_memory_guard(int newmode) 188int system_memory_guard(int newmode)
@@ -195,27 +197,68 @@ void set_cpu_frequency(long frequency)
195{ 197{
196 if (cpu_frequency == frequency) 198 if (cpu_frequency == frequency)
197 return; 199 return;
198 200
199 /* CPU/COP frequencies can be scaled between Fbus (min) and Fsys (max). 201 int oldlevel = disable_irq_save();
200 Fbus should not be set below ~32Mhz with LCD enabled or the display 202
201 will be garbled. */ 203#if 1
202 if (frequency == CPUFREQ_MAX) 204 if (frequency == CPUFREQ_MAX)
203 { 205 {
206 /* FCLK_CPU = PLL0, HCLK = PLL0 / 2 */
207 CLKCON = (CLKCON & ~0xFF00FF00) | 0x20003100;
208 /* PCLK = HCLK / 2 */
209 CLKCON2 |= 0x200;
210 /* Switch to ASYNCHRONOUS mode */
211 asm volatile(
212 "mrc p15, 0, r0,c1,c0 \n\t"
213 "orr r0, r0, #0xc0000000 \n\t"
214 "mcr p15, 0, r0,c1,c0 \n\t"
215 ::: "r0"
216 );
217 }
218 else
219 {
220 /* Switch to FASTBUS mode */
221 asm volatile(
222 "mrc p15, 0, r0,c1,c0 \n\t"
223 "bic r0, r0, #0xc0000000 \n\t"
224 "mcr p15, 0, r0,c1,c0 \n\t"
225 ::: "r0"
226 );
227 /* PCLK = HCLK */
228 CLKCON2 &= ~0x200;
229 /* FCLK_CPU = OFF, HCLK = PLL0 / 4 */
230 CLKCON = (CLKCON & ~0xFF00FF00) | 0x80003300;
204 } 231 }
205 else if (frequency == CPUFREQ_NORMAL) 232
233#else /* Alternative: Also clock down the PLL. Doesn't seem to save much
234 current, but results in high switching latency. */
235
236 if (frequency == CPUFREQ_MAX)
206 { 237 {
238 CLKCON &= ~0xFF00FF00; /* Everything back to the OSC */
239 PLLCON &= ~1; /* Power down PLL0 */
240 PLL0PMS = 0x021200; /* 192 MHz */
241 PLL0LCNT = 8100;
242 PLLCON |= 1; /* Power up PLL0 */
243 while (!(PLLLOCK & 1)); /* Wait for PLL to lock */
244 CLKCON2 |= 0x200; /* PCLK = HCLK / 2 */
245 CLKCON |= 0x20003100; /* FCLK_CPU = PLL0, PCLK = PLL0 / 2 */
207 } 246 }
208 else 247 else
209 { 248 {
249 CLKCON &= ~0xFF00FF00; /* Everything back to the OSC */
250 CLKCON2 &= ~0x200; /* PCLK = HCLK */
251 PLLCON &= ~1; /* Power down PLL0 */
252 PLL0PMS = 0x000500; /* 48 MHz */
253 PLL0LCNT = 8100;
254 PLLCON |= 1; /* Power up PLL0 */
255 while (!(PLLLOCK & 1)); /* Wait for PLL to lock */
256 CLKCON |= 0x20002000; /* FCLK_CPU = PLL0, PCLK = PLL0 */
210 } 257 }
211 258#endif
212 asm volatile (
213 "nop \n\t"
214 "nop \n\t"
215 "nop \n\t"
216 );
217 259
218 cpu_frequency = frequency; 260 cpu_frequency = frequency;
261 restore_irq(oldlevel);
219} 262}
220 263
221#endif 264#endif