blob: 64ee0cc21024f84b7a176cded82d8fdcf1a94fdb [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>
Simon Glass9b61c7c2019-11-14 12:57:41 -070011#include <irq_func.h>
wdenkc0aa5c52003-12-06 19:49:23 +000012#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
Mario Six3c516552018-08-06 10:23:38 +020018#ifndef CONFIG_MPC83XX_TIMER
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020019#ifndef CONFIG_SYS_WATCHDOG_FREQ
20#define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
wdenkc0aa5c52003-12-06 19:49:23 +000021#endif
22
wdenkc0aa5c52003-12-06 19:49:23 +000023static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
24
wdenkc0aa5c52003-12-06 19:49:23 +000025static __inline__ unsigned long get_dec (void)
26{
27 unsigned long val;
28
29 asm volatile ("mfdec %0":"=r" (val):);
30
31 return val;
32}
33
34
35static __inline__ void set_dec (unsigned long val)
36{
37 if (val)
38 asm volatile ("mtdec %0"::"r" (val));
39}
Mario Six3c516552018-08-06 10:23:38 +020040#endif /* !CONFIG_MPC83XX_TIMER */
wdenkc0aa5c52003-12-06 19:49:23 +000041
Simon Glassf87959b2019-11-14 12:57:40 -070042void enable_interrupts(void)
wdenkc0aa5c52003-12-06 19:49:23 +000043{
44 set_msr (get_msr () | MSR_EE);
45}
46
47/* returns flag if MSR_EE was set before */
Simon Glassf87959b2019-11-14 12:57:40 -070048int disable_interrupts(void)
wdenkc0aa5c52003-12-06 19:49:23 +000049{
50 ulong msr = get_msr ();
51
52 set_msr (msr & ~MSR_EE);
53 return ((msr & MSR_EE) != 0);
54}
55
Mario Six3c516552018-08-06 10:23:38 +020056#ifndef CONFIG_MPC83XX_TIMER
Simon Glassf87959b2019-11-14 12:57:40 -070057int interrupt_init(void)
wdenkc0aa5c52003-12-06 19:49:23 +000058{
wdenk1ebf41e2004-01-02 14:00:00 +000059 /* call cpu specific function from $(CPU)/interrupts.c */
Tom Rinice103982017-08-13 22:44:37 -040060 interrupt_init_cpu (&decrementer_count);
wdenkc0aa5c52003-12-06 19:49:23 +000061
62 set_dec (decrementer_count);
63
64 set_msr (get_msr () | MSR_EE);
65
66 return (0);
67}
68
69static volatile ulong timestamp = 0;
70
Simon Glassf87959b2019-11-14 12:57:40 -070071void timer_interrupt(struct pt_regs *regs)
wdenkc0aa5c52003-12-06 19:49:23 +000072{
73 /* call cpu specific function from $(CPU)/interrupts.c */
74 timer_interrupt_cpu (regs);
75
76 /* Restore Decrementer Count */
77 set_dec (decrementer_count);
78
79 timestamp++;
80
81#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +020082 if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
wdenkc0aa5c52003-12-06 19:49:23 +000083 WATCHDOG_RESET ();
84#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
85
Uri Mashiach4892d392017-01-19 10:51:45 +020086#ifdef CONFIG_LED_STATUS
Simon Glass9ea8f9f2019-11-14 12:57:12 -070087 status_led_tick(timestamp);
Uri Mashiach4892d392017-01-19 10:51:45 +020088#endif /* CONFIG_LED_STATUS */
wdenkc0aa5c52003-12-06 19:49:23 +000089}
90
wdenkc0aa5c52003-12-06 19:49:23 +000091ulong get_timer (ulong base)
92{
93 return (timestamp - base);
94}
Mario Six3c516552018-08-06 10:23:38 +020095#endif /* !CONFIG_MPC83XX_TIMER */