1 /* 2 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 3 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <arch.h> 9 10 #include <drivers/delay_timer.h> 11 #include <lib/mmio.h> 12 #include <lib/utils_def.h> 13 #include <plat/common/platform.h> 14 15 #include <tegra_def.h> 16 #include <tegra_private.h> 17 tegra_timer_get_value(void)18static uint32_t tegra_timer_get_value(void) 19 { 20 /* enable cntps_tval_el1 timer, mask interrupt */ 21 write_cntps_ctl_el1(CNTP_CTL_IMASK_BIT | CNTP_CTL_ENABLE_BIT); 22 23 /* 24 * Generic delay timer implementation expects the timer to be a down 25 * counter. The value is clipped from 64 to 32 bits. 26 */ 27 return (uint32_t)(read_cntps_tval_el1()); 28 } 29 30 /* 31 * Initialise the architecture provided counter as the delay timer. 32 */ tegra_delay_timer_init(void)33void tegra_delay_timer_init(void) 34 { 35 static timer_ops_t tegra_timer_ops; 36 37 /* Value in ticks */ 38 uint32_t multiplier = MHZ_TICKS_PER_SEC; 39 40 /* Value in ticks per second (Hz) */ 41 uint32_t divider = plat_get_syscnt_freq2(); 42 43 /* Reduce multiplier and divider by dividing them repeatedly by 10 */ 44 while (((multiplier % 10U) == 0U) && ((divider % 10U) == 0U)) { 45 multiplier /= 10U; 46 divider /= 10U; 47 } 48 49 /* enable cntps_tval_el1 timer, mask interrupt */ 50 write_cntps_ctl_el1(CNTP_CTL_IMASK_BIT | CNTP_CTL_ENABLE_BIT); 51 52 /* register the timer */ 53 tegra_timer_ops.get_timer_value = tegra_timer_get_value; 54 tegra_timer_ops.clk_mult = multiplier; 55 tegra_timer_ops.clk_div = divider; 56 timer_init(&tegra_timer_ops); 57 } 58