1 /* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7 #pragma once 8 9 #include <config.h> 10 11 #define TISR_OVF_FLAG BIT(1) 12 #define TISR_MATCH_FLAG BIT(0) 13 14 struct timer { 15 uint32_t tidr; /* GPTIMER_TIDR 0x00 */ 16 uint32_t padding1[3]; 17 uint32_t cfg; /* GPTIMER_CFG 0x10 */ 18 uint32_t tistat; /* GPTIMER_TISTAT 0x14 */ 19 uint32_t tisr; /* GPTIMER_TISR 0x18 */ 20 uint32_t tier; /* GPTIMER_TIER 0x1C */ 21 uint32_t twer; /* GPTIMER_TWER 0x20 */ 22 uint32_t tclr; /* GPTIMER_TCLR 0x24 */ 23 uint32_t tcrr; /* GPTIMER_TCRR 0x28 */ 24 uint32_t tldr; /* GPTIMER_TLDR 0x2C */ 25 uint32_t ttgr; /* GPTIMER_TTGR 0x30 */ 26 uint32_t twps; /* GPTIMER_TWPS 0x34 */ 27 uint32_t tmar; /* GPTIMER_TMAR 0x38 */ 28 uint32_t tcar1; /* GPTIMER_TCAR1 0x3C */ 29 uint32_t tsicr; /* GPTIMER_TSICR 0x40 */ 30 uint32_t tcar2; /* GPTIMER_TCAR2 0x44 */ 31 uint32_t tpir; /* GPTIMER_TPIR 0x48 */ 32 uint32_t tnir; /* GPTIMER_TNIR 0x4C */ 33 uint32_t tcvr; /* GPTIMER_TCVR 0x50 */ 34 uint32_t tocr; /* GPTIMER_TOCR 0x54 */ 35 uint32_t towr; /* GPTIMER_TOWR 0x58 */ 36 }; 37 typedef volatile struct timer timer_t; 38 extern timer_t *timer; 39 40 #ifdef CONFIG_KERNEL_MCS 41 /* this is a 32-bit timer, track high_bits here */ 42 extern uint32_t high_bits; 43 44 /** DONT_TRANSLATE */ setDeadline(ticks_t deadline)45static inline void setDeadline(ticks_t deadline) 46 { 47 timer->tmar = (uint32_t) deadline; 48 } 49 50 /** DONT_TRANSLATE */ getCurrentTime(void)51static inline ticks_t getCurrentTime(void) 52 { 53 bool_t overflow = !!(timer->tisr & TISR_OVF_FLAG); 54 return (((uint64_t) high_bits + overflow) << 32llu) + timer->tcrr; 55 } 56 57 /** DONT_TRANSLATE */ ackDeadlineIRQ(void)58static inline void ackDeadlineIRQ(void) 59 { 60 /* check if this is an overflow irq */ 61 if (timer->tisr & TISR_OVF_FLAG) { 62 high_bits++; 63 } 64 65 /* ack everything */ 66 timer->tisr = TISR_OVF_FLAG | TISR_MATCH_FLAG; 67 assert((timer->tisr & TISR_OVF_FLAG) == 0); 68 } 69 #else /* CONFIG_KERNEL_MCS */ resetTimer(void)70static inline void resetTimer(void) 71 { 72 timer->tisr = TISR_OVF_FLAG; 73 ackInterrupt(KERNEL_TIMER_IRQ); 74 } 75 #endif /* !CONFIG_KERNEL_MCS */ 76