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