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