summaryrefslogtreecommitdiff
path: root/firmware/target/arm/system-pp502x.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-10-16 01:25:17 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-10-16 01:25:17 +0000
commita9b2fb5ee3114fe835f6515b6aeae7454f66d821 (patch)
treefc4e96d0c1f215565918406c8827b16b806c1345 /firmware/target/arm/system-pp502x.c
parenta3fbbc9fa7e12fd3fce122bbd235dc362050e024 (diff)
downloadrockbox-a9b2fb5ee3114fe835f6515b6aeae7454f66d821.tar.gz
rockbox-a9b2fb5ee3114fe835f6515b6aeae7454f66d821.zip
Finally full multicore support for PortalPlayer 502x targets with an eye towards the possibility of other types. All SVN targets the low-lag code to speed up blocking operations. Most files are modified here simple due to a name change to actually support a real event object and a param change to create_thread. Add some use of new features but just sit on things for a bit and leave full integration for later. Work will continue on to address size on sensitive targets and simplify things if possible. Any PP target having problems with SWP can easily be changed to sw corelocks with one #define change in config.h though only PP5020 has shown an issue and seems to work without any difficulties.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15134 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/system-pp502x.c')
-rw-r--r--firmware/target/arm/system-pp502x.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c
index 576459d6c1..d24d19f747 100644
--- a/firmware/target/arm/system-pp502x.c
+++ b/firmware/target/arm/system-pp502x.c
@@ -21,10 +21,6 @@
21#include "i2s.h" 21#include "i2s.h"
22#include "i2c-pp.h" 22#include "i2c-pp.h"
23 23
24#if NUM_CORES > 1
25struct mutex boostctrl_mtx NOCACHEBSS_ATTR;
26#endif
27
28#ifndef BOOTLOADER 24#ifndef BOOTLOADER
29extern void TIMER1(void); 25extern void TIMER1(void);
30extern void TIMER2(void); 26extern void TIMER2(void);
@@ -129,16 +125,42 @@ static void init_cache(void)
129} 125}
130 126
131#ifdef HAVE_ADJUSTABLE_CPU_FREQ 127#ifdef HAVE_ADJUSTABLE_CPU_FREQ
128void scale_suspend_core(bool suspend) ICODE_ATTR;
129void scale_suspend_core(bool suspend)
130{
131 unsigned int core = CURRENT_CORE;
132 unsigned int othercore = 1 - core;
133 static unsigned long proc_bits IBSS_ATTR;
134 static int oldstatus IBSS_ATTR;
135
136 if (suspend)
137 {
138 oldstatus = set_interrupt_status(IRQ_FIQ_DISABLED, IRQ_FIQ_STATUS);
139 proc_bits = PROC_CTL(othercore) & 0xc0000000;
140 PROC_CTL(othercore) = 0x40000000; nop;
141 PROC_CTL(core) = 0x48000003; nop;
142 }
143 else
144 {
145 PROC_CTL(core) = 0x4800001f; nop;
146 if (proc_bits == 0)
147 PROC_CTL(othercore) = 0;
148 set_interrupt_status(oldstatus, IRQ_FIQ_STATUS);
149 }
150}
151
152void set_cpu_frequency(long frequency) ICODE_ATTR;
132void set_cpu_frequency(long frequency) 153void set_cpu_frequency(long frequency)
133#else 154#else
134static void pp_set_cpu_frequency(long frequency) 155static void pp_set_cpu_frequency(long frequency)
135#endif 156#endif
136{ 157{
137#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) 158#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
138 /* Using mutex or spinlock isn't safe here. */ 159 spinlock_lock(&boostctrl_spin);
139 while (test_and_set(&boostctrl_mtx.locked, 1)) ;
140#endif 160#endif
141 161
162 scale_suspend_core(true);
163
142 cpu_frequency = frequency; 164 cpu_frequency = frequency;
143 165
144 switch (frequency) 166 switch (frequency)
@@ -149,17 +171,20 @@ static void pp_set_cpu_frequency(long frequency)
149 * have this limitation (and the post divider?) */ 171 * have this limitation (and the post divider?) */
150 case CPUFREQ_MAX: 172 case CPUFREQ_MAX:
151 CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ 173 CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */
152 DEV_TIMING1 = 0x00000808; 174 DEV_TIMING1 = 0x00000303;
153#if CONFIG_CPU == PP5020 175#if CONFIG_CPU == PP5020
154 PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */ 176 PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */
155 PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */ 177 PLL_STATUS = 0xd19b; /* unlock frequencies > 66MHz */
156 PLL_CONTROL = 0x8a020a03; /* repeat setup */ 178 PLL_CONTROL = 0x8a020a03; /* repeat setup */
179 scale_suspend_core(false);
157 udelay(500); /* wait for relock */ 180 udelay(500); /* wait for relock */
158#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) 181#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
159 PLL_CONTROL = 0x8a121403; /* (20/3 * 24MHz) / 2 */ 182 PLL_CONTROL = 0x8a121403; /* (20/3 * 24MHz) / 2 */
183 scale_suspend_core(false);
160 udelay(250); 184 udelay(250);
161 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ 185 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
162#endif 186#endif
187 scale_suspend_core(true);
163 break; 188 break;
164 189
165 case CPUFREQ_NORMAL: 190 case CPUFREQ_NORMAL:
@@ -167,18 +192,23 @@ static void pp_set_cpu_frequency(long frequency)
167 DEV_TIMING1 = 0x00000303; 192 DEV_TIMING1 = 0x00000303;
168#if CONFIG_CPU == PP5020 193#if CONFIG_CPU == PP5020
169 PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */ 194 PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */
195 scale_suspend_core(false);
170 udelay(500); /* wait for relock */ 196 udelay(500); /* wait for relock */
171#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) 197#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
172 PLL_CONTROL = 0x8a220501; /* (5/1 * 24MHz) / 4 */ 198 PLL_CONTROL = 0x8a220501; /* (5/1 * 24MHz) / 4 */
199 scale_suspend_core(false);
173 udelay(250); 200 udelay(250);
174 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */ 201 while (!(PLL_STATUS & 0x80000000)); /* wait for relock */
175#endif 202#endif
203 scale_suspend_core(true);
176 break; 204 break;
177 205
178 case CPUFREQ_SLEEP: 206 case CPUFREQ_SLEEP:
179 CLOCK_SOURCE = 0x10002202; /* source #2: 32kHz, #1, #3, #4: 24MHz */ 207 CLOCK_SOURCE = 0x10002202; /* source #2: 32kHz, #1, #3, #4: 24MHz */
180 PLL_CONTROL &= ~0x80000000; /* disable PLL */ 208 PLL_CONTROL &= ~0x80000000; /* disable PLL */
209 scale_suspend_core(false);
181 udelay(10000); /* let 32kHz source stabilize? */ 210 udelay(10000); /* let 32kHz source stabilize? */
211 scale_suspend_core(true);
182 break; 212 break;
183 213
184 default: 214 default:
@@ -186,12 +216,19 @@ static void pp_set_cpu_frequency(long frequency)
186 DEV_TIMING1 = 0x00000303; 216 DEV_TIMING1 = 0x00000303;
187 PLL_CONTROL &= ~0x80000000; /* disable PLL */ 217 PLL_CONTROL &= ~0x80000000; /* disable PLL */
188 cpu_frequency = CPUFREQ_DEFAULT; 218 cpu_frequency = CPUFREQ_DEFAULT;
219 PROC_CTL(CURRENT_CORE) = 0x4800001f; nop;
189 break; 220 break;
190 } 221 }
222
223 if (frequency == CPUFREQ_MAX)
224 DEV_TIMING1 = 0x00000808;
225
191 CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf0000000) | 0x20000000; /* select source #2 */ 226 CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf0000000) | 0x20000000; /* select source #2 */
192 227
228 scale_suspend_core(false);
229
193#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) 230#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
194 boostctrl_mtx.locked = 0; 231 spinlock_unlock(&boostctrl_spin);
195#endif 232#endif
196} 233}
197#endif /* !BOOTLOADER */ 234#endif /* !BOOTLOADER */
@@ -256,7 +293,7 @@ void system_init(void)
256 293
257#ifdef HAVE_ADJUSTABLE_CPU_FREQ 294#ifdef HAVE_ADJUSTABLE_CPU_FREQ
258#if NUM_CORES > 1 295#if NUM_CORES > 1
259 spinlock_init(&boostctrl_mtx); 296 cpu_boost_init();
260#endif 297#endif
261#else 298#else
262 pp_set_cpu_frequency(CPUFREQ_MAX); 299 pp_set_cpu_frequency(CPUFREQ_MAX);