summaryrefslogtreecommitdiff
path: root/firmware/target/arm/system-pp502x.c
diff options
context:
space:
mode:
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);