diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-10-16 01:25:17 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-10-16 01:25:17 +0000 |
commit | a9b2fb5ee3114fe835f6515b6aeae7454f66d821 (patch) | |
tree | fc4e96d0c1f215565918406c8827b16b806c1345 /firmware/target/arm/system-pp502x.c | |
parent | a3fbbc9fa7e12fd3fce122bbd235dc362050e024 (diff) | |
download | rockbox-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.c | 55 |
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 | ||
25 | struct mutex boostctrl_mtx NOCACHEBSS_ATTR; | ||
26 | #endif | ||
27 | |||
28 | #ifndef BOOTLOADER | 24 | #ifndef BOOTLOADER |
29 | extern void TIMER1(void); | 25 | extern void TIMER1(void); |
30 | extern void TIMER2(void); | 26 | extern 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 |
128 | void scale_suspend_core(bool suspend) ICODE_ATTR; | ||
129 | void 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 | |||
152 | void set_cpu_frequency(long frequency) ICODE_ATTR; | ||
132 | void set_cpu_frequency(long frequency) | 153 | void set_cpu_frequency(long frequency) |
133 | #else | 154 | #else |
134 | static void pp_set_cpu_frequency(long frequency) | 155 | static 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); |