xref: /openbmc/u-boot/arch/powerpc/lib/interrupts.c (revision 4e710ebb4463c8e031eb269c012fbadb2479608b)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2a47a12beSStefan Roese /*
3a47a12beSStefan Roese  * (C) Copyright 2000-2002
4a47a12beSStefan Roese  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5a47a12beSStefan Roese  *
6a47a12beSStefan Roese  * (C) Copyright 2003
7a47a12beSStefan Roese  * Gleb Natapov <gnatapov@mrv.com>
8a47a12beSStefan Roese  */
9a47a12beSStefan Roese 
10a47a12beSStefan Roese #include <common.h>
11a47a12beSStefan Roese #include <asm/processor.h>
12a47a12beSStefan Roese #include <watchdog.h>
132d8d190cSUri Mashiach #ifdef CONFIG_LED_STATUS
14a47a12beSStefan Roese #include <status_led.h>
15a47a12beSStefan Roese #endif
16a47a12beSStefan Roese 
17*2c21749dSMario Six #ifndef CONFIG_MPC83XX_TIMER
18a47a12beSStefan Roese #ifdef CONFIG_SHOW_ACTIVITY
19a47a12beSStefan Roese void board_show_activity (ulong) __attribute__((weak, alias("__board_show_activity")));
20a47a12beSStefan Roese 
__board_show_activity(ulong dummy)21a47a12beSStefan Roese void __board_show_activity (ulong dummy)
22a47a12beSStefan Roese {
23a47a12beSStefan Roese 	return;
24a47a12beSStefan Roese }
25a47a12beSStefan Roese #endif /* CONFIG_SHOW_ACTIVITY */
26a47a12beSStefan Roese 
27a47a12beSStefan Roese #ifndef CONFIG_SYS_WATCHDOG_FREQ
28a47a12beSStefan Roese #define CONFIG_SYS_WATCHDOG_FREQ (CONFIG_SYS_HZ / 2)
29a47a12beSStefan Roese #endif
30a47a12beSStefan Roese 
31a47a12beSStefan Roese static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
32a47a12beSStefan Roese 
get_dec(void)33a47a12beSStefan Roese static __inline__ unsigned long get_dec (void)
34a47a12beSStefan Roese {
35a47a12beSStefan Roese 	unsigned long val;
36a47a12beSStefan Roese 
37a47a12beSStefan Roese 	asm volatile ("mfdec %0":"=r" (val):);
38a47a12beSStefan Roese 
39a47a12beSStefan Roese 	return val;
40a47a12beSStefan Roese }
41a47a12beSStefan Roese 
42a47a12beSStefan Roese 
set_dec(unsigned long val)43a47a12beSStefan Roese static __inline__ void set_dec (unsigned long val)
44a47a12beSStefan Roese {
45a47a12beSStefan Roese 	if (val)
46a47a12beSStefan Roese 		asm volatile ("mtdec %0"::"r" (val));
47a47a12beSStefan Roese }
48*2c21749dSMario Six #endif /* !CONFIG_MPC83XX_TIMER */
49a47a12beSStefan Roese 
enable_interrupts(void)50a47a12beSStefan Roese void enable_interrupts (void)
51a47a12beSStefan Roese {
52a47a12beSStefan Roese 	set_msr (get_msr () | MSR_EE);
53a47a12beSStefan Roese }
54a47a12beSStefan Roese 
55a47a12beSStefan Roese /* returns flag if MSR_EE was set before */
disable_interrupts(void)56a47a12beSStefan Roese int disable_interrupts (void)
57a47a12beSStefan Roese {
58a47a12beSStefan Roese 	ulong msr = get_msr ();
59a47a12beSStefan Roese 
60a47a12beSStefan Roese 	set_msr (msr & ~MSR_EE);
61a47a12beSStefan Roese 	return ((msr & MSR_EE) != 0);
62a47a12beSStefan Roese }
63a47a12beSStefan Roese 
64*2c21749dSMario Six #ifndef CONFIG_MPC83XX_TIMER
interrupt_init(void)65a47a12beSStefan Roese int interrupt_init (void)
66a47a12beSStefan Roese {
67a47a12beSStefan Roese 	/* call cpu specific function from $(CPU)/interrupts.c */
68deff9b1dSTom Rini 	interrupt_init_cpu (&decrementer_count);
69a47a12beSStefan Roese 
70a47a12beSStefan Roese 	set_dec (decrementer_count);
71a47a12beSStefan Roese 
72a47a12beSStefan Roese 	set_msr (get_msr () | MSR_EE);
73a47a12beSStefan Roese 
74a47a12beSStefan Roese 	return (0);
75a47a12beSStefan Roese }
76a47a12beSStefan Roese 
77a47a12beSStefan Roese static volatile ulong timestamp = 0;
78a47a12beSStefan Roese 
timer_interrupt(struct pt_regs * regs)79a47a12beSStefan Roese void timer_interrupt (struct pt_regs *regs)
80a47a12beSStefan Roese {
81a47a12beSStefan Roese 	/* call cpu specific function from $(CPU)/interrupts.c */
82a47a12beSStefan Roese 	timer_interrupt_cpu (regs);
83a47a12beSStefan Roese 
84a47a12beSStefan Roese 	/* Restore Decrementer Count */
85a47a12beSStefan Roese 	set_dec (decrementer_count);
86a47a12beSStefan Roese 
87a47a12beSStefan Roese 	timestamp++;
88a47a12beSStefan Roese 
89a47a12beSStefan Roese #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
90a47a12beSStefan Roese 	if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
91a47a12beSStefan Roese 		WATCHDOG_RESET ();
92a47a12beSStefan Roese #endif    /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
93a47a12beSStefan Roese 
942d8d190cSUri Mashiach #ifdef CONFIG_LED_STATUS
95a47a12beSStefan Roese 	status_led_tick (timestamp);
962d8d190cSUri Mashiach #endif /* CONFIG_LED_STATUS */
97a47a12beSStefan Roese 
98a47a12beSStefan Roese #ifdef CONFIG_SHOW_ACTIVITY
99a47a12beSStefan Roese 	board_show_activity (timestamp);
100a47a12beSStefan Roese #endif /* CONFIG_SHOW_ACTIVITY */
101a47a12beSStefan Roese }
102a47a12beSStefan Roese 
get_timer(ulong base)103a47a12beSStefan Roese ulong get_timer (ulong base)
104a47a12beSStefan Roese {
105a47a12beSStefan Roese 	return (timestamp - base);
106a47a12beSStefan Roese }
107*2c21749dSMario Six #endif /* !CONFIG_MPC83XX_TIMER */
108