embox
86 строк · 2.2 Кб
1/**
2* @file
3*
4* @date 05 aug 2015
5* @author: Anton Bondarev
6*/
7
8#include <sys/mman.h>9
10#include <drivers/common/memory.h>11#include <hal/clock.h>12#include <hal/reg.h>13#include <kernel/irq.h>14#include <kernel/printk.h>15#include <kernel/time/clock_source.h>16#include <kernel/time/time.h>17
18#define TIMER_BASE OPTION_GET(NUMBER, base_addr)19
20/* Interrupt vector for timer (TMR1) */
21#define CLOCK_IRQ 522
23/* The clock rate per second */
24#define CLOCK_RATE 48054841L25
26/* The initial counter value */
27#define TIMER_COUNT (CLOCK_RATE / JIFFIES_PERIOD)28
29/* Timer 1 registers */
30#define TMR_LOAD (TIMER_BASE + 0x000)31#define TMR_VAL (TIMER_BASE + 0x004)32#define TMR_CTRL (TIMER_BASE + 0x008)33#define TMR_CLR (TIMER_BASE + 0x00c)34#define TMR_BGLOAD (TIMER_BASE + 0x024)35
36/* Timer control register */
37#define TCTRL_DISABLE 0x0038#define TCTRL_ENABLE 0x8039#define TCTRL_PERIODIC 0x4040#define TCTRL_INTEN 0x2041#define TCTRL_SCALE256 0x0842#define TCTRL_SCALE16 0x0443#define TCTRL_32BIT 0x0244#define TCTRL_ONESHOT 0x0145
46static int integratorcp_clock_setup(struct clock_source *cs) {47/* Setup counter value */48REG32_STORE(TMR_CTRL, TCTRL_DISABLE);49REG32_STORE(TMR_LOAD, TIMER_COUNT);50REG32_ORIN(TMR_CTRL, (TCTRL_ENABLE | TCTRL_PERIODIC));51
52/* Enable timer interrupt */53REG32_ORIN(TMR_CTRL, TCTRL_INTEN);54
55return 0;56}
57
58static struct time_event_device integratorcp_event_device = {59.set_periodic = integratorcp_clock_setup,60.name = "integratorcp_clk",61.irq_nr = CLOCK_IRQ,62};63
64static cycle_t integratorcp_counter_read(struct clock_source *cs) {65return REG32_LOAD(TMR_VAL) & 0xFFFF;66}
67
68static struct time_counter_device integratorcp_counter_device = {69.cycle_hz = CLOCK_RATE,70.read = integratorcp_counter_read,71};72
73static irq_return_t clock_handler(unsigned int irq_nr, void *dev_id) {74clock_tick_handler(dev_id);75REG32_STORE(TMR_CLR, 0x01); /* Clear timer interrupt */76return IRQ_HANDLED;77}
78
79static int integratorcp_cs_init(struct clock_source *cs) {80return irq_attach(CLOCK_IRQ, clock_handler, 0, cs, "integratorcp_clk");81}
82
83CLOCK_SOURCE_DEF(integratorcp, integratorcp_cs_init, NULL,84&integratorcp_event_device, &integratorcp_counter_device);85
86PERIPH_MEMORY_DEFINE(integratorcp_clock, TIMER_BASE, 0x30);87