xref: /rk3399_rockchip-uboot/arch/powerpc/lib/interrupts.c (revision 2d8d190c8394b43c0989cdb04a50cb48d4e1f8da)
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>
14*2d8d190cSUri 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 
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 extern int interrupt_init_cpu (unsigned *);
32a47a12beSStefan Roese extern void timer_interrupt_cpu (struct pt_regs *);
33a47a12beSStefan Roese 
34a47a12beSStefan Roese static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
35a47a12beSStefan Roese 
36a47a12beSStefan Roese static __inline__ unsigned long get_msr (void)
37a47a12beSStefan Roese {
38a47a12beSStefan Roese 	unsigned long msr;
39a47a12beSStefan Roese 
40a47a12beSStefan Roese 	asm volatile ("mfmsr %0":"=r" (msr):);
41a47a12beSStefan Roese 
42a47a12beSStefan Roese 	return msr;
43a47a12beSStefan Roese }
44a47a12beSStefan Roese 
45a47a12beSStefan Roese static __inline__ void set_msr (unsigned long msr)
46a47a12beSStefan Roese {
47a47a12beSStefan Roese 	asm volatile ("mtmsr %0"::"r" (msr));
48a47a12beSStefan Roese }
49a47a12beSStefan Roese 
50a47a12beSStefan Roese static __inline__ unsigned long get_dec (void)
51a47a12beSStefan Roese {
52a47a12beSStefan Roese 	unsigned long val;
53a47a12beSStefan Roese 
54a47a12beSStefan Roese 	asm volatile ("mfdec %0":"=r" (val):);
55a47a12beSStefan Roese 
56a47a12beSStefan Roese 	return val;
57a47a12beSStefan Roese }
58a47a12beSStefan Roese 
59a47a12beSStefan Roese 
60a47a12beSStefan Roese static __inline__ void set_dec (unsigned long val)
61a47a12beSStefan Roese {
62a47a12beSStefan Roese 	if (val)
63a47a12beSStefan Roese 		asm volatile ("mtdec %0"::"r" (val));
64a47a12beSStefan Roese }
65a47a12beSStefan Roese 
66a47a12beSStefan Roese 
67a47a12beSStefan Roese void enable_interrupts (void)
68a47a12beSStefan Roese {
69a47a12beSStefan Roese 	set_msr (get_msr () | MSR_EE);
70a47a12beSStefan Roese }
71a47a12beSStefan Roese 
72a47a12beSStefan Roese /* returns flag if MSR_EE was set before */
73a47a12beSStefan Roese int disable_interrupts (void)
74a47a12beSStefan Roese {
75a47a12beSStefan Roese 	ulong msr = get_msr ();
76a47a12beSStefan Roese 
77a47a12beSStefan Roese 	set_msr (msr & ~MSR_EE);
78a47a12beSStefan Roese 	return ((msr & MSR_EE) != 0);
79a47a12beSStefan Roese }
80a47a12beSStefan Roese 
81a47a12beSStefan Roese int interrupt_init (void)
82a47a12beSStefan Roese {
83a47a12beSStefan Roese 	int ret;
84a47a12beSStefan Roese 
85a47a12beSStefan Roese 	/* call cpu specific function from $(CPU)/interrupts.c */
86a47a12beSStefan Roese 	ret = interrupt_init_cpu (&decrementer_count);
87a47a12beSStefan Roese 
88a47a12beSStefan Roese 	if (ret)
89a47a12beSStefan Roese 		return ret;
90a47a12beSStefan Roese 
91a47a12beSStefan Roese 	set_dec (decrementer_count);
92a47a12beSStefan Roese 
93a47a12beSStefan Roese 	set_msr (get_msr () | MSR_EE);
94a47a12beSStefan Roese 
95a47a12beSStefan Roese 	return (0);
96a47a12beSStefan Roese }
97a47a12beSStefan Roese 
98a47a12beSStefan Roese static volatile ulong timestamp = 0;
99a47a12beSStefan Roese 
100a47a12beSStefan Roese void timer_interrupt (struct pt_regs *regs)
101a47a12beSStefan Roese {
102a47a12beSStefan Roese 	/* call cpu specific function from $(CPU)/interrupts.c */
103a47a12beSStefan Roese 	timer_interrupt_cpu (regs);
104a47a12beSStefan Roese 
105a47a12beSStefan Roese 	/* Restore Decrementer Count */
106a47a12beSStefan Roese 	set_dec (decrementer_count);
107a47a12beSStefan Roese 
108a47a12beSStefan Roese 	timestamp++;
109a47a12beSStefan Roese 
110a47a12beSStefan Roese #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
111a47a12beSStefan Roese 	if ((timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0)
112a47a12beSStefan Roese 		WATCHDOG_RESET ();
113a47a12beSStefan Roese #endif    /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
114a47a12beSStefan Roese 
115*2d8d190cSUri Mashiach #ifdef CONFIG_LED_STATUS
116a47a12beSStefan Roese 	status_led_tick (timestamp);
117*2d8d190cSUri Mashiach #endif /* CONFIG_LED_STATUS */
118a47a12beSStefan Roese 
119a47a12beSStefan Roese #ifdef CONFIG_SHOW_ACTIVITY
120a47a12beSStefan Roese 	board_show_activity (timestamp);
121a47a12beSStefan Roese #endif /* CONFIG_SHOW_ACTIVITY */
122a47a12beSStefan Roese }
123a47a12beSStefan Roese 
124a47a12beSStefan Roese ulong get_timer (ulong base)
125a47a12beSStefan Roese {
126a47a12beSStefan Roese 	return (timestamp - base);
127a47a12beSStefan Roese }
128