summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2007-07-26 15:07:16 +0000
committerJens Arnold <amiconn@rockbox.org>2007-07-26 15:07:16 +0000
commit8d3ac97affb770e8eede81cb43ce5d5597fd428b (patch)
treede34e0f45a557e57417685ae3d674413b9e44d64
parent5c1d259fe2eda5f5bf09f8f56361edf563e806a8 (diff)
downloadrockbox-8d3ac97affb770e8eede81cb43ce5d5597fd428b.zip
rockbox-8d3ac97affb770e8eede81cb43ce5d5597fd428b.tar.gz
rockbox-8d3ac97affb770e8eede81cb43ce5d5597fd428b.tar.bz2
rockbox-8d3ac97affb770e8eede81cb43ce5d5597fd428b.tar.xz
Clean up PP502x CPU clock setup code and use the full 80MHz when boosted.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14004 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/pp5020.h3
-rw-r--r--firmware/target/arm/system-arm.h14
-rw-r--r--firmware/target/arm/system-pp502x.c165
-rw-r--r--firmware/target/arm/system-target.h17
4 files changed, 100 insertions, 99 deletions
diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h
index f35b4c4..108b776 100644
--- a/firmware/export/pp5020.h
+++ b/firmware/export/pp5020.h
@@ -135,6 +135,7 @@
#define CLOCK_SOURCE (*(volatile unsigned long *)(0x60006020))
#define PLL_CONTROL (*(volatile unsigned long *)(0x60006034))
#define PLL_STATUS (*(volatile unsigned long *)(0x6000603c))
+#define CLCD_CLOCK_SRC (*(volatile unsigned long *)(0x600060a0))
/* Processors Control */
#define CPU_CTL (*(volatile unsigned long *)(0x60007000))
@@ -254,6 +255,8 @@
#define PP_VER1 (*(volatile unsigned long *)(0x70000000))
#define PP_VER2 (*(volatile unsigned long *)(0x70000004))
#define DEV_INIT (*(volatile unsigned long *)(0x70000020))
+/* some timing that needs to be handled during clock setup */
+#define DEV_TIMING1 (*(volatile unsigned long *)(0x70000034))
#define INIT_USB 0x80000000
diff --git a/firmware/target/arm/system-arm.h b/firmware/target/arm/system-arm.h
index 37c367f..1a9cccc 100644
--- a/firmware/target/arm/system-arm.h
+++ b/firmware/target/arm/system-arm.h
@@ -26,20 +26,6 @@
have conflicts with another system-target.h elsewhere so include a
subheader from here. */
-/* TODO: Implement set_irq_level and check CPU frequencies */
-
-#if CONFIG_CPU != S3C2440 && CONFIG_CPU != PNX0101
-
-/* TODO: Finish targeting this stuff */
-#define CPUFREQ_DEFAULT_MULT 4
-#define CPUFREQ_DEFAULT 24000000
-#define CPUFREQ_NORMAL_MULT 5
-#define CPUFREQ_NORMAL 30000000
-#define CPUFREQ_MAX_MULT 13
-#define CPUFREQ_MAX 78000000
-
-#endif
-
static inline uint16_t swap16(uint16_t value)
/*
result[15..8] = value[ 7..0];
diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c
index 748e106..5d989c0 100644
--- a/firmware/target/arm/system-pp502x.c
+++ b/firmware/target/arm/system-pp502x.c
@@ -114,12 +114,11 @@ void irq(void)
#endif
#endif /* BOOTLOADER */
-/* TODO: The following two function have been lifted straight from IPL, and
- hence have a lot of numeric addresses used straight. I'd like to use
+/* TODO: The following function has been lifted straight from IPL, and
+ hence has a lot of numeric addresses used straight. I'd like to use
#defines for these, but don't know what most of them are for or even what
they should be named. Because of this I also have no way of knowing how
- to extend the funtions to do alternate cache configurations and/or
- some other CPU frequency scaling. */
+ to extend the funtions to do alternate cache configurations. */
#ifndef BOOTLOADER
static void ipod_init_cache(void)
@@ -144,93 +143,98 @@ static void ipod_init_cache(void)
for (i = 0x10000000; i < 0x10002000; i += 16)
inb(i);
}
-#endif
-/* Not all iPod targets support CPU freq. boosting yet */
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
void set_cpu_frequency(long frequency)
+#else
+static void pp_set_cpu_frequency(long frequency)
+#endif
{
- unsigned long postmult, pll_control;
- unsigned long unknown1, unknown2;
+ unsigned long clcd_clock_src;
+ bool use_pll = true;
-# if NUM_CORES > 1
+#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
/* Using mutex or spinlock isn't safe here. */
while (test_and_set(&boostctrl_mtx.locked, 1)) ;
-# endif
-
- if (frequency == CPUFREQ_NORMAL)
- postmult = CPUFREQ_NORMAL_MULT;
- else if (frequency == CPUFREQ_MAX)
- postmult = CPUFREQ_MAX_MULT;
- else
- postmult = CPUFREQ_DEFAULT_MULT;
- cpu_frequency = frequency;
+#endif
#ifdef SANSA_E200
i2s_scale_attn_level(CPUFREQ_DEFAULT);
#endif
- unknown2 = inl(0x600060a0);
-
- outl(inl(0x70000020) | (1<<30), 0x70000020); /* Enable PLL power */
-
- /* Set clock source #1 to 24MHz and select it */
- outl((inl(0x60006020) & 0x0ffffff0) | 0x10000002, 0x60006020);
-
- outl(inl(0x600060a0) & ~0xc0000000, 0x600060a0);
-
- unknown1 = (138 * postmult + 255) >> 8;
- if (unknown1 > 15)
- unknown1 = 15;
- outl((unknown1 << 8) | unknown1, 0x70000034);
+ cpu_frequency = frequency;
+ clcd_clock_src = CLCD_CLOCK_SRC; /* save selected color LCD clock source */
- /* PLL frequency = (24/4)*postmult */
- pll_control = 0x8a020000 | 4 | (postmult << 8);
- outl(pll_control, 0x60006034);
-# if CONFIG_CPU == PP5020
- outl(0xd19b, 0x6000603c); /* magic sequence */
- outl(pll_control, 0x60006034);
- udelay(500); /* wait for relock */
-# else /* PP5022, PP5024 */
- udelay(250);
- while (!(inl(0x6000603c) & 0x80000000)); /* wait for relock */
-# endif
+ CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf000000f) | 0x10000002;
+ /* set clock source 1 to 24MHz and select it */
+ CLCD_CLOCK_SRC &= ~0xc0000000; /* select 24MHz as color LCD clock source */
- /* Select PLL as clock source? */
- outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020);
+ switch (frequency)
+ {
+#if CONFIG_CPU == PP5020
+ case CPUFREQ_MAX:
+ DEV_TIMING1 = 0x00000808;
+ PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */
+ PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */
+ PLL_CONTROL = 0x8a020a03; /* repeat setup */
+ udelay(500); /* wait for relock */
+ break;
+
+ case CPUFREQ_NORMAL:
+ DEV_TIMING1 = 0x00000303;
+ PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */
+ udelay(500); /* wait for relock */
+ break;
+
+ default:
+ DEV_TIMING1 = 0x00000303;
+ PLL_CONTROL &= ~0x80000000; /* disable PLL */
+ use_pll = false;
+ cpu_frequency = CPUFREQ_DEFAULT;
+ break;
+
+#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
+ /* Note: The PP5022 PLL must be run at >= 96MHz
+ * Bits 20..21 select the post divider (1/2/4/8).
+ * PP5026 is similar to PP5022 except it doesn't
+ * have this limitation (and the post divider?) */
+ case CPUFREQ_MAX:
+ DEV_TIMING1 = 0x00000808;
+ PLL_CONTROL = 0x8a121403; /* (20/3 * 24MHz) / 2 */
+ udelay(250);
+ while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
+ break;
+
+ case CPUFREQ_NORMAL:
+ DEV_TIMING1 = 0x00000303;
+ PLL_CONTROL = 0x8a220501; /* (5/1 * 24MHz) / 4 */
+ udelay(250);
+ while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
+ break;
+
+ default:
+ DEV_TIMING1 = 0x00000303;
+ PLL_CONTROL &= ~0x80000000; /* disable PLL */
+ use_pll = false;
+ cpu_frequency = CPUFREQ_DEFAULT;
+ break;
+#endif
+ }
+ if (use_pll) /* set clock source 2 to PLL and select it */
+ CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf00000f0) | 0x20000070;
- inl(0x600060a0); /* sync pipeline (?) */
- outl(unknown2, 0x600060a0);
+ CLCD_CLOCK_SRC; /* dummy read (to sync the write pipeline??) */
+ CLCD_CLOCK_SRC = clcd_clock_src; /* restore saved value */
#ifdef SANSA_E200
i2s_scale_attn_level(frequency);
#endif
-# if NUM_CORES > 1
+#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
boostctrl_mtx.locked = 0;
-# endif
-}
-#elif !defined(BOOTLOADER)
-void ipod_set_cpu_frequency(void)
-{
-/* For e200, just use clocking set up by OF loader for now */
-#ifndef SANSA_E200
- /* Enable PLL? */
- outl(inl(0x70000020) | (1<<30), 0x70000020);
-
- /* Select 24MHz crystal as clock source? */
- outl((inl(0x60006020) & 0x0ffffff0) | 0x10000002, 0x60006020);
-
- /* Clock frequency = (24/8)*25 = 75MHz */
- outl(0x8a020000 | 8 | (25 << 8), 0x60006034);
- /* Wait for PLL relock? */
- udelay(500);
-
- /* Select PLL as clock source? */
- outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020);
-#endif /* SANSA_E200 */
-}
#endif
+}
+#endif /* !BOOTLOADER */
void system_init(void)
{
@@ -273,29 +277,20 @@ void system_init(void)
#ifdef SANSA_E200
/* outl(0x00000000, 0x6000b000); */
outl(inl(0x6000a000) | 0x80000000, 0x6000a000); /* Init DMA controller? */
- }
+#endif
- ipod_init_cache();
-#else /* !sansa E200 */
+ DEV_INIT |= 1 << 30; /* enable PLL power */
-# if NUM_CORES > 1 && defined(HAVE_ADJUSTABLE_CPU_FREQ)
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+#if NUM_CORES > 1
spinlock_init(&boostctrl_mtx);
-# endif
-
-#if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES == 1)
- ipod_set_cpu_frequency();
#endif
- }
-#if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
- else
- {
- ipod_set_cpu_frequency();
- }
+#else
+ pp_set_cpu_frequency(CPUFREQ_MAX);
#endif
+ }
ipod_init_cache();
-#endif /* SANSA_E200 */
-
#endif /* BOOTLOADER */
}
diff --git a/firmware/target/arm/system-target.h b/firmware/target/arm/system-target.h
index 2a06ee4..5c73f4d 100644
--- a/firmware/target/arm/system-target.h
+++ b/firmware/target/arm/system-target.h
@@ -22,6 +22,23 @@
#include "system-arm.h"
+/* TODO: This header is actually portalplayer specific, and should be
+ * moved into an appropriate subdir (or even split in 2). */
+
+#if CONFIG_CPU == PP5002
+#define CPUFREQ_DEFAULT_MULT 4
+#define CPUFREQ_DEFAULT 24000000
+#define CPUFREQ_NORMAL_MULT 5
+#define CPUFREQ_NORMAL 30000000
+#define CPUFREQ_MAX_MULT 13
+#define CPUFREQ_MAX 78000000
+
+#else /* PP5022, PP5024 */
+#define CPUFREQ_DEFAULT 24000000
+#define CPUFREQ_NORMAL 30000000
+#define CPUFREQ_MAX 80000000
+#endif
+
#define inl(a) (*(volatile unsigned long *) (a))
#define outl(a,b) (*(volatile unsigned long *) (b) = (a))
#define inb(a) (*(volatile unsigned char *) (a))