xref: /rk3399_rockchip-uboot/arch/powerpc/lib/interrupts.c (revision deff9b1d2ab24955cc4f881d63a701f40d6b491f)
1a47a12beSStefan Roese /*
2a47a12beSStefan Roese  * (C) Copyright 2000-2002
3a47a12beSStefan Roese  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4a47a12beSStefan Roese  *
5a47a12beSStefan Roese  * (C) Copyright 2003
6a47a12beSStefan Roese  * Gleb Natapov <gnatapov@mrv.com>
7a47a12beSStefan Roese  *
81a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
9a47a12beSStefan Roese  */
10a47a12beSStefan Roese 
11a47a12beSStefan Roese #include <common.h>
12a47a12beSStefan Roese #include <asm/processor.h>
13a47a12beSStefan Roese #include <watchdog.h>
142d8d190cSUri Mashiach #ifdef CONFIG_LED_STATUS
15a47a12beSStefan Roese #include <status_led.h>
16a47a12beSStefan Roese #endif
17a47a12beSStefan Roese 
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 }
48a47a12beSStefan Roese 
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 
interrupt_init(void)64a47a12beSStefan Roese int interrupt_init (void)
65a47a12beSStefan Roese {
66a47a12beSStefan Roese 	/* call cpu specific function from $(CPU)/interrupts.c */
67*deff9b1dSTom Rini 	interrupt_init_cpu (&decrementer_count);
68a47a12beSStefan Roese 
69a47a12beSStefan Roese 	set_dec (decrementer_count);
70a47a12beSStefan Roese 
71a47a12beSStefan Roese 	set_msr (get_msr () | MSR_EE);
72a47a12beSStefan Roese 
73a47a12beSStefan Roese 	return (0);
74a47a12beSStefan Roese }
75a47a12beSStefan Roese 
76a47a12beSStefan Roese static volatile ulong timestamp = 0;
77a47a12beSStefan Roese 
timer_interrupt(struct pt_regs * regs)78a47a12beSStefan Roese void timer_interrupt (struct pt_regs *regs)
79a47a12beSStefan Roese {
80a47a12beSStefan Roese 	/* call cpu specific function from $(CPU)/interrupts.c */
81a47a12beSStefan Roese 	timer_interrupt_cpu (regs);
82a47a12beSStefan Roese 
83a47a12beSStefan Roese 	/* Restore Decrementer Count */
84a47a12beSStefan Roese 	set_dec (decrementer_count);
85a47a12beSStefan Roese 
86a47a12beSStefan Roese 	timestamp++;
87a47a12beSStefan Roese 
88a47a12beSStefan Roese #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
89a47a12beSStefan Roese 	if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
90a47a12beSStefan Roese 		WATCHDOG_RESET ();
91a47a12beSStefan Roese #endif    /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
92a47a12beSStefan Roese 
932d8d190cSUri Mashiach #ifdef CONFIG_LED_STATUS
94a47a12beSStefan Roese 	status_led_tick (timestamp);
952d8d190cSUri Mashiach #endif /* CONFIG_LED_STATUS */
96a47a12beSStefan Roese 
97a47a12beSStefan Roese #ifdef CONFIG_SHOW_ACTIVITY
98a47a12beSStefan Roese 	board_show_activity (timestamp);
99a47a12beSStefan Roese #endif /* CONFIG_SHOW_ACTIVITY */
100a47a12beSStefan Roese }
101a47a12beSStefan Roese 
get_timer(ulong base)102a47a12beSStefan Roese ulong get_timer (ulong base)
103a47a12beSStefan Roese {
104a47a12beSStefan Roese 	return (timestamp - base);
105a47a12beSStefan Roese }
106