blob: f63e5cf799b820b83a85349add228d9f6f18e5eb [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
wdenkc0aa5c52003-12-06 19:49:23 +00002/*
3 * (C) Copyright 2000-2002
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 *
6 * (C) Copyright 2003
7 * Gleb Natapov <gnatapov@mrv.com>
wdenkc0aa5c52003-12-06 19:49:23 +00008 */
9
10#include <common.h>
11#include <asm/processor.h>
12#include <watchdog.h>
Uri Mashiach4892d392017-01-19 10:51:45 +020013#ifdef CONFIG_LED_STATUS
wdenkc0aa5c52003-12-06 19:49:23 +000014#include <status_led.h>
15#endif
16
17#ifdef CONFIG_SHOW_ACTIVITY
Wolfgang Denkec3d2522008-09-09 10:08:02 +020018void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
19
20void __board_show_activity (ulong dummy)
21{
22 return;
23}
wdenkc0aa5c52003-12-06 19:49:23 +000024#endif /* CONFIG_SHOW_ACTIVITY */
25
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020026#ifndef CONFIG_SYS_WATCHDOG_FREQ
27#define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
wdenkc0aa5c52003-12-06 19:49:23 +000028#endif
29
wdenkc0aa5c52003-12-06 19:49:23 +000030static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
31
wdenkc0aa5c52003-12-06 19:49:23 +000032static __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
42static __inline__ void set_dec (unsigned long val)
43{
44 if (val)
45 asm volatile ("mtdec %0"::"r" (val));
46}
47
48
49void enable_interrupts (void)
50{
51 set_msr (get_msr () | MSR_EE);
52}
53
54/* returns flag if MSR_EE was set before */
55int disable_interrupts (void)
56{
57 ulong msr = get_msr ();
58
59 set_msr (msr & ~MSR_EE);
60 return ((msr & MSR_EE) != 0);
61}
62
63int interrupt_init (void)
64{
wdenk1ebf41e2004-01-02 14:00:00 +000065 /* call cpu specific function from $(CPU)/interrupts.c */
Tom Rinice103982017-08-13 22:44:37 -040066 interrupt_init_cpu (&decrementer_count);
wdenkc0aa5c52003-12-06 19:49:23 +000067
68 set_dec (decrementer_count);
69
70 set_msr (get_msr () | MSR_EE);
71
72 return (0);
73}
74
75static volatile ulong timestamp = 0;
76
77void 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)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020088 if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
wdenkc0aa5c52003-12-06 19:49:23 +000089 WATCHDOG_RESET ();
90#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
91
Uri Mashiach4892d392017-01-19 10:51:45 +020092#ifdef CONFIG_LED_STATUS
wdenk1ebf41e2004-01-02 14:00:00 +000093 status_led_tick (timestamp);
Uri Mashiach4892d392017-01-19 10:51:45 +020094#endif /* CONFIG_LED_STATUS */
wdenkc0aa5c52003-12-06 19:49:23 +000095
96#ifdef CONFIG_SHOW_ACTIVITY
97 board_show_activity (timestamp);
98#endif /* CONFIG_SHOW_ACTIVITY */
99}
100
wdenkc0aa5c52003-12-06 19:49:23 +0000101ulong get_timer (ulong base)
102{
103 return (timestamp - base);
104}