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