Do core interrupt masking in a less general fashion and save some instructions to...
[kugel-rb.git] / firmware / target / coldfire / system-target.h
blob14b3207c0c4f18962d324850871cfb412185035b
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 ****************************************************************************/
19 #ifndef SYSTEM_TARGET_H
20 #define SYSTEM_TARGET_H
22 #define nop \
23 asm volatile ("trapf")
25 #define or_l(mask, address) \
26 asm \
27 ("or.l %0,(%1)" \
28 : \
29 : /* %0 */ "d"(mask), \
30 /* %1 */ "a"(address))
32 #define and_l(mask, address) \
33 asm \
34 ("and.l %0,(%1)" \
35 : \
36 : /* %0 */ "d"(mask), \
37 /* %1 */ "a"(address))
39 #define eor_l(mask, address) \
40 asm \
41 ("eor.l %0,(%1)" \
42 : \
43 : /* %0 */ "d"(mask), \
44 /* %1 */ "a"(address))
46 #define add_l(addend, address) \
47 asm \
48 ("add.l %0, (%1)" \
49 : \
50 : /* %0 */ "r"(addend), \
51 /* %1 */ "a"(address))
53 #define EMAC_ROUND 0x10
54 #define EMAC_FRACTIONAL 0x20
55 #define EMAC_SATURATE 0x80
57 static inline void coldfire_set_macsr(unsigned long flags)
59 asm volatile ("move.l %0, %%macsr" : : "i,r" (flags));
62 static inline unsigned long coldfire_get_macsr(void)
64 unsigned long m;
66 asm volatile ("move.l %%macsr, %0" : "=r" (m));
67 return m;
70 /* ColdFire IRQ Levels/Priorities in Rockbox summary:
71 * DMA0 - level 6, priority 0 (playback)
72 * DMA1 - level 6, priority 1 (recording)
73 * TIMER1 - level 4, priority 0 (timers)
74 * TIMER0 - level 3, priority 0 (ticks)
75 * GPI0 - level 3, priority 0 (pcf50606 PMU, secondary controller)
77 #define HIGHEST_IRQ_LEVEL (5<<8) /* Disable all but DMA and higher */
78 #define DMA_IRQ_LEVEL (6<<8) /* Disable DMA and lower */
79 #define DISABLE_INTERRUPTS (7<<8) /* Disable all but NMIs */
80 static inline int set_irq_level(int level)
82 int oldlevel;
83 /* Read the old level and set the new one */
85 /* Not volatile - can be removed if oldlevel isn't used */
86 asm ("move.w %%sr, %0" : "=d"(oldlevel));
87 /* Keep supervisor state set */
88 asm volatile ("move.w %0, %%sr \n" : : "d"(level | 0x2000));
89 return oldlevel;
92 /* Enable all interrupts */
93 static inline void enable_irq(void)
95 int tmp;
96 /* Using move.w over the compiler's move.l saves 2 bytes per instance */
97 asm volatile ("move.w %1, %0 \n"
98 "move.w %0, %%sr \n"
99 : "=&d"(tmp) : "i"(0x2000));
102 /* Disable interrupts up to HIGHEST_IRQ_LEVEL */
103 static inline void disable_irq(void)
105 int tmp;
106 /* Using move.w over the compiler's move.l saves 2 bytes per instance */
107 asm volatile ("move.w %1, %0 \n"
108 "move.w %0, %%sr \n"
109 : "=&d"(tmp)
110 : "i"(0x2000 | HIGHEST_IRQ_LEVEL));
113 static inline int disable_irq_save(void)
115 int oldlevel, tmp;
116 /* Using move.w over the compiler's move.l saves 2 bytes per instance */
117 asm volatile ("move.w %%sr, %1 \n"
118 "move.w %2, %0 \n"
119 "move.w %0, %%sr \n"
120 : "=&d"(tmp), "=d"(oldlevel)
121 : "i"(0x2000 | HIGHEST_IRQ_LEVEL));
122 return oldlevel;
125 static inline void restore_irq(int oldlevel)
127 /* Restore the sr value returned by disable_irq_save or
128 * set_irq_level */
129 asm volatile ("move.w %0, %%sr" : : "d"(oldlevel));
132 static inline uint16_t swap16(uint16_t value)
134 result[15..8] = value[ 7..0];
135 result[ 7..0] = value[15..8];
138 return (value >> 8) | (value << 8);
141 static inline uint32_t SWAW32(uint32_t value)
143 result[31..16] = value[15.. 0];
144 result[15.. 0] = value[31..16];
147 asm ("swap %%0" : "+r"(value));
148 return value;
151 static inline uint32_t swap32(uint32_t value)
153 result[31..24] = value[ 7.. 0];
154 result[23..16] = value[15.. 8];
155 result[15.. 8] = value[23..16];
156 result[ 7.. 0] = value[31..24];
159 uint32_t mask = 0x00FF00FF;
160 asm ( /* val = ABCD */
161 "and.l %[val],%[mask] \n" /* mask = .B.D */
162 "eor.l %[mask],%[val] \n" /* val = A.C. */
163 "lsl.l #8,%[mask] \n" /* mask = B.D. */
164 "lsr.l #8,%[val] \n" /* val = .A.C */
165 "or.l %[mask],%[val] \n" /* val = BADC */
166 "swap %[val] \n" /* val = DCBA */
167 : /* outputs */
168 [val] "+d"(value),
169 [mask]"+d"(mask)
171 return value;
174 static inline uint32_t swap_odd_even32(uint32_t value)
177 result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
178 result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
180 uint32_t mask = 0x00FF00FF;
181 asm ( /* val = ABCD */
182 "and.l %[val],%[mask] \n" /* mask = .B.D */
183 "eor.l %[mask],%[val] \n" /* val = A.C. */
184 "lsl.l #8,%[mask] \n" /* mask = B.D. */
185 "lsr.l #8,%[val] \n" /* val = .A.C */
186 "or.l %[mask],%[val] \n" /* val = BADC */
187 : /* outputs */
188 [val] "+d"(value),
189 [mask]"+d"(mask)
191 return value;
194 #define HAVE_INVALIDATE_ICACHE
195 static inline void invalidate_icache(void)
197 asm volatile ("move.l #0x01000000,%d0\n"
198 "movec.l %d0,%cacr\n"
199 "move.l #0x80000000,%d0\n"
200 "movec.l %d0,%cacr");
203 #define DEFAULT_PLLCR_AUDIO_BITS 0x10400000
204 void coldfire_set_pllcr_audio_bits(long bits);
206 /* Set DATAINCONTROL without disturbing FIFO reset state */
207 void coldfire_set_dataincontrol(unsigned long value);
209 #ifndef HAVE_ADJUSTABLE_CPU_FREQ
210 extern void cf_set_cpu_frequency(long frequency);
211 #endif
213 /* 11.2896 MHz */
214 #define CPUFREQ_DEFAULT_MULT 1
215 #define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ)
216 /* 45.1584 MHz */
217 #define CPUFREQ_NORMAL_MULT 4
218 #define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ)
219 /* 124.1856 MHz */
220 #define CPUFREQ_MAX_MULT 11
221 #define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ)
223 #endif /* SYSTEM_TARGET_H */