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