1*a47a12beSStefan Roese /* 2*a47a12beSStefan Roese * (C) Copyright 2000-2002 3*a47a12beSStefan Roese * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4*a47a12beSStefan Roese * 5*a47a12beSStefan Roese * (C) Copyright 2003 6*a47a12beSStefan Roese * Gleb Natapov <gnatapov@mrv.com> 7*a47a12beSStefan Roese * 8*a47a12beSStefan Roese * See file CREDITS for list of people who contributed to this 9*a47a12beSStefan Roese * project. 10*a47a12beSStefan Roese * 11*a47a12beSStefan Roese * This program is free software; you can redistribute it and/or 12*a47a12beSStefan Roese * modify it under the terms of the GNU General Public License as 13*a47a12beSStefan Roese * published by the Free Software Foundation; either version 2 of 14*a47a12beSStefan Roese * the License, or (at your option) any later version. 15*a47a12beSStefan Roese * 16*a47a12beSStefan Roese * This program is distributed in the hope that it will be useful, 17*a47a12beSStefan Roese * but WITHOUT ANY WARRANTY; without even the implied warranty of 18*a47a12beSStefan Roese * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19*a47a12beSStefan Roese * GNU General Public License for more details. 20*a47a12beSStefan Roese * 21*a47a12beSStefan Roese * You should have received a copy of the GNU General Public License 22*a47a12beSStefan Roese * along with this program; if not, write to the Free Software 23*a47a12beSStefan Roese * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 24*a47a12beSStefan Roese * MA 02111-1307 USA 25*a47a12beSStefan Roese */ 26*a47a12beSStefan Roese 27*a47a12beSStefan Roese #include <common.h> 28*a47a12beSStefan Roese #include <asm/processor.h> 29*a47a12beSStefan Roese #include <watchdog.h> 30*a47a12beSStefan Roese #ifdef CONFIG_STATUS_LED 31*a47a12beSStefan Roese #include <status_led.h> 32*a47a12beSStefan Roese #endif 33*a47a12beSStefan Roese 34*a47a12beSStefan Roese #ifdef CONFIG_SHOW_ACTIVITY 35*a47a12beSStefan Roese void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity"))); 36*a47a12beSStefan Roese 37*a47a12beSStefan Roese void __board_show_activity (ulong dummy) 38*a47a12beSStefan Roese { 39*a47a12beSStefan Roese return; 40*a47a12beSStefan Roese } 41*a47a12beSStefan Roese #endif /* CONFIG_SHOW_ACTIVITY */ 42*a47a12beSStefan Roese 43*a47a12beSStefan Roese #ifndef CONFIG_SYS_WATCHDOG_FREQ 44*a47a12beSStefan Roese #define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2) 45*a47a12beSStefan Roese #endif 46*a47a12beSStefan Roese 47*a47a12beSStefan Roese extern int interrupt_init_cpu (unsigned *); 48*a47a12beSStefan Roese extern void timer_interrupt_cpu (struct pt_regs *); 49*a47a12beSStefan Roese 50*a47a12beSStefan Roese static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */ 51*a47a12beSStefan Roese 52*a47a12beSStefan Roese static __inline__ unsigned long get_msr (void) 53*a47a12beSStefan Roese { 54*a47a12beSStefan Roese unsigned long msr; 55*a47a12beSStefan Roese 56*a47a12beSStefan Roese asm volatile ("mfmsr %0":"=r" (msr):); 57*a47a12beSStefan Roese 58*a47a12beSStefan Roese return msr; 59*a47a12beSStefan Roese } 60*a47a12beSStefan Roese 61*a47a12beSStefan Roese static __inline__ void set_msr (unsigned long msr) 62*a47a12beSStefan Roese { 63*a47a12beSStefan Roese asm volatile ("mtmsr %0"::"r" (msr)); 64*a47a12beSStefan Roese } 65*a47a12beSStefan Roese 66*a47a12beSStefan Roese static __inline__ unsigned long get_dec (void) 67*a47a12beSStefan Roese { 68*a47a12beSStefan Roese unsigned long val; 69*a47a12beSStefan Roese 70*a47a12beSStefan Roese asm volatile ("mfdec %0":"=r" (val):); 71*a47a12beSStefan Roese 72*a47a12beSStefan Roese return val; 73*a47a12beSStefan Roese } 74*a47a12beSStefan Roese 75*a47a12beSStefan Roese 76*a47a12beSStefan Roese static __inline__ void set_dec (unsigned long val) 77*a47a12beSStefan Roese { 78*a47a12beSStefan Roese if (val) 79*a47a12beSStefan Roese asm volatile ("mtdec %0"::"r" (val)); 80*a47a12beSStefan Roese } 81*a47a12beSStefan Roese 82*a47a12beSStefan Roese 83*a47a12beSStefan Roese void enable_interrupts (void) 84*a47a12beSStefan Roese { 85*a47a12beSStefan Roese set_msr (get_msr () | MSR_EE); 86*a47a12beSStefan Roese } 87*a47a12beSStefan Roese 88*a47a12beSStefan Roese /* returns flag if MSR_EE was set before */ 89*a47a12beSStefan Roese int disable_interrupts (void) 90*a47a12beSStefan Roese { 91*a47a12beSStefan Roese ulong msr = get_msr (); 92*a47a12beSStefan Roese 93*a47a12beSStefan Roese set_msr (msr & ~MSR_EE); 94*a47a12beSStefan Roese return ((msr & MSR_EE) != 0); 95*a47a12beSStefan Roese } 96*a47a12beSStefan Roese 97*a47a12beSStefan Roese int interrupt_init (void) 98*a47a12beSStefan Roese { 99*a47a12beSStefan Roese int ret; 100*a47a12beSStefan Roese 101*a47a12beSStefan Roese /* call cpu specific function from $(CPU)/interrupts.c */ 102*a47a12beSStefan Roese ret = interrupt_init_cpu (&decrementer_count); 103*a47a12beSStefan Roese 104*a47a12beSStefan Roese if (ret) 105*a47a12beSStefan Roese return ret; 106*a47a12beSStefan Roese 107*a47a12beSStefan Roese set_dec (decrementer_count); 108*a47a12beSStefan Roese 109*a47a12beSStefan Roese set_msr (get_msr () | MSR_EE); 110*a47a12beSStefan Roese 111*a47a12beSStefan Roese return (0); 112*a47a12beSStefan Roese } 113*a47a12beSStefan Roese 114*a47a12beSStefan Roese static volatile ulong timestamp = 0; 115*a47a12beSStefan Roese 116*a47a12beSStefan Roese void timer_interrupt (struct pt_regs *regs) 117*a47a12beSStefan Roese { 118*a47a12beSStefan Roese /* call cpu specific function from $(CPU)/interrupts.c */ 119*a47a12beSStefan Roese timer_interrupt_cpu (regs); 120*a47a12beSStefan Roese 121*a47a12beSStefan Roese /* Restore Decrementer Count */ 122*a47a12beSStefan Roese set_dec (decrementer_count); 123*a47a12beSStefan Roese 124*a47a12beSStefan Roese timestamp++; 125*a47a12beSStefan Roese 126*a47a12beSStefan Roese #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) 127*a47a12beSStefan Roese if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) 128*a47a12beSStefan Roese WATCHDOG_RESET (); 129*a47a12beSStefan Roese #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ 130*a47a12beSStefan Roese 131*a47a12beSStefan Roese #ifdef CONFIG_STATUS_LED 132*a47a12beSStefan Roese status_led_tick (timestamp); 133*a47a12beSStefan Roese #endif /* CONFIG_STATUS_LED */ 134*a47a12beSStefan Roese 135*a47a12beSStefan Roese #ifdef CONFIG_SHOW_ACTIVITY 136*a47a12beSStefan Roese board_show_activity (timestamp); 137*a47a12beSStefan Roese #endif /* CONFIG_SHOW_ACTIVITY */ 138*a47a12beSStefan Roese } 139*a47a12beSStefan Roese 140*a47a12beSStefan Roese void reset_timer (void) 141*a47a12beSStefan Roese { 142*a47a12beSStefan Roese timestamp = 0; 143*a47a12beSStefan Roese } 144*a47a12beSStefan Roese 145*a47a12beSStefan Roese ulong get_timer (ulong base) 146*a47a12beSStefan Roese { 147*a47a12beSStefan Roese return (timestamp - base); 148*a47a12beSStefan Roese } 149*a47a12beSStefan Roese 150*a47a12beSStefan Roese void set_timer (ulong t) 151*a47a12beSStefan Roese { 152*a47a12beSStefan Roese timestamp = t; 153*a47a12beSStefan Roese } 154