diff --git a/firmware/export/config/ipod6g.h b/firmware/export/config/ipod6g.h index 1941074d57..7e6faf8d6d 100644 --- a/firmware/export/config/ipod6g.h +++ b/firmware/export/config/ipod6g.h @@ -207,7 +207,7 @@ #define HAVE_HARDWARE_CLICK /* Define this if you have adjustable CPU frequency */ -//#define HAVE_ADJUSTABLE_CPU_FREQ +#define HAVE_ADJUSTABLE_CPU_FREQ #define BOOTFILE_EXT "ipod" #define BOOTFILE "rockbox." BOOTFILE_EXT diff --git a/firmware/target/arm/s5l8702/debug-s5l8702.c b/firmware/target/arm/s5l8702/debug-s5l8702.c index 0697e92aed..27d1ccb7b8 100644 --- a/firmware/target/arm/s5l8702/debug-s5l8702.c +++ b/firmware/target/arm/s5l8702/debug-s5l8702.c @@ -58,6 +58,8 @@ bool dbg_hw_info(void) if(state == 0) { _DEBUG_PRINTF("CPU:"); + _DEBUG_PRINTF("speed: %d MHz", ((CLKCON0 & 1) ? + CPUFREQ_NORMAL : CPUFREQ_MAX) / 1000000); _DEBUG_PRINTF("current_tick: %d", (unsigned int)current_tick); line++; diff --git a/firmware/target/arm/s5l8702/ipod6g/power-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/power-ipod6g.c index 973e26968f..12948f581d 100644 --- a/firmware/target/arm/s5l8702/ipod6g/power-ipod6g.c +++ b/firmware/target/arm/s5l8702/ipod6g/power-ipod6g.c @@ -40,6 +40,9 @@ void power_off(void) void power_init(void) { idepowered = false; + + /* DOWN1CTL: CPU DVM step time = 30us (default: no DVM) */ + pmu_write(0x20, 2); } void ide_power_enable(bool on) diff --git a/firmware/target/arm/s5l8702/kernel-s5l8702.c b/firmware/target/arm/s5l8702/kernel-s5l8702.c index af54e4dca4..b39b384696 100644 --- a/firmware/target/arm/s5l8702/kernel-s5l8702.c +++ b/firmware/target/arm/s5l8702/kernel-s5l8702.c @@ -39,13 +39,14 @@ void tick_start(unsigned int interval_in_ms) { int cycles = 10 * interval_in_ms; - /* configure timer for 10 kHz */ + /* configure timer for 10 kHz (external source) */ TBCMD = (1 << 1); /* TB_CLR */ - TBPRE = 337 - 1; /* prescaler */ + TBPRE = 75 - 1; /* prescaler */ /* 12 MHz / 16 / 75 = 10 KHz */ TBCON = (0 << 13) | /* TB_INT1_EN */ (1 << 12) | /* TB_INT0_EN */ (0 << 11) | /* TB_START */ (2 << 8) | /* TB_CS = PCLK / 16 */ + (1 << 6) | /* UNKNOWN bit */ /* external 12 MHz clock (?) */ (0 << 4); /* TB_MODE_SEL = interval mode */ TBDATA0 = cycles; /* set interval period */ TBCMD = (1 << 0); /* TB_EN */ diff --git a/firmware/target/arm/s5l8702/system-s5l8702.c b/firmware/target/arm/s5l8702/system-s5l8702.c index 124f016118..c3f20c506b 100644 --- a/firmware/target/arm/s5l8702/system-s5l8702.c +++ b/firmware/target/arm/s5l8702/system-s5l8702.c @@ -255,16 +255,52 @@ void set_cpu_frequency(long frequency) if (cpu_frequency == frequency) return; - //TODO: Need to understand this better + /* + * CPU scaling parameters: + * CPUFREQ_MAX: CPU = 216MHz, AHB = 108MHz, Vcore = 1.200V + * CPUFREQ_NORMAL: CPU = 54MHz, AHB = 54MHz, Vcore = 1.050V + * + * CLKCON0 sets PLL2->FCLK divider (CPU clock) + * CLKCON1 sets FCLK->HCLK divider (AHB clock) + * + * HCLK is derived from FCLK, the system goes unstable if HCLK + * is out of the range 54-108 MHz, so two stages are required to + * switch FCLK (216 MHz <-> 54 MHz), adjusting HCLK in between + * to ensure system stability. + */ if (frequency == CPUFREQ_MAX) { + /* Vcore = 1.200V */ + pmu_write(0x1e, 0x17); + + /* FCLK = PLL2 / 2 (FCLK = 108MHz, HCLK = 108MHz) */ + CLKCON0 = 0x3011; + udelay(50); + + /* HCLK = FCLK / 2 (HCLK = 54MHz) */ CLKCON1 = 0x404101; + udelay(50); + + /* FCLK = PLL2 (FCLK = 216MHz, HCLK = 108MHz) */ CLKCON0 = 0x3000; + udelay(100); } else { + /* FCLK = PLL2 / 2 (FCLK = 108MHz, HCLK = 54MHz) */ CLKCON0 = 0x3011; + udelay(50); + + /* HCLK = FCLK (HCLK = 108MHz) */ CLKCON1 = 0x4001; + udelay(50); + + /* FCLK = PLL2 / 4 (FCLK = 54MHz, HCLK = 54MHz) */ + CLKCON0 = 0x3013; + udelay(100); + + /* Vcore = 1.050V */ + pmu_write(0x1e, 0x11); } cpu_frequency = frequency; diff --git a/firmware/target/arm/s5l8702/system-target.h b/firmware/target/arm/s5l8702/system-target.h index 799efb7006..ba05c2f6fb 100644 --- a/firmware/target/arm/s5l8702/system-target.h +++ b/firmware/target/arm/s5l8702/system-target.h @@ -26,8 +26,8 @@ #define CPUFREQ_SLEEP 32768 #define CPUFREQ_MAX 216000000 -#define CPUFREQ_DEFAULT 108000000 -#define CPUFREQ_NORMAL 108000000 +#define CPUFREQ_DEFAULT 54000000 +#define CPUFREQ_NORMAL 54000000 #define STORAGE_WANTS_ALIGN