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