xref: /rk3399_ARM-atf/bl32/tsp/tsp_timer.c (revision 8545a8744b541cc6855e3218c4565e76697fb002)
1 /*
2  * Copyright (c) 2014, 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 #include <arch_helpers.h>
31 #include <assert.h>
32 #include <tsp.h>
33 
34 /*******************************************************************************
35  * Data structure to keep track of per-cpu secure generic timer context across
36  * power management operations.
37  ******************************************************************************/
38 typedef struct timer_context {
39 	uint64_t cval;
40 	uint32_t ctl;
41 } timer_context_t;
42 
43 static timer_context_t pcpu_timer_context[PLATFORM_CORE_COUNT];
44 
45 /*******************************************************************************
46  * This function initializes the generic timer to fire every 0.5 second
47  ******************************************************************************/
48 void tsp_generic_timer_start()
49 {
50 	uint64_t cval;
51 	uint32_t ctl = 0;
52 
53 	/* The timer will fire every 0.5 second */
54 	cval = read_cntpct_el0() + (read_cntfrq_el0() >> 1);
55 	write_cntps_cval_el1(cval);
56 
57 	/* Enable the secure physical timer */
58 	set_cntp_ctl_enable(ctl);
59 	write_cntps_ctl_el1(ctl);
60 }
61 
62 /*******************************************************************************
63  * This function deasserts the timer interrupt and sets it up again
64  ******************************************************************************/
65 void tsp_generic_timer_handler()
66 {
67 	/* Ensure that the timer did assert the interrupt */
68 	assert(get_cntp_ctl_istatus(read_cntps_ctl_el1()));
69 
70 	/* Disable the timer and reprogram it */
71 	write_cntps_ctl_el1(0);
72 	tsp_generic_timer_start();
73 }
74 
75 /*******************************************************************************
76  * This function deasserts the timer interrupt prior to cpu power down
77  ******************************************************************************/
78 void tsp_generic_timer_stop()
79 {
80 	/* Disable the timer */
81 	write_cntps_ctl_el1(0);
82 }
83 
84 /*******************************************************************************
85  * This function saves the timer context prior to cpu suspension
86  ******************************************************************************/
87 void tsp_generic_timer_save()
88 {
89 	uint32_t linear_id = platform_get_core_pos(read_mpidr());
90 
91 	pcpu_timer_context[linear_id].cval = read_cntps_cval_el1();
92 	pcpu_timer_context[linear_id].ctl = read_cntps_ctl_el1();
93 	flush_dcache_range((uint64_t) &pcpu_timer_context[linear_id],
94 			   sizeof(pcpu_timer_context[linear_id]));
95 }
96 
97 /*******************************************************************************
98  * This function restores the timer context post cpu resummption
99  ******************************************************************************/
100 void tsp_generic_timer_restore()
101 {
102 	uint32_t linear_id = platform_get_core_pos(read_mpidr());
103 
104 	write_cntps_cval_el1(pcpu_timer_context[linear_id].cval);
105 	write_cntps_ctl_el1(pcpu_timer_context[linear_id].ctl);
106 }
107