embox

Форк
0
131 строка · 3.7 Кб
1
/**
2
 * @file e2k.c
3
 * @brief Stub
4
 * @author Denis Deryugin <deryugin.denis@gmail.com>
5
 * @version
6
 * @date 20.12.2017
7
 */
8
#include <util/log.h>
9

10
#include <stdint.h>
11
#include <asm/io.h>
12

13
#include <embox/unit.h>
14
#include <framework/mod/options.h>
15

16
#include <hal/clock.h>
17
#include <kernel/irq.h>
18
#include <kernel/time/clock_source.h>
19
#include <kernel/time/time_device.h>
20

21
#include <hal/ipl.h>
22
#include <e2k_api.h>
23
#include <e2k_mas.h>
24

25

26

27
#include <asm/mpspec.h>
28

29
static uint64_t clock_base = 0;
30

31
#define E2K_CLOCK_BASE ((uint32_t)clock_base)
32

33
#define IRQ_NR     OPTION_GET(NUMBER, irq_num)
34
#define LT_FREQ    OPTION_GET(NUMBER, freq)
35

36
#define E2K_COUNTER_LIMIT	(E2K_CLOCK_BASE + 0x00)
37
#define E2K_COUNTER_START_VALUE	(E2K_CLOCK_BASE + 0x04)
38
#define E2K_COUNTER		(E2K_CLOCK_BASE + 0x08)
39
#define E2K_COUNTER_CONTROL	(E2K_CLOCK_BASE + 0x0c)
40
#define E2K_WD_COUNTER		(E2K_CLOCK_BASE + 0x10)
41
#define E2K_WD_COUNTER_LOW	(E2K_CLOCK_BASE + 0x10)
42
#define E2K_WD_COUNTER_HIGH	(E2K_CLOCK_BASE + 0x14)
43
#define E2K_WD_LIMIT		(E2K_CLOCK_BASE + 0x18)
44
#define E2K_POWER_COUNTER	(E2K_CLOCK_BASE + 0x1c)
45
#define E2K_POWER_COUNTER_LOW	(E2K_CLOCK_BASE + 0x1c)
46
#define E2K_POWER_COUNTER_HIGH	(E2K_CLOCK_BASE + 0x20)
47
#define E2K_WD_CONTROL		(E2K_CLOCK_BASE + 0x24)
48
#define E2K_RESET_COUNTER	(E2K_CLOCK_BASE + 0x28)
49
#define E2K_RESET_COUNTER_LOW	(E2K_CLOCK_BASE + 0x28)
50
#define E2K_RESET_COUNTER_HIGH	(E2K_CLOCK_BASE + 0x2c)
51

52
/* counters registers structure */
53
#define	LT_COUNTER_SHIFT	9	/* [30: 9] counters value */
54
#define	LT_COUNTER_LIMIT_SHIFT	31	/* [31] Limit bit */
55
#define	LT_COUNTER_LIMIT_BIT	(1 << LT_COUNTER_LIMIT_SHIFT)
56

57
#define	LT_WRITE_COUNTER_VALUE(count)	((count) << LT_COUNTER_SHIFT)
58
#define	LT_READ_COUNTER_VALUE(count)	((count) >> LT_COUNTER_SHIFT)
59
#define	LT_NSEC_PER_COUNTER_INCR	100	/* 10 MHz == 100 nunosec */
60

61
/* counter control register structure */
62
#define	LT_COUNTER_CNTR_START	0x00000001	/* start/stop timer */
63
#define	LT_COUNTER_CNTR_INVERTL	0x00000002	/* invert limit bit */
64
#define	LT_COUNTER_CNTR_LINIT	0x00000004	/* Limit bit initial state */
65
						/* 1 - limit bit set to 1 */
66

67
#define	LT_COUNTER_CNTR_LAUNCH	(LT_COUNTER_CNTR_START)
68
#define	LT_INVERT_COUNTER_CNTR_LAUNCH	(LT_COUNTER_CNTR_LAUNCH | \
69
						LT_COUNTER_CNTR_INVERTL | \
70
						LT_COUNTER_CNTR_LINIT)
71
#define	LT_COUNTER_CNTR_STOP	(0)
72

73
#define WD_CLOCK_TICK_RATE 10000000L
74
#define WD_LATCH(tick_rate) (((tick_rate) + HZ/2) / HZ)
75
#define WD_LIMIT_SHIFT	12
76
#define	WD_WRITE_COUNTER_VALUE(count) (count)
77
#define	WD_READ_COUNTER_VALUE(count) ((count) << WD_LIMIT_SHIFT)
78
#define WD_SET_COUNTER_VAL(sek)	\
79
		(WD_WRITE_COUNTER_VALUE(WD_CLOCK_TICK_RATE * (sek)))
80

81
#define	WD_INTR_MODE	0x1
82
#define	WD_ENABLE	0x2
83
#define	WD_EVENT	0x4
84

85
static irq_return_t e2k_clock_handler(unsigned int irq_nr, void *dev_id) {
86
	clock_tick_handler(dev_id);
87
	return IRQ_HANDLED;
88
}
89

90
static int e2k_clock_init(struct clock_source *cs) {
91
	uint32_t clock_hz = (10000000 + LT_FREQ / 2) / LT_FREQ;
92

93
	clock_base = mpspec_get_clock_base();
94
	if (clock_base == 0) {
95
		log_error(" Error: MP_TIMER record not found, ");
96
		return -1;
97
	}
98

99
	irq_attach(IRQ_NR, e2k_clock_handler, 0, cs, "e2k clock");
100

101
	/* Setup frequency */
102
	e2k_write32(clock_hz << 9, E2K_COUNTER_LIMIT);
103
	e2k_write32(LT_INVERT_COUNTER_CNTR_LAUNCH, E2K_COUNTER_CONTROL);
104

105
	return 0;
106
}
107

108
static int e2k_clock_set_periodic(struct clock_source *cs) {
109
	return 0;
110
}
111

112
static cycle_t e2k_clock_read(struct clock_source *cs) {
113
	cycle_t res;
114

115
	res = e2k_read64(E2K_POWER_COUNTER);
116

117
	return res;
118
}
119

120
static struct time_event_device e2k_clock_event = {
121
	.set_periodic   = e2k_clock_set_periodic,
122
	.irq_nr = IRQ_NR
123
};
124

125
static struct time_counter_device e2k_clock_counter = {
126
	.read     = e2k_clock_read,
127
	.cycle_hz = 10000000,
128
};
129

130
CLOCK_SOURCE_DEF(e2k_clock, e2k_clock_init, NULL,
131
		&e2k_clock_event, &e2k_clock_counter);
132

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.