xref: /rk3399_ARM-atf/plat/rockchip/rk3399/drivers/m0/src/stopwatch.c (revision 51faada71a219a8b94cd8d8e423f0f22e9da4d8f)
1 /*
2  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <m0_param.h>
32 #include "rk3399_mcu.h"
33 
34 /* use 24MHz SysTick */
35 #define US_TO_CYCLE(US)	(US * 24)
36 
37 #define SYST_CST	0xe000e010
38 /* enable counter */
39 #define ENABLE		(1 << 0)
40 /* count down to 0 does not cause SysTick exception to pend */
41 #define TICKINT		(1 << 1)
42 /* core clock used for SysTick */
43 #define CLKSOURCE	(1 << 2)
44 
45 #define COUNTFLAG	(1 << 16)
46 #define SYST_RVR	0xe000e014
47 #define MAX_VALUE	0xffffff
48 #define MAX_USECS	(MAX_VALUE / US_TO_CYCLE(1))
49 #define SYST_CVR	0xe000e018
50 #define SYST_CALIB	0xe000e01c
51 
52 unsigned int remaining_usecs;
53 
54 static inline void stopwatch_set_usecs(void)
55 {
56 	unsigned int cycle;
57 	unsigned int usecs = MIN(MAX_USECS, remaining_usecs);
58 
59 	remaining_usecs -= usecs;
60 	cycle = US_TO_CYCLE(usecs);
61 	mmio_write_32(SYST_RVR, cycle);
62 	mmio_write_32(SYST_CVR, 0);
63 
64 	mmio_write_32(SYST_CST, ENABLE | TICKINT | CLKSOURCE);
65 }
66 
67 void stopwatch_init_usecs_expire(unsigned int usecs)
68 {
69 	/*
70 	 * Enter an inifite loop if the stopwatch is in use. This will allow the
71 	 * state to be analyzed with a debugger.
72 	 */
73 	if (mmio_read_32(SYST_CST) & ENABLE)
74 		while (1)
75 			;
76 
77 	remaining_usecs = usecs;
78 	stopwatch_set_usecs();
79 }
80 
81 int stopwatch_expired(void)
82 {
83 	int val = mmio_read_32(SYST_CST);
84 	if ((val & COUNTFLAG) || !(val & ENABLE)) {
85 		if (!remaining_usecs)
86 			return 1;
87 
88 		stopwatch_set_usecs();
89 	}
90 
91 	return 0;
92 }
93 
94 void stopwatch_reset(void)
95 {
96 	mmio_clrbits_32(SYST_CST, ENABLE);
97 	remaining_usecs = 0;
98 }
99