blob: 46fa18c63fb0bced53366522242b912eaa566e4f [file] [log] [blame]
wdenkc0aa5c52003-12-06 19:49:23 +00001/*
2 * (C) Copyright 2000-2002
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * (C) Copyright 2003
6 * Gleb Natapov <gnatapov@mrv.com>
7 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
wdenkc0aa5c52003-12-06 19:49:23 +00009 */
10
11#include <common.h>
12#include <asm/processor.h>
13#include <watchdog.h>
Uri Mashiach4892d392017-01-19 10:51:45 +020014#ifdef CONFIG_LED_STATUS
wdenkc0aa5c52003-12-06 19:49:23 +000015#include <status_led.h>
16#endif
17
18#ifdef CONFIG_SHOW_ACTIVITY
Wolfgang Denkec3d2522008-09-09 10:08:02 +020019void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
20
21void __board_show_activity (ulong dummy)
22{
23 return;
24}
wdenkc0aa5c52003-12-06 19:49:23 +000025#endif /* CONFIG_SHOW_ACTIVITY */
26
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020027#ifndef CONFIG_SYS_WATCHDOG_FREQ
28#define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
wdenkc0aa5c52003-12-06 19:49:23 +000029#endif
30
wdenkc0aa5c52003-12-06 19:49:23 +000031static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
32
wdenkc0aa5c52003-12-06 19:49:23 +000033static __inline__ unsigned long get_dec (void)
34{
35 unsigned long val;
36
37 asm volatile ("mfdec %0":"=r" (val):);
38
39 return val;
40}
41
42
43static __inline__ void set_dec (unsigned long val)
44{
45 if (val)
46 asm volatile ("mtdec %0"::"r" (val));
47}
48
49
50void enable_interrupts (void)
51{
52 set_msr (get_msr () | MSR_EE);
53}
54
55/* returns flag if MSR_EE was set before */
56int disable_interrupts (void)
57{
58 ulong msr = get_msr ();
59
60 set_msr (msr & ~MSR_EE);
61 return ((msr & MSR_EE) != 0);
62}
63
64int interrupt_init (void)
65{
66 int ret;
67
wdenk1ebf41e2004-01-02 14:00:00 +000068 /* call cpu specific function from $(CPU)/interrupts.c */
wdenkc0aa5c52003-12-06 19:49:23 +000069 ret = interrupt_init_cpu (&decrementer_count);
70
71 if (ret)
72 return ret;
73
74 set_dec (decrementer_count);
75
76 set_msr (get_msr () | MSR_EE);
77
78 return (0);
79}
80
81static volatile ulong timestamp = 0;
82
83void timer_interrupt (struct pt_regs *regs)
84{
85 /* call cpu specific function from $(CPU)/interrupts.c */
86 timer_interrupt_cpu (regs);
87
88 /* Restore Decrementer Count */
89 set_dec (decrementer_count);
90
91 timestamp++;
92
93#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020094 if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
wdenkc0aa5c52003-12-06 19:49:23 +000095 WATCHDOG_RESET ();
96#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
97
Uri Mashiach4892d392017-01-19 10:51:45 +020098#ifdef CONFIG_LED_STATUS
wdenk1ebf41e2004-01-02 14:00:00 +000099 status_led_tick (timestamp);
Uri Mashiach4892d392017-01-19 10:51:45 +0200100#endif /* CONFIG_LED_STATUS */
wdenkc0aa5c52003-12-06 19:49:23 +0000101
102#ifdef CONFIG_SHOW_ACTIVITY
103 board_show_activity (timestamp);
104#endif /* CONFIG_SHOW_ACTIVITY */
105}
106
wdenkc0aa5c52003-12-06 19:49:23 +0000107ulong get_timer (ulong base)
108{
109 return (timestamp - base);
110}