embox

Форк
0
121 строка · 3.2 Кб
1
/**
2
 * @file
3
 * @brief i.MX General Purpose Timer.
4
 * @note See i.MX 8M Dual/8M QuadLite/8M Quad Applications Processors Reference
5
 *       Manual for more details
6
 * @author Denis Deryugin <deryugin.denis@gmail.com>
7
 * @version 0.1
8
 * @date 2019-07-23
9
 */
10

11
#include <sys/mman.h>
12

13
#include <drivers/common/memory.h>
14
#include <hal/clock.h>
15
#include <hal/reg.h>
16
#include <hal/system.h>
17
#include <kernel/printk.h>
18
#include <kernel/irq.h>
19
#include <kernel/time/clock_source.h>
20
#include <embox/unit.h>
21
#include <util/log.h>
22

23
#define GPT_BASE_ADDR OPTION_GET(NUMBER, base_addr)
24
#define GPT_IRQ       OPTION_GET(NUMBER, irq_num)
25

26
#define GPT_CR                 (GPT_BASE_ADDR + 0x00)
27
# define GPT_CR_EN             (1 << 0)
28
# define GPT_CR_ENMOD          (1 << 1)
29
# define GPT_CR_CLKSRC_OFFT    6
30
# define GPT_CR_CLKSRC_MASK    0x7
31
# define GPT_CR_OM1_OFFT       20
32
# define GPT_CR_OM1_MASK       0x7
33
# define GPT_CR_SWR            (1 << 15)
34
#define GPT_PR                 (GPT_BASE_ADDR + 0x04)
35
# define GPT_PR_PRESCALER_MASK (0xFFF)
36
#define GPT_SR                 (GPT_BASE_ADDR + 0x08)
37
# define GPT_SR_OF1            (1 << 0)
38
# define GPT_SR_OF2            (1 << 1)
39
# define GPT_SR_OF3            (1 << 2)
40
# define GPT_SR_ROV            (1 << 5)
41
# define GPT_SR_MASK           0x1F
42
#define GPT_IR                 (GPT_BASE_ADDR + 0x0C)
43
# define GPT_IR_OF1            (1 << 0)
44
# define GPT_IR_OF2            (1 << 1)
45
# define GPT_IR_OF3            (1 << 2)
46
# define GPT_IR_ROVIE          (1 << 5)
47
#define GPT_OCR1               (GPT_BASE_ADDR + 0x10)
48
#define GPT_OCR2               (GPT_BASE_ADDR + 0x14)
49
#define GPT_OCR3               (GPT_BASE_ADDR + 0x18)
50
#define GPT_ICR1               (GPT_BASE_ADDR + 0x1C)
51
#define GPT_ICR2               (GPT_BASE_ADDR + 0x20)
52
#define GPT_CNT                (GPT_BASE_ADDR + 0x24)
53

54
#define PERIPHCLK       (SYS_CLOCK / 2)
55
#define TARGET_FREQ		OPTION_GET(NUMBER, freq)
56
#define LOAD_VALUE		PERIPHCLK / (TARGET_FREQ - 1)
57

58
static irq_return_t clock_handler(unsigned int irq_nr, void *data) {
59
	clock_tick_handler(data);
60

61
	REG32_STORE(GPT_IR, GPT_IR_OF1);
62

63
	return IRQ_HANDLED;
64
}
65

66
static int gpt_timer_init(struct clock_source *cs) {
67
	REG32_STORE(GPT_CR, 0);
68

69
	irq_attach(GPT_IRQ,
70
		  clock_handler,
71
		  0,
72
		  cs,
73
		  "i.MX General Purpose Timer");
74
	return 0;
75
}
76

77
static int this_set_periodic(struct clock_source *cs) {
78
	/* Init timer as described in 12.1.5.1 in IMX8MDQLQRM.pdf */
79
	REG32_STORE(GPT_CR, 0);
80

81
	REG32_STORE(GPT_IR, 0);
82

83
	REG32_STORE(GPT_CR, GPT_CR_SWR);
84

85
	while (REG32_LOAD(GPT_CR) & GPT_CR_SWR);
86

87
	REG32_STORE(GPT_CR, (1 << GPT_CR_CLKSRC_OFFT));
88

89
	REG32_STORE(GPT_SR, GPT_SR_MASK);
90

91
	REG32_ORIN(GPT_CR, GPT_CR_ENMOD);
92

93
	REG32_ORIN(GPT_CR, GPT_CR_EN);
94

95
	REG32_ORIN(GPT_CR, 0x1 << 20);
96

97
	REG32_STORE(GPT_IR, GPT_IR_OF1);
98

99
	REG32_STORE(GPT_OCR1, LOAD_VALUE);
100

101
	return 0;
102
}
103

104
static cycle_t this_read(struct clock_source *cs) {
105
	return REG32_LOAD(GPT_CNT);
106
}
107

108
static struct time_event_device gpt_timer_event = {
109
	.set_periodic = this_set_periodic,
110
	.irq_nr = GPT_IRQ,
111
};
112

113
static struct time_counter_device gpt_timer_counter = {
114
	.read = this_read,
115
	.cycle_hz = 1000,
116
};
117

118
PERIPH_MEMORY_DEFINE(gpt_timer, GPT_BASE_ADDR, 0x28);
119

120
CLOCK_SOURCE_DEF(gpt_timer, gpt_timer_init, NULL,
121
	&gpt_timer_event, &gpt_timer_counter);
122

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

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

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

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