From 9b4fd8e5406e60c39d6b99c358ae5c112e4176d9 Mon Sep 17 00:00:00 2001 From: jethead71 Date: Fri, 5 Oct 2007 23:24:46 +0000 Subject: [PATCH] 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 --- firmware/export/pp5020.h | 5 +-- firmware/kernel.c | 64 ++++++++++++++++++++++--------------- firmware/target/arm/system-pp502x.c | 22 ++++--------- firmware/thread.c | 1 - 4 files changed, 47 insertions(+), 45 deletions(-) diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h index cbaa64d31..af7810158 100644 --- a/firmware/export/pp5020.h +++ b/firmware/export/pp5020.h @@ -116,8 +116,9 @@ #define RTC (*(volatile unsigned long *)(0x60005014)) /* Device Controller */ -#define DEV_RS (*(volatile unsigned long *)(0x60006004)) -#define DEV_EN (*(volatile unsigned long *)(0x6000600c)) +#define DEV_RS (*(volatile unsigned long *)(0x60006004)) +#define DEV_OFF_MASK (*(volatile unsigned long *)(0x60006008)) +#define DEV_EN (*(volatile unsigned long *)(0x6000600c)) #define DEV_SYSTEM 0x00000004 #define DEV_SER0 0x00000040 diff --git a/firmware/kernel.c b/firmware/kernel.c index 03be6db62..1b6e9f933 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c @@ -44,22 +44,18 @@ static int num_queues NOCACHEBSS_ATTR; void kernel_init(void) { /* Init the threading API */ -#if NUM_CORES > 1 - if (CURRENT_CORE == COP) + init_threads(); + + /* Other processors will not reach this point in a multicore build. + * In a single-core build with multiple cores they fall-through and + * sleep in cop_main without returning. */ + if (CURRENT_CORE == CPU) { - /* This enables the interrupt but it won't be active until - the timer is actually started and interrupts are unmasked */ + memset(tick_funcs, 0, sizeof(tick_funcs)); + num_queues = 0; + memset(all_queues, 0, sizeof(all_queues)); tick_start(1000/HZ); } -#endif - - init_threads(); - - /* No processor other than the CPU will proceed here */ - 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) @@ -573,8 +569,8 @@ void TIMER1(void) TIMER1_VAL; /* Read value to ack IRQ */ - /* Run through the list of tick tasks (using main core - - COP does not dispatch ticks to this subroutine) */ + /* Run through the list of tick tasks using main CPU core - + wake up the COP through its control interface to provide pulse */ for (i = 0;i < MAX_NUM_TICK_TASKS;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++; } #endif @@ -591,17 +608,12 @@ void TIMER1(void) void tick_start(unsigned int interval_in_ms) { #ifndef BOOTLOADER - if(CURRENT_CORE == CPU) - { - TIMER1_CFG = 0x0; - TIMER1_VAL; - /* enable timer */ - TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000 - 1); - /* unmask interrupt source */ - CPU_INT_EN = TIMER1_MASK; - } else { - COP_INT_EN = TIMER1_MASK; - } + TIMER1_CFG = 0x0; + TIMER1_VAL; + /* enable timer */ + TIMER1_CFG = 0xc0000000 | (interval_in_ms*1000 - 1); + /* unmask interrupt source */ + CPU_INT_EN = TIMER1_MASK; #else /* We don't enable interrupts in the bootloader */ (void)interval_in_ms; diff --git a/firmware/target/arm/system-pp502x.c b/firmware/target/arm/system-pp502x.c index 7f6332cdf..576459d6c 100644 --- a/firmware/target/arm/system-pp502x.c +++ b/firmware/target/arm/system-pp502x.c @@ -134,15 +134,12 @@ void set_cpu_frequency(long frequency) static void pp_set_cpu_frequency(long frequency) #endif { - unsigned long clcd_clock_src; - #if defined(HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1) /* Using mutex or spinlock isn't safe here. */ while (test_and_set(&boostctrl_mtx.locked, 1)) ; #endif cpu_frequency = frequency; - clcd_clock_src = CLCD_CLOCK_SRC; /* save selected color LCD clock source */ switch (frequency) { @@ -152,7 +149,6 @@ static void pp_set_cpu_frequency(long frequency) * have this limitation (and the post divider?) */ case CPUFREQ_MAX: CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ - CLCD_CLOCK_SRC &= ~0xc0000000; /* select 24MHz as color LCD clock source */ DEV_TIMING1 = 0x00000808; #if CONFIG_CPU == PP5020 PLL_CONTROL = 0x8a020a03; /* 10/3 * 24MHz */ @@ -168,7 +164,6 @@ static void pp_set_cpu_frequency(long frequency) case CPUFREQ_NORMAL: CLOCK_SOURCE = 0x10007772; /* source #1: 24MHz, #2, #3, #4: PLL */ - CLCD_CLOCK_SRC &= ~0xc0000000; /* select 24MHz as color LCD clock source */ DEV_TIMING1 = 0x00000303; #if CONFIG_CPU == PP5020 PLL_CONTROL = 0x8a020504; /* 5/4 * 24MHz */ @@ -182,14 +177,12 @@ static void pp_set_cpu_frequency(long frequency) case CPUFREQ_SLEEP: 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 */ udelay(10000); /* let 32kHz source stabilize? */ break; default: CLOCK_SOURCE = 0x10002222; /* source #1, #2, #3, #4: 24MHz */ - CLCD_CLOCK_SRC &= ~0xc0000000; /* select 24MHz as color LCD clock source */ DEV_TIMING1 = 0x00000303; PLL_CONTROL &= ~0x80000000; /* disable PLL */ 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 */ - 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) boostctrl_mtx.locked = 0; #endif @@ -213,17 +203,17 @@ void system_init(void) { #if defined(SANSA_E200) || defined(SANSA_C200) /* Reset all devices */ - outl(inl(0x60006008) | 0x20, 0x60006008); + DEV_OFF_MASK |= 0x20; DEV_RS = 0x3bfffef8; - outl(0xffffffff, 0x60006008); + DEV_OFF_MASK = -1; DEV_RS = 0; - outl(0x00000000, 0x60006008); -#elif defined (IRIVER_H10) + DEV_OFF_MASK = 0; + #elif defined (IRIVER_H10) DEV_RS = 0x3ffffef8; - outl(0xffffffff, 0x60006008); + DEV_OFF_MASK = -1; outl(inl(0x70000024) | 0xc0, 0x70000024); DEV_RS = 0; - outl(0x00000000, 0x60006008); + DEV_OFF_MASK = 0; #endif #if !defined(SANSA_E200) && !defined(SANSA_C200) diff --git a/firmware/thread.c b/firmware/thread.c index 3508a6450..619a1e135 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -1095,7 +1095,6 @@ void init_threads(void) /* Get COP safely primed inside switch_thread where it will remain * until a thread actually exists on it */ CPU_CTL = PROC_WAKE; - set_irq_level(0); remove_thread(NULL); #endif /* NUM_CORES */ } -- 2.11.4.GIT