blob: 92b8a0bceacf4a89b3b4c0f38984aeb39e38c107 [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
Tom Rinidec7ea02024-05-20 13:35:03 -060010#include <asm/ppc.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
Simon Glass6b9f0102020-05-10 11:40:06 -060017#include <asm/ptrace.h>
wdenkc0aa5c52003-12-06 19:49:23 +000018
Mario Six3c516552018-08-06 10:23:38 +020019#ifndef CONFIG_MPC83XX_TIMER
Tom Rini364d0022023-01-10 11:19:45 -050020#ifndef CFG_SYS_WATCHDOG_FREQ
21#define CFG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
wdenkc0aa5c52003-12-06 19:49:23 +000022#endif
23
wdenkc0aa5c52003-12-06 19:49:23 +000024static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
25
wdenkc0aa5c52003-12-06 19:49:23 +000026static __inline__ unsigned long get_dec (void)
27{
28 unsigned long val;
29
30 asm volatile ("mfdec %0":"=r" (val):);
31
32 return val;
33}
34
35
36static __inline__ void set_dec (unsigned long val)
37{
38 if (val)
39 asm volatile ("mtdec %0"::"r" (val));
40}
Mario Six3c516552018-08-06 10:23:38 +020041#endif /* !CONFIG_MPC83XX_TIMER */
wdenkc0aa5c52003-12-06 19:49:23 +000042
Simon Glassf87959b2019-11-14 12:57:40 -070043void enable_interrupts(void)
wdenkc0aa5c52003-12-06 19:49:23 +000044{
45 set_msr (get_msr () | MSR_EE);
46}
47
48/* returns flag if MSR_EE was set before */
Simon Glassf87959b2019-11-14 12:57:40 -070049int disable_interrupts(void)
wdenkc0aa5c52003-12-06 19:49:23 +000050{
51 ulong msr = get_msr ();
52
53 set_msr (msr & ~MSR_EE);
54 return ((msr & MSR_EE) != 0);
55}
56
Mario Six3c516552018-08-06 10:23:38 +020057#ifndef CONFIG_MPC83XX_TIMER
Simon Glassf87959b2019-11-14 12:57:40 -070058int interrupt_init(void)
wdenkc0aa5c52003-12-06 19:49:23 +000059{
wdenk1ebf41e2004-01-02 14:00:00 +000060 /* call cpu specific function from $(CPU)/interrupts.c */
Tom Rinice103982017-08-13 22:44:37 -040061 interrupt_init_cpu (&decrementer_count);
wdenkc0aa5c52003-12-06 19:49:23 +000062
63 set_dec (decrementer_count);
64
65 set_msr (get_msr () | MSR_EE);
66
67 return (0);
68}
69
70static volatile ulong timestamp = 0;
71
Simon Glassf87959b2019-11-14 12:57:40 -070072void timer_interrupt(struct pt_regs *regs)
wdenkc0aa5c52003-12-06 19:49:23 +000073{
74 /* call cpu specific function from $(CPU)/interrupts.c */
75 timer_interrupt_cpu (regs);
76
77 /* Restore Decrementer Count */
78 set_dec (decrementer_count);
79
80 timestamp++;
81
82#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
Tom Rini364d0022023-01-10 11:19:45 -050083 if (CFG_SYS_WATCHDOG_FREQ && (timestamp % (CFG_SYS_WATCHDOG_FREQ)) == 0)
Stefan Roese80877fa2022-09-02 14:10:46 +020084 schedule();
wdenkc0aa5c52003-12-06 19:49:23 +000085#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
86
Uri Mashiach4892d392017-01-19 10:51:45 +020087#ifdef CONFIG_LED_STATUS
Simon Glass9ea8f9f2019-11-14 12:57:12 -070088 status_led_tick(timestamp);
Uri Mashiach4892d392017-01-19 10:51:45 +020089#endif /* CONFIG_LED_STATUS */
wdenkc0aa5c52003-12-06 19:49:23 +000090}
91
wdenkc0aa5c52003-12-06 19:49:23 +000092ulong get_timer (ulong base)
93{
94 return (timestamp - base);
95}
Mario Six3c516552018-08-06 10:23:38 +020096#endif /* !CONFIG_MPC83XX_TIMER */