Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
| 10 | * Copyright (C) 2002 by Alan Korr |
| 11 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 12 | * 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 Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 16 | * |
| 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 Sevakis | d95c390 | 2007-04-13 20:55:48 +0000 | [diff] [blame] | 24 | #define nop \ |
| 25 | asm volatile ("trapf") |
| 26 | |
Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 27 | #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 Sevakis | 6689cb0 | 2007-04-10 14:18:30 +0000 | [diff] [blame] | 48 | #define add_l(addend, address) \ |
| 49 | asm \ |
| 50 | ("add.l %0, (%1)" \ |
| 51 | : \ |
| 52 | : /* %0 */ "r"(addend), \ |
| 53 | /* %1 */ "a"(address)) |
| 54 | |
Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 55 | #define EMAC_ROUND 0x10 |
| 56 | #define EMAC_FRACTIONAL 0x20 |
| 57 | #define EMAC_SATURATE 0x80 |
| 58 | |
| 59 | static inline void coldfire_set_macsr(unsigned long flags) |
| 60 | { |
| 61 | asm volatile ("move.l %0, %%macsr" : : "i,r" (flags)); |
| 62 | } |
| 63 | |
| 64 | static 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 Sevakis | 633f388 | 2007-03-07 06:23:02 +0000 | [diff] [blame] | 72 | /* 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 Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 82 | static inline int set_irq_level(int level) |
| 83 | { |
| 84 | int oldlevel; |
| 85 | /* Read the old level and set the new one */ |
Michael Sevakis | af395f4 | 2008-03-26 01:50:41 +0000 | [diff] [blame] | 86 | |
| 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 Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 91 | return oldlevel; |
| 92 | } |
| 93 | |
Michael Sevakis | af395f4 | 2008-03-26 01:50:41 +0000 | [diff] [blame] | 94 | /* Enable all interrupts */ |
| 95 | static 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 */ |
| 105 | static 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 | |
| 115 | static 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 | |
| 127 | static 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 Sevakis | e754b16 | 2007-03-29 05:30:25 +0000 | [diff] [blame] | 134 | static inline uint16_t swap16(uint16_t value) |
Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 135 | /* |
| 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 Sevakis | d767064 | 2007-03-29 05:53:46 +0000 | [diff] [blame] | 143 | static inline uint32_t SWAW32(uint32_t value) |
Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 144 | /* |
| 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 Sevakis | e754b16 | 2007-03-29 05:30:25 +0000 | [diff] [blame] | 153 | static inline uint32_t swap32(uint32_t value) |
Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 154 | /* |
| 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 Sevakis | e754b16 | 2007-03-29 05:30:25 +0000 | [diff] [blame] | 161 | uint32_t mask = 0x00FF00FF; |
Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 162 | 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 Sevakis | e754b16 | 2007-03-29 05:30:25 +0000 | [diff] [blame] | 176 | static inline uint32_t swap_odd_even32(uint32_t value) |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 177 | { |
| 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 Sevakis | ee6bb1b | 2007-03-29 19:22:11 +0000 | [diff] [blame] | 182 | uint32_t mask = 0x00FF00FF; |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 183 | 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 Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 193 | return value; |
| 194 | } |
| 195 | |
Michael Sevakis | d95c390 | 2007-04-13 20:55:48 +0000 | [diff] [blame] | 196 | #define HAVE_INVALIDATE_ICACHE |
Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 197 | static inline void invalidate_icache(void) |
| 198 | { |
| 199 | asm volatile ("move.l #0x01000000,%d0\n" |
| 200 | "movec.l %d0,%cacr\n" |
Jens Arnold | 3674af6 | 2007-10-17 20:45:13 +0000 | [diff] [blame] | 201 | "move.l #0x80000000,%d0\n" |
Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 202 | "movec.l %d0,%cacr"); |
| 203 | } |
| 204 | |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 205 | #define DEFAULT_PLLCR_AUDIO_BITS 0x10400000 |
Michael Sevakis | 0f5cb94 | 2006-11-06 18:07:30 +0000 | [diff] [blame] | 206 | void coldfire_set_pllcr_audio_bits(long bits); |
| 207 | |
Michael Sevakis | 8867d00 | 2007-03-05 08:14:27 +0000 | [diff] [blame] | 208 | /* Set DATAINCONTROL without disturbing FIFO reset state */ |
| 209 | void coldfire_set_dataincontrol(unsigned long value); |
| 210 | |
Steve Bavin | c90c18e | 2007-10-02 07:54:50 +0000 | [diff] [blame] | 211 | #ifndef HAVE_ADJUSTABLE_CPU_FREQ |
| 212 | extern void cf_set_cpu_frequency(long frequency); |
| 213 | #endif |
| 214 | |
Michael Sevakis | f29cae0 | 2006-10-30 14:17:14 +0000 | [diff] [blame] | 215 | /* 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 */ |