arm:omap timers remove hardcoded base address.

Omap timers remove hardcoded base address and add some initial
support for the beaglebone's timers. Frclock_util will need
refactoring to remain independent of the ARM flavour.

Change-Id: I2b5d04e930364262c81b5686de634c0a51796b23
This commit is contained in:
Kees Jongenburger 2013-05-23 18:02:23 +02:00
parent 534b19187e
commit 3139ce9631
4 changed files with 331 additions and 93 deletions

View file

@ -29,7 +29,6 @@ static int freepdes[MAXFREEPDES];
static u32_t phys_get32(phys_bytes v); static u32_t phys_get32(phys_bytes v);
extern vir_bytes omap3_gptimer10_base = OMAP3_GPTIMER10_BASE;
void mem_clear_mapcache(void) void mem_clear_mapcache(void)
{ {
@ -726,14 +725,28 @@ int arch_phys_map(const int index,
return OK; return OK;
} }
else if (index == device_mem_mapping_index) { else if (index == device_mem_mapping_index) {
#ifdef DM37XX
/* map device memory */ /* map device memory */
*addr = 0x48000000; *addr = 0x48000000;
*len = 0x02000000; *len = 0x02000000;
#endif
#ifdef AM335X
/* map device memory until 0x5700 SGX */
*addr = 0x44000000;
*len = 0x06000000;
#endif
*flags = VMMF_UNCACHED | VMMF_WRITE; *flags = VMMF_UNCACHED | VMMF_WRITE;
return OK; return OK;
} }
else if (index == frclock_index) { else if (index == frclock_index) {
#ifdef DM37XX
*addr = OMAP3_GPTIMER10_BASE; *addr = OMAP3_GPTIMER10_BASE;
#endif
#ifdef AM335X
*addr = AM335X_DMTIMER7_BASE;
#endif
*len = ARM_PAGE_SIZE; *len = ARM_PAGE_SIZE;
*flags = VMMF_USER; *flags = VMMF_USER;
return OK; return OK;
@ -774,7 +787,13 @@ int arch_phys_map_reply(const int index, const vir_bytes addr)
return OK; return OK;
} }
else if (index == frclock_index) { else if (index == frclock_index) {
omap3_gptimer10_base = minix_kerninfo.minix_frclock = addr; #ifdef DM37XX
minix_kerninfo.minix_frclock = addr;
#endif
#ifdef AM335X
minix_kerninfo.minix_frclock = addr;
#endif
return OK; return OK;
} }

View file

@ -2,7 +2,10 @@
#include "kernel/clock.h" #include "kernel/clock.h"
#include <sys/types.h> #include <sys/types.h>
#include <machine/cpu.h> #include <machine/cpu.h>
#include <minix/mmio.h>
#include <io.h> #include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include "arch_proto.h" #include "arch_proto.h"
#include "omap_timer.h" #include "omap_timer.h"
#include "omap_intr.h" #include "omap_intr.h"
@ -10,15 +13,130 @@
static irq_hook_t omap3_timer_hook; /* interrupt handler hook */ static irq_hook_t omap3_timer_hook; /* interrupt handler hook */
static u64_t high_frc; static u64_t high_frc;
vir_bytes omap3_gptimer10_base; struct omap_timer_registers;
struct omap_timer {
vir_bytes base;
int irq_nr;
struct omap_timer_registers *regs;
};
struct omap_timer_registers {
vir_bytes TIDR;
vir_bytes TIOCP_CFG;
vir_bytes TISTAT;
vir_bytes TISR;
vir_bytes TIER;
vir_bytes TWER;
vir_bytes TCLR;
vir_bytes TCRR;
vir_bytes TLDR;
vir_bytes TTGR;
vir_bytes TWPS;
vir_bytes TMAR;
vir_bytes TCAR1;
vir_bytes TSICR;
vir_bytes TCAR2;
vir_bytes TPIR;
vir_bytes TNIR;
vir_bytes TCVR;
vir_bytes TOCR;
vir_bytes TOWR;
};
static struct omap_timer_registers regs_v1 = {
.TIDR = OMAP3_TIMER_TIDR,
.TIOCP_CFG = OMAP3_TIMER_TIOCP_CFG,
.TISTAT = OMAP3_TIMER_TISTAT,
.TISR = OMAP3_TIMER_TISR,
.TIER = OMAP3_TIMER_TIER,
.TWER = OMAP3_TIMER_TWER,
.TCLR = OMAP3_TIMER_TCLR,
.TCRR = OMAP3_TIMER_TCRR,
.TLDR = OMAP3_TIMER_TLDR,
.TTGR = OMAP3_TIMER_TTGR,
.TWPS = OMAP3_TIMER_TWPS,
.TMAR = OMAP3_TIMER_TMAR,
.TCAR1 = OMAP3_TIMER_TCAR1,
.TSICR = OMAP3_TIMER_TSICR,
.TCAR2 = OMAP3_TIMER_TCAR2,
.TPIR = OMAP3_TIMER_TPIR,
.TNIR = OMAP3_TIMER_TNIR,
.TCVR = OMAP3_TIMER_TCVR,
.TOCR = OMAP3_TIMER_TOCR,
.TOWR = OMAP3_TIMER_TOWR,
};
#ifdef DM37XX
static struct omap_timer timer = {
.base = OMAP3_GPTIMER1_BASE,
.irq_nr = OMAP3_GPT1_IRQ,
.regs = &regs_v1
};
/* free running timer */
static struct omap_timer fr_timer = {
.base = OMAP3_GPTIMER10_BASE,
.irq_nr = OMAP3_GPT10_IRQ,
.regs = &regs_v1
};
#endif
#ifdef AM335X
/* AM335X has a different ip block for the non
1ms timers */
static struct omap_timer_registers regs_v2 = {
.TIDR = AM335X_TIMER_TIDR,
.TIOCP_CFG = AM335X_TIMER_TIOCP_CFG,
.TISTAT = AM335X_TIMER_IRQSTATUS_RAW,
.TISR = AM335X_TIMER_IRQSTATUS,
.TIER = AM335X_TIMER_IRQENABLE_SET,
.TWER = AM335X_TIMER_IRQWAKEEN,
.TCLR = AM335X_TIMER_TCLR,
.TCRR = AM335X_TIMER_TCRR,
.TLDR = AM335X_TIMER_TLDR,
.TTGR = AM335X_TIMER_TTGR,
.TWPS = AM335X_TIMER_TWPS,
.TMAR = AM335X_TIMER_TMAR,
.TCAR1 = AM335X_TIMER_TCAR1,
.TSICR = AM335X_TIMER_TSICR,
.TCAR2 = AM335X_TIMER_TCAR2,
.TPIR = -1 , /* UNDEF */
.TNIR = -1 , /* UNDEF */
.TCVR = -1 , /* UNDEF */
.TOCR = -1 , /* UNDEF */
.TOWR = -1 /* UNDEF */
};
/* normal timer */
static struct omap_timer timer = {
.base = AM335X_DMTIMER1_1MS_BASE,
.irq_nr = AM335X_INT_TINT1_1MS,
.regs = &regs_v1
};
/* free running timer */
static struct omap_timer fr_timer = {
.base = AM335X_DMTIMER7_BASE,
.irq_nr = AM335X_INT_TINT7,
.regs = &regs_v2
};
#endif
static int done = 0;
int omap3_register_timer_handler(const irq_handler_t handler) int omap3_register_timer_handler(const irq_handler_t handler)
{ {
/* Initialize the CLOCK's interrupt hook. */ /* Initialize the CLOCK's interrupt hook. */
omap3_timer_hook.proc_nr_e = NONE; omap3_timer_hook.proc_nr_e = NONE;
omap3_timer_hook.irq = OMAP3_GPT1_IRQ; omap3_timer_hook.irq = timer.irq_nr;
put_irq_handler(&omap3_timer_hook, OMAP3_GPT1_IRQ, handler); put_irq_handler(&omap3_timer_hook, timer.irq_nr, handler);
return 0; return 0;
} }
@ -27,75 +145,113 @@ void omap3_frclock_init(void)
{ {
u32_t tisr; u32_t tisr;
/* Stop timer */ /* enable the clock */
mmio_clear(OMAP3_GPTIMER10_TCLR, OMAP3_TCLR_ST); #ifdef AM335X
/* Disable the module and wait for the module to be disabled */
set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,CM_MODULEMODE_DISABLED);
while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_DISABLE);
set32(CLKSEL_TIMER7_CLK,CLKSEL_TIMER7_CLK_SEL_MASK, CLKSEL_TIMER7_CLK_SEL_SEL2);
while( (read32(CLKSEL_TIMER7_CLK) & CLKSEL_TIMER7_CLK_SEL_MASK) != CLKSEL_TIMER7_CLK_SEL_SEL2);
/* enable the module and wait for the module to be ready */
set32(CM_PER_TIMER7_CLKCTRL,CM_MODULEMODE_MASK,CM_MODULEMODE_ENABLE);
while( (mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_FUNC);
#endif
/* Stop timer */
mmio_clear(fr_timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST);
#ifdef DM37XX
/* Use functional clock source for GPTIMER10 */ /* Use functional clock source for GPTIMER10 */
mmio_set(OMAP3_CM_CLKSEL_CORE, OMAP3_CLKSEL_GPT10); mmio_set(OMAP3_CM_CLKSEL_CORE, OMAP3_CLKSEL_GPT10);
#endif
#ifdef DM37XX
/* Scale timer down to 13/8 = 1.625 Mhz to roughly get microsecond ticks */ /* Scale timer down to 13/8 = 1.625 Mhz to roughly get microsecond ticks */
/* The scale is computed as 2^(PTV+1). So if PTV == 2, we get 2^3 = 8. /* The scale is computed as 2^(PTV+1). So if PTV == 2, we get 2^3 = 8.
*/ */
mmio_set(OMAP3_GPTIMER10_TCLR, (2 << OMAP3_TCLR_PTV)); mmio_set(fr_timer.base + fr_timer.regs->TCLR, (2 << OMAP3_TCLR_PTV));
#endif
#ifdef AM335X
/* 24Mhz / 16 = 1.5 Mhz */
mmio_set(fr_timer.base + fr_timer.regs->TCLR, (3 << OMAP3_TCLR_PTV));
#endif
/* Start and auto-reload at 0 */ /* Start and auto-reload at 0 */
mmio_write(OMAP3_GPTIMER10_TLDR, 0x0); mmio_write(fr_timer.base + fr_timer.regs->TLDR, 0x0);
mmio_write(OMAP3_GPTIMER10_TCRR, 0x0); mmio_write(fr_timer.base + fr_timer.regs->TCRR, 0x0);
/* Set up overflow interrupt */ /* Set up overflow interrupt */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG | tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG; OMAP3_TISR_TCAR_IT_FLAG;
mmio_write(OMAP3_GPTIMER10_TISR, tisr); /* Clear interrupt status */ mmio_write(fr_timer.base + fr_timer.regs->TISR, tisr); /* Clear interrupt status */
mmio_write(OMAP3_GPTIMER10_TIER, OMAP3_TIER_OVF_IT_ENA); mmio_write(fr_timer.base + fr_timer.regs->TIER, OMAP3_TIER_OVF_IT_ENA);
/* Start timer */ /* Start timer */
mmio_set(OMAP3_GPTIMER10_TCLR, mmio_set(fr_timer.base + fr_timer.regs->TCLR,
OMAP3_TCLR_OVF_TRG|OMAP3_TCLR_AR|OMAP3_TCLR_ST|OMAP3_TCLR_PRE); OMAP3_TCLR_OVF_TRG|OMAP3_TCLR_AR|OMAP3_TCLR_ST|OMAP3_TCLR_PRE);
} }
void omap3_frclock_stop() void omap3_frclock_stop()
{ {
mmio_clear(OMAP3_GPTIMER10_TCLR, OMAP3_TCLR_ST); mmio_clear(fr_timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST);
} }
void omap3_timer_init(unsigned freq) void omap3_timer_init(unsigned freq)
{ {
u32_t tisr; u32_t tisr;
#ifdef AM335X
/* disable the module and wait for the module to be disabled */
set32(CM_WKUP_TIMER1_CLKCTRL, CM_MODULEMODE_MASK,CM_MODULEMODE_DISABLED);
while( (mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_DISABLE);
set32(CLKSEL_TIMER1MS_CLK,CLKSEL_TIMER1MS_CLK_SEL_MASK, CLKSEL_TIMER1MS_CLK_SEL_SEL2);
while( (read32(CLKSEL_TIMER1MS_CLK) & CLKSEL_TIMER1MS_CLK_SEL_MASK) != CLKSEL_TIMER1MS_CLK_SEL_SEL2);
/* enable the module and wait for the module to be ready */
set32(CM_WKUP_TIMER1_CLKCTRL,CM_MODULEMODE_MASK,CM_MODULEMODE_ENABLE);
while( (mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST) != CM_CLKCTRL_IDLEST_FUNC);
#endif
/* Stop timer */ /* Stop timer */
mmio_clear(OMAP3_GPTIMER1_TCLR, OMAP3_TCLR_ST); mmio_clear(timer.base + fr_timer.regs->TCLR, OMAP3_TCLR_ST);
#ifdef DM37XX
/* Use 32 KHz clock source for GPTIMER1 */ /* Use 32 KHz clock source for GPTIMER1 */
mmio_clear(OMAP3_CM_CLKSEL_WKUP, OMAP3_CLKSEL_GPT1); mmio_clear(OMAP3_CM_CLKSEL_WKUP, OMAP3_CLKSEL_GPT1);
#endif
/* Use 1-ms tick mode for GPTIMER1 TRM 16.2.4.2.1 */ /* Use 1-ms tick mode for GPTIMER1 TRM 16.2.4.2.1 */
mmio_write(OMAP3_GPTIMER1_TPIR, 232000); mmio_write(timer.base + timer.regs->TPIR, 232000);
mmio_write(OMAP3_GPTIMER1_TNIR, -768000); mmio_write(timer.base + timer.regs->TNIR, -768000);
mmio_write(OMAP3_GPTIMER1_TLDR, 0xffffffe0); mmio_write(timer.base + timer.regs->TLDR, 0xffffffe0);
mmio_write(OMAP3_GPTIMER1_TCRR, 0xffffffe0); mmio_write(timer.base + timer.regs->TCRR, 0xffffffe0);
/* Set up overflow interrupt */ /* Set up overflow interrupt */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG | tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG; OMAP3_TISR_TCAR_IT_FLAG;
mmio_write(OMAP3_GPTIMER1_TISR, tisr); /* Clear interrupt status */ mmio_write(timer.base + timer.regs->TISR, tisr); /* Clear interrupt status */
mmio_write(OMAP3_GPTIMER1_TIER, OMAP3_TIER_OVF_IT_ENA); mmio_write(timer.base + timer.regs->TIER, OMAP3_TIER_OVF_IT_ENA);
omap3_irq_unmask(OMAP3_GPT1_IRQ); omap3_irq_unmask(timer.irq_nr);
/* Start timer */ /* Start timer */
mmio_set(OMAP3_GPTIMER1_TCLR, mmio_set(timer.base + timer.regs->TCLR,
OMAP3_TCLR_OVF_TRG|OMAP3_TCLR_AR|OMAP3_TCLR_ST); OMAP3_TCLR_OVF_TRG|OMAP3_TCLR_AR|OMAP3_TCLR_ST);
} }
void omap3_timer_stop() void omap3_timer_stop()
{ {
mmio_clear(OMAP3_GPTIMER1_TCLR, OMAP3_TCLR_ST); mmio_clear(timer.base + timer.regs->TCLR, OMAP3_TCLR_ST);
} }
static u32_t read_frc(void) static u32_t read_frc(void)
{ {
u32_t frc = *(u32_t *) ((char *) omap3_gptimer10_base + OMAP3_TCRR); if (done == 0)
return frc; return 0;
return mmio_read(fr_timer.base + fr_timer.regs->TCRR);
} }
static void frc_overflow_check(void) static void frc_overflow_check(void)
@ -114,9 +270,14 @@ void omap3_timer_int_handler()
/* Clear all interrupts */ /* Clear all interrupts */
u32_t tisr; u32_t tisr;
/* when the kernel itself is running interrupts are disabled.
* We should therefore also read the overflow counter to detect
* this as to not miss events.
*/
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG | tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG; OMAP3_TISR_TCAR_IT_FLAG;
mmio_write(OMAP3_GPTIMER1_TISR, tisr); mmio_write(timer.base + timer.regs->TISR, tisr);
frc_overflow_check(); frc_overflow_check();
} }

View file

@ -1,6 +1,8 @@
#ifndef _OMAP_TIMER_REGISTERS_H #ifndef _OMAP_TIMER_REGISTERS_H
#define _OMAP_TIMER_REGISTERS_H #define _OMAP_TIMER_REGISTERS_H
#ifdef DM37XX
/* General-purpose timer register map */ /* General-purpose timer register map */
#define OMAP3_GPTIMER1_BASE 0x48318000 /* GPTIMER1 physical address */ #define OMAP3_GPTIMER1_BASE 0x48318000 /* GPTIMER1 physical address */
#define OMAP3_GPTIMER2_BASE 0x49032000 /* GPTIMER2 physical address */ #define OMAP3_GPTIMER2_BASE 0x49032000 /* GPTIMER2 physical address */
@ -14,27 +16,60 @@
#define OMAP3_GPTIMER10_BASE 0x48086000 /* GPTIMER10 physical address */ #define OMAP3_GPTIMER10_BASE 0x48086000 /* GPTIMER10 physical address */
#define OMAP3_GPTIMER11_BASE 0x48088000 /* GPTIMER11 physical address */ #define OMAP3_GPTIMER11_BASE 0x48088000 /* GPTIMER11 physical address */
#endif /* DM37XX */
/* General-purpose timer registers */ /* General-purpose timer registers */
#define OMAP3_TIDR 0x000 /* IP revision code */ #define OMAP3_TIMER_TIDR 0x000 /* IP revision code */
#define OMAP3_TIOCP_CFG 0x010 /* Controls params for GP timer L4 interface */ #define OMAP3_TIMER_TIOCP_CFG 0x010 /* Controls params for GP timer L4 interface */
#define OMAP3_TISTAT 0x014 /* Status (excl. interrupt status) */ #define OMAP3_TIMER_TISTAT 0x014 /* Status (excl. interrupt status) */
#define OMAP3_TISR 0x018 /* Pending interrupt status */ #define OMAP3_TIMER_TISR 0x018 /* Pending interrupt status */
#define OMAP3_TIER 0x01C /* Interrupt enable */ #define OMAP3_TIMER_TIER 0x01C /* Interrupt enable */
#define OMAP3_TWER 0x020 /* Wakeup enable */ #define OMAP3_TIMER_TWER 0x020 /* Wakeup enable */
#define OMAP3_TCLR 0x024 /* Controls optional features */ #define OMAP3_TIMER_TCLR 0x024 /* Controls optional features */
#define OMAP3_TCRR 0x028 /* Internal counter value */ #define OMAP3_TIMER_TCRR 0x028 /* Internal counter value */
#define OMAP3_TLDR 0x02C /* Timer load value */ #define OMAP3_TIMER_TLDR 0x02C /* Timer load value */
#define OMAP3_TTGR 0x030 /* Triggers counter reload */ #define OMAP3_TIMER_TTGR 0x030 /* Triggers counter reload */
#define OMAP3_TWPS 0x034 /* Indicates if Write-Posted pending */ #define OMAP3_TIMER_TWPS 0x034 /* Indicates if Write-Posted pending */
#define OMAP3_TMAR 0x038 /* Value to be compared with counter */ #define OMAP3_TIMER_TMAR 0x038 /* Value to be compared with counter */
#define OMAP3_TCAR1 0x03C /* First captured value of counter register */ #define OMAP3_TIMER_TCAR1 0x03C /* First captured value of counter register */
#define OMAP3_TSICR 0x040 /* Control posted mode and functional SW reset */ #define OMAP3_TIMER_TSICR 0x040 /* Control posted mode and functional SW reset */
#define OMAP3_TCAR2 0x044 /* Second captured value of counter register */ #define OMAP3_TIMER_TCAR2 0x044 /* Second captured value of counter register */
#define OMAP3_TPIR 0x048 /* Positive increment (1 ms tick) */ #define OMAP3_TIMER_TPIR 0x048 /* Positive increment (1 ms tick) */
#define OMAP3_TNIR 0x04C /* Negative increment (1 ms tick) */ #define OMAP3_TIMER_TNIR 0x04C /* Negative increment (1 ms tick) */
#define OMAP3_TCVR 0x050 /* Defines TCRR is sub/over-period (1 ms tick) */ #define OMAP3_TIMER_TCVR 0x050 /* Defines TCRR is sub/over-period (1 ms tick) */
#define OMAP3_TOCR 0x054 /* Masks tick interrupt */ #define OMAP3_TIMER_TOCR 0x054 /* Masks tick interrupt */
#define OMAP3_TOWR 0x058 /* Number of masked overflow interrupts */ #define OMAP3_TIMER_TOWR 0x058 /* Number of masked overflow interrupts */
#ifdef AM335X
#define AM335X_DMTIMER0_BASE 0x44E05000 /* DMTimer0 Registers */
#define AM335X_DMTIMER1_1MS_BASE 0x44E31000 /* DMTimer1 1ms Registers (Accurate 1ms timer) */
#define AM335X_DMTIMER2_BASE 0x48040000 /* DMTimer2 Registers */
#define AM335X_DMTIMER3_BASE 0x48042000 /* DMTimer3 Registers */
#define AM335X_DMTIMER4_BASE 0x48044000 /* DMTimer4 Registers */
#define AM335X_DMTIMER5_BASE 0x48046000 /* DMTimer5 Registers */
#define AM335X_DMTIMER6_BASE 0x48048000 /* DMTimer6 Registers */
#define AM335X_DMTIMER7_BASE 0x4804A000 /* DMTimer7 Registers */
/* General-purpose timer registers AM335x non 1MS timers have different offsets */
#define AM335X_TIMER_TIDR 0x000 /* IP revision code */
#define AM335X_TIMER_TIOCP_CFG 0x010 /* Controls params for GP timer L4 interface */
#define AM335X_TIMER_IRQSTATUS_RAW 0x024 /* Timer IRQSTATUS Raw Register */
#define AM335X_TIMER_IRQSTATUS 0x028 /* Timer IRQSTATUS Register */
#define AM335X_TIMER_IRQENABLE_SET 0x02C /* Timer IRQENABLE Set Register */
#define AM335X_TIMER_IRQENABLE_CLR 0x030 /* Timer IRQENABLE Clear Register */
#define AM335X_TIMER_IRQWAKEEN 0x034 /* Timer IRQ Wakeup Enable Register */
#define AM335X_TIMER_TCLR 0x038 /* Controls optional features */
#define AM335X_TIMER_TCRR 0x03C /* Internal counter value */
#define AM335X_TIMER_TLDR 0x040 /* Timer load value */
#define AM335X_TIMER_TTGR 0x044 /* Triggers counter reload */
#define AM335X_TIMER_TWPS 0x048 /* Indicates if Write-Posted pending */
#define AM335X_TIMER_TMAR 0x04C /* Value to be compared with counter */
#define AM335X_TIMER_TCAR1 0x050 /* First captured value of counter register */
#define AM335X_TIMER_TSICR 0x054 /* Control posted mode and functional SW reset */
#define AM335X_TIMER_TCAR2 0x058 /* Second captured value of counter register */
#endif
/* Interrupt status register fields */ /* Interrupt status register fields */
#define OMAP3_TISR_MAT_IT_FLAG (1 << 0) /* Pending match interrupt status */ #define OMAP3_TISR_MAT_IT_FLAG (1 << 0) /* Pending match interrupt status */
@ -50,58 +85,68 @@
#define OMAP3_TCLR_ST (1 << 0) /* Start/stop timer */ #define OMAP3_TCLR_ST (1 << 0) /* Start/stop timer */
#define OMAP3_TCLR_AR (1 << 1) /* Autoreload or one-shot mode */ #define OMAP3_TCLR_AR (1 << 1) /* Autoreload or one-shot mode */
#define OMAP3_TCLR_PRE (1 << 5) /* Prescaler on */ #define OMAP3_TCLR_PRE (1 << 5) /* Prescaler on */
#define OMAP3_TCLR_PTV 2 #define OMAP3_TCLR_PTV 2
#define OMAP3_TCLR_OVF_TRG (1 << 10) /* Overflow trigger */ #define OMAP3_TCLR_OVF_TRG (1 << 10) /* Overflow trigger */
#define OMAP3_GPTIMER1_TIDR (OMAP3_GPTIMER1_BASE + OMAP3_TIDR) #ifdef DM37XX
#define OMAP3_GPTIMER1_TIOCP_CFG (OMAP3_GPTIMER1_BASE + OMAP3_TIOCP_CFG)
#define OMAP3_GPTIMER1_TISTAT (OMAP3_GPTIMER1_BASE + OMAP3_TISTAT)
#define OMAP3_GPTIMER1_TISR (OMAP3_GPTIMER1_BASE + OMAP3_TISR)
#define OMAP3_GPTIMER1_TIER (OMAP3_GPTIMER1_BASE + OMAP3_TIER)
#define OMAP3_GPTIMER1_TWER (OMAP3_GPTIMER1_BASE + OMAP3_TWER)
#define OMAP3_GPTIMER1_TCLR (OMAP3_GPTIMER1_BASE + OMAP3_TCLR)
#define OMAP3_GPTIMER1_TCRR (OMAP3_GPTIMER1_BASE + OMAP3_TCRR)
#define OMAP3_GPTIMER1_TLDR (OMAP3_GPTIMER1_BASE + OMAP3_TLDR)
#define OMAP3_GPTIMER1_TTGR (OMAP3_GPTIMER1_BASE + OMAP3_TTGR)
#define OMAP3_GPTIMER1_TWPS (OMAP3_GPTIMER1_BASE + OMAP3_TWPS)
#define OMAP3_GPTIMER1_TMAR (OMAP3_GPTIMER1_BASE + OMAP3_TMAR)
#define OMAP3_GPTIMER1_TCAR1 (OMAP3_GPTIMER1_BASE + OMAP3_TCAR1)
#define OMAP3_GPTIMER1_TSICR (OMAP3_GPTIMER1_BASE + OMAP3_TSICR)
#define OMAP3_GPTIMER1_TCAR2 (OMAP3_GPTIMER1_BASE + OMAP3_TCAR2)
#define OMAP3_GPTIMER1_TPIR (OMAP3_GPTIMER1_BASE + OMAP3_TPIR)
#define OMAP3_GPTIMER1_TNIR (OMAP3_GPTIMER1_BASE + OMAP3_TNIR)
#define OMAP3_GPTIMER1_TCVR (OMAP3_GPTIMER1_BASE + OMAP3_TCVR)
#define OMAP3_GPTIMER1_TOCR (OMAP3_GPTIMER1_BASE + OMAP3_TOCR)
#define OMAP3_GPTIMER1_TOWR (OMAP3_GPTIMER1_BASE + OMAP3_TOWR)
#define OMAP3_GPTIMER10_TIDR (OMAP3_GPTIMER10_BASE + OMAP3_TIDR)
#define OMAP3_GPTIMER10_TIOCP_CFG (OMAP3_GPTIMER10_BASE + OMAP3_TIOCP_CFG)
#define OMAP3_GPTIMER10_TISTAT (OMAP3_GPTIMER10_BASE + OMAP3_TISTAT)
#define OMAP3_GPTIMER10_TISR (OMAP3_GPTIMER10_BASE + OMAP3_TISR)
#define OMAP3_GPTIMER10_TIER (OMAP3_GPTIMER10_BASE + OMAP3_TIER)
#define OMAP3_GPTIMER10_TWER (OMAP3_GPTIMER10_BASE + OMAP3_TWER)
#define OMAP3_GPTIMER10_TCLR (OMAP3_GPTIMER10_BASE + OMAP3_TCLR)
#define OMAP3_GPTIMER10_TCRR (OMAP3_GPTIMER10_BASE + OMAP3_TCRR)
#define OMAP3_GPTIMER10_TLDR (OMAP3_GPTIMER10_BASE + OMAP3_TLDR)
#define OMAP3_GPTIMER10_TTGR (OMAP3_GPTIMER10_BASE + OMAP3_TTGR)
#define OMAP3_GPTIMER10_TWPS (OMAP3_GPTIMER10_BASE + OMAP3_TWPS)
#define OMAP3_GPTIMER10_TMAR (OMAP3_GPTIMER10_BASE + OMAP3_TMAR)
#define OMAP3_GPTIMER10_TCAR1 (OMAP3_GPTIMER10_BASE + OMAP3_TCAR1)
#define OMAP3_GPTIMER10_TSICR (OMAP3_GPTIMER10_BASE + OMAP3_TSICR)
#define OMAP3_GPTIMER10_TCAR2 (OMAP3_GPTIMER10_BASE + OMAP3_TCAR2)
#define OMAP3_GPTIMER10_TPIR (OMAP3_GPTIMER10_BASE + OMAP3_TPIR)
#define OMAP3_GPTIMER10_TNIR (OMAP3_GPTIMER10_BASE + OMAP3_TNIR)
#define OMAP3_GPTIMER10_TCVR (OMAP3_GPTIMER10_BASE + OMAP3_TCVR)
#define OMAP3_GPTIMER10_TOCR (OMAP3_GPTIMER10_BASE + OMAP3_TOCR)
#define OMAP3_GPTIMER10_TOWR (OMAP3_GPTIMER10_BASE + OMAP3_TOWR)
#define OMAP3_CM_CLKSEL_GFX 0x48004b40 #define OMAP3_CM_CLKSEL_GFX 0x48004b40
#define OMAP3_CM_CLKEN_PLL 0x48004d00 #define OMAP3_CM_CLKEN_PLL 0x48004d00
#define OMAP3_CM_FCLKEN1_CORE 0x48004A00 #define OMAP3_CM_FCLKEN1_CORE 0x48004A00
#define OMAP3_CM_CLKSEL_CORE 0x48004A40 /* GPT10 src clock sel. */ #define OMAP3_CM_CLKSEL_CORE 0x48004A40 /* GPT10 src clock sel. */
#define OMAP3_CM_FCLKEN_PER 0x48005000 #define OMAP3_CM_FCLKEN_PER 0x48005000
#define OMAP3_CM_CLKSEL_PER 0x48005040 #define OMAP3_CM_CLKSEL_PER 0x48005040
#define OMAP3_CM_CLKSEL_WKUP 0x48004c40 /* GPT1 source clock selection */ #define OMAP3_CM_CLKSEL_WKUP 0x48004c40 /* GPT1 source clock selection */
#endif /* DM37XX */
#ifdef AM335X
#define CM_MODULEMODE_MASK (0x3 << 0)
#define CM_MODULEMODE_ENABLE (0x2 << 0)
#define CM_MODULEMODE_DISABLED (0x0 << 0)
#define CM_CLKCTRL_IDLEST (0x3 << 16)
#define CM_CLKCTRL_IDLEST_FUNC (0x0 << 16)
#define CM_CLKCTRL_IDLEST_TRANS (0x1 << 16)
#define CM_CLKCTRL_IDLEST_IDLE (0x2 << 16)
#define CM_CLKCTRL_IDLEST_DISABLE (0x3 << 16)
#define CM_WKUP_BASE 0x44E00400 /* Clock Module Wakeup Registers */
#define CM_WKUP_TIMER1_CLKCTRL (CM_WKUP_BASE + 0xC4) /* This register manages the TIMER1 clocks. [Memory Mapped] */
#define CM_PER_BASE 0x44E00000 /* Clock Module Peripheral Registers */
#define CM_PER_TIMER7_CLKCTRL (CM_PER_BASE + 0x7C) /* This register manages the TIMER7 clocks. [Memory Mapped] */
/* CM_DPLL registers */
#define CM_DPLL_BASE 0x44E00500 /* Clock Module PLL Registers */
#define CLKSEL_TIMER1MS_CLK (CM_DPLL_BASE + 0x28)
#define CLKSEL_TIMER1MS_CLK_SEL_MASK (0x7 << 0)
#define CLKSEL_TIMER1MS_CLK_SEL_SEL1 (0x0 << 0) /* Select CLK_M_OSC clock */
#define CLKSEL_TIMER1MS_CLK_SEL_SEL2 (0x1 << 0) /* Select CLK_32KHZ clock */
#define CLKSEL_TIMER1MS_CLK_SEL_SEL3 (0x2 << 0) /* Select TCLKIN clock */
#define CLKSEL_TIMER1MS_CLK_SEL_SEL4 (0x3 << 0) /* Select CLK_RC32K clock */
#define CLKSEL_TIMER1MS_CLK_SEL_SEL5 (0x4 << 0) /* Selects the CLK_32768 from 32KHz Crystal Osc */
#define CLKSEL_TIMER7_CLK (CM_DPLL_BASE + 0x04)
#define CLKSEL_TIMER7_CLK_SEL_MASK (0x3 << 0)
#define CLKSEL_TIMER7_CLK_SEL_SEL1 (0x0 << 0) /* Select TCLKIN clock */
#define CLKSEL_TIMER7_CLK_SEL_SEL2 (0x1 << 0) /* Select CLK_M_OSC clock */
#define CLKSEL_TIMER7_CLK_SEL_SEL3 (0x2 << 0) /* Select CLK_32KHZ clock */
#define CLKSEL_TIMER7_CLK_SEL_SEL4 (0x3 << 0) /* Reserved */
#endif /* AM335X */
#define OMAP3_CLKSEL_GPT1 (1 << 0) /* Selects GPTIMER 1 source #define OMAP3_CLKSEL_GPT1 (1 << 0) /* Selects GPTIMER 1 source
* clock: * clock:

View file

@ -11,7 +11,15 @@
#include <sys/types.h> #include <sys/types.h>
#include <assert.h> #include <assert.h>
#ifdef DM37XX
//keesj:todo we don't want to hardcode these values here but ratter
//get them using a system call. the same applies for the time offset
static u64_t calib_hz = 1625000, Hz; static u64_t calib_hz = 1625000, Hz;
#endif
#ifdef AM335X
static u64_t calib_hz = 1500000, Hz;
#endif
#define MICROHZ 1000000ULL /* number of micros per second */ #define MICROHZ 1000000ULL /* number of micros per second */
#define MICROSPERTICK(h) (MICROHZ/(h)) /* number of micros per HZ tick */ #define MICROSPERTICK(h) (MICROHZ/(h)) /* number of micros per HZ tick */
@ -56,7 +64,12 @@ read_frclock(u32_t *frclk)
volatile u32_t *frclock; volatile u32_t *frclock;
assert(frclk); assert(frclk);
frclock = (u32_t *)((u8_t *) _minix_kerninfo->minix_frclock+OMAP3_TCRR); #ifdef DM37XX
frclock = (u32_t *)((u8_t *) _minix_kerninfo->minix_frclock + OMAP3_TIMER_TCRR);
#endif
#ifdef AM335X
frclock = (u32_t *)((u8_t *) _minix_kerninfo->minix_frclock + AM335X_TIMER_TCRR);
#endif
*frclk = *frclock; *frclk = *frclock;
} }