9
#include <drivers/common/memory.h>
10
#include <drivers/irqctrl.h>
14
#include <hal/system.h>
15
#include <kernel/irq.h>
16
#include <kernel/time/clock_source.h>
17
#include <kernel/printk.h>
18
#include <util/binalign.h>
20
#include <embox/unit.h>
24
#define CM_FCLKEN_WKUP 0x48004C00
25
#define CM_ICLKEN_WKUP 0x48004C10
26
#define CM_CLKSEL_WKUP 0x48004C40
28
#define GPTIMER1_BASE ((void *) 0x48318000)
29
#define GPTIMER1_IRQ 37
53
} __attribute__((packed));
55
#define OMAP_LOAD_VALUE 0xffffffe0
59
#define GPTIMER_TCLR_START (1 << 0)
60
#define GPTIMER_TCLR_AUTORELOAD (1 << 1)
62
#define GPTIMER_TIER_OVERFLOW (1 << 1)
63
#define GPTIMER_TISR_OVERFLOW (1 << 1)
65
static irq_return_t clock_handler(unsigned int irq_nr, void *data) {
66
volatile struct gptimerxx_x *gptimer = GPTIMER1_BASE;
67
clock_tick_handler(data);
68
REG_STORE(&gptimer->tisr, GPTIMER_TISR_OVERFLOW);
72
static int omap3_clk_set_periodic(struct clock_source *cs) {
73
volatile struct gptimerxx_x *gptimer = GPTIMER1_BASE;
75
REG_ORIN(CM_FCLKEN_WKUP, 1);
76
REG_ORIN(CM_ICLKEN_WKUP, 1);
77
REG_ANDIN(CM_CLKSEL_WKUP, ~1);
79
REG_STORE(&gptimer->cfg, 0x2);
81
REG_STORE(&gptimer->tpir, 232000);
82
REG_STORE(&gptimer->tnir, -768000);
84
REG_STORE(&gptimer->tcrr, OMAP_LOAD_VALUE);
85
REG_STORE(&gptimer->tldr, OMAP_LOAD_VALUE);
87
REG_STORE(&gptimer->tclr, GPTIMER_TCLR_START | GPTIMER_TCLR_AUTORELOAD);
89
REG_STORE(&gptimer->tier, GPTIMER_TIER_OVERFLOW);
90
REG_STORE(&gptimer->twer, GPTIMER_TIER_OVERFLOW);
95
static struct time_event_device omap3_clk_event = {
96
.set_periodic = omap3_clk_set_periodic,
97
.irq_nr = GPTIMER1_IRQ,
100
static int omap_clk_init(struct clock_source *cs) {
102
return irq_attach(GPTIMER1_IRQ, clock_handler, 0, cs, "omap3_clk");
105
PERIPH_MEMORY_DEFINE(omap3_gptimer, (uintptr_t) GPTIMER1_BASE, 0x1000);
107
PERIPH_MEMORY_DEFINE(omap3_cm, CM_FCLKEN_WKUP, 0x50);
109
CLOCK_SOURCE_DEF(omap3_clk, omap_clk_init, NULL,
110
&omap3_clk_event, NULL);