Improved CPU clock setup for PP502x. PP5020 and PP5022 are not register compatible here, so define the PP5022 targets properly, and introduce a CPU_PP502x macro for easier family check. Improves stability on PP5020 (less freezing, tested with Mini G1) and reduces clock change penalty (500us on PP5020; uses the relock bit on PP5022).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13763 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2007-07-02 05:16:40 +00:00
parent 36de1a4d08
commit fe23dc8f15
14 changed files with 100 additions and 68 deletions

View file

@ -405,6 +405,34 @@ static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
#endif /* (CONFIG_CPU == SH7034 || CPU_COLDFIRE) */
#ifndef SIMULATOR
#ifdef CPU_PP502x
static int perfcheck(void)
{
int result;
int old_level = set_irq_level(HIGHEST_IRQ_LEVEL);
asm (
"mov %[res], #0 \n"
"ldr r0, [%[timr]] \n"
"add r0, r0, %[tmo] \n"
"1: \n"
"add %[res], %[res], #1 \n"
"ldr r1, [%[timr]] \n"
"cmp r1, r0 \n"
"bmi 1b \n"
:
[res]"=&r"(result)
:
[timr]"r"(&USEC_TIMER),
[tmo]"r"(10226)
:
"r0", "r1"
);
set_irq_level(old_level);
return result;
}
#endif
#ifdef HAVE_LCD_BITMAP
static bool dbg_hw_info(void)
{
@ -535,7 +563,7 @@ static bool dbg_hw_info(void)
if (action_userabort(TIMEOUT_BLOCK))
return false;
}
#elif CONFIG_CPU == PP5020
#elif defined(CPU_PP502x)
char buf[32];
char pp_version[] = { (PP_VER2 >> 24) & 0xff, (PP_VER2 >> 16) & 0xff,
(PP_VER2 >> 8) & 0xff, (PP_VER2) & 0xff,
@ -553,6 +581,10 @@ static bool dbg_hw_info(void)
snprintf(buf, sizeof(buf), "PP version: %s", pp_version);
lcd_puts(0, 2, buf);
snprintf(buf, sizeof(buf), "Est. clock (kHz): %d", perfcheck());
lcd_puts(0, 3, buf);
lcd_update();
while(1)
@ -1020,7 +1052,7 @@ bool dbg_ports(void)
return false;
}
#elif CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#elif defined(CPU_PP502x)
unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
@ -1066,6 +1098,17 @@ bool dbg_ports(void)
lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "GPIO_F: %02x GPIO_L: %02x", gpio_f, gpio_l);
lcd_puts(0, line++, buf);
line++;
snprintf(buf, sizeof(buf), "CLOCK_SRC: %08lx", inl(0x60006020));
lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "PLL_CONTROL: %08lx", inl(0x60006034));
lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "PLL_STATUS: %08lx", inl(0x6000603c));
lcd_puts(0, line++, buf);
snprintf(buf, sizeof(buf), "DEV_PLL: %08lx", inl(0x70000020));
lcd_puts(0, line++, buf);
#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
line++;
snprintf(buf, sizeof(buf), "ADC_BATTERY: %02x", adc_read(ADC_BATTERY));
@ -1297,7 +1340,7 @@ static bool dbg_cpufreq(void)
snprintf(buf, sizeof(buf), "boost_counter: %d", get_cpu_boost_counter());
lcd_puts(0, line++, buf);
lcd_update();
button = get_action(CONTEXT_STD,HZ/10);

View file

@ -76,8 +76,8 @@
#ifndef SIMULATOR
/* Define this if you have a PortalPlayer PP5020 */
#define CONFIG_CPU PP5020
/* Define this if you have a PortalPlayer PP5022 */
#define CONFIG_CPU PP5022
/* Define this if you want to use the PP5020 i2c interface */
#define CONFIG_I2C I2C_PP5020

View file

@ -74,10 +74,8 @@
#ifndef SIMULATOR
/* The Nano actually has a PP5021 - but it's register compatible with
the 5020 so Rockbox doesn't care. */
/* Define this if you have a PortalPlayer PP5020 */
#define CONFIG_CPU PP5020
/* Define this if you have a PortalPlayer PP5022 */
#define CONFIG_CPU PP5022
/* Define this if you want to use the PP5020 i2c interface */
#define CONFIG_I2C I2C_PP5020

View file

@ -74,10 +74,8 @@
#ifndef SIMULATOR
/* The Nano actually has a PP5021 - but it's register compatible with
the 5020 so Rockbox doesn't care. */
/* Define this if you have a PortalPlayer PP5020 */
#define CONFIG_CPU PP5020
/* Define this if you have a PortalPlayer PP5022 */
#define CONFIG_CPU PP5022
/* Define this if you want to use the PP5020 i2c interface */
#define CONFIG_I2C I2C_PP5020

View file

@ -43,9 +43,10 @@
#define MCF5250 5250
#define PP5002 5002
#define PP5020 5020
#define PP5022 5022
#define PP5024 5024
#define PNX0101 101
#define S3C2440 2440
#define PP5024 5024
#define TMS320DSC25 25
/* CONFIG_KEYPAD */
@ -279,8 +280,11 @@
#endif
/* define for all cpus from PP family */
#if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5024)
#if (CONFIG_CPU == PP5002)
#define CPU_PP
#elif (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
#define CPU_PP
#define CPU_PP502x
#endif
/* define for all cpus from ARM family */

View file

@ -27,7 +27,7 @@
#if CONFIG_CPU == MCF5250
#include "mcf5250.h"
#endif
#if CONFIG_CPU == PP5020
#if (CONFIG_CPU == PP5020) || (CONFIG_CPU == PP5022)
#include "pp5020.h"
#endif
#if CONFIG_CPU == PP5002

View file

@ -105,7 +105,7 @@ void rolo_restart(const unsigned char* source, unsigned char* dest,
{
long i;
unsigned char* localdest = dest;
#if (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024)
#ifdef CPU_PP502x
unsigned long* memmapregs = (unsigned long*)0xf000f000;
#endif
@ -120,7 +120,7 @@ void rolo_restart(const unsigned char* source, unsigned char* dest,
"jmp (%0) \n"
: : "a"(dest)
);
#elif (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024)
#elif defined(CPU_PP502x)
/* Tell the COP that we've finished loading and started rebooting */
cpu_message = 0;

View file

@ -25,8 +25,8 @@
* setup. Needs investigation. */
.section .icode,"ax",%progbits
.equ .ata_port, 0xc00031e0
#elif CONFIG_CPU == PP5020
/* Verified working on (PP5020, PP5021, PP5022) targets */
#elif defined CPU_PP502x
/* Verified working on (PP5020, PP5022) targets */
.section .icode,"ax",%progbits
.equ .ata_port, 0xc30001e0
#elif CONFIG_CPU == S3C2440

View file

@ -17,7 +17,7 @@
*
****************************************************************************/
#if (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020)
#ifdef CPU_PP
#if (CONFIG_CPU == PP5002)
@ -26,7 +26,7 @@
#define ATA_IOBASE 0xc00031e0
#define ATA_CONTROL (*((volatile unsigned char*)(0xc00033f8)))
#elif (CONFIG_CPU == PP5020)
#elif defined CPU_PP502x
/* asm optimized reading and writing */
#define ATA_OPTIMIZED_READING

View file

@ -41,7 +41,7 @@ static inline bool timer_check(int clock_start, int usecs)
#if CONFIG_CPU == PP5002
#define IPOD_LCD_BASE 0xc0001000
#define IPOD_LCD_BUSY_MASK 0x80000000
#else /* PP5020 */
#else /* PP502x */
#define IPOD_LCD_BASE 0x70003000
#define IPOD_LCD_BUSY_MASK 0x00008000
#endif

View file

@ -30,7 +30,7 @@ static int rec_peak_left, rec_peak_right;
#endif
/** DMA **/
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
#define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f000000) >> 24)
#elif CONFIG_CPU == PP5002
#define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x7800000) >> 23)
@ -52,7 +52,7 @@ size_t p_size IBSS_ATTR;
actually needs to do so when calling pcm_callback_for_more. C version is
still included below for reference.
*/
#ifdef CPU_PP
#if 1
void fiq(void) ICODE_ATTR __attribute__((naked));
void fiq(void)
{
@ -154,12 +154,12 @@ void fiq(void)
"b .exit \n\t"
);
}
#else /* !(CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002) */
#else /* C version for reference */
void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ")));
void fiq(void)
{
/* Clear interrupt */
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
IISCONFIG &= ~(1 << 1);
#elif CONFIG_CPU == PP5002
inl(0xcf001040);
@ -170,7 +170,7 @@ void fiq(void)
while (p_size) {
if (FIFO_FREE_COUNT < 2) {
/* Enable interrupt */
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
IISCONFIG |= (1 << 1);
#elif CONFIG_CPU == PP5002
IISFIFO_CFG |= (1<<9);
@ -197,7 +197,7 @@ void fiq(void)
/* No more data, so disable the FIFO/FIQ */
pcm_play_dma_stop();
}
#endif /* CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002 */
#endif /* ASM / C selection */
void pcm_play_dma_start(const void *addr, size_t size)
{
@ -206,7 +206,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
pcm_playing = true;
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
CPU_INT_PRIORITY |= I2S_MASK; /* FIQ priority for I2S */
CPU_INT_EN = I2S_MASK; /* Enable I2S interrupt */
#else
@ -220,7 +220,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
enable_fiq();
/* Enable playback FIFO */
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
IISCONFIG |= (1 << 29);
#elif CONFIG_CPU == PP5002
IISCONFIG |= 0x4;
@ -231,7 +231,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
while (p_size > 0) {
if (FIFO_FREE_COUNT < 2) {
/* Enable interrupt */
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
IISCONFIG |= (1 << 1);
#elif CONFIG_CPU == PP5002
IISFIFO_CFG |= (1<<9);
@ -256,7 +256,7 @@ void pcm_play_dma_stop(void)
pcm_playing = false;
pcm_paused = false;
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
/* Disable playback FIFO and interrupt */
IISCONFIG &= ~((1 << 29) | (1 << 1));
#elif CONFIG_CPU == PP5002
@ -273,7 +273,7 @@ void pcm_play_dma_stop(void)
void pcm_play_pause_pause(void)
{
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
/* Disable playback FIFO and interrupt */
IISCONFIG &= ~((1 << 29) | (1 << 1));
#elif CONFIG_CPU == PP5002
@ -293,7 +293,7 @@ void pcm_play_pause_unpause(void)
enable_fiq();
/* Enable playback FIFO */
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
IISCONFIG |= (1 << 29);
#elif CONFIG_CPU == PP5002
IISCONFIG |= 0x4;
@ -304,7 +304,7 @@ void pcm_play_pause_unpause(void)
while (p_size > 0) {
if (FIFO_FREE_COUNT < 2) {
/* Enable interrupt */
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
IISCONFIG |= (1 << 1);
#elif CONFIG_CPU == PP5002
IISFIFO_CFG |= (1<<9);
@ -445,7 +445,7 @@ void fiq_record(void)
int status = 0;
/* Clear interrupt */
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
IISCONFIG &= ~(1 << 0);
#elif CONFIG_CPU == PP5002
/* TODO */
@ -454,7 +454,7 @@ void fiq_record(void)
while (p_size > 0) {
if (FIFO_FREE_COUNT < 2) {
/* enable interrupt */
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
IISCONFIG |= (1 << 0);
#elif CONFIG_CPU == PP5002
/* TODO */
@ -499,7 +499,7 @@ void pcm_record_more(void *start, size_t size)
rec_peak_addr = start; /* Start peaking at dest */
p = start; /* Start of RX buffer */
p_size = size; /* Bytes to transfer */
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
IISCONFIG |= (1 << 0);
#elif CONFIG_CPU == PP5002
/* TODO */
@ -558,7 +558,7 @@ void pcm_init_recording(void)
pcm_recording = false;
pcm_callback_more_ready = NULL;
#if (CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024)
#ifdef CPU_PP502x
#if defined(IPOD_COLOR) || defined (IPOD_4G)
/* The usual magic from IPL - I'm guessing this configures the headphone
socket to be input or output - in this case, input. */

View file

@ -151,7 +151,7 @@ static void ipod_init_cache(void)
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
void set_cpu_frequency(long frequency)
{
unsigned long postmult;
unsigned long postmult, pll_control;
# if NUM_CORES > 1
/* Using mutex or spinlock isn't safe here. */
@ -168,35 +168,24 @@ void set_cpu_frequency(long frequency)
/* Enable PLL? */
outl(inl(0x70000020) | (1<<30), 0x70000020);
/* Select 24MHz crystal as clock source? */
outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020);
outl((inl(0x60006020) & 0x0ffffff0) | 0x10000002, 0x60006020);
/* Clock frequency = (24/8)*postmult */
outl(0xaa020000 | 8 | (postmult << 8), 0x60006034);
/* Wait for PLL relock? */
udelay(2000);
pll_control = 0x8a020000 | 8 | (postmult << 8);
outl(pll_control, 0x60006034);
# if CONFIG_CPU == PP5020
outl(0xd198, 0x6000603c); /* magic sequence */
outl(pll_control, 0x60006034);
udelay(500); /* wait for relock */
# else /* PP5022, PP5024 */
while (!(inl(0x6000603c) & 0x80000000)); /* wait for relock */
# endif
/* Select PLL as clock source? */
outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020);
# if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
/* We don't know why the timer interrupt gets disabled on the PP5020
based ipods, but without the following line, the 4Gs will freeze
when CPU frequency changing is enabled.
Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used
elsewhere to enable interrupts) doesn't work, we need "|=".
It's not needed on the PP5021 and PP5022 ipods.
*/
/* unmask interrupt source */
CPU_INT_EN |= TIMER1_MASK;
COP_INT_EN |= TIMER1_MASK;
# endif
# if NUM_CORES > 1
boostctrl_mtx.locked = 0;
# endif
@ -213,9 +202,9 @@ void ipod_set_cpu_frequency(void)
outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020);
/* Clock frequency = (24/8)*25 = 75MHz */
outl(0xaa020000 | 8 | (25 << 8), 0x60006034);
outl(0x8a020000 | 8 | (25 << 8), 0x60006034);
/* Wait for PLL relock? */
udelay(2000);
udelay(500);
/* Select PLL as clock source? */
outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020);

View file

@ -36,7 +36,7 @@ static inline void udelay(unsigned usecs)
while (TIME_BEFORE(USEC_TIMER, stop));
}
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
#ifdef CPU_PP502x
static inline unsigned int current_core(void)
{
/*

View file

@ -43,7 +43,7 @@ int audiohw_init(void) {
/* reset I2C */
i2c_init();
#if CONFIG_CPU == PP5020
#ifdef CPU_PP502x
/* normal outputs for CDI and I2S pin groups */
DEV_INIT &= ~0x300;