X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cpu%2Fmpc86xx%2Finterrupts.c;h=49820bbd81138fdb0675d5c62bf6b8651d84ddf4;hb=ee89bf2782406b1f87088b4764aeb6f811d82526;hp=b5cd439e53d97b00ce4389482c24d3279e71e4b8;hpb=5c9efb36a6b5431423f52888a0e3b4b515fe7eca;p=oweals%2Fu-boot.git diff --git a/cpu/mpc86xx/interrupts.c b/cpu/mpc86xx/interrupts.c index b5cd439e53..49820bbd81 100644 --- a/cpu/mpc86xx/interrupts.c +++ b/cpu/mpc86xx/interrupts.c @@ -9,7 +9,7 @@ * Xianghua Xiao (X.Xiao@motorola.com) * * (C) Copyright 2004 Freescale Semiconductor. (MPC86xx Port) - * Jeff Brown (Jeffrey@freescale.com) + * Jeff Brown * Srikanth Srinivasan (srikanth.srinivasan@freescale.com) * * See file CREDITS for list of people who contributed to this @@ -37,12 +37,11 @@ #include #include -unsigned long decrementer_count; /* count value for 1e6/HZ microseconds */ - - +unsigned long decrementer_count; /* count value for 1e6/HZ microseconds */ unsigned long timestamp; -static __inline__ unsigned long get_msr (void) + +static __inline__ unsigned long get_msr(void) { unsigned long msr; @@ -51,12 +50,12 @@ static __inline__ unsigned long get_msr (void) return msr; } -static __inline__ void set_msr (unsigned long msr) +static __inline__ void set_msr(unsigned long msr) { asm volatile ("mtmsr %0"::"r" (msr)); } -static __inline__ unsigned long get_dec (void) +static __inline__ unsigned long get_dec(void) { unsigned long val; @@ -65,61 +64,81 @@ static __inline__ unsigned long get_dec (void) return val; } - -static __inline__ void set_dec (unsigned long val) +static __inline__ void set_dec(unsigned long val) { if (val) asm volatile ("mtdec %0"::"r" (val)); } /* interrupt is not supported yet */ -int interrupt_init_cpu (unsigned *decrementer_count) +int interrupt_init_cpu(unsigned *decrementer_count) { - return 0; + return 0; } - -int interrupt_init (void) +int interrupt_init(void) { int ret; + /* + * The IRQ0 on Rev 2 is pulled high (low in Rev 1.x) to + * implement PEX10 errata. As INT is active high, it + * will cause core to take 0x500 interrupt. + * + * Due to the PIC's default pass through mode, as soon + * as interrupts are enabled (MSR[EE] = 1), an interrupt + * will be taken and u-boot will hang. This is due to a + * hardware change (per an errata fix) on new revisions + * of the board with Rev 2.x parts. + * + * Setting the PIC to mixed mode prevents the hang. + */ + if ((get_svr() & 0xf0) == 0x20) { + volatile immap_t *immr = (immap_t *)CFG_IMMR; + immr->im_pic.gcr = MPC86xx_PICGCR_RST; + while (immr->im_pic.gcr & MPC86xx_PICGCR_RST); + immr->im_pic.gcr = MPC86xx_PICGCR_MODE; + } + /* call cpu specific function from $(CPU)/interrupts.c */ - ret = interrupt_init_cpu (&decrementer_count); + ret = interrupt_init_cpu(&decrementer_count); if (ret) return ret; - decrementer_count = get_tbclk()/CFG_HZ; - debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n", (get_tbclk()/1000000), decrementer_count); + decrementer_count = get_tbclk() / CFG_HZ; + debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n", + (get_tbclk() / 1000000), + decrementer_count); - set_dec (decrementer_count); + set_dec(decrementer_count); - set_msr (get_msr () | MSR_EE); + set_msr(get_msr() | MSR_EE); - debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n", get_msr(), get_dec()); + debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n", + get_msr(), + get_dec()); return 0; } - -void enable_interrupts (void) +void enable_interrupts(void) { - set_msr (get_msr () | MSR_EE); + set_msr(get_msr() | MSR_EE); } /* returns flag if MSR_EE was set before */ -int disable_interrupts (void) +int disable_interrupts(void) { - ulong msr = get_msr (); + ulong msr = get_msr(); - set_msr (msr & ~MSR_EE); + set_msr(msr & ~MSR_EE); return (msr & MSR_EE) != 0; } - void increment_timestamp(void) { - timestamp++; + timestamp++; } /* @@ -127,81 +146,71 @@ void increment_timestamp(void) * with interrupts disabled. * Trivial implementation - no need to be really accurate. */ -void -timer_interrupt_cpu (struct pt_regs *regs) +void timer_interrupt_cpu(struct pt_regs *regs) { /* nothing to do here */ } - -void timer_interrupt (struct pt_regs *regs) +void timer_interrupt(struct pt_regs *regs) { - /* call cpu specific function from $(CPU)/interrupts.c */ - timer_interrupt_cpu (regs); + /* call cpu specific function from $(CPU)/interrupts.c */ + timer_interrupt_cpu(regs); - timestamp++; + timestamp++; - ppcDcbf(×tamp); + ppcDcbf(×tamp); - /* Restore Decrementer Count */ - set_dec (decrementer_count); + /* Restore Decrementer Count */ + set_dec(decrementer_count); #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) if ((timestamp % (CFG_WATCHDOG_FREQ)) == 0) - WATCHDOG_RESET (); -#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ + WATCHDOG_RESET(); +#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ #ifdef CONFIG_STATUS_LED - status_led_tick (timestamp); + status_led_tick(timestamp); #endif /* CONFIG_STATUS_LED */ #ifdef CONFIG_SHOW_ACTIVITY - board_show_activity (timestamp); + board_show_activity(timestamp); #endif /* CONFIG_SHOW_ACTIVITY */ - } -void reset_timer (void) +void reset_timer(void) { - timestamp = 0; + timestamp = 0; } -ulong get_timer (ulong base) +ulong get_timer(ulong base) { - return timestamp - base; + return timestamp - base; } -void set_timer (ulong t) +void set_timer(ulong t) { - timestamp = t; + timestamp = t; } /* * Install and free a interrupt handler. Not implemented yet. */ -void -irq_install_handler(int vec, interrupt_handler_t *handler, void *arg) +void irq_install_handler(int vec, interrupt_handler_t *handler, void *arg) { } -void -irq_free_handler(int vec) +void irq_free_handler(int vec) { } - - -/******************************************************************************* - * +/* * irqinfo - print information about PCI devices,not implemented. - * */ -int -do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { - printf ("\nInterrupt-unsupported:\n"); + printf("\nInterrupt-unsupported:\n"); return 0; } @@ -209,14 +218,7 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) /* * Handle external interrupts */ -void -external_interrupt(struct pt_regs *regs) +void external_interrupt(struct pt_regs *regs) { puts("external_interrupt (oops!)\n"); } - - - - - -