[U-Boot] Kirkwood register and interrupt issues
Bernhard Schuster
bernhard.schuster at excito.com
Thu Nov 8 14:34:07 CET 2012
Dear mailinglist subscribers,
I am currently trying to write a suspend (via wait-for-interrupt, cp15 instruction) function in the u-boot context which will recover on a gpio edge event.
Thus I am trying to enable interrupts via the interrupt function the linux kernel uses (see end of this mail).
Unfortunately the cp15 instruction never recovered.
Now I am stuck with this, I try to write some registers to configure timers (to force create cyclic interrupts) and unmask all kind of interrupts, but the intended values actually never get written to the registers. I am really puzzled.
Any help, demo implementation or tipp is really appreciated.
Best regards
Bernhard
post scriptum:
=============================================================
code (chunk from init function):
struct kwcpu_registers *cpureg = (struct kwcpu_registers*)(KW_REGISTER(0x20100));
writel (&cpureg->ahb_mbus_mask_irq, 0xFFFFFFFF);
writel (&cpureg->ahb_mbus_cause_irq, 0);
struct kwgpio_registers *gpio0reg = (struct kwgpio_registers*)(KW_GPIO0_BASE);
struct kwgpio_registers *gpio1reg = (struct kwgpio_registers*)(KW_GPIO1_BASE);
//unmask edge fun, disable level stuff
writel (&gpio0reg->irq_mask, 0xFFFFFFFF);
writel (&gpio0reg->irq_level, 0);
writel (&gpio1reg->irq_mask, 0xFFFFFFFF);
writel (&gpio1reg->irq_level, 0);
struct kwtimer_registers *timer = (struct kwtimer_registers*)(KW_TIMER_BASE);
writel (&timer->t0, 0x000FFFFF);
writel (&timer->reload0, 0x00000FFF);
writel (&timer->t1, 0x000FFFFF);
writel (&timer->reload1, 0x00000FFF);
writel (&timer->ctl, 0x0F); //enable both timers, no watchdog
printf ("cpu config 0x%08x\n", readl(&cpureg->config));
printf ("cpu ctrl_stat 0x%08x\n", readl(&cpureg->ctrl_stat));
printf ("mbus mask 0x%08x\n", readl(&cpureg->ahb_mbus_mask_irq));
printf ("mbus cause 0x%08x\n", readl(&cpureg->ahb_mbus_cause_irq));
printf ("timer 0 RELOAD VAL 0x%08x\n", readl(&timer->reload0));
printf ("timer 1 RELOAD VAL 0x%08x\n", readl(&timer->reload1));
printf ("GPIO 0 Edge 0x%08x\n", readl(&gpio0reg->irq_mask));
printf ("GPIO 0 Level 0x%08x\n", readl(&gpio0reg->irq_level));
printf ("GPIO 1 Edge 0x%08x\n", readl(&gpio1reg->irq_mask));
printf ("GPIO 1 Level 0x%08x\n", readl(&gpio1reg->irq_level));
printf ("0x%08x (low interrupt cause)\n", (u32) readl (KW_REGISTER(0x20200)));
printf ("0x%08x (high interrupt cause)\n", (u32) readl (KW_REGISTER(0x20210)));
output from the above indented chunk:
cpu config 0x00100036
cpu ctrl_stat 0x00000001
mbus mask 0x00000000
mbus cause 0x00000002 //mbus interrupt source detected
timer 0 RELOAD VAL 0xffffffff //just wrong, we did write 0x00000FFF to that one
timer 1 RELOAD VAL 0x00000000 //just wrong 0x00000FFF
GPIO 0 Edge 0x00000000 // wrong
GPIO 0 Level 0x00000000 // wrong
GPIO 1 Edge 0x00000000 // wrong
GPIO 1 Level 0x00000000 // wrong
0x00800000 (low interrupt cause) // spi interrupt detected, not expected
0x00000000 (high interrupt cause)
=============================================================
/*
* Enable IRQs
*/
inline void arch_local_irq_enable(void)
{
unsigned long temp;
__asm__ __volatile__(
"mrs %0, cpsr @ arch_local_irq_enable\n"
"bic %0, %0, #128\n"
"msr cpsr_c, %0"
: "=r" (temp)
:
: "memory", "cc");
}
/*
* Disable IRQs
*/
inline void arch_local_irq_disable(void)
{
unsigned long temp;
__asm__ __volatile__(
"mrs %0, cpsr @ arch_local_irq_disable\n"
"orr %0, %0, #128\n"
"msr cpsr_c, %0"
: "=r" (temp)
:
: "memory", "cc");
}
More information about the U-Boot
mailing list