Hadi Asyrafi | 616da77 | 2019-06-27 11:34:03 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2019, 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 | |
Hadi Asyrafi | 6a240c7 | 2019-08-01 15:21:20 +0800 | [diff] [blame] | 12 | #define SOCFPGA_GLOBAL_TIMER 0xffd01000 |
| 13 | #define SOCFPGA_GLOBAL_TIMER_EN 0x3 |
Hadi Asyrafi | 616da77 | 2019-06-27 11:34:03 +0800 | [diff] [blame] | 14 | |
| 15 | /******************************************************************** |
| 16 | * The timer delay function |
| 17 | ********************************************************************/ |
| 18 | static uint32_t socfpga_get_timer_value(void) |
| 19 | { |
| 20 | /* |
| 21 | * Generic delay timer implementation expects the timer to be a down |
| 22 | * counter. We apply bitwise NOT operator to the tick values returned |
| 23 | * by read_cntpct_el0() to simulate the down counter. The value is |
| 24 | * clipped from 64 to 32 bits. |
| 25 | */ |
| 26 | return (uint32_t)(~read_cntpct_el0()); |
| 27 | } |
| 28 | |
| 29 | static const timer_ops_t plat_timer_ops = { |
| 30 | .get_timer_value = socfpga_get_timer_value, |
| 31 | .clk_mult = 1, |
| 32 | .clk_div = PLAT_SYS_COUNTER_FREQ_IN_MHZ, |
| 33 | }; |
| 34 | |
| 35 | void socfpga_delay_timer_init(void) |
| 36 | { |
| 37 | timer_init(&plat_timer_ops); |
Hadi Asyrafi | 6a240c7 | 2019-08-01 15:21:20 +0800 | [diff] [blame] | 38 | mmio_write_32(SOCFPGA_GLOBAL_TIMER, SOCFPGA_GLOBAL_TIMER_EN); |
Hadi Asyrafi | 616da77 | 2019-06-27 11:34:03 +0800 | [diff] [blame] | 39 | } |