iPod: First working audio driver
[Rockbox.git] / firmware / export / system.h
blob0434425ffd5dd794d56dc24230fe74f045eb85c1
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Alan Korr
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #ifndef __SYSTEM_H__
21 #define __SYSTEM_H__
23 #include "cpu.h"
24 #include "config.h"
25 #include "stdbool.h"
27 extern void system_reboot (void);
28 extern void system_init(void);
30 extern long cpu_frequency;
32 #if CONFIG_CPU==PP5020
33 #define inl(a) (*(volatile unsigned long *) (a))
34 #define outl(a,b) (*(volatile unsigned long *) (b) = (a))
35 #define inb(a) (*(volatile unsigned char *) (a))
36 #define outb(a,b) (*(volatile unsigned char *) (b) = (a))
37 #define inw(a) (*(volatile unsigned short *) (a))
38 #define outw(a,b) (*(volatile unsigned short *) (b) = (a))
39 static inline void udelay(unsigned usecs)
41 unsigned start = inl(0x60005010);
42 while ((inl(0x60005010) - start) < usecs);
44 #endif
46 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
47 #define FREQ cpu_frequency
48 void set_cpu_frequency(long frequency);
49 void cpu_boost(bool on_off);
50 void cpu_idle_mode(bool on_off);
51 #else
52 #define FREQ CPU_FREQ
53 #define set_cpu_frequency(frequency)
54 #define cpu_boost(on_off)
55 #define cpu_idle_mode(on_off)
56 #endif
58 #define BAUDRATE 9600
60 #ifndef NULL
61 #define NULL ((void*)0)
62 #endif
64 #ifndef MIN
65 #define MIN(a, b) (((a)<(b))?(a):(b))
66 #endif
68 #ifndef MAX
69 #define MAX(a, b) (((a)>(b))?(a):(b))
70 #endif
72 #ifdef ROCKBOX_LITTLE_ENDIAN
73 #define letoh16(x) (x)
74 #define letoh32(x) (x)
75 #define htole16(x) (x)
76 #define htole32(x) (x)
77 #define betoh16(x) swap16(x)
78 #define betoh32(x) swap32(x)
79 #define htobe16(x) swap16(x)
80 #define htobe32(x) swap32(x)
81 #else
82 #define letoh16(x) swap16(x)
83 #define letoh32(x) swap32(x)
84 #define htole16(x) swap16(x)
85 #define htole32(x) swap32(x)
86 #define betoh16(x) (x)
87 #define betoh32(x) (x)
88 #define htobe16(x) (x)
89 #define htobe32(x) (x)
90 #endif
93 #define nop \
94 asm volatile ("nop")
96 /* gcc 3.4 changed the format of the constraints */
97 #if (__GNUC__ >= 3) && (__GNUC_MINOR__ > 3) || (__GNUC__ >= 4)
98 #define I_CONSTRAINT "I08"
99 #else
100 #define I_CONSTRAINT "I"
101 #endif
103 /* Utilize the user break controller to catch invalid memory accesses. */
104 int system_memory_guard(int newmode);
106 enum {
107 MEMGUARD_KEEP = -1, /* don't change the mode; for reading */
108 MEMGUARD_NONE = 0, /* catch nothing */
109 MEMGUARD_FLASH_WRITES, /* catch writes to area 02 (flash ROM) */
110 MEMGUARD_ZERO_AREA, /* catch all accesses to areas 00 and 01 */
111 MAXMEMGUARD
115 #if CONFIG_CPU == SH7034
116 #define or_b(mask, address) \
117 asm \
118 ("or.b %0,@(r0,gbr)" \
120 : /* %0 */ I_CONSTRAINT((char)(mask)), \
121 /* %1 */ "z"(address-GBR))
123 #define and_b(mask, address) \
124 asm \
125 ("and.b %0,@(r0,gbr)" \
127 : /* %0 */ I_CONSTRAINT((char)(mask)), \
128 /* %1 */ "z"(address-GBR))
130 #define xor_b(mask, address) \
131 asm \
132 ("xor.b %0,@(r0,gbr)" \
134 : /* %0 */ I_CONSTRAINT((char)(mask)), \
135 /* %1 */ "z"(address-GBR))
137 #elif defined(CPU_COLDFIRE)
138 #define or_l(mask, address) \
139 asm \
140 ("or.l %0,(%1)" \
142 : /* %0 */ "d"(mask), \
143 /* %1 */ "a"(address))
145 #define and_l(mask, address) \
146 asm \
147 ("and.l %0,(%1)" \
149 : /* %0 */ "d"(mask), \
150 /* %1 */ "a"(address))
152 #define eor_l(mask, address) \
153 asm \
154 ("eor.l %0,(%1)" \
156 : /* %0 */ "d"(mask), \
157 /* %1 */ "a"(address))
159 #define EMAC_ROUND 0x10
160 #define EMAC_FRACTIONAL 0x20
161 #define EMAC_SATURATE 0x80
163 static inline void coldfire_set_macsr(unsigned long flags)
165 asm volatile ("move.l %0, %%macsr" : : "i,r" (flags));
168 static inline unsigned long coldfire_get_macsr(void)
170 unsigned long m;
172 asm volatile ("move.l %%macsr, %0" : "=r" (m));
173 return m;
176 #endif
178 #ifndef SIMULATOR
180 /****************************************************************************
181 * Interrupt level setting
182 * The level is left shifted 4 bits
183 ****************************************************************************/
184 #if CONFIG_CPU == SH7034
185 #define HIGHEST_IRQ_LEVEL (15<<4)
186 static inline int set_irq_level(int level)
188 int i;
189 /* Read the old level and set the new one */
190 asm volatile ("stc sr, %0" : "=r" (i));
191 asm volatile ("ldc %0, sr" : : "r" (level));
192 return i;
195 static inline unsigned short swap16(unsigned short value)
197 result[15..8] = value[ 7..0];
198 result[ 7..0] = value[15..8];
201 unsigned short result;
202 asm volatile ("swap.b\t%1,%0" : "=r"(result) : "r"(value));
203 return result;
206 static inline unsigned long SWAW32(unsigned long value)
208 result[31..16] = value[15.. 0];
209 result[15.. 0] = value[31..16];
212 unsigned long result;
213 asm volatile ("swap.w\t%1,%0" : "=r"(result) : "r"(value));
214 return result;
217 static inline unsigned long swap32(unsigned long value)
219 result[31..24] = value[ 7.. 0];
220 result[23..16] = value[15.. 8];
221 result[15.. 8] = value[23..16];
222 result[ 7.. 0] = value[31..24];
225 asm volatile ("swap.b\t%0,%0\n"
226 "swap.w\t%0,%0\n"
227 "swap.b\t%0,%0\n" : "+r"(value));
228 return value;
231 #define invalidate_icache()
233 #elif defined(CPU_COLDFIRE)
234 #define HIGHEST_IRQ_LEVEL (7<<8)
235 static inline int set_irq_level(int level)
237 int oldlevel;
238 /* Read the old level and set the new one */
239 asm volatile ("move.w %%sr,%0\n"
240 "or.l #0x2000,%1\n"
241 "move.w %1,%%sr\n" : "=d" (oldlevel), "+d" (level) : );
242 return oldlevel;
245 static inline unsigned short swap16(unsigned short value)
247 result[15..8] = value[ 7..0];
248 result[ 7..0] = value[15..8];
251 return (value >> 8) | (value << 8);
254 static inline unsigned long SWAW32(unsigned long value)
256 result[31..16] = value[15.. 0];
257 result[15.. 0] = value[31..16];
260 asm ("swap %%0" : "+r"(value));
261 return value;
264 static inline unsigned long swap32(unsigned long value)
266 result[31..24] = value[ 7.. 0];
267 result[23..16] = value[15.. 8];
268 result[15.. 8] = value[23..16];
269 result[ 7.. 0] = value[31..24];
272 unsigned long mask = 0x00FF00FF;
273 asm ( /* val = ABCD */
274 "and.l %[val],%[mask] \n" /* mask = .B.D */
275 "eor.l %[mask],%[val] \n" /* val = A.C. */
276 "lsl.l #8,%[mask] \n" /* mask = B.D. */
277 "lsr.l #8,%[val] \n" /* val = .A.C */
278 "or.l %[mask],%[val] \n" /* val = BADC */
279 "swap %[val] \n" /* val = DCBA */
280 : /* outputs */
281 [val] "+d"(value),
282 [mask]"+d"(mask)
284 return value;
287 static inline void invalidate_icache(void)
289 asm volatile ("move.l #0x01000000,%d0\n"
290 "movec.l %d0,%cacr\n"
291 "move.l #0x80000000,%d0\n"
292 "movec.l %d0,%cacr");
295 #define CPUFREQ_DEFAULT_MULT 1
296 #define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ)
297 #define CPUFREQ_NORMAL_MULT 4
298 #define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ)
299 #define CPUFREQ_MAX_MULT 11
300 #define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ)
302 #elif defined(CPU_ARM)
304 /* TODO: Implement set_irq_level and check CPU frequencies */
306 #define CPUFREQ_DEFAULT CPU_FREQ
307 #define CPUFREQ_NORMAL 37500000
308 #define CPUFREQ_MAX 75000000
310 static inline unsigned short swap16(unsigned short value)
312 result[15..8] = value[ 7..0];
313 result[ 7..0] = value[15..8];
316 return (value >> 8) | (value << 8);
319 static inline unsigned long swap32(unsigned long value)
321 result[31..24] = value[ 7.. 0];
322 result[23..16] = value[15.. 8];
323 result[15.. 8] = value[23..16];
324 result[ 7.. 0] = value[31..24];
327 unsigned long hi = swap16(value >> 16);
328 unsigned long lo = swap16(value & 0xffff);
329 return (lo << 16) | hi;
332 #define HIGHEST_IRQ_LEVEL (1)
334 static inline int set_irq_level(int level)
336 unsigned long cpsr;
337 /* Read the old level and set the new one */
338 asm volatile ("mrs %0,cpsr" : "=r" (cpsr));
339 asm volatile ("msr cpsr_c,%0"
340 : : "r" ((cpsr & ~0x80) | (level << 7)));
341 return (cpsr >> 7) & 1;
344 static inline void enable_fiq(void)
346 /* enable FIQ */
347 asm volatile (
348 "mrs r0, cpsr \n"\
349 "bic r0, r0, #0x40 \n"\
350 "msr cpsr_c, r0 "
351 : : : "r0"
355 #define invalidate_icache()
357 #if CONFIG_CPU == PNX0101
358 typedef void (*interrupt_handler_t)(void);
360 void irq_set_int_handler(int n, interrupt_handler_t handler);
361 void irq_enable_int(int n);
362 #endif
364 #elif CONFIG_CPU == TCC730
366 extern int smsc_version(void);
368 extern void smsc_delay(void);
370 extern void set_pll_freq(int pll_index, long freq_out);
373 extern void* volatile interrupt_vector[16] __attribute__ ((section(".idata")));
375 extern void ddma_transfer(int dir, int mem, void* intAddr, long extAddr,
376 int num);
379 #define HIGHEST_IRQ_LEVEL (1)
380 static inline int set_irq_level(int level)
382 int result;
383 __asm__ ("ld %0, 0\n\t"
384 "tstsr ie\n\t"
385 "incc %0" : "=r"(result));
386 if (level > 0)
387 __asm__ volatile ("clrsr ie");
388 else
389 __asm__ volatile ("setsr ie");
391 return result;
394 static inline unsigned short swap16(unsigned short value)
396 result[15..8] = value[ 7..0];
397 result[ 7..0] = value[15..8];
400 return (value >> 8) | (value << 8);
403 static inline unsigned long swap32(unsigned long value)
405 result[31..24] = value[ 7.. 0];
406 result[23..16] = value[15.. 8];
407 result[15.. 8] = value[23..16];
408 result[ 7.. 0] = value[31..24];
411 unsigned long hi = swap16(value >> 16);
412 unsigned long lo = swap16(value & 0xffff);
413 return (lo << 16) | hi;
416 /* Archos uses:
418 22MHz: busy wait on dma
419 32MHz: normal
420 80Mhz: heavy load
424 #define CPUFREQ_DEFAULT CPU_FREQ
425 #define CPUFREQ_NORMAL (32000000)
426 #define CPUFREQ_MAX (80000000)
428 #define invalidate_icache()
430 #endif
431 #else
433 static inline unsigned short swap16(unsigned short value)
435 result[15..8] = value[ 7..0];
436 result[ 7..0] = value[15..8];
439 return (value >> 8) | (value << 8);
442 static inline unsigned long swap32(unsigned long value)
444 result[31..24] = value[ 7.. 0];
445 result[23..16] = value[15.. 8];
446 result[15.. 8] = value[23..16];
447 result[ 7.. 0] = value[31..24];
450 unsigned long hi = swap16(value >> 16);
451 unsigned long lo = swap16(value & 0xffff);
452 return (lo << 16) | hi;
456 #define invalidate_icache()
458 #endif
460 #endif