1/** 2 * \file 3 * \brief ARM Cortex A15 Generic Timer driver. 4 */ 5 6/* 7 * Copyright (c) 2016, ETH Zurich. 8 * All rights reserved. 9 * 10 * This file is distributed under the terms in the attached LICENSE file. 11 * If you do not find this file, copies can be found by writing to: 12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 13 */ 14 15#include <kernel.h> 16 17/* Return the current value of the CNTFRQ (count frequency) register, the rate 18 * at which the system counter counts. */ 19static inline uint32_t 20a15_gt_frequency(void) { 21 uint32_t cntfrq; 22 __asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(cntfrq)); 23 return cntfrq; 24} 25 26/* Set the CNTFRQ register. Note that this does *not* set the actual 27 * frequency of the timer, just the value that software sees. */ 28static inline void 29a15_gt_set_cntfrq(uint32_t cntfrq) { 30 __asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(cntfrq)); 31} 32 33/* Return the current counter value. */ 34static inline uint64_t 35a15_gt_counter(void) { 36 uint32_t lo, hi; 37 __asm volatile("mrrc p15, 0, %0, %1, c14" : "=r"(lo), "=r"(hi)); 38 return (((uint64_t)hi) << 32) | lo; 39} 40 41/* Trigger a timeout interrupt t counter ticks from now. */ 42static inline void 43a15_gt_timeout(uint32_t t) { 44 /* Write CNTP_TVAL, the physical counter timer value register. */ 45 __asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r"(t)); 46} 47 48static inline void a15_gt_set_control(uint32_t cntp_ctl) { 49 __asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r"(cntp_ctl)); 50} 51 52static inline void a15_gt_set_comparator(systime_t timeout) { 53 uint32_t lo, hi; 54 55 lo = timeout; 56 hi = timeout >> 32; 57 __asm volatile("mcrr p15, 2, %0, %1, c14" : : "r" (lo), "r" (hi)); 58 uint32_t cntp_ctl = (1 << 0) /* ENABLE*/; 59 a15_gt_set_control(cntp_ctl); 60} 61 62static inline void a15_gt_mask_interrupt(void) { 63 uint32_t cntp_ctl = (1 << 1) | (1 << 0) /* IMASK and ENABLE*/; 64 a15_gt_set_control(cntp_ctl); 65} 66 67void a15_gt_init(void); 68