Ryan Harkin | 0392579 | 2015-03-17 14:52:39 +0000 | [diff] [blame] | 1 | /* |
Ambroise Vincent | a88a35d | 2019-02-14 09:48:21 +0000 | [diff] [blame] | 2 | * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. |
Ryan Harkin | 0392579 | 2015-03-17 14:52:39 +0000 | [diff] [blame] | 3 | * |
dp-arm | fa3cf0b | 2017-05-03 09:38:09 +0100 | [diff] [blame] | 4 | * SPDX-License-Identifier: BSD-3-Clause |
Ryan Harkin | 0392579 | 2015-03-17 14:52:39 +0000 | [diff] [blame] | 5 | */ |
| 6 | |
| 7 | #include <assert.h> |
Antonio Nino Diaz | e0f9063 | 2018-12-14 00:18:21 +0000 | [diff] [blame] | 8 | |
Ambroise Vincent | a88a35d | 2019-02-14 09:48:21 +0000 | [diff] [blame] | 9 | #include <drivers/arm/sp804_delay_timer.h> |
Antonio Nino Diaz | e0f9063 | 2018-12-14 00:18:21 +0000 | [diff] [blame] | 10 | #include <drivers/delay_timer.h> |
| 11 | #include <lib/mmio.h> |
Ryan Harkin | 0392579 | 2015-03-17 14:52:39 +0000 | [diff] [blame] | 12 | |
| 13 | uintptr_t sp804_base_addr; |
| 14 | |
| 15 | #define SP804_TIMER1_LOAD (sp804_base_addr + 0x000) |
| 16 | #define SP804_TIMER1_VALUE (sp804_base_addr + 0x004) |
| 17 | #define SP804_TIMER1_CONTROL (sp804_base_addr + 0x008) |
| 18 | #define SP804_TIMER1_BGLOAD (sp804_base_addr + 0x018) |
| 19 | |
| 20 | #define TIMER_CTRL_ONESHOT (1 << 0) |
| 21 | #define TIMER_CTRL_32BIT (1 << 1) |
| 22 | #define TIMER_CTRL_DIV1 (0 << 2) |
| 23 | #define TIMER_CTRL_DIV16 (1 << 2) |
| 24 | #define TIMER_CTRL_DIV256 (2 << 2) |
| 25 | #define TIMER_CTRL_IE (1 << 5) |
| 26 | #define TIMER_CTRL_PERIODIC (1 << 6) |
| 27 | #define TIMER_CTRL_ENABLE (1 << 7) |
| 28 | |
| 29 | /******************************************************************** |
| 30 | * The SP804 timer delay function |
| 31 | ********************************************************************/ |
| 32 | uint32_t sp804_get_timer_value(void) |
| 33 | { |
| 34 | return mmio_read_32(SP804_TIMER1_VALUE); |
| 35 | } |
| 36 | |
| 37 | /******************************************************************** |
| 38 | * Initialize the 1st timer in the SP804 dual timer with a base |
| 39 | * address and a timer ops |
| 40 | ********************************************************************/ |
| 41 | void sp804_timer_ops_init(uintptr_t base_addr, const timer_ops_t *ops) |
| 42 | { |
| 43 | assert(base_addr != 0); |
| 44 | assert(ops != 0 && ops->get_timer_value == sp804_get_timer_value); |
| 45 | |
| 46 | sp804_base_addr = base_addr; |
| 47 | timer_init(ops); |
| 48 | |
| 49 | /* disable timer1 */ |
| 50 | mmio_write_32(SP804_TIMER1_CONTROL, 0); |
| 51 | mmio_write_32(SP804_TIMER1_LOAD, UINT32_MAX); |
| 52 | mmio_write_32(SP804_TIMER1_VALUE, UINT32_MAX); |
| 53 | |
| 54 | /* enable as a free running 32-bit counter */ |
| 55 | mmio_write_32(SP804_TIMER1_CONTROL, |
| 56 | TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE); |
| 57 | } |