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