xref: /rk3399_ARM-atf/bl32/tsp/tsp_timer.c (revision 82cb2c1ad9897473743f08437d0a3995bed561b9)
1fa9c08b7SAchin Gupta /*
2fd650ff6SSoby Mathew  * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
3fa9c08b7SAchin Gupta  *
4*82cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
5fa9c08b7SAchin Gupta  */
6fa9c08b7SAchin Gupta #include <arch_helpers.h>
7fa9c08b7SAchin Gupta #include <assert.h>
85f0cdb05SDan Handley #include <platform.h>
9da0af78aSDan Handley #include "tsp_private.h"
10fa9c08b7SAchin Gupta 
11fa9c08b7SAchin Gupta /*******************************************************************************
12fa9c08b7SAchin Gupta  * Data structure to keep track of per-cpu secure generic timer context across
13fa9c08b7SAchin Gupta  * power management operations.
14fa9c08b7SAchin Gupta  ******************************************************************************/
15fa9c08b7SAchin Gupta typedef struct timer_context {
16fa9c08b7SAchin Gupta 	uint64_t cval;
17fa9c08b7SAchin Gupta 	uint32_t ctl;
18fa9c08b7SAchin Gupta } timer_context_t;
19fa9c08b7SAchin Gupta 
20fa9c08b7SAchin Gupta static timer_context_t pcpu_timer_context[PLATFORM_CORE_COUNT];
21fa9c08b7SAchin Gupta 
22fa9c08b7SAchin Gupta /*******************************************************************************
23fa9c08b7SAchin Gupta  * This function initializes the generic timer to fire every 0.5 second
24fa9c08b7SAchin Gupta  ******************************************************************************/
254f2104ffSJuan Castillo void tsp_generic_timer_start(void)
26fa9c08b7SAchin Gupta {
27fa9c08b7SAchin Gupta 	uint64_t cval;
28fa9c08b7SAchin Gupta 	uint32_t ctl = 0;
29fa9c08b7SAchin Gupta 
30fa9c08b7SAchin Gupta 	/* The timer will fire every 0.5 second */
31fa9c08b7SAchin Gupta 	cval = read_cntpct_el0() + (read_cntfrq_el0() >> 1);
32fa9c08b7SAchin Gupta 	write_cntps_cval_el1(cval);
33fa9c08b7SAchin Gupta 
34fa9c08b7SAchin Gupta 	/* Enable the secure physical timer */
35fa9c08b7SAchin Gupta 	set_cntp_ctl_enable(ctl);
36fa9c08b7SAchin Gupta 	write_cntps_ctl_el1(ctl);
37fa9c08b7SAchin Gupta }
38fa9c08b7SAchin Gupta 
39fa9c08b7SAchin Gupta /*******************************************************************************
40fa9c08b7SAchin Gupta  * This function deasserts the timer interrupt and sets it up again
41fa9c08b7SAchin Gupta  ******************************************************************************/
424f2104ffSJuan Castillo void tsp_generic_timer_handler(void)
43fa9c08b7SAchin Gupta {
44fa9c08b7SAchin Gupta 	/* Ensure that the timer did assert the interrupt */
45fa9c08b7SAchin Gupta 	assert(get_cntp_ctl_istatus(read_cntps_ctl_el1()));
46fa9c08b7SAchin Gupta 
47edfda10aSSandrine Bailleux 	/*
48edfda10aSSandrine Bailleux 	 * Disable the timer and reprogram it. The barriers ensure that there is
49edfda10aSSandrine Bailleux 	 * no reordering of instructions around the reprogramming code.
50edfda10aSSandrine Bailleux 	 */
51edfda10aSSandrine Bailleux 	isb();
52fa9c08b7SAchin Gupta 	write_cntps_ctl_el1(0);
53fa9c08b7SAchin Gupta 	tsp_generic_timer_start();
54edfda10aSSandrine Bailleux 	isb();
55fa9c08b7SAchin Gupta }
56fa9c08b7SAchin Gupta 
57fa9c08b7SAchin Gupta /*******************************************************************************
58fa9c08b7SAchin Gupta  * This function deasserts the timer interrupt prior to cpu power down
59fa9c08b7SAchin Gupta  ******************************************************************************/
604f2104ffSJuan Castillo void tsp_generic_timer_stop(void)
61fa9c08b7SAchin Gupta {
62fa9c08b7SAchin Gupta 	/* Disable the timer */
63fa9c08b7SAchin Gupta 	write_cntps_ctl_el1(0);
64fa9c08b7SAchin Gupta }
65fa9c08b7SAchin Gupta 
66fa9c08b7SAchin Gupta /*******************************************************************************
67fa9c08b7SAchin Gupta  * This function saves the timer context prior to cpu suspension
68fa9c08b7SAchin Gupta  ******************************************************************************/
694f2104ffSJuan Castillo void tsp_generic_timer_save(void)
70fa9c08b7SAchin Gupta {
71fd650ff6SSoby Mathew 	uint32_t linear_id = plat_my_core_pos();
72fa9c08b7SAchin Gupta 
73fa9c08b7SAchin Gupta 	pcpu_timer_context[linear_id].cval = read_cntps_cval_el1();
74fa9c08b7SAchin Gupta 	pcpu_timer_context[linear_id].ctl = read_cntps_ctl_el1();
75fa9c08b7SAchin Gupta 	flush_dcache_range((uint64_t) &pcpu_timer_context[linear_id],
76fa9c08b7SAchin Gupta 			   sizeof(pcpu_timer_context[linear_id]));
77fa9c08b7SAchin Gupta }
78fa9c08b7SAchin Gupta 
79fa9c08b7SAchin Gupta /*******************************************************************************
80fa9c08b7SAchin Gupta  * This function restores the timer context post cpu resummption
81fa9c08b7SAchin Gupta  ******************************************************************************/
824f2104ffSJuan Castillo void tsp_generic_timer_restore(void)
83fa9c08b7SAchin Gupta {
84fd650ff6SSoby Mathew 	uint32_t linear_id = plat_my_core_pos();
85fa9c08b7SAchin Gupta 
86fa9c08b7SAchin Gupta 	write_cntps_cval_el1(pcpu_timer_context[linear_id].cval);
87fa9c08b7SAchin Gupta 	write_cntps_ctl_el1(pcpu_timer_context[linear_id].ctl);
88fa9c08b7SAchin Gupta }
89