summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Bauer <fred.w.bauer@gmail.com>2010-12-14 22:08:43 +0000
committerFred Bauer <fred.w.bauer@gmail.com>2010-12-14 22:08:43 +0000
commit279dff1c21c17e6598c8597a7987ded0e526269c (patch)
treeec297e17341ede39beb3ae6eef39e3beaca0bfe5
parent990cbf302eb04f80174c50040492fa7db6fbad6d (diff)
downloadrockbox-279dff1c21c17e6598c8597a7987ded0e526269c.tar.gz
rockbox-279dff1c21c17e6598c8597a7987ded0e526269c.zip
FS#11765: Improve AMSv1 Battery Life by Lowering CPU and Peripheral clocks. Unboosted CPU and peripheral clock is now 31MHz. Boosted CPU and pclk are 186MHz and 62MHz, respectively.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28834 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/as3525/clock-target.h15
-rw-r--r--firmware/target/arm/as3525/debug-as3525.c11
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c42
-rw-r--r--firmware/target/arm/as3525/system-as3525.c42
4 files changed, 94 insertions, 16 deletions
diff --git a/firmware/target/arm/as3525/clock-target.h b/firmware/target/arm/as3525/clock-target.h
index 97d6edb3d1..135164b25b 100644
--- a/firmware/target/arm/as3525/clock-target.h
+++ b/firmware/target/arm/as3525/clock-target.h
@@ -114,17 +114,19 @@
114 /* *5/8 = 240MHz 120, 80, 60, 48, 40 */ 114 /* *5/8 = 240MHz 120, 80, 60, 48, 40 */
115//#define AS3525_PLLA_SETTING 0x2630 115//#define AS3525_PLLA_SETTING 0x2630
116 116
117#define AS3525_FCLK_PREDIV 0 /* div = (8-n)/8 Enter manually & postdiv will be calculated*/ 117#define AS3525_FCLK_PREDIV 2 /* div = (8-n)/8 Enter manually & postdiv will be calculated*/
118 /* 0 gives you the PLLA 1st line choices, 1 the 2nd line etc. */ 118 /* 0 gives you the PLLA 1st line choices, 1 the 2nd line etc. */
119 119
120#define AS3525_FCLK_FREQ 248000000 /* Boosted FCLK frequency */ 120#define AS3525_FCLK_FREQ 186000000 /* Boosted FCLK frequency - over 200MHz */
121#define AS3525_DRAM_FREQ 62000000 /* Initial DRAM frequency */ 121 /* requires CVDDp bumped to 1.2V */
122#define AS3525_DRAM_FREQ 31000000 /* Initial DRAM frequency */
123#define AS3525_DRAM_FREQ_BOOSTED 62000000
122/* AS3525_PCLK_FREQ != AS3525_DRAM_FREQ/1 will boot to white lcd screen */ 124/* AS3525_PCLK_FREQ != AS3525_DRAM_FREQ/1 will boot to white lcd screen */
123 125
124#endif /* CONFIG_CPU == AS3525v2 */ 126#endif /* CONFIG_CPU == AS3525v2 */
125 127
126#define AS3525_PCLK_FREQ (AS3525_DRAM_FREQ/1) /* PCLK divided from DRAM freq */ 128#define AS3525_PCLK_FREQ (AS3525_DRAM_FREQ/1) /* PCLK divided from DRAM freq */
127 129#define AS3525_PCLK_FREQ_BOOSTED (AS3525_DRAM_FREQ_BOOSTED/1)
128#define AS3525_DBOP_FREQ (AS3525_PCLK_FREQ/1) /* DBOP divided from PCLK freq */ 130#define AS3525_DBOP_FREQ (AS3525_PCLK_FREQ/1) /* DBOP divided from PCLK freq */
129 131
130/** ****************************************************************************/ 132/** ****************************************************************************/
@@ -169,6 +171,9 @@
169 /*unable to use AS3525_PCLK_DIV1 != 0 successfuly so far*/ 171 /*unable to use AS3525_PCLK_DIV1 != 0 successfuly so far*/
170#define AS3525_PCLK_DIV1 (CLK_DIV(AS3525_DRAM_FREQ, AS3525_PCLK_FREQ) - 1)/* div = 1/(n+1)*/ 172#define AS3525_PCLK_DIV1 (CLK_DIV(AS3525_DRAM_FREQ, AS3525_PCLK_FREQ) - 1)/* div = 1/(n+1)*/
171#define AS3525_PCLK_DIV0 (CLK_DIV(AS3525_PLLA_FREQ, AS3525_DRAM_FREQ) - 1) /*div=1/(n+1)*/ 173#define AS3525_PCLK_DIV0 (CLK_DIV(AS3525_PLLA_FREQ, AS3525_DRAM_FREQ) - 1) /*div=1/(n+1)*/
174#define AS3525_PCLK_DIV1_BOOSTED (CLK_DIV(AS3525_DRAM_FREQ_BOOSTED, AS3525_PCLK_FREQ_BOOSTED) - 1)
175#define AS3525_PCLK_DIV0_BOOSTED (CLK_DIV(AS3525_PLLA_FREQ, AS3525_PCLK_FREQ_BOOSTED) - 1)
176
172#else 177#else
173 178
174#define AS3525_PCLK_SEL AS3525_CLK_FCLK 179#define AS3525_PCLK_SEL AS3525_CLK_FCLK
@@ -179,8 +184,10 @@
179 /* PCLK as Source */ 184 /* PCLK as Source */
180 #define AS3525_DBOP_DIV (CLK_DIV(AS3525_PCLK_FREQ, AS3525_DBOP_FREQ) - 1) /*div=1/(n+1)*/ 185 #define AS3525_DBOP_DIV (CLK_DIV(AS3525_PCLK_FREQ, AS3525_DBOP_FREQ) - 1) /*div=1/(n+1)*/
181 #define AS3525_I2C_PRESCALER CLK_DIV(AS3525_PCLK_FREQ, AS3525_I2C_FREQ) 186 #define AS3525_I2C_PRESCALER CLK_DIV(AS3525_PCLK_FREQ, AS3525_I2C_FREQ)
187 #define AS3525_I2C_PRESCALER_BOOSTED CLK_DIV(AS3525_PCLK_FREQ_BOOSTED, AS3525_I2C_FREQ)
182 #define AS3525_I2C_FREQ 400000 188 #define AS3525_I2C_FREQ 400000
183 #define AS3525_SD_IDENT_DIV ((CLK_DIV(AS3525_PCLK_FREQ, AS3525_SD_IDENT_FREQ) / 2) - 1) 189 #define AS3525_SD_IDENT_DIV ((CLK_DIV(AS3525_PCLK_FREQ, AS3525_SD_IDENT_FREQ) / 2) - 1)
190 #define AS3525_SD_IDENT_DIV_BOOSTED ((CLK_DIV(AS3525_PCLK_FREQ_BOOSTED, AS3525_SD_IDENT_FREQ) / 2) - 1)
184 #define AS3525_SD_IDENT_FREQ 400000 /* must be between 100 & 400 kHz */ 191 #define AS3525_SD_IDENT_FREQ 400000 /* must be between 100 & 400 kHz */
185 #define AS3525_SSP_PRESCALER ((CLK_DIV(AS3525_PCLK_FREQ, AS3525_SSP_FREQ) + 1) & ~1) /* must be an even number */ 192 #define AS3525_SSP_PRESCALER ((CLK_DIV(AS3525_PCLK_FREQ, AS3525_SSP_FREQ) + 1) & ~1) /* must be an even number */
186 #define AS3525_SSP_FREQ 12000000 193 #define AS3525_SSP_FREQ 12000000
diff --git a/firmware/target/arm/as3525/debug-as3525.c b/firmware/target/arm/as3525/debug-as3525.c
index 513295edcb..9950ccd9c6 100644
--- a/firmware/target/arm/as3525/debug-as3525.c
+++ b/firmware/target/arm/as3525/debug-as3525.c
@@ -182,7 +182,12 @@ static int calc_freq(int clk)
182 return 0; 182 return 0;
183 } 183 }
184 case CLK_I2C: 184 case CLK_I2C:
185 return calc_freq(CLK_PCLK)/AS3525_I2C_PRESCALER; 185#if CONFIG_CPU == AS3525
186 if (cpu_frequency == CPUFREQ_MAX)
187 return calc_freq(CLK_PCLK)/AS3525_I2C_PRESCALER_BOOSTED;
188 else
189#endif
190 return calc_freq(CLK_PCLK)/AS3525_I2C_PRESCALER;
186 case CLK_I2SI: 191 case CLK_I2SI:
187 switch((CGU_AUDIO>>12) & 3) { 192 switch((CGU_AUDIO>>12) & 3) {
188 case 0: 193 case 0:
@@ -218,7 +223,7 @@ static int calc_freq(int clk)
218 case CLK_SD_MCLK_MSD: 223 case CLK_SD_MCLK_MSD:
219 if(!(MCI_SD & (1<<8))) 224 if(!(MCI_SD & (1<<8)))
220 return 0; 225 return 0;
221 else if(MCI_SD & (1<<10)) 226 else if(MCI_SD & (1<<10)) /* bypass */
222 return calc_freq(CLK_PCLK); 227 return calc_freq(CLK_PCLK);
223 else 228 else
224 return calc_freq(CLK_PCLK)/(((MCI_SD & 0xff)+1)*2); 229 return calc_freq(CLK_PCLK)/(((MCI_SD & 0xff)+1)*2);
@@ -347,7 +352,7 @@ bool __dbg_hw_info(void)
347 calc_freq(CLK_SD_MCLK_NAND)/1000000); 352 calc_freq(CLK_SD_MCLK_NAND)/1000000);
348#ifdef HAVE_MULTIDRIVE 353#ifdef HAVE_MULTIDRIVE
349 lcd_putsf(0, line++, "uSD :%3dMHz %3dMHz", 354 lcd_putsf(0, line++, "uSD :%3dMHz %3dMHz",
350 ((AS3525_PCLK_FREQ/ 1000000) / 355 ((calc_freq(CLK_PCLK)/ 1000000) /
351 ((last_sd & MCI_CLOCK_BYPASS) ? 1: (((last_sd & 0xff) + 1) * 2))), 356 ((last_sd & MCI_CLOCK_BYPASS) ? 1: (((last_sd & 0xff) + 1) * 2))),
352 calc_freq(CLK_SD_MCLK_MSD)/1000000); 357 calc_freq(CLK_SD_MCLK_MSD)/1000000);
353#endif 358#endif
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index 0dc29c8aa5..6f11145ee6 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -116,9 +116,8 @@ static void init_pl180_controller(const int drive);
116static tCardInfo card_info[NUM_DRIVES]; 116static tCardInfo card_info[NUM_DRIVES];
117 117
118/* maximum timeouts recommanded in the SD Specification v2.00 */ 118/* maximum timeouts recommanded in the SD Specification v2.00 */
119#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */ 119#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ*(cpu_frequency==CPUFREQ_MAX?2:1)) / 1000 * 100) /* 100 ms */
120#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */ 120#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ*(cpu_frequency==CPUFREQ_MAX?2:1)) / 1000 * 250) /* 250 ms */
121
122/* for compatibility */ 121/* for compatibility */
123static long last_disk_activity = -1; 122static long last_disk_activity = -1;
124 123
@@ -140,6 +139,8 @@ static struct wakeup transfer_completion_signal;
140static volatile unsigned int transfer_error[NUM_VOLUMES]; 139static volatile unsigned int transfer_error[NUM_VOLUMES];
141#define PL180_MAX_TRANSFER_ERRORS 10 140#define PL180_MAX_TRANSFER_ERRORS 10
142 141
142extern long cpu_frequency;
143
143#define UNALIGNED_NUM_SECTORS 10 144#define UNALIGNED_NUM_SECTORS 10
144static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32))); /* align on cache line size */ 145static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS* SD_BLOCK_SIZE] __attribute__((aligned(32))); /* align on cache line size */
145static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0]); 146static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0]);
@@ -283,7 +284,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
283#define MCI_HALFSPEED (MCI_CLOCK_ENABLE) /* MCLK/2 */ 284#define MCI_HALFSPEED (MCI_CLOCK_ENABLE) /* MCLK/2 */
284#define MCI_QUARTERSPEED (MCI_CLOCK_ENABLE | 1) /* MCLK/4 */ 285#define MCI_QUARTERSPEED (MCI_CLOCK_ENABLE | 1) /* MCLK/4 */
285#define MCI_IDENTSPEED (MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV) /* IDENT */ 286#define MCI_IDENTSPEED (MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV) /* IDENT */
286 287#define MCI_IDENTSPEED_BOOSTED (MCI_CLOCK_ENABLE | AS3525_SD_IDENT_DIV_BOOSTED)
287static int sd_init_card(const int drive) 288static int sd_init_card(const int drive)
288{ 289{
289 unsigned long response; 290 unsigned long response;
@@ -293,7 +294,10 @@ static int sd_init_card(const int drive)
293 card_info[drive].rca = 0; 294 card_info[drive].rca = 0;
294 295
295 /* MCLCK on and set to 400kHz ident frequency */ 296 /* MCLCK on and set to 400kHz ident frequency */
296 MCI_CLOCK(drive) = MCI_IDENTSPEED; 297 if (cpu_frequency == CPUFREQ_MAX)
298 MCI_CLOCK(drive) = MCI_IDENTSPEED_BOOSTED;
299 else
300 MCI_CLOCK(drive) = MCI_IDENTSPEED;
297 301
298 /* 100 - 400kHz clock required for Identification Mode */ 302 /* 100 - 400kHz clock required for Identification Mode */
299 /* Start of Card Identification Mode ************************************/ 303 /* Start of Card Identification Mode ************************************/
@@ -375,8 +379,12 @@ static int sd_init_card(const int drive)
375 MCI_CLOCK(drive) = MCI_HALFSPEED; /* MCICLK = IDE_CLK/2 = 25 MHz */ 379 MCI_CLOCK(drive) = MCI_HALFSPEED; /* MCICLK = IDE_CLK/2 = 25 MHz */
376#if defined(HAVE_MULTIDRIVE) 380#if defined(HAVE_MULTIDRIVE)
377 else 381 else
378 /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/ 382 { /* PCLK = 31Mhz (62 boosted) MCI = 31Mhz(hs) or 15.5 */
379 MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED); 383 if (cpu_frequency == CPUFREQ_MAX )
384 MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED);
385 else
386 MCI_CLOCK(drive) = (hs_card ? MCI_FULLSPEED : MCI_HALFSPEED);
387 }
380#endif 388#endif
381 389
382 /* CMD7 w/rca: Select card to put it in TRAN state */ 390 /* CMD7 w/rca: Select card to put it in TRAN state */
@@ -523,6 +531,26 @@ static void sd_thread(void)
523 } 531 }
524} 532}
525 533
534#ifdef HAVE_MULTIDRIVE
535void sd_set_boosted_divider(void)
536{
537 if ( !sd_enabled )
538 return;
539 /* 62Mhz/2 - 62/4 */
540 MCI_CLOCK(SD_SLOT_AS3525) = (hs_card ?
541 MCI_HALFSPEED : MCI_QUARTERSPEED);
542}
543
544void sd_set_unboosted_divider(void)
545{
546 if ( !sd_enabled )
547 return;
548 /* 31Mhz/1 - 31/2 */
549 MCI_CLOCK(SD_SLOT_AS3525) = (hs_card ?
550 MCI_FULLSPEED : MCI_HALFSPEED);
551}
552#endif
553
526static void init_pl180_controller(const int drive) 554static void init_pl180_controller(const int drive)
527{ 555{
528 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0; 556 MCI_COMMAND(drive) = MCI_DATA_CTRL(drive) = 0;
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c
index d8059715d0..2c4543fa33 100644
--- a/firmware/target/arm/as3525/system-as3525.c
+++ b/firmware/target/arm/as3525/system-as3525.c
@@ -33,6 +33,12 @@
33#include "backlight-target.h" 33#include "backlight-target.h"
34#include "lcd.h" 34#include "lcd.h"
35 35
36/* FIXME */
37#define I2C2_CPSR0 *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x1C))
38#define I2C2_CPSR1 *((volatile unsigned int *)(I2C_AUDIO_BASE + 0x20))
39extern void sd_set_boosted_divider(void);
40extern void sd_set_unboosted_divider(void);
41
36#define default_interrupt(name) \ 42#define default_interrupt(name) \
37 extern __attribute__((weak,alias("UIRQ"))) void name (void) 43 extern __attribute__((weak,alias("UIRQ"))) void name (void)
38 44
@@ -286,7 +292,12 @@ void system_init(void)
286#endif 292#endif
287 293
288 /* Initialize power management settings */ 294 /* Initialize power management settings */
295#if CONFIG_CPU == AS3525
296 ascodec_write(AS3514_CVDD_DCDC3, AS314_CP_DCDC3_SETTING|CVDD_1_10);
297#else
289 ascodec_write(AS3514_CVDD_DCDC3, AS314_CP_DCDC3_SETTING); 298 ascodec_write(AS3514_CVDD_DCDC3, AS314_CP_DCDC3_SETTING);
299#endif
300
290#if CONFIG_TUNER 301#if CONFIG_TUNER
291 fmradio_i2c_init(); 302 fmradio_i2c_init();
292#endif 303#endif
@@ -354,7 +365,9 @@ void set_cpu_frequency(long frequency)
354{ 365{
355 if(frequency == CPUFREQ_MAX) 366 if(frequency == CPUFREQ_MAX)
356 { 367 {
357#ifdef HAVE_ADJUSTABLE_CPU_VOLTAGE 368#if defined(HAVE_ADJUSTABLE_CPU_VOLTAGE) && (CPUFREQ_MAX > 200000000)
369 /* This doesn't work anymore. It was written before ascodec
370 was switched to use interrupts */
358 /* Increasing frequency so boost voltage before change */ 371 /* Increasing frequency so boost voltage before change */
359 ascodec_write(AS3514_CVDD_DCDC3, (AS314_CP_DCDC3_SETTING | CVDD_1_20)); 372 ascodec_write(AS3514_CVDD_DCDC3, (AS314_CP_DCDC3_SETTING | CVDD_1_20));
360 373
@@ -374,10 +387,35 @@ void set_cpu_frequency(long frequency)
374 "mcr p15, 0, r0, c1, c0 \n" 387 "mcr p15, 0, r0, c1, c0 \n"
375 : : : "r0" ); 388 : : : "r0" );
376 389
390#ifdef HAVE_MULTIDRIVE
391 /* Set uSD frequency */
392 sd_set_boosted_divider();
393#endif
394 /* Set I2C frequency */
395 I2C2_CPSR0 = AS3525_I2C_PRESCALER_BOOSTED & 0xFF; /* 8 lsb */
396 I2C2_CPSR1 = (AS3525_I2C_PRESCALER_BOOSTED >> 8) & 0x3; /* 2 msb */
397 /* Set PCLK frequency */
398 CGU_PERI = ((CGU_PERI & ~0x7F) | /* reset divider & clksel bits */
399 (AS3525_PCLK_DIV0_BOOSTED << 2) |
400 (AS3525_PCLK_DIV1_BOOSTED << 6) |
401 AS3525_PCLK_SEL);
377 cpu_frequency = CPUFREQ_MAX; 402 cpu_frequency = CPUFREQ_MAX;
378 } 403 }
379 else 404 else
380 { 405 {
406 /* Set I2C frequency */
407 I2C2_CPSR0 = AS3525_I2C_PRESCALER & 0xFF; /* 8 lsb */
408 I2C2_CPSR1 = (AS3525_I2C_PRESCALER >> 8) & 0x3; /* 2 msb */
409 /* Set PCLK frequency */
410 CGU_PERI = ((CGU_PERI & ~0x7F) | /* reset divider & clksel bits */
411 (AS3525_PCLK_DIV0 << 2) |
412 (AS3525_PCLK_DIV1 << 6) |
413 AS3525_PCLK_SEL);
414
415#ifdef HAVE_MULTIDRIVE
416 /* Set uSD frequency */
417 sd_set_unboosted_divider();
418#endif
381 asm volatile( 419 asm volatile(
382 "mrc p15, 0, r0, c1, c0 \n" 420 "mrc p15, 0, r0, c1, c0 \n"
383 "bic r0, r0, #3<<30 \n" /* fastbus clocking */ 421 "bic r0, r0, #3<<30 \n" /* fastbus clocking */
@@ -387,7 +425,7 @@ void set_cpu_frequency(long frequency)
387 /* FCLK is unused so put it to the lowest freq we can */ 425 /* FCLK is unused so put it to the lowest freq we can */
388 CGU_PROC = ((0xf << 4) | (0x3 << 2) | AS3525_CLK_MAIN); 426 CGU_PROC = ((0xf << 4) | (0x3 << 2) | AS3525_CLK_MAIN);
389 427
390#ifdef HAVE_ADJUSTABLE_CPU_VOLTAGE 428#if defined(HAVE_ADJUSTABLE_CPU_VOLTAGE) && (CPUFREQ_MAX > 200000000)
391 /* Decreasing frequency so reduce voltage after change */ 429 /* Decreasing frequency so reduce voltage after change */
392 ascodec_write(AS3514_CVDD_DCDC3, (AS314_CP_DCDC3_SETTING | CVDD_1_10)); 430 ascodec_write(AS3514_CVDD_DCDC3, (AS314_CP_DCDC3_SETTING | CVDD_1_10));
393#endif /* HAVE_ADJUSTABLE_CPU_VOLTAGE */ 431#endif /* HAVE_ADJUSTABLE_CPU_VOLTAGE */