embox
87 строк · 2.4 Кб
1/**
2* @file
3*
4* @brief RISC-V build-in timer
5*
6* @date 12.12.2019
7* @author Anastasia Nizharadze
8*/
9
10#include <errno.h>
11#include <stdint.h>
12
13#include <asm/interrupts.h>
14#include <asm/regs.h>
15#include <framework/mod/options.h>
16#include <hal/clock.h>
17#include <hal/reg.h>
18#include <hal/system.h>
19#include <kernel/irq.h>
20#include <kernel/time/clock_source.h>
21#include <kernel/time/time.h>
22
23#define BASE_ADDR OPTION_GET(NUMBER, base_addr)
24
25#define COUNT_OFFSET (RTC_CLOCK / JIFFIES_PERIOD)
26
27#define RTC_CLOCK OPTION_GET(NUMBER, rtc_freq)
28
29#define SCR1_TIMER_ENABLE_S 0
30#define SCR1_TIMER_ENABLE_M (1 << SCR1_TIMER_ENABLE_S)
31
32#define SCR1_TIMER_CLKSRC_S 1
33#define SCR1_TIMER_CLKSRC_M (1 << SCR1_TIMER_CLKSRC_S)
34#define SCR1_TIMER_CLKSRC_INTERNAL_M (0 << SCR1_TIMER_CLKSRC_S)
35#define SCR1_TIMER_CLKSRC_RTC_M (1 << SCR1_TIMER_CLKSRC_S)
36
37struct mikron_clk_regs {
38volatile uint32_t TIMER_CTRL;
39volatile uint32_t TIMER_DIV;
40volatile uint32_t MTIME;
41volatile uint32_t MTIMEH;
42volatile uint32_t MTIMECMP;
43volatile uint32_t MTIMECMPH;
44};
45
46static struct mikron_clk_regs *SCR1_TIMER = (void*)(uintptr_t)BASE_ADDR;
47
48static int clock_handler(unsigned int irq_nr, void *dev_id) {
49//REG64_STORE(MTIMECMP, REG64_LOAD(MTIME) + COUNT_OFFSET);
50*(unsigned long long *) &SCR1_TIMER->MTIMECMP += COUNT_OFFSET;
51
52clock_tick_handler(dev_id);
53
54return IRQ_HANDLED;
55}
56
57static int riscv_clock_setup(struct clock_source *cs) {
58//REG64_STORE(MTIMECMP, REG64_LOAD(MTIME) + COUNT_OFFSET);
59
60*(unsigned long long *) &SCR1_TIMER->MTIME = 0;
61*(unsigned long long *) &SCR1_TIMER->MTIMECMP = COUNT_OFFSET;
62//SCR1_TIMER->TIMER_CTRL |= SCR1_TIMER_ENABLE_M;
63
64return ENOERR;
65}
66
67static int mikron_clk_init(struct clock_source *cs) {
68//REG64_STORE(MTIMECMP, REG64_LOAD(MTIME) + COUNT_OFFSET);
69SCR1_TIMER->TIMER_DIV = 0;
70*(unsigned long long *) &SCR1_TIMER->MTIME = 0;
71*(unsigned long long *) &SCR1_TIMER->MTIMECMP = COUNT_OFFSET;
72SCR1_TIMER->TIMER_CTRL |= SCR1_TIMER_ENABLE_M;
73//SCR1_TIMER->TIMER_CTRL &= ~SCR1_TIMER_ENABLE_M;
74enable_timer_interrupts();
75
76return ENOERR;
77}
78
79static struct time_event_device riscv_event_device = {
80.set_periodic = riscv_clock_setup,
81.name = "mikron_clk",
82.irq_nr = IRQ_TIMER,
83};
84
85CLOCK_SOURCE_DEF(mikron_clk, mikron_clk_init, NULL, &riscv_event_device, NULL);
86
87RISCV_TIMER_IRQ_DEF(clock_handler, &CLOCK_SOURCE_NAME(mikron_clk));
88