summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702/system-s5l8702.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s5l8702/system-s5l8702.c')
-rw-r--r--firmware/target/arm/s5l8702/system-s5l8702.c63
1 files changed, 20 insertions, 43 deletions
diff --git a/firmware/target/arm/s5l8702/system-s5l8702.c b/firmware/target/arm/s5l8702/system-s5l8702.c
index 014ed910de..3e84e5cf54 100644
--- a/firmware/target/arm/s5l8702/system-s5l8702.c
+++ b/firmware/target/arm/s5l8702/system-s5l8702.c
@@ -27,6 +27,7 @@
27#include "gpio-s5l8702.h" 27#include "gpio-s5l8702.h"
28#include "dma-s5l8702.h" 28#include "dma-s5l8702.h"
29#include "uart-s5l8702.h" 29#include "uart-s5l8702.h"
30#include "clocking-s5l8702.h"
30 31
31#define default_interrupt(name) \ 32#define default_interrupt(name) \
32 extern __attribute__((weak,alias("UIRQ"))) void name (void) 33 extern __attribute__((weak,alias("UIRQ"))) void name (void)
@@ -180,9 +181,24 @@ void fiq_dummy(void)
180 ); 181 );
181} 182}
182 183
184static struct clocking_mode clk_modes[] =
185{
186 /* cdiv hdiv hprat hsdiv */ /* CClk HClk PClk SM1Clk FPS */
187 { 1, 2, 2, 4 }, /* 216 108 54 27 42 */
188#ifdef HAVE_ADJUSTABLE_CPU_FREQ
189 { 4, 4, 2, 2 }, /* 54 54 27 27 21 */
190#endif
191};
192#define N_CLK_MODES (sizeof(clk_modes) / sizeof(struct clocking_mode))
193
194enum {
195 CLK_BOOST = 0,
196 CLK_UNBOOST = N_CLK_MODES - 1,
197};
183 198
184void system_init(void) 199void system_init(void)
185{ 200{
201 clocking_init(clk_modes, 0);
186 gpio_init(); 202 gpio_init();
187 pmu_init(); 203 pmu_init();
188 dma_init(); 204 dma_init();
@@ -223,61 +239,22 @@ int system_memory_guard(int newmode)
223} 239}
224 240
225#ifdef HAVE_ADJUSTABLE_CPU_FREQ 241#ifdef HAVE_ADJUSTABLE_CPU_FREQ
226
227void set_cpu_frequency(long frequency) 242void set_cpu_frequency(long frequency)
228{ 243{
229 if (cpu_frequency == frequency) 244 if (cpu_frequency == frequency)
230 return; 245 return;
231 246
232 /*
233 * CPU scaling parameters:
234 * CPUFREQ_MAX: CPU = 216MHz, AHB = 108MHz, Vcore = 1.200V
235 * CPUFREQ_NORMAL: CPU = 54MHz, AHB = 54MHz, Vcore = 1.050V
236 *
237 * CLKCON0 sets PLL2->FCLK divider (CPU clock)
238 * CLKCON1 sets FCLK->HCLK divider (AHB clock)
239 *
240 * HCLK is derived from FCLK, the system goes unstable if HCLK
241 * is out of the range 54-108 MHz, so two stages are required to
242 * switch FCLK (216 MHz <-> 54 MHz), adjusting HCLK in between
243 * to ensure system stability.
244 */
245 if (frequency == CPUFREQ_MAX) 247 if (frequency == CPUFREQ_MAX)
246 { 248 {
247 /* Vcore = 1.200V */ 249 pmu_write(0x1e, 0x13); /* Vcore = 1100 mV */
248 pmu_write(0x1e, 0x17); 250 set_clocking_level(CLK_BOOST);
249
250 /* FCLK = PLL2 / 2 (FCLK = 108MHz, HCLK = 108MHz) */
251 CLKCON0 = 0x3011;
252 udelay(50);
253
254 /* HCLK = FCLK / 2 (HCLK = 54MHz) */
255 CLKCON1 = 0x404101;
256 udelay(50);
257
258 /* FCLK = PLL2 (FCLK = 216MHz, HCLK = 108MHz) */
259 CLKCON0 = 0x3000;
260 udelay(100);
261 } 251 }
262 else 252 else
263 { 253 {
264 /* FCLK = PLL2 / 2 (FCLK = 108MHz, HCLK = 54MHz) */ 254 set_clocking_level(CLK_UNBOOST);
265 CLKCON0 = 0x3011; 255 pmu_write(0x1e, 0xf); /* Vcore = 1000 mV */
266 udelay(50);
267
268 /* HCLK = FCLK (HCLK = 108MHz) */
269 CLKCON1 = 0x4001;
270 udelay(50);
271
272 /* FCLK = PLL2 / 4 (FCLK = 54MHz, HCLK = 54MHz) */
273 CLKCON0 = 0x3013;
274 udelay(100);
275
276 /* Vcore = 1.050V */
277 pmu_write(0x1e, 0x11);
278 } 256 }
279 257
280 cpu_frequency = frequency; 258 cpu_frequency = frequency;
281} 259}
282
283#endif 260#endif