1fa9c08b7SAchin Gupta /* 2*fd650ff6SSoby Mathew * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. 3fa9c08b7SAchin Gupta * 4fa9c08b7SAchin Gupta * Redistribution and use in source and binary forms, with or without 5fa9c08b7SAchin Gupta * modification, are permitted provided that the following conditions are met: 6fa9c08b7SAchin Gupta * 7fa9c08b7SAchin Gupta * Redistributions of source code must retain the above copyright notice, this 8fa9c08b7SAchin Gupta * list of conditions and the following disclaimer. 9fa9c08b7SAchin Gupta * 10fa9c08b7SAchin Gupta * Redistributions in binary form must reproduce the above copyright notice, 11fa9c08b7SAchin Gupta * this list of conditions and the following disclaimer in the documentation 12fa9c08b7SAchin Gupta * and/or other materials provided with the distribution. 13fa9c08b7SAchin Gupta * 14fa9c08b7SAchin Gupta * Neither the name of ARM nor the names of its contributors may be used 15fa9c08b7SAchin Gupta * to endorse or promote products derived from this software without specific 16fa9c08b7SAchin Gupta * prior written permission. 17fa9c08b7SAchin Gupta * 18fa9c08b7SAchin Gupta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19fa9c08b7SAchin Gupta * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20fa9c08b7SAchin Gupta * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21fa9c08b7SAchin Gupta * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22fa9c08b7SAchin Gupta * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23fa9c08b7SAchin Gupta * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24fa9c08b7SAchin Gupta * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25fa9c08b7SAchin Gupta * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26fa9c08b7SAchin Gupta * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27fa9c08b7SAchin Gupta * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28fa9c08b7SAchin Gupta * POSSIBILITY OF SUCH DAMAGE. 29fa9c08b7SAchin Gupta */ 30fa9c08b7SAchin Gupta #include <arch_helpers.h> 31fa9c08b7SAchin Gupta #include <assert.h> 325f0cdb05SDan Handley #include <platform.h> 33da0af78aSDan Handley #include "tsp_private.h" 34fa9c08b7SAchin Gupta 35fa9c08b7SAchin Gupta /******************************************************************************* 36fa9c08b7SAchin Gupta * Data structure to keep track of per-cpu secure generic timer context across 37fa9c08b7SAchin Gupta * power management operations. 38fa9c08b7SAchin Gupta ******************************************************************************/ 39fa9c08b7SAchin Gupta typedef struct timer_context { 40fa9c08b7SAchin Gupta uint64_t cval; 41fa9c08b7SAchin Gupta uint32_t ctl; 42fa9c08b7SAchin Gupta } timer_context_t; 43fa9c08b7SAchin Gupta 44fa9c08b7SAchin Gupta static timer_context_t pcpu_timer_context[PLATFORM_CORE_COUNT]; 45fa9c08b7SAchin Gupta 46fa9c08b7SAchin Gupta /******************************************************************************* 47fa9c08b7SAchin Gupta * This function initializes the generic timer to fire every 0.5 second 48fa9c08b7SAchin Gupta ******************************************************************************/ 494f2104ffSJuan Castillo void tsp_generic_timer_start(void) 50fa9c08b7SAchin Gupta { 51fa9c08b7SAchin Gupta uint64_t cval; 52fa9c08b7SAchin Gupta uint32_t ctl = 0; 53fa9c08b7SAchin Gupta 54fa9c08b7SAchin Gupta /* The timer will fire every 0.5 second */ 55fa9c08b7SAchin Gupta cval = read_cntpct_el0() + (read_cntfrq_el0() >> 1); 56fa9c08b7SAchin Gupta write_cntps_cval_el1(cval); 57fa9c08b7SAchin Gupta 58fa9c08b7SAchin Gupta /* Enable the secure physical timer */ 59fa9c08b7SAchin Gupta set_cntp_ctl_enable(ctl); 60fa9c08b7SAchin Gupta write_cntps_ctl_el1(ctl); 61fa9c08b7SAchin Gupta } 62fa9c08b7SAchin Gupta 63fa9c08b7SAchin Gupta /******************************************************************************* 64fa9c08b7SAchin Gupta * This function deasserts the timer interrupt and sets it up again 65fa9c08b7SAchin Gupta ******************************************************************************/ 664f2104ffSJuan Castillo void tsp_generic_timer_handler(void) 67fa9c08b7SAchin Gupta { 68fa9c08b7SAchin Gupta /* Ensure that the timer did assert the interrupt */ 69fa9c08b7SAchin Gupta assert(get_cntp_ctl_istatus(read_cntps_ctl_el1())); 70fa9c08b7SAchin Gupta 71edfda10aSSandrine Bailleux /* 72edfda10aSSandrine Bailleux * Disable the timer and reprogram it. The barriers ensure that there is 73edfda10aSSandrine Bailleux * no reordering of instructions around the reprogramming code. 74edfda10aSSandrine Bailleux */ 75edfda10aSSandrine Bailleux isb(); 76fa9c08b7SAchin Gupta write_cntps_ctl_el1(0); 77fa9c08b7SAchin Gupta tsp_generic_timer_start(); 78edfda10aSSandrine Bailleux isb(); 79fa9c08b7SAchin Gupta } 80fa9c08b7SAchin Gupta 81fa9c08b7SAchin Gupta /******************************************************************************* 82fa9c08b7SAchin Gupta * This function deasserts the timer interrupt prior to cpu power down 83fa9c08b7SAchin Gupta ******************************************************************************/ 844f2104ffSJuan Castillo void tsp_generic_timer_stop(void) 85fa9c08b7SAchin Gupta { 86fa9c08b7SAchin Gupta /* Disable the timer */ 87fa9c08b7SAchin Gupta write_cntps_ctl_el1(0); 88fa9c08b7SAchin Gupta } 89fa9c08b7SAchin Gupta 90fa9c08b7SAchin Gupta /******************************************************************************* 91fa9c08b7SAchin Gupta * This function saves the timer context prior to cpu suspension 92fa9c08b7SAchin Gupta ******************************************************************************/ 934f2104ffSJuan Castillo void tsp_generic_timer_save(void) 94fa9c08b7SAchin Gupta { 95*fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 96fa9c08b7SAchin Gupta 97fa9c08b7SAchin Gupta pcpu_timer_context[linear_id].cval = read_cntps_cval_el1(); 98fa9c08b7SAchin Gupta pcpu_timer_context[linear_id].ctl = read_cntps_ctl_el1(); 99fa9c08b7SAchin Gupta flush_dcache_range((uint64_t) &pcpu_timer_context[linear_id], 100fa9c08b7SAchin Gupta sizeof(pcpu_timer_context[linear_id])); 101fa9c08b7SAchin Gupta } 102fa9c08b7SAchin Gupta 103fa9c08b7SAchin Gupta /******************************************************************************* 104fa9c08b7SAchin Gupta * This function restores the timer context post cpu resummption 105fa9c08b7SAchin Gupta ******************************************************************************/ 1064f2104ffSJuan Castillo void tsp_generic_timer_restore(void) 107fa9c08b7SAchin Gupta { 108*fd650ff6SSoby Mathew uint32_t linear_id = plat_my_core_pos(); 109fa9c08b7SAchin Gupta 110fa9c08b7SAchin Gupta write_cntps_cval_el1(pcpu_timer_context[linear_id].cval); 111fa9c08b7SAchin Gupta write_cntps_ctl_el1(pcpu_timer_context[linear_id].ctl); 112fa9c08b7SAchin Gupta } 113