blob: e589933f565695884a25ccc600f349011a625b3b [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
wdenka8c7c702003-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>
wdenka8c7c702003-12-06 19:49:23 +00008 */
9
10#include <common.h>
11#include <asm/processor.h>
12#include <watchdog.h>
Uri Mashiach2d8d1902017-01-19 10:51:45 +020013#ifdef CONFIG_LED_STATUS
wdenka8c7c702003-12-06 19:49:23 +000014#include <status_led.h>
15#endif
16
Mario Six2c217492018-08-06 10:23:38 +020017#ifndef CONFIG_MPC83XX_TIMER
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020018#ifndef CONFIG_SYS_WATCHDOG_FREQ
19#define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
wdenka8c7c702003-12-06 19:49:23 +000020#endif
21
wdenka8c7c702003-12-06 19:49:23 +000022static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
23
wdenka8c7c702003-12-06 19:49:23 +000024static __inline__ unsigned long get_dec (void)
25{
26 unsigned long val;
27
28 asm volatile ("mfdec %0":"=r" (val):);
29
30 return val;
31}
32
33
34static __inline__ void set_dec (unsigned long val)
35{
36 if (val)
37 asm volatile ("mtdec %0"::"r" (val));
38}
Mario Six2c217492018-08-06 10:23:38 +020039#endif /* !CONFIG_MPC83XX_TIMER */
wdenka8c7c702003-12-06 19:49:23 +000040
41void enable_interrupts (void)
42{
43 set_msr (get_msr () | MSR_EE);
44}
45
46/* returns flag if MSR_EE was set before */
47int disable_interrupts (void)
48{
49 ulong msr = get_msr ();
50
51 set_msr (msr & ~MSR_EE);
52 return ((msr & MSR_EE) != 0);
53}
54
Mario Six2c217492018-08-06 10:23:38 +020055#ifndef CONFIG_MPC83XX_TIMER
wdenka8c7c702003-12-06 19:49:23 +000056int interrupt_init (void)
57{
wdenkd4ca31c2004-01-02 14:00:00 +000058 /* call cpu specific function from $(CPU)/interrupts.c */
Tom Rinideff9b12017-08-13 22:44:37 -040059 interrupt_init_cpu (&decrementer_count);
wdenka8c7c702003-12-06 19:49:23 +000060
61 set_dec (decrementer_count);
62
63 set_msr (get_msr () | MSR_EE);
64
65 return (0);
66}
67
68static volatile ulong timestamp = 0;
69
70void timer_interrupt (struct pt_regs *regs)
71{
72 /* call cpu specific function from $(CPU)/interrupts.c */
73 timer_interrupt_cpu (regs);
74
75 /* Restore Decrementer Count */
76 set_dec (decrementer_count);
77
78 timestamp++;
79
80#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020081 if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
wdenka8c7c702003-12-06 19:49:23 +000082 WATCHDOG_RESET ();
83#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
84
Uri Mashiach2d8d1902017-01-19 10:51:45 +020085#ifdef CONFIG_LED_STATUS
wdenkd4ca31c2004-01-02 14:00:00 +000086 status_led_tick (timestamp);
Uri Mashiach2d8d1902017-01-19 10:51:45 +020087#endif /* CONFIG_LED_STATUS */
wdenka8c7c702003-12-06 19:49:23 +000088}
89
wdenka8c7c702003-12-06 19:49:23 +000090ulong get_timer (ulong base)
91{
92 return (timestamp - base);
93}
Mario Six2c217492018-08-06 10:23:38 +020094#endif /* !CONFIG_MPC83XX_TIMER */