Skip to content
Snippets Groups Projects
Commit ea07ad04 authored by Anna Lyons's avatar Anna Lyons Committed by Kent Mcleod
Browse files

omap3: implement tickless timer driver

Update the existing omap driver to implement the new tickless api.
parent bdc56112
No related branches found
No related tags found
No related merge requests found
......@@ -13,9 +13,10 @@
#ifndef __DRIVER_TIMER_OMAP3_H
#define __DRIVER_TIMER_OMAP3_H
#include <plat/machine/devices_gen.h>
#include <config.h>
#define TISR_OVF_FLAG BIT(1)
#define TISR_MATCH_FLAG BIT(0)
struct timer {
uint32_t tidr; /* GPTIMER_TIDR 0x00 */
......@@ -43,10 +44,40 @@ struct timer {
typedef volatile struct timer timer_t;
extern timer_t *timer;
#ifdef CONFIG_KERNEL_MCS
/* this is a 32-bit timer, track high_bits here */
extern uint32_t high_bits;
/** DONT_TRANSLATE */
static inline void setDeadline(ticks_t deadline)
{
timer->tmar = (uint32_t) deadline;
}
/** DONT_TRANSLATE */
static inline ticks_t getCurrentTime(void)
{
bool_t overflow = !!(timer->tisr & TISR_OVF_FLAG);
return (((uint64_t) high_bits + overflow) << 32llu) + timer->tcrr;
}
/** DONT_TRANSLATE */
static inline void ackDeadlineIRQ(void)
{
/* check if this is an overflow irq */
if (timer->tisr & TISR_OVF_FLAG) {
high_bits++;
}
/* ack everything */
timer->tisr = TISR_OVF_FLAG | TISR_MATCH_FLAG;
assert((timer->tisr & TISR_OVF_FLAG) == 0);
}
#else /* CONFIG_KERNEL_MCS */
static inline void resetTimer(void)
{
timer->tisr = TISR_OVF_FLAG;
ackInterrupt(KERNEL_TIMER_IRQ);
}
#endif /* !CONFIG_KERNEL_MCS */
#endif /* !__DRIVER_TIMER_OMAP3_H */
......@@ -19,8 +19,6 @@
#include <plat/machine/devices_gen.h>
#include <plat/machine/hardware.h>
#define TIMER_INTERVAL_MS (CONFIG_TIMER_TICK_MS)
#define TIOCP_CFG_SOFTRESET BIT(1)
#define TCLR_AUTORELOAD BIT(1)
#define TCLR_COMPAREENABLE BIT(6)
......@@ -30,6 +28,37 @@
timer_t *timer = (timer_t *) TIMER_PPTR;
#ifdef CONFIG_KERNEL_MCS
#define INTCPS_SYSCONFIG_SOFTRESET BIT(1)
#define INTCPS_SYSSTATUS_RESETDONE BIT(0)
uint32_t high_bits = 0;
BOOT_CODE void initTimer(void)
{
/* Configure gptimer9 as kernel timer */
timer->cfg = TIOCP_CFG_SOFTRESET;
/* disable */
timer->tclr = 0;
/* wait for reset */
while (!timer->tistat);
maskInterrupt(/*disable*/ true, KERNEL_TIMER_IRQ);
/* Set the reload value */
timer->tldr = 0u;
/* Enables interrupt on overflow and match */
timer->tier |= (TIER_OVERFLOWENABLE | TIER_MATCHENABLE);
/* Clear the read register */
timer->tcrr = 0u;
/* start the timer */
timer->tclr = TCLR_AUTORELOAD | TCLR_STARTTIMER | TCLR_COMPAREENABLE;
}
#else /* CONFIG_KERNEL_MCS */
#define TIMER_INTERVAL_MS (CONFIG_TIMER_TICK_MS)
BOOT_CODE void initTimer(void)
{
/* Configure gptimer9 as kernel timer */
......@@ -51,3 +80,4 @@ BOOT_CODE void initTimer(void)
/* Set autoreload and start the timer */
timer->tclr = TCLR_AUTORELOAD | TCLR_STARTTIMER;
}
#endif /* !CONFIG_KERNEL_MCS */
......@@ -27,6 +27,9 @@ if(KernelPlatformOMAP3)
MAX_IRQ 95
INTERRUPT_CONTROLLER drivers/irq/omap3.h
TIMER drivers/timer/omap3430.h
CLK_MAGIC 1321528399llu
CLK_SHIFT 34u
KERNEL_WCET 10u
)
endif()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment