blob: 84ec6ed4b0eb5d8cba281f9baa0ac0579b8ddc66 [file] [log] [blame]
Michael Sevakisf29cae02006-10-30 14:17:14 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Michael Sevakisf29cae02006-10-30 14:17:14 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef SYSTEM_TARGET_H
22#define SYSTEM_TARGET_H
23
Michael Sevakisd95c3902007-04-13 20:55:48 +000024#define nop \
25 asm volatile ("trapf")
26
Michael Sevakisf29cae02006-10-30 14:17:14 +000027#define or_l(mask, address) \
28 asm \
29 ("or.l %0,(%1)" \
30 : \
31 : /* %0 */ "d"(mask), \
32 /* %1 */ "a"(address))
33
34#define and_l(mask, address) \
35 asm \
36 ("and.l %0,(%1)" \
37 : \
38 : /* %0 */ "d"(mask), \
39 /* %1 */ "a"(address))
40
41#define eor_l(mask, address) \
42 asm \
43 ("eor.l %0,(%1)" \
44 : \
45 : /* %0 */ "d"(mask), \
46 /* %1 */ "a"(address))
47
Michael Sevakis6689cb02007-04-10 14:18:30 +000048#define add_l(addend, address) \
49 asm \
50 ("add.l %0, (%1)" \
51 : \
52 : /* %0 */ "r"(addend), \
53 /* %1 */ "a"(address))
54
Michael Sevakisf29cae02006-10-30 14:17:14 +000055#define EMAC_ROUND 0x10
56#define EMAC_FRACTIONAL 0x20
57#define EMAC_SATURATE 0x80
58
59static inline void coldfire_set_macsr(unsigned long flags)
60{
61 asm volatile ("move.l %0, %%macsr" : : "i,r" (flags));
62}
63
64static inline unsigned long coldfire_get_macsr(void)
65{
66 unsigned long m;
67
68 asm volatile ("move.l %%macsr, %0" : "=r" (m));
69 return m;
70}
71
Michael Sevakis633f3882007-03-07 06:23:02 +000072/* ColdFire IRQ Levels/Priorities in Rockbox summary:
73 * DMA0 - level 6, priority 0 (playback)
74 * DMA1 - level 6, priority 1 (recording)
75 * TIMER1 - level 4, priority 0 (timers)
76 * TIMER0 - level 3, priority 0 (ticks)
77 * GPI0 - level 3, priority 0 (pcf50606 PMU, secondary controller)
78 */
79#define HIGHEST_IRQ_LEVEL (5<<8) /* Disable all but DMA and higher */
80#define DMA_IRQ_LEVEL (6<<8) /* Disable DMA and lower */
81#define DISABLE_INTERRUPTS (7<<8) /* Disable all but NMIs */
Michael Sevakisf29cae02006-10-30 14:17:14 +000082static inline int set_irq_level(int level)
83{
84 int oldlevel;
85 /* Read the old level and set the new one */
Michael Sevakisaf395f42008-03-26 01:50:41 +000086
87 /* Not volatile - can be removed if oldlevel isn't used */
88 asm ("move.w %%sr, %0" : "=d"(oldlevel));
89 /* Keep supervisor state set */
90 asm volatile ("move.w %0, %%sr \n" : : "d"(level | 0x2000));
Michael Sevakisf29cae02006-10-30 14:17:14 +000091 return oldlevel;
92}
93
Michael Sevakisaf395f42008-03-26 01:50:41 +000094/* Enable all interrupts */
95static inline void enable_irq(void)
96{
97 int tmp;
98 /* Using move.w over the compiler's move.l saves 2 bytes per instance */
99 asm volatile ("move.w %1, %0 \n"
100 "move.w %0, %%sr \n"
101 : "=&d"(tmp) : "i"(0x2000));
102}
103
104/* Disable interrupts up to HIGHEST_IRQ_LEVEL */
105static inline void disable_irq(void)
106{
107 int tmp;
108 /* Using move.w over the compiler's move.l saves 2 bytes per instance */
109 asm volatile ("move.w %1, %0 \n"
110 "move.w %0, %%sr \n"
111 : "=&d"(tmp)
112 : "i"(0x2000 | HIGHEST_IRQ_LEVEL));
113}
114
115static inline int disable_irq_save(void)
116{
117 int oldlevel, tmp;
118 /* Using move.w over the compiler's move.l saves 2 bytes per instance */
119 asm volatile ("move.w %%sr, %1 \n"
120 "move.w %2, %0 \n"
121 "move.w %0, %%sr \n"
122 : "=&d"(tmp), "=d"(oldlevel)
123 : "i"(0x2000 | HIGHEST_IRQ_LEVEL));
124 return oldlevel;
125}
126
127static inline void restore_irq(int oldlevel)
128{
129 /* Restore the sr value returned by disable_irq_save or
130 * set_irq_level */
131 asm volatile ("move.w %0, %%sr" : : "d"(oldlevel));
132}
133
Michael Sevakise754b162007-03-29 05:30:25 +0000134static inline uint16_t swap16(uint16_t value)
Michael Sevakisf29cae02006-10-30 14:17:14 +0000135 /*
136 result[15..8] = value[ 7..0];
137 result[ 7..0] = value[15..8];
138 */
139{
140 return (value >> 8) | (value << 8);
141}
142
Michael Sevakisd7670642007-03-29 05:53:46 +0000143static inline uint32_t SWAW32(uint32_t value)
Michael Sevakisf29cae02006-10-30 14:17:14 +0000144 /*
145 result[31..16] = value[15.. 0];
146 result[15.. 0] = value[31..16];
147 */
148{
149 asm ("swap %%0" : "+r"(value));
150 return value;
151}
152
Michael Sevakise754b162007-03-29 05:30:25 +0000153static inline uint32_t swap32(uint32_t value)
Michael Sevakisf29cae02006-10-30 14:17:14 +0000154 /*
155 result[31..24] = value[ 7.. 0];
156 result[23..16] = value[15.. 8];
157 result[15.. 8] = value[23..16];
158 result[ 7.. 0] = value[31..24];
159 */
160{
Michael Sevakise754b162007-03-29 05:30:25 +0000161 uint32_t mask = 0x00FF00FF;
Michael Sevakisf29cae02006-10-30 14:17:14 +0000162 asm ( /* val = ABCD */
163 "and.l %[val],%[mask] \n" /* mask = .B.D */
164 "eor.l %[mask],%[val] \n" /* val = A.C. */
165 "lsl.l #8,%[mask] \n" /* mask = B.D. */
166 "lsr.l #8,%[val] \n" /* val = .A.C */
167 "or.l %[mask],%[val] \n" /* val = BADC */
168 "swap %[val] \n" /* val = DCBA */
169 : /* outputs */
170 [val] "+d"(value),
171 [mask]"+d"(mask)
172 );
173 return value;
174}
175
Michael Sevakise754b162007-03-29 05:30:25 +0000176static inline uint32_t swap_odd_even32(uint32_t value)
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000177{
178 /*
179 result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
180 result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
181 */
Michael Sevakisee6bb1b2007-03-29 19:22:11 +0000182 uint32_t mask = 0x00FF00FF;
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000183 asm ( /* val = ABCD */
184 "and.l %[val],%[mask] \n" /* mask = .B.D */
185 "eor.l %[mask],%[val] \n" /* val = A.C. */
186 "lsl.l #8,%[mask] \n" /* mask = B.D. */
187 "lsr.l #8,%[val] \n" /* val = .A.C */
188 "or.l %[mask],%[val] \n" /* val = BADC */
189 : /* outputs */
190 [val] "+d"(value),
191 [mask]"+d"(mask)
192 );
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000193 return value;
194}
195
Michael Sevakisd95c3902007-04-13 20:55:48 +0000196#define HAVE_INVALIDATE_ICACHE
Michael Sevakisf29cae02006-10-30 14:17:14 +0000197static inline void invalidate_icache(void)
198{
199 asm volatile ("move.l #0x01000000,%d0\n"
200 "movec.l %d0,%cacr\n"
Jens Arnold3674af62007-10-17 20:45:13 +0000201 "move.l #0x80000000,%d0\n"
Michael Sevakisf29cae02006-10-30 14:17:14 +0000202 "movec.l %d0,%cacr");
203}
204
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000205#define DEFAULT_PLLCR_AUDIO_BITS 0x10400000
Michael Sevakis0f5cb942006-11-06 18:07:30 +0000206void coldfire_set_pllcr_audio_bits(long bits);
207
Michael Sevakis8867d002007-03-05 08:14:27 +0000208/* Set DATAINCONTROL without disturbing FIFO reset state */
209void coldfire_set_dataincontrol(unsigned long value);
210
Steve Bavinc90c18e2007-10-02 07:54:50 +0000211#ifndef HAVE_ADJUSTABLE_CPU_FREQ
212extern void cf_set_cpu_frequency(long frequency);
213#endif
214
Michael Sevakisf29cae02006-10-30 14:17:14 +0000215/* 11.2896 MHz */
216#define CPUFREQ_DEFAULT_MULT 1
217#define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ)
218/* 45.1584 MHz */
219#define CPUFREQ_NORMAL_MULT 4
220#define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ)
221/* 124.1856 MHz */
222#define CPUFREQ_MAX_MULT 11
223#define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ)
224
225#endif /* SYSTEM_TARGET_H */