1 /* 2 * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved. 3 * Copyright (c) 2024, Altera Corporation. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <assert.h> 9 #include <arch_helpers.h> 10 #include <drivers/delay_timer.h> 11 #include <lib/mmio.h> 12 #include "socfpga_plat_def.h" 13 14 #if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX 15 #include "agilex_clock_manager.h" 16 #elif PLATFORM_MODEL == PLAT_SOCFPGA_N5X 17 #include "n5x_clock_manager.h" 18 #elif PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10 19 #include "s10_clock_manager.h" 20 #endif 21 22 #define SOCFPGA_GLOBAL_TIMER PLAT_TIMER_BASE_ADDR 23 #define SOCFPGA_GLOBAL_TIMER_EN 0x3 24 25 static timer_ops_t plat_timer_ops; 26 /******************************************************************** 27 * The timer delay function 28 ********************************************************************/ socfpga_get_timer_value(void)29static uint32_t socfpga_get_timer_value(void) 30 { 31 /* 32 * Generic delay timer implementation expects the timer to be a down 33 * counter. We apply bitwise NOT operator to the tick values returned 34 * by read_cntpct_el0() to simulate the down counter. The value is 35 * clipped from 64 to 32 bits. 36 */ 37 return (uint32_t)(~read_cntpct_el0()); 38 } 39 socfpga_delay_timer_init_args(void)40void socfpga_delay_timer_init_args(void) 41 { 42 plat_timer_ops.get_timer_value = socfpga_get_timer_value; 43 plat_timer_ops.clk_mult = 1; 44 plat_timer_ops.clk_div = PLAT_SYS_COUNTER_FREQ_IN_MHZ; 45 46 timer_init(&plat_timer_ops); 47 } 48 socfpga_delay_timer_init(void)49void socfpga_delay_timer_init(void) 50 { 51 socfpga_delay_timer_init_args(); 52 mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN); 53 54 asm volatile("msr cntp_ctl_el0, %0" : : "r" (SOCFPGA_GLOBAL_TIMER_EN)); 55 asm volatile("msr cntp_tval_el0, %0" : : "r" (~0)); 56 } 57