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