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