1
0
Fork 0
forked from len0rd/rockbox

Stabilize PP5020 targets - tested on H10 5/20GB and iPod Color. Use no interrupts on COP but pulse it through the control interface. Don't mess with LCD clocking during clock changes. Give a reset register a name (DEV_OFF_MASK).

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14998 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2007-10-05 23:24:46 +00:00
parent c27ae40ca2
commit 18e87ff1c0
4 changed files with 48 additions and 46 deletions

View file

@ -116,8 +116,9 @@
#define RTC (*(volatile unsigned long *)(0x60005014)) #define RTC (*(volatile unsigned long *)(0x60005014))
/* Device Controller */ /* Device Controller */
#define DEV_RS (*(volatile unsigned long *)(0x60006004)) #define DEV_RS (*(volatile unsigned long *)(0x60006004))
#define DEV_EN (*(volatile unsigned long *)(0x6000600c)) #define DEV_OFF_MASK (*(volatile unsigned long *)(0x60006008))
#define DEV_EN (*(volatile unsigned long *)(0x6000600c))
#define DEV_SYSTEM 0x00000004 #define DEV_SYSTEM 0x00000004
#define DEV_SER0 0x00000040 #define DEV_SER0 0x00000040

View file

@ -44,22 +44,18 @@ static int num_queues NOCACHEBSS_ATTR;
void kernel_init(void) void kernel_init(void)
{ {
/* Init the threading API */ /* Init the threading API */
#if NUM_CORES > 1
if (CURRENT_CORE == COP)
{
/* This enables the interrupt but it won't be active until
the timer is actually started and interrupts are unmasked */
tick_start(1000/HZ);
}
#endif
init_threads(); init_threads();
/* No processor other than the CPU will proceed here */ /* Other processors will not reach this point in a multicore build.
memset(tick_funcs, 0, sizeof(tick_funcs)); * In a single-core build with multiple cores they fall-through and
num_queues = 0; * sleep in cop_main without returning. */
memset(all_queues, 0, sizeof(all_queues)); if (CURRENT_CORE == CPU)
tick_start(1000/HZ); {
memset(tick_funcs, 0, sizeof(tick_funcs));
num_queues = 0;
memset(all_queues, 0, sizeof(all_queues));
tick_start(1000/HZ);
}
} }
void sleep(int ticks) void sleep(int ticks)
@ -573,8 +569,8 @@ void TIMER1(void)
TIMER1_VAL; /* Read value to ack IRQ */ TIMER1_VAL; /* Read value to ack IRQ */
/* Run through the list of tick tasks (using main core - /* Run through the list of tick tasks using main CPU core -
COP does not dispatch ticks to this subroutine) */ wake up the COP through its control interface to provide pulse */
for (i = 0;i < MAX_NUM_TICK_TASKS;i++) for (i = 0;i < MAX_NUM_TICK_TASKS;i++)
{ {
if (tick_funcs[i]) if (tick_funcs[i])
@ -583,6 +579,27 @@ void TIMER1(void)
} }
} }
#if NUM_CORES > 1
#ifdef CPU_PP502x
{
/* If COP is sleeping - give it a kick */
/* TODO: Use a mailbox in addition to make sure it doesn't go to
* sleep if kicked just as it's headed to rest to make sure its
* tick checks won't be jittery. Don't bother at all if it owns no
* threads. */
unsigned int cop_ctl;
cop_ctl = COP_CTL;
if (cop_ctl & PROC_SLEEP)
{
COP_CTL = cop_ctl & ~PROC_SLEEP;
}
}
#else
/* TODO: PP5002 */
#endif
#endif /* NUM_CORES */
current_tick++; current_tick++;
} }
#endif #endif
@ -591,17 +608,12 @@ void TIMER1(void)
void tick_start(unsigned int interval_in_ms) void tick_start(unsigned int interval_in_ms)
{ {
#ifndef BOOTLOADER #ifndef BOOTLOADER
if(CURRENT_CORE == CPU) TIMER1_CFG = 0x0;
{ TIMER1_VAL;
TIMER1_CFG = 0x0; /* enable timer */
TIMER1_VAL; TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000 - 1);
/* enable timer */ /* unmask interrupt source */
TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000 - 1); CPU_INT_EN = TIMER1_MASK;
/* unmask interrupt source */
CPU_INT_EN = TIMER1_MASK;
} else {
COP_INT_EN = TIMER1_MASK;
}
#else #else
/* We don't enable interrupts in the bootloader */ /* We don't enable interrupts in the bootloader */
(void)interval_in_ms; (void)interval_in_ms;

View file

@ -134,15 +134,12 @@ void set_cpu_frequency(long frequency)
static void pp_set_cpu_frequency(long frequency) static void pp_set_cpu_frequency(long frequency)
#endif #endif
{ {
unsigned long clcd_clock_src;
#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
/* Using mutex or spinlock isn't safe here. */ /* Using mutex or spinlock isn't safe here. */
while (test_and_set(&boostctrl_mtx.locked, 1)) ; while (test_and_set(&boostctrl_mtx.locked, 1)) ;
#endif #endif
cpu_frequency = frequency; cpu_frequency = frequency;
clcd_clock_src = CLCD_CLOCK_SRC; /* save selected color LCD clock source */
switch (frequency) switch (frequency)
{ {
@ -152,7 +149,6 @@ static void pp_set_cpu_frequency(long frequency)
* have this limitation (and the post divider?) */ * have this limitation (and the post divider?) */
case CPUFREQ_MAX: case CPUFREQ_MAX:
CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */
CLCD_CLOCK_SRC &= ~0xc0000000; /* select 24MHz as color LCD clock source */
DEV_TIMING1 = 0x00000808; DEV_TIMING1 = 0x00000808;
#if CONFIG_CPU == PP5020 #if CONFIG_CPU == PP5020
PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */ PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */
@ -168,7 +164,6 @@ static void pp_set_cpu_frequency(long frequency)
case CPUFREQ_NORMAL: case CPUFREQ_NORMAL:
CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */
CLCD_CLOCK_SRC &= ~0xc0000000; /* select 24MHz as color LCD clock source */
DEV_TIMING1 = 0x00000303; DEV_TIMING1 = 0x00000303;
#if CONFIG_CPU == PP5020 #if CONFIG_CPU == PP5020
PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */ PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */
@ -182,14 +177,12 @@ static void pp_set_cpu_frequency(long frequency)
case CPUFREQ_SLEEP: case CPUFREQ_SLEEP:
CLOCK_SOURCE = 0x10002202; /* source #2: 32kHz, #1, #3, #4: 24MHz */ CLOCK_SOURCE = 0x10002202; /* source #2: 32kHz, #1, #3, #4: 24MHz */
CLCD_CLOCK_SRC &= ~0xc0000000; /* select 24MHz as color LCD clock source */
PLL_CONTROL &= ~0x80000000; /* disable PLL */ PLL_CONTROL &= ~0x80000000; /* disable PLL */
udelay(10000); /* let 32kHz source stabilize? */ udelay(10000); /* let 32kHz source stabilize? */
break; break;
default: default:
CLOCK_SOURCE = 0x10002222; /* source #1, #2, #3, #4: 24MHz */ CLOCK_SOURCE = 0x10002222; /* source #1, #2, #3, #4: 24MHz */
CLCD_CLOCK_SRC &= ~0xc0000000; /* select 24MHz as color LCD clock source */
DEV_TIMING1 = 0x00000303; DEV_TIMING1 = 0x00000303;
PLL_CONTROL &= ~0x80000000; /* disable PLL */ PLL_CONTROL &= ~0x80000000; /* disable PLL */
cpu_frequency = CPUFREQ_DEFAULT; cpu_frequency = CPUFREQ_DEFAULT;
@ -197,9 +190,6 @@ static void pp_set_cpu_frequency(long frequency)
} }
CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf0000000) | 0x20000000; /* select source #2 */ CLOCK_SOURCE = (CLOCK_SOURCE & ~0xf0000000) | 0x20000000; /* select source #2 */
CLCD_CLOCK_SRC; /* dummy read (to sync the write pipeline??) */
CLCD_CLOCK_SRC = clcd_clock_src; /* restore saved value */
#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
boostctrl_mtx.locked = 0; boostctrl_mtx.locked = 0;
#endif #endif
@ -213,17 +203,17 @@ void system_init(void)
{ {
#if defined(SANSA_E200) || defined(SANSA_C200) #if defined(SANSA_E200) || defined(SANSA_C200)
/* Reset all devices */ /* Reset all devices */
outl(inl(0x60006008) | 0x20, 0x60006008); DEV_OFF_MASK |= 0x20;
DEV_RS = 0x3bfffef8; DEV_RS = 0x3bfffef8;
outl(0xffffffff, 0x60006008); DEV_OFF_MASK = -1;
DEV_RS = 0; DEV_RS = 0;
outl(0x00000000, 0x60006008); DEV_OFF_MASK = 0;
#elif defined (IRIVER_H10) #elif defined (IRIVER_H10)
DEV_RS = 0x3ffffef8; DEV_RS = 0x3ffffef8;
outl(0xffffffff, 0x60006008); DEV_OFF_MASK = -1;
outl(inl(0x70000024) | 0xc0, 0x70000024); outl(inl(0x70000024) | 0xc0, 0x70000024);
DEV_RS = 0; DEV_RS = 0;
outl(0x00000000, 0x60006008); DEV_OFF_MASK = 0;
#endif #endif
#if !defined(SANSA_E200) && !defined(SANSA_C200) #if !defined(SANSA_E200) && !defined(SANSA_C200)

View file

@ -1095,7 +1095,6 @@ void init_threads(void)
/* Get COP safely primed inside switch_thread where it will remain /* Get COP safely primed inside switch_thread where it will remain
* until a thread actually exists on it */ * until a thread actually exists on it */
CPU_CTL = PROC_WAKE; CPU_CTL = PROC_WAKE;
set_irq_level(0);
remove_thread(NULL); remove_thread(NULL);
#endif /* NUM_CORES */ #endif /* NUM_CORES */
} }