Home | History | Annotate | Download | only in lib
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2000-2002
      4  * Wolfgang Denk, DENX Software Engineering, wd (at) denx.de.
      5  *
      6  * (C) Copyright 2003
      7  * Gleb Natapov <gnatapov (at) mrv.com>
      8  */
      9 
     10 #include <common.h>
     11 #include <asm/processor.h>
     12 #include <watchdog.h>
     13 #ifdef CONFIG_LED_STATUS
     14 #include <status_led.h>
     15 #endif
     16 
     17 #ifdef CONFIG_SHOW_ACTIVITY
     18 void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
     19 
     20 void __board_show_activity (ulong dummy)
     21 {
     22 	return;
     23 }
     24 #endif /* CONFIG_SHOW_ACTIVITY */
     25 
     26 #ifndef CONFIG_SYS_WATCHDOG_FREQ
     27 #define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
     28 #endif
     29 
     30 static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
     31 
     32 static __inline__ unsigned long get_dec (void)
     33 {
     34 	unsigned long val;
     35 
     36 	asm volatile ("mfdec %0":"=r" (val):);
     37 
     38 	return val;
     39 }
     40 
     41 
     42 static __inline__ void set_dec (unsigned long val)
     43 {
     44 	if (val)
     45 		asm volatile ("mtdec %0"::"r" (val));
     46 }
     47 
     48 
     49 void enable_interrupts (void)
     50 {
     51 	set_msr (get_msr () | MSR_EE);
     52 }
     53 
     54 /* returns flag if MSR_EE was set before */
     55 int disable_interrupts (void)
     56 {
     57 	ulong msr = get_msr ();
     58 
     59 	set_msr (msr & ~MSR_EE);
     60 	return ((msr & MSR_EE) != 0);
     61 }
     62 
     63 int interrupt_init (void)
     64 {
     65 	/* call cpu specific function from $(CPU)/interrupts.c */
     66 	interrupt_init_cpu (&decrementer_count);
     67 
     68 	set_dec (decrementer_count);
     69 
     70 	set_msr (get_msr () | MSR_EE);
     71 
     72 	return (0);
     73 }
     74 
     75 static volatile ulong timestamp = 0;
     76 
     77 void timer_interrupt (struct pt_regs *regs)
     78 {
     79 	/* call cpu specific function from $(CPU)/interrupts.c */
     80 	timer_interrupt_cpu (regs);
     81 
     82 	/* Restore Decrementer Count */
     83 	set_dec (decrementer_count);
     84 
     85 	timestamp++;
     86 
     87 #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
     88 	if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
     89 		WATCHDOG_RESET ();
     90 #endif    /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
     91 
     92 #ifdef CONFIG_LED_STATUS
     93 	status_led_tick (timestamp);
     94 #endif /* CONFIG_LED_STATUS */
     95 
     96 #ifdef CONFIG_SHOW_ACTIVITY
     97 	board_show_activity (timestamp);
     98 #endif /* CONFIG_SHOW_ACTIVITY */
     99 }
    100 
    101 ulong get_timer (ulong base)
    102 {
    103 	return (timestamp - base);
    104 }
    105