diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/tcc780x/system-target.h | 4 | ||||
-rw-r--r-- | firmware/target/arm/tcc780x/system-tcc780x.c | 134 |
2 files changed, 67 insertions, 71 deletions
diff --git a/firmware/target/arm/tcc780x/system-target.h b/firmware/target/arm/tcc780x/system-target.h index 15508bc8bf..158bc44190 100644 --- a/firmware/target/arm/tcc780x/system-target.h +++ b/firmware/target/arm/tcc780x/system-target.h | |||
@@ -21,8 +21,8 @@ | |||
21 | 21 | ||
22 | #include "system-arm.h" | 22 | #include "system-arm.h" |
23 | 23 | ||
24 | #define CPUFREQ_DEFAULT 98784000 | 24 | #define CPUFREQ_DEFAULT 32000000 |
25 | #define CPUFREQ_NORMAL 98784000 | 25 | #define CPUFREQ_NORMAL 48000000 |
26 | #define CPUFREQ_MAX 192000000 | 26 | #define CPUFREQ_MAX 192000000 |
27 | 27 | ||
28 | #define inl(a) (*(volatile unsigned long *) (a)) | 28 | #define inl(a) (*(volatile unsigned long *) (a)) |
diff --git a/firmware/target/arm/tcc780x/system-tcc780x.c b/firmware/target/arm/tcc780x/system-tcc780x.c index cf4256e879..f6392b023a 100644 --- a/firmware/target/arm/tcc780x/system-tcc780x.c +++ b/firmware/target/arm/tcc780x/system-tcc780x.c | |||
@@ -151,59 +151,6 @@ void fiq_handler(void) | |||
151 | #endif /* !defined(BOOTLOADER) */ | 151 | #endif /* !defined(BOOTLOADER) */ |
152 | 152 | ||
153 | 153 | ||
154 | /* TODO: | ||
155 | a) this is not the place for this function | ||
156 | b) it currently ignores the supplied frequency and uses default values | ||
157 | c) if the PLL being set drives any PCKs, an appropriate new clock divider | ||
158 | will have to be re-calculated for those PCKs (the OF maintains a list of | ||
159 | PCK frequencies for this purpose). | ||
160 | */ | ||
161 | void set_pll_frequency(unsigned int pll_number, unsigned int frequency) | ||
162 | { | ||
163 | int i = 0; | ||
164 | |||
165 | if (pll_number > 1) return; | ||
166 | |||
167 | /* The frequency parameter is currently ignored and temporary values are | ||
168 | used (PLL0=192Mhz, PLL1=216Mhz). The D2 firmware uses a lookup table | ||
169 | to derive the values of PLLxCFG from a the supplied frequency. | ||
170 | Presumably we will need to do something similar. */ | ||
171 | if (pll_number == 0) | ||
172 | { | ||
173 | /* drive CPU off Xin while switching */ | ||
174 | CLKCTRL = 0xB00FF014; /* Xin enable, Fsys driven by Xin, Fbus = Fsys, | ||
175 | MCPU=Fbus, SCPU=Fbus */ | ||
176 | |||
177 | asm volatile ( | ||
178 | "nop \n\t" | ||
179 | "nop \n\t" | ||
180 | ); | ||
181 | |||
182 | PLL0CFG |= (1<<31); /* power down */ | ||
183 | CLKDIVC = CLKDIVC &~ (0xff << 24); /* disable PLL0 divider */ | ||
184 | PLL0CFG = 0x80019808; /* set for 192Mhz (with power down) */ | ||
185 | PLL0CFG = PLL0CFG &~ (1<<31); /* power up */ | ||
186 | |||
187 | CLKCTRL = (CLKCTRL & ~0x1f) | 0x800FF010; | ||
188 | |||
189 | asm volatile ( | ||
190 | "nop \n\t" | ||
191 | "nop \n\t" | ||
192 | ); | ||
193 | } | ||
194 | else if (pll_number == 1) | ||
195 | { | ||
196 | PLL1CFG |= (1<<31); /* power down */ | ||
197 | CLKDIVC = CLKDIVC &~ (0xff << 16); /* disable PLL1 divider */ | ||
198 | PLL1CFG = 0x80002503; /* set for 216Mhz (with power down)*/ | ||
199 | PLL1CFG = PLL1CFG &~ (1<<31); /* power up */ | ||
200 | } | ||
201 | |||
202 | i = 0x1000; | ||
203 | while (--i) {}; | ||
204 | } | ||
205 | |||
206 | |||
207 | /* TODO - these should live in the target-specific directories and | 154 | /* TODO - these should live in the target-specific directories and |
208 | once we understand what all the GPIO pins do, move the init to the | 155 | once we understand what all the GPIO pins do, move the init to the |
209 | specific driver for that hardware. For now, we just perform the | 156 | specific driver for that hardware. For now, we just perform the |
@@ -242,7 +189,14 @@ static void clock_init(void) | |||
242 | int i; | 189 | int i; |
243 | 190 | ||
244 | CSCFG3 = (CSCFG3 &~ 0x3fff) | 0x841; | 191 | CSCFG3 = (CSCFG3 &~ 0x3fff) | 0x841; |
245 | CLKCTRL = (CLKCTRL & ~0xff) | 0x14; | 192 | |
193 | /* Enable Xin (12Mhz), Fsys = Xin, Fbus = Fsys/2, MCPU=Fsys, SCPU=Fsys */ | ||
194 | CLKCTRL = 0x800FF014; | ||
195 | |||
196 | asm volatile ( | ||
197 | "nop \n\t" | ||
198 | "nop \n\t" | ||
199 | ); | ||
246 | 200 | ||
247 | PCLK_RFREQ = 0x1401002d; /* RAM refresh source = Xin (4) / 0x2d = 266kHz */ | 201 | PCLK_RFREQ = 0x1401002d; /* RAM refresh source = Xin (4) / 0x2d = 266kHz */ |
248 | 202 | ||
@@ -252,13 +206,27 @@ static void clock_init(void) | |||
252 | MCFG1 |= 1; | 206 | MCFG1 |= 1; |
253 | SDCFG1 = (SDCFG &~ 0x7000) | 0x2000; | 207 | SDCFG1 = (SDCFG &~ 0x7000) | 0x2000; |
254 | 208 | ||
255 | PLL0CFG |= 0x80000000; /* power down */ | 209 | /* Configure PLL0 to 192Mhz, for CPU scaling */ |
256 | PLL0CFG = 0x14010000; /* power up, source = Xin (4) undivided = 12Mhz */ | 210 | PLL0CFG |= (1<<31); /* power down */ |
211 | CLKDIVC = CLKDIVC &~ (0xff << 24); /* disable PLL0 divider */ | ||
212 | PLL0CFG = 0x80019808; /* set for 192Mhz (with power down) */ | ||
213 | PLL0CFG = PLL0CFG &~ (1<<31); /* power up */ | ||
214 | |||
215 | /* Configure PLL1 to 216Mz, for LCD clock (when divided by 2) */ | ||
216 | PLL1CFG |= (1<<31); /* power down */ | ||
217 | CLKDIVC = CLKDIVC &~ (0xff << 16); /* disable PLL1 divider */ | ||
218 | PLL1CFG = 0x80002503; /* set for 216Mhz (with power down)*/ | ||
219 | PLL1CFG = PLL1CFG &~ (1<<31); /* power up */ | ||
257 | 220 | ||
258 | i = 0x8000; | 221 | i = 0x8000; |
259 | while (--i) {}; | 222 | while (--i) {}; |
260 | 223 | ||
261 | CLKCTRL = (CLKCTRL &~ 0x1f) | 0x800FF010; /* CPU and COP driven by PLL0 */ | 224 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
225 | set_cpu_frequency(CPUFREQ_NORMAL); | ||
226 | #else | ||
227 | /* 48Mhz: Fsys = PLL0 (192Mhz) Fbus = Fsys/4 CPU = Fbus, COP = Fbus */ | ||
228 | CLKCTRL = (1<<31) | (3<<28) | (3<<4); | ||
229 | #endif | ||
262 | 230 | ||
263 | asm volatile ( | 231 | asm volatile ( |
264 | "nop \n\t" | 232 | "nop \n\t" |
@@ -274,8 +242,6 @@ static void clock_init(void) | |||
274 | #ifdef COWON_D2 | 242 | #ifdef COWON_D2 |
275 | void system_init(void) | 243 | void system_init(void) |
276 | { | 244 | { |
277 | int i; | ||
278 | |||
279 | MBCFG = 0x19; | 245 | MBCFG = 0x19; |
280 | 246 | ||
281 | if (TCC780_VER == 0) | 247 | if (TCC780_VER == 0) |
@@ -296,6 +262,7 @@ void system_init(void) | |||
296 | VCTRL |= (1<<31); /* Reading from VNIRQ clears that interrupt */ | 262 | VCTRL |= (1<<31); /* Reading from VNIRQ clears that interrupt */ |
297 | 263 | ||
298 | /* Write IRQ priority registers using ints - a freeze occurs otherwise */ | 264 | /* Write IRQ priority registers using ints - a freeze occurs otherwise */ |
265 | int i; | ||
299 | for (i = 0; i < 7; i++) | 266 | for (i = 0; i < 7; i++) |
300 | { | 267 | { |
301 | IRQ_PRIORITY_TABLE[i] = ((int*)irqpriority)[i]; | 268 | IRQ_PRIORITY_TABLE[i] = ((int*)irqpriority)[i]; |
@@ -307,33 +274,62 @@ void system_init(void) | |||
307 | 274 | ||
308 | gpio_init(); | 275 | gpio_init(); |
309 | clock_init(); | 276 | clock_init(); |
310 | |||
311 | /* TODO: these almost certainly shouldn't be here */ | ||
312 | set_pll_frequency(0, 192000000); /* drives CPU */ | ||
313 | set_pll_frequency(1, 216000000); /* drives LCD PXCLK - divided by 2 */ | ||
314 | } | 277 | } |
315 | #endif | 278 | #endif |
316 | 279 | ||
317 | 280 | ||
318 | void system_reboot(void) | 281 | void system_reboot(void) |
319 | { | 282 | { |
320 | #warning function not implemented | 283 | SWRESET = -1; |
321 | } | 284 | } |
322 | 285 | ||
323 | int system_memory_guard(int newmode) | 286 | int system_memory_guard(int newmode) |
324 | { | 287 | { |
325 | #warning function not implemented | ||
326 | |||
327 | (void)newmode; | 288 | (void)newmode; |
328 | return 0; | 289 | return 0; |
329 | } | 290 | } |
330 | 291 | ||
331 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 292 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
332 | 293 | ||
294 | /* Note: This is not currently enabled because switching seems to | ||
295 | cause an occasional freeze. To be investigated. */ | ||
296 | |||
333 | void set_cpu_frequency(long frequency) | 297 | void set_cpu_frequency(long frequency) |
334 | { | 298 | { |
335 | #warning function not implemented | 299 | /* CPU/COP frequencies can be scaled between Fbus (min) and Fsys (max). |
336 | (void)frequency; | 300 | Fbus should not be set below ~32Mhz with LCD enabled or the display |
301 | will be garbled. */ | ||
302 | if (frequency == CPUFREQ_MAX) | ||
303 | { | ||
304 | /* 192Mhz: | ||
305 | Fsys = PLL0 (192Mhz) | ||
306 | Fbus = Fsys/2 | ||
307 | CPU = Fsys, COP = Fsys */ | ||
308 | CLKCTRL = (1<<31) | (0xFF<<12) | (1<<4); | ||
309 | } | ||
310 | else if (frequency == CPUFREQ_NORMAL) | ||
311 | { | ||
312 | /* 48Mhz: | ||
313 | Fsys = PLL0 (192Mhz) | ||
314 | Fbus = Fsys/4 | ||
315 | CPU = Fbus, COP = Fbus */ | ||
316 | CLKCTRL = (1<<31) | (3<<28) | (3<<4); | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | /* 32Mhz: | ||
321 | Fsys = PLL0 (192Mhz) | ||
322 | Fbus = Fsys/6 | ||
323 | CPU = Fbus, COP = Fbus */ | ||
324 | CLKCTRL = (1<<31) | (3<<28) | (5<<4); | ||
325 | } | ||
326 | |||
327 | asm volatile ( | ||
328 | "nop \n\t" | ||
329 | "nop \n\t" | ||
330 | ); | ||
331 | |||
332 | cpu_frequency = frequency; | ||
337 | } | 333 | } |
338 | 334 | ||
339 | #endif | 335 | #endif |