forked from Imagelibrary/seL4
kzm: implement MCS timer driver
- use gpt, so we can have overflow and compare interrupts at the same time (epit only allows compare) - set the gpt to use the ipg_highfreq timer, as the standard ipg is too low and breaks the timer calculations
This commit is contained in:
72
include/drivers/timer/imx31-gpt.h
Normal file
72
include/drivers/timer/imx31-gpt.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2019, Data61
|
||||
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
|
||||
* ABN 41 687 119 230.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(DATA61_GPL)
|
||||
*/
|
||||
|
||||
#ifndef __DRIVERS_TIMER_IMX31_GPT_H
|
||||
#define __DRIVERS_TIMER_IMX31_GPT_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifndef CONFIG_KERNEL_MCS
|
||||
#error "This driver should only be selected for MCS kernel"
|
||||
#endif /* CONFIG_KERNEL_MCS */
|
||||
|
||||
/* gptir and gptsr bits */
|
||||
#define OF1IE 0 /* output compare 1 */
|
||||
#define ROV 5 /* roll over */
|
||||
|
||||
/* Memory map for GPT (General Purpose Timer). */
|
||||
struct timer {
|
||||
uint32_t gptcr; /* control */
|
||||
uint32_t gptpr; /* prescaler */
|
||||
uint32_t gptsr; /* status register */
|
||||
uint32_t gptir; /* interrupt register */
|
||||
uint32_t gptcr1;
|
||||
uint32_t gptcr2;
|
||||
uint32_t gptcr3;
|
||||
uint32_t gpticr1;
|
||||
uint32_t gpticr2;
|
||||
uint32_t gptcnt;
|
||||
};
|
||||
typedef volatile struct timer timer_t;
|
||||
extern timer_t *gpt;
|
||||
extern ticks_t high_bits;
|
||||
|
||||
static inline ticks_t getCurrentTime(void)
|
||||
{
|
||||
return ((high_bits + !!(gpt->gptsr & BIT(ROV))) << 32llu) + gpt->gptcnt;
|
||||
}
|
||||
|
||||
static inline void setDeadline(ticks_t deadline)
|
||||
{
|
||||
if (((uint32_t) deadline) > gpt->gptcnt) {
|
||||
/* turn on compare irq */
|
||||
gpt->gptir |= BIT(OF1IE);
|
||||
/* set the deadline */
|
||||
do {
|
||||
gpt->gptcr1 = (uint32_t) deadline;
|
||||
} while (gpt->gptcr1 != (uint32_t) deadline);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ackDeadlineIRQ(void)
|
||||
{
|
||||
if (gpt->gptsr & BIT(ROV)) {
|
||||
high_bits++;
|
||||
}
|
||||
|
||||
/* turn off compare irq */
|
||||
gpt->gptir &= ~(BIT(OF1IE));
|
||||
/* ack either irq */
|
||||
gpt->gptsr |= (BIT(OF1IE) | BIT(ROV));
|
||||
}
|
||||
|
||||
#endif /* !__DRIVERS_TIMER_IMX31_GPT_H */
|
||||
@@ -37,6 +37,7 @@ register_driver(
|
||||
PREFIX src/drivers/timer
|
||||
CFILES "imx31-epit.c"
|
||||
)
|
||||
register_driver(compatibility_strings "fsl,imx31-gpt" PREFIX src/drivers/timer CFILES "imx31-gpt.c")
|
||||
register_driver(
|
||||
compatibility_strings "ti,omap3430-timer"
|
||||
PREFIX src/drivers/timer
|
||||
|
||||
53
src/drivers/timer/imx31-gpt.c
Normal file
53
src/drivers/timer/imx31-gpt.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2019, Data61
|
||||
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
|
||||
* ABN 41 687 119 230.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(DATA61_GPL)
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <types.h>
|
||||
#include <machine/io.h>
|
||||
#include <kernel/vspace.h>
|
||||
#include <arch/machine.h>
|
||||
#include <arch/kernel/vspace.h>
|
||||
#include <linker.h>
|
||||
|
||||
/* gptcr bits */
|
||||
#define EN 0
|
||||
#define ENMOD 1
|
||||
#define FRR 9
|
||||
#define CLKSRC 6
|
||||
#define SWR 15
|
||||
|
||||
timer_t *gpt = (timer_t *) TIMER_PPTR;
|
||||
ticks_t high_bits = 0;
|
||||
|
||||
enum IPGConstants {
|
||||
IPG_CLK = 1,
|
||||
IPG_CLK_HIGHFREQ = 2,
|
||||
IPG_CLK_32K = 3
|
||||
};
|
||||
|
||||
interrupt_t active_irq = irqInvalid;
|
||||
|
||||
BOOT_CODE void initTimer(void)
|
||||
{
|
||||
/* reset the gpt */
|
||||
gpt->gptcr = 0;
|
||||
/* clear the status register */
|
||||
gpt->gptcr = 0x3F;
|
||||
/* software reset */
|
||||
gpt->gptcr = BIT(SWR);
|
||||
/* configure the gpt */
|
||||
gpt->gptcr = BIT(ENMOD) | BIT(FRR) | (IPG_CLK_HIGHFREQ << CLKSRC);
|
||||
/* enable overflow irq */
|
||||
gpt->gptir = BIT(ROV);
|
||||
/* turn it on */
|
||||
gpt->gptcr |= BIT(EN);
|
||||
}
|
||||
@@ -22,14 +22,24 @@ if(KernelPlatformKZM)
|
||||
set(KernelArmMach "imx" CACHE INTERNAL "")
|
||||
list(APPEND KernelDTSList "tools/dts/kzm.dts")
|
||||
list(APPEND KernelDTSList "src/plat/imx31/overlay-kzm.dts")
|
||||
if(KernelIsMCS)
|
||||
list(APPEND KernelDTSList "src/plat/imx31/mcs-overlay-kzm.dts")
|
||||
set(TimerFrequency 18600000llu) # 18.6MHz -- calculated by trial and error, roughly precise
|
||||
set(TimerDriver drivers/timer/imx31-gpt.h)
|
||||
else()
|
||||
set(TimerFrequency 32768llu)
|
||||
set(TimerDriver drivers/timer/imx31-epit.h)
|
||||
add_bf_source_old("KernelPlatformKZM" "imx31-epit.bf" "include" "drivers/timer")
|
||||
endif()
|
||||
declare_default_headers(
|
||||
TIMER_FREQUENCY 32768llu
|
||||
TIMER_FREQUENCY ${TimerFrequency}
|
||||
MAX_IRQ 63
|
||||
INTERRUPT_CONTROLLER drivers/irq/imx31.h
|
||||
TIMER drivers/timer/imx31-epit.h
|
||||
TIMER ${TimerDriver}
|
||||
KERNEL_WCET 10u
|
||||
CLK_SHIFT 47u
|
||||
CLK_MAGIC 7566531633llu
|
||||
)
|
||||
endif()
|
||||
|
||||
add_sources(DEP "KernelPlatformKZM" CFILES src/plat/imx31/machine/hardware.c)
|
||||
|
||||
add_bf_source_old("KernelPlatformKZM" "imx31-epit.bf" "include" "drivers/timer")
|
||||
|
||||
21
src/plat/imx31/mcs-overlay-kzm.dts
Normal file
21
src/plat/imx31/mcs-overlay-kzm.dts
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2019, Data61
|
||||
* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
|
||||
* ABN 41 687 119 230.
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(DATA61_GPL)
|
||||
*/
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
seL4,kernel-devices =
|
||||
"serial0",
|
||||
&{/interrupt-controller@68000000},
|
||||
&{/l2cc@30000000},
|
||||
&{/soc/aips@53f00000/timer@53f90000};
|
||||
};
|
||||
};
|
||||
@@ -176,6 +176,7 @@ devices:
|
||||
index: 0
|
||||
kernel: TIMER_PPTR
|
||||
interrupts:
|
||||
# IMX6 also has the imx31-gpt.
|
||||
KERNEL_TIMER_IRQ: 0
|
||||
# i.MX EPIT (no Linux binding, this is seL4-specific.)
|
||||
- compatible:
|
||||
@@ -186,6 +187,15 @@ devices:
|
||||
kernel: EPIT_PPTR
|
||||
interrupts:
|
||||
KERNEL_TIMER_IRQ: 0
|
||||
# i.MX GPT
|
||||
- compatible:
|
||||
- fsl,imx31-gpt
|
||||
regions:
|
||||
- executeNever: true
|
||||
index: 0
|
||||
kernel: TIMER_PPTR
|
||||
interrupts:
|
||||
KERNEL_TIMER_IRQ: 0
|
||||
# QCOM Krait timer (timer/qcom,msm-timer.txt)
|
||||
- compatible:
|
||||
- qcom,kpss-timer
|
||||
|
||||
Reference in New Issue
Block a user