2006-10-30 14:17:14 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright (C) 2002 by Alan Korr
|
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2006-10-30 14:17:14 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
#ifndef SYSTEM_TARGET_H
|
|
|
|
#define SYSTEM_TARGET_H
|
|
|
|
|
2007-04-13 20:55:48 +00:00
|
|
|
#define nop \
|
|
|
|
asm volatile ("trapf")
|
|
|
|
|
2006-10-30 14:17:14 +00:00
|
|
|
#define or_l(mask, address) \
|
|
|
|
asm \
|
|
|
|
("or.l %0,(%1)" \
|
|
|
|
: \
|
|
|
|
: /* %0 */ "d"(mask), \
|
|
|
|
/* %1 */ "a"(address))
|
|
|
|
|
|
|
|
#define and_l(mask, address) \
|
|
|
|
asm \
|
|
|
|
("and.l %0,(%1)" \
|
|
|
|
: \
|
|
|
|
: /* %0 */ "d"(mask), \
|
|
|
|
/* %1 */ "a"(address))
|
|
|
|
|
|
|
|
#define eor_l(mask, address) \
|
|
|
|
asm \
|
|
|
|
("eor.l %0,(%1)" \
|
|
|
|
: \
|
|
|
|
: /* %0 */ "d"(mask), \
|
|
|
|
/* %1 */ "a"(address))
|
|
|
|
|
2007-04-10 14:18:30 +00:00
|
|
|
#define add_l(addend, address) \
|
|
|
|
asm \
|
|
|
|
("add.l %0, (%1)" \
|
|
|
|
: \
|
|
|
|
: /* %0 */ "r"(addend), \
|
|
|
|
/* %1 */ "a"(address))
|
|
|
|
|
2006-10-30 14:17:14 +00:00
|
|
|
#define EMAC_ROUND 0x10
|
|
|
|
#define EMAC_FRACTIONAL 0x20
|
2009-01-25 15:59:43 +00:00
|
|
|
#define EMAC_UNSIGNED 0x40
|
2006-10-30 14:17:14 +00:00
|
|
|
#define EMAC_SATURATE 0x80
|
|
|
|
|
|
|
|
static inline void coldfire_set_macsr(unsigned long flags)
|
|
|
|
{
|
|
|
|
asm volatile ("move.l %0, %%macsr" : : "i,r" (flags));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned long coldfire_get_macsr(void)
|
|
|
|
{
|
|
|
|
unsigned long m;
|
|
|
|
|
|
|
|
asm volatile ("move.l %%macsr, %0" : "=r" (m));
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2007-03-07 06:23:02 +00:00
|
|
|
/* ColdFire IRQ Levels/Priorities in Rockbox summary:
|
|
|
|
* DMA0 - level 6, priority 0 (playback)
|
|
|
|
* DMA1 - level 6, priority 1 (recording)
|
|
|
|
* TIMER1 - level 4, priority 0 (timers)
|
|
|
|
* TIMER0 - level 3, priority 0 (ticks)
|
|
|
|
* GPI0 - level 3, priority 0 (pcf50606 PMU, secondary controller)
|
|
|
|
*/
|
|
|
|
#define HIGHEST_IRQ_LEVEL (5<<8) /* Disable all but DMA and higher */
|
|
|
|
#define DMA_IRQ_LEVEL (6<<8) /* Disable DMA and lower */
|
|
|
|
#define DISABLE_INTERRUPTS (7<<8) /* Disable all but NMIs */
|
2006-10-30 14:17:14 +00:00
|
|
|
static inline int set_irq_level(int level)
|
|
|
|
{
|
|
|
|
int oldlevel;
|
|
|
|
/* Read the old level and set the new one */
|
2008-03-26 01:50:41 +00:00
|
|
|
|
|
|
|
/* Not volatile - can be removed if oldlevel isn't used */
|
|
|
|
asm ("move.w %%sr, %0" : "=d"(oldlevel));
|
|
|
|
/* Keep supervisor state set */
|
|
|
|
asm volatile ("move.w %0, %%sr \n" : : "d"(level | 0x2000));
|
|
|
|
return oldlevel;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Enable all interrupts */
|
|
|
|
static inline void enable_irq(void)
|
|
|
|
{
|
|
|
|
int tmp;
|
|
|
|
/* Using move.w over the compiler's move.l saves 2 bytes per instance */
|
|
|
|
asm volatile ("move.w %1, %0 \n"
|
|
|
|
"move.w %0, %%sr \n"
|
|
|
|
: "=&d"(tmp) : "i"(0x2000));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Disable interrupts up to HIGHEST_IRQ_LEVEL */
|
|
|
|
static inline void disable_irq(void)
|
|
|
|
{
|
|
|
|
int tmp;
|
|
|
|
/* Using move.w over the compiler's move.l saves 2 bytes per instance */
|
|
|
|
asm volatile ("move.w %1, %0 \n"
|
|
|
|
"move.w %0, %%sr \n"
|
|
|
|
: "=&d"(tmp)
|
|
|
|
: "i"(0x2000 | HIGHEST_IRQ_LEVEL));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int disable_irq_save(void)
|
|
|
|
{
|
|
|
|
int oldlevel, tmp;
|
|
|
|
/* Using move.w over the compiler's move.l saves 2 bytes per instance */
|
|
|
|
asm volatile ("move.w %%sr, %1 \n"
|
|
|
|
"move.w %2, %0 \n"
|
|
|
|
"move.w %0, %%sr \n"
|
|
|
|
: "=&d"(tmp), "=d"(oldlevel)
|
|
|
|
: "i"(0x2000 | HIGHEST_IRQ_LEVEL));
|
2006-10-30 14:17:14 +00:00
|
|
|
return oldlevel;
|
|
|
|
}
|
|
|
|
|
2008-03-26 01:50:41 +00:00
|
|
|
static inline void restore_irq(int oldlevel)
|
|
|
|
{
|
|
|
|
/* Restore the sr value returned by disable_irq_save or
|
|
|
|
* set_irq_level */
|
|
|
|
asm volatile ("move.w %0, %%sr" : : "d"(oldlevel));
|
|
|
|
}
|
|
|
|
|
2007-03-29 05:30:25 +00:00
|
|
|
static inline uint16_t swap16(uint16_t value)
|
2006-10-30 14:17:14 +00:00
|
|
|
/*
|
|
|
|
result[15..8] = value[ 7..0];
|
|
|
|
result[ 7..0] = value[15..8];
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
return (value >> 8) | (value << 8);
|
|
|
|
}
|
|
|
|
|
2007-03-29 05:53:46 +00:00
|
|
|
static inline uint32_t SWAW32(uint32_t value)
|
2006-10-30 14:17:14 +00:00
|
|
|
/*
|
|
|
|
result[31..16] = value[15.. 0];
|
|
|
|
result[15.. 0] = value[31..16];
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
asm ("swap %%0" : "+r"(value));
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2007-03-29 05:30:25 +00:00
|
|
|
static inline uint32_t swap32(uint32_t value)
|
2006-10-30 14:17:14 +00:00
|
|
|
/*
|
|
|
|
result[31..24] = value[ 7.. 0];
|
|
|
|
result[23..16] = value[15.. 8];
|
|
|
|
result[15.. 8] = value[23..16];
|
|
|
|
result[ 7.. 0] = value[31..24];
|
|
|
|
*/
|
|
|
|
{
|
2007-03-29 05:30:25 +00:00
|
|
|
uint32_t mask = 0x00FF00FF;
|
2006-10-30 14:17:14 +00:00
|
|
|
asm ( /* val = ABCD */
|
|
|
|
"and.l %[val],%[mask] \n" /* mask = .B.D */
|
|
|
|
"eor.l %[mask],%[val] \n" /* val = A.C. */
|
|
|
|
"lsl.l #8,%[mask] \n" /* mask = B.D. */
|
|
|
|
"lsr.l #8,%[val] \n" /* val = .A.C */
|
|
|
|
"or.l %[mask],%[val] \n" /* val = BADC */
|
|
|
|
"swap %[val] \n" /* val = DCBA */
|
|
|
|
: /* outputs */
|
|
|
|
[val] "+d"(value),
|
|
|
|
[mask]"+d"(mask)
|
|
|
|
);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2007-03-29 05:30:25 +00:00
|
|
|
static inline uint32_t swap_odd_even32(uint32_t value)
|
2006-11-06 18:07:30 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
|
|
|
|
result[23..16],[ 7.. 0] = value[31..24],[15.. 8]
|
|
|
|
*/
|
2007-03-29 19:22:11 +00:00
|
|
|
uint32_t mask = 0x00FF00FF;
|
2006-11-06 18:07:30 +00:00
|
|
|
asm ( /* val = ABCD */
|
|
|
|
"and.l %[val],%[mask] \n" /* mask = .B.D */
|
|
|
|
"eor.l %[mask],%[val] \n" /* val = A.C. */
|
|
|
|
"lsl.l #8,%[mask] \n" /* mask = B.D. */
|
|
|
|
"lsr.l #8,%[val] \n" /* val = .A.C */
|
|
|
|
"or.l %[mask],%[val] \n" /* val = BADC */
|
|
|
|
: /* outputs */
|
|
|
|
[val] "+d"(value),
|
|
|
|
[mask]"+d"(mask)
|
|
|
|
);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2009-02-11 12:55:51 +00:00
|
|
|
#define HAVE_CPUCACHE_INVALIDATE
|
2006-10-30 14:17:14 +00:00
|
|
|
|
2006-11-06 18:07:30 +00:00
|
|
|
#define DEFAULT_PLLCR_AUDIO_BITS 0x10400000
|
|
|
|
void coldfire_set_pllcr_audio_bits(long bits);
|
|
|
|
|
2007-03-05 08:14:27 +00:00
|
|
|
/* Set DATAINCONTROL without disturbing FIFO reset state */
|
|
|
|
void coldfire_set_dataincontrol(unsigned long value);
|
|
|
|
|
2007-10-02 07:54:50 +00:00
|
|
|
#ifndef HAVE_ADJUSTABLE_CPU_FREQ
|
|
|
|
extern void cf_set_cpu_frequency(long frequency);
|
|
|
|
#endif
|
|
|
|
|
2006-10-30 14:17:14 +00:00
|
|
|
/* 11.2896 MHz */
|
|
|
|
#define CPUFREQ_DEFAULT_MULT 1
|
|
|
|
#define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ)
|
2009-01-13 14:56:20 +00:00
|
|
|
/* 45.1584 MHz */
|
|
|
|
#define CPUFREQ_NORMAL_MULT 4
|
2006-10-30 14:17:14 +00:00
|
|
|
#define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ)
|
2009-01-13 14:56:20 +00:00
|
|
|
/* 124.1856 MHz */
|
|
|
|
#define CPUFREQ_MAX_MULT 11
|
2006-10-30 14:17:14 +00:00
|
|
|
#define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ)
|
|
|
|
|
|
|
|
#endif /* SYSTEM_TARGET_H */
|