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#ifndef CONFIG_KERNEL_MCS 12#error "This driver should only be selected for MCS kernel" 13#endif /* CONFIG_KERNEL_MCS */ 14 15/* gptir and gptsr bits */ 16#define OF1IE 0 /* output compare 1 */ 17#define ROV 5 /* roll over */ 18 19/* Memory map for GPT (General Purpose Timer). */ 20struct timer { 21 uint32_t gptcr; /* control */ 22 uint32_t gptpr; /* prescaler */ 23 uint32_t gptsr; /* status register */ 24 uint32_t gptir; /* interrupt register */ 25 uint32_t gptcr1; 26 uint32_t gptcr2; 27 uint32_t gptcr3; 28 uint32_t gpticr1; 29 uint32_t gpticr2; 30 uint32_t gptcnt; 31}; 32typedef volatile struct timer timer_t; 33extern timer_t *gpt; 34extern ticks_t high_bits; 35 36static inline ticks_t getCurrentTime(void) 37{ 38 return ((high_bits + !!(gpt->gptsr & BIT(ROV))) << 32llu) + gpt->gptcnt; 39} 40 41static inline void setDeadline(ticks_t deadline) 42{ 43 if (((uint32_t) deadline) > gpt->gptcnt) { 44 /* turn on compare irq */ 45 gpt->gptir |= BIT(OF1IE); 46 /* set the deadline */ 47 do { 48 gpt->gptcr1 = (uint32_t) deadline; 49 } while (gpt->gptcr1 != (uint32_t) deadline); 50 } 51} 52 53static inline void ackDeadlineIRQ(void) 54{ 55 if (gpt->gptsr & BIT(ROV)) { 56 high_bits++; 57 } 58 59 /* turn off compare irq */ 60 gpt->gptir &= ~(BIT(OF1IE)); 61 /* ack either irq */ 62 gpt->gptsr |= (BIT(OF1IE) | BIT(ROV)); 63} 64 65