Skip to content

Commit bc236f9

Browse files
ekohandelkartben
authored andcommitted
drivers: timer: Add MMU awareness to TI DM Timer
Map the timer register space using DEVICE_MMIO_NAMED_MAP so if the MMU is enabled, the register space is mapped correctly in the virtual memory. Signed-off-by: Abe Kohandel <[email protected]>
1 parent fb635f6 commit bc236f9

File tree

1 file changed

+79
-45
lines changed

1 file changed

+79
-45
lines changed

drivers/timer/ti_dmtimer.c

Lines changed: 79 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,36 @@
1717

1818
#define DT_DRV_COMPAT ti_am654_timer
1919

20-
#define TIMER_BASE_ADDR DT_INST_REG_ADDR(0)
21-
2220
#define TIMER_IRQ_NUM DT_INST_IRQN(0)
2321
#define TIMER_IRQ_PRIO DT_INST_IRQ(0, priority)
2422
#define TIMER_IRQ_FLAGS DT_INST_IRQ(0, flags)
2523

26-
#define CYC_PER_TICK ((uint32_t)(sys_clock_hw_cycles_per_sec() \
27-
/ CONFIG_SYS_CLOCK_TICKS_PER_SEC))
24+
#define CYC_PER_TICK ((uint32_t)(sys_clock_hw_cycles_per_sec() / CONFIG_SYS_CLOCK_TICKS_PER_SEC))
2825

2926
#define MAX_TICKS ((k_ticks_t)(UINT32_MAX / CYC_PER_TICK) - 1)
3027

31-
static struct k_spinlock lock;
28+
#define DEV_CFG(_dev) ((const struct ti_dm_timer_config *)(_dev)->config)
29+
#define DEV_DATA(_dev) ((struct ti_dm_timer_data *)(_dev)->data)
30+
31+
struct ti_dm_timer_config {
32+
DEVICE_MMIO_NAMED_ROM(reg_base);
33+
};
3234

33-
static uint32_t last_cycle;
35+
struct ti_dm_timer_data {
36+
DEVICE_MMIO_NAMED_RAM(reg_base);
37+
struct k_spinlock lock;
38+
uint32_t last_cycle;
39+
};
3440

35-
#define TI_DM_TIMER_READ(reg) sys_read32(TIMER_BASE_ADDR + TI_DM_TIMER_ ## reg)
41+
static const struct device *systick_timer_dev;
3642

37-
#define TI_DM_TIMER_MASK(reg) TI_DM_TIMER_ ## reg ## _MASK
38-
#define TI_DM_TIMER_SHIFT(reg) TI_DM_TIMER_ ## reg ## _SHIFT
39-
#define TI_DM_TIMER_WRITE(data, reg, bits) \
40-
ti_dm_timer_write_masks(data, \
41-
TIMER_BASE_ADDR + TI_DM_TIMER_ ## reg, \
42-
TI_DM_TIMER_MASK(reg ## _ ## bits), \
43-
TI_DM_TIMER_SHIFT(reg ## _ ## bits))
43+
#define TI_DM_TIMER_MASK(reg) TI_DM_TIMER_##reg##_MASK
44+
#define TI_DM_TIMER_SHIFT(reg) TI_DM_TIMER_##reg##_SHIFT
45+
46+
#define TI_DM_TIMER_READ(dev, reg) sys_read32(DEVICE_MMIO_GET(dev) + TI_DM_TIMER_##reg)
47+
#define TI_DM_TIMER_WRITE(dev, data, reg, bits) \
48+
ti_dm_timer_write_masks(data, DEVICE_MMIO_GET(dev) + TI_DM_TIMER_##reg, \
49+
TI_DM_TIMER_MASK(reg##_##bits), TI_DM_TIMER_SHIFT(reg##_##bits))
4450

4551
static void ti_dm_timer_write_masks(uint32_t data, uint32_t reg, uint32_t mask, uint32_t shift)
4652
{
@@ -51,39 +57,46 @@ static void ti_dm_timer_write_masks(uint32_t data, uint32_t reg, uint32_t mask,
5157
sys_write32(reg_val, reg);
5258
}
5359

54-
static void ti_dmtimer_isr(void *data)
60+
static void ti_dmtimer_isr(void *param)
5561
{
62+
ARG_UNUSED(param);
63+
64+
struct ti_dm_timer_data *data = systick_timer_dev->data;
65+
5666
/* If no pending event */
57-
if (!TI_DM_TIMER_READ(IRQSTATUS)) {
67+
if (!TI_DM_TIMER_READ(systick_timer_dev, IRQSTATUS)) {
5868
return;
5969
}
6070

61-
k_spinlock_key_t key = k_spin_lock(&lock);
71+
k_spinlock_key_t key = k_spin_lock(&data->lock);
6272

63-
uint32_t curr_cycle = TI_DM_TIMER_READ(TCRR);
64-
uint32_t delta_cycles = curr_cycle - last_cycle;
73+
uint32_t curr_cycle = TI_DM_TIMER_READ(systick_timer_dev, TCRR);
74+
uint32_t delta_cycles = curr_cycle - data->last_cycle;
6575
uint32_t delta_ticks = delta_cycles / CYC_PER_TICK;
6676

67-
last_cycle = curr_cycle;
77+
data->last_cycle = curr_cycle;
6878

6979
/* ACK match interrupt */
70-
TI_DM_TIMER_WRITE(1, IRQSTATUS, MAT_IT_FLAG);
80+
TI_DM_TIMER_WRITE(systick_timer_dev, 1, IRQSTATUS, MAT_IT_FLAG);
7181

7282
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
7383
/* Setup next match time */
7484
uint64_t next_cycle = curr_cycle + CYC_PER_TICK;
7585

76-
TI_DM_TIMER_WRITE(next_cycle, TMAR, COMPARE_VALUE);
86+
TI_DM_TIMER_WRITE(systick_timer_dev, next_cycle, TMAR, COMPARE_VALUE);
7787
}
7888

79-
k_spin_unlock(&lock, key);
89+
k_spin_unlock(&data->lock, key);
8090

8191
sys_clock_announce(delta_ticks);
8292
}
8393

8494
void sys_clock_set_timeout(int32_t ticks, bool idle)
8595
{
8696
ARG_UNUSED(idle);
97+
98+
struct ti_dm_timer_data *data = systick_timer_dev->data;
99+
87100
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
88101
/* Not supported on tickful kernels */
89102
return;
@@ -92,80 +105,101 @@ void sys_clock_set_timeout(int32_t ticks, bool idle)
92105
ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks;
93106
ticks = CLAMP(ticks, 1, (int32_t)MAX_TICKS);
94107

95-
k_spinlock_key_t key = k_spin_lock(&lock);
108+
k_spinlock_key_t key = k_spin_lock(&data->lock);
96109

97110
/* Setup next match time */
98-
uint32_t curr_cycle = TI_DM_TIMER_READ(TCRR);
111+
uint32_t curr_cycle = TI_DM_TIMER_READ(systick_timer_dev, TCRR);
99112
uint32_t next_cycle = curr_cycle + (ticks * CYC_PER_TICK);
100113

101-
TI_DM_TIMER_WRITE(next_cycle, TMAR, COMPARE_VALUE);
114+
TI_DM_TIMER_WRITE(systick_timer_dev, next_cycle, TMAR, COMPARE_VALUE);
102115

103-
k_spin_unlock(&lock, key);
116+
k_spin_unlock(&data->lock, key);
104117
}
105118

106119
uint32_t sys_clock_cycle_get_32(void)
107120
{
108-
k_spinlock_key_t key = k_spin_lock(&lock);
121+
struct ti_dm_timer_data *data = systick_timer_dev->data;
122+
123+
k_spinlock_key_t key = k_spin_lock(&data->lock);
109124

110-
uint32_t curr_cycle = TI_DM_TIMER_READ(TCRR);
125+
uint32_t curr_cycle = TI_DM_TIMER_READ(systick_timer_dev, TCRR);
111126

112-
k_spin_unlock(&lock, key);
127+
k_spin_unlock(&data->lock, key);
113128

114129
return curr_cycle;
115130
}
116131

117132
unsigned int sys_clock_elapsed(void)
118133
{
134+
struct ti_dm_timer_data *data = systick_timer_dev->data;
135+
119136
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
120137
/* Always return 0 for tickful kernel system */
121138
return 0;
122139
}
123140

124-
k_spinlock_key_t key = k_spin_lock(&lock);
141+
k_spinlock_key_t key = k_spin_lock(&data->lock);
125142

126-
uint32_t curr_cycle = TI_DM_TIMER_READ(TCRR);
127-
uint32_t delta_cycles = curr_cycle - last_cycle;
143+
uint32_t curr_cycle = TI_DM_TIMER_READ(systick_timer_dev, TCRR);
144+
uint32_t delta_cycles = curr_cycle - data->last_cycle;
128145
uint32_t delta_ticks = delta_cycles / CYC_PER_TICK;
129146

130-
k_spin_unlock(&lock, key);
147+
k_spin_unlock(&data->lock, key);
131148

132149
return delta_ticks;
133150
}
134151

135152
static int sys_clock_driver_init(void)
136153
{
137-
last_cycle = 0;
154+
struct ti_dm_timer_data *data;
155+
156+
systick_timer_dev = DEVICE_DT_GET(DT_NODELABEL(systick_timer));
157+
158+
data = systick_timer_dev->data;
159+
160+
data->last_cycle = 0;
161+
162+
DEVICE_MMIO_NAMED_MAP(systick_timer_dev, reg_base, K_MEM_CACHE_NONE);
138163

139164
IRQ_CONNECT(TIMER_IRQ_NUM, TIMER_IRQ_PRIO, ti_dmtimer_isr, NULL, TIMER_IRQ_FLAGS);
140165

141166
/* Disable prescalar */
142-
TI_DM_TIMER_WRITE(0, TCLR, PRE);
167+
TI_DM_TIMER_WRITE(systick_timer_dev, 0, TCLR, PRE);
143168

144169
/* Select autoreload mode */
145-
TI_DM_TIMER_WRITE(1, TCLR, AR);
170+
TI_DM_TIMER_WRITE(systick_timer_dev, 1, TCLR, AR);
146171

147172
/* Enable match interrupt */
148-
TI_DM_TIMER_WRITE(1, IRQENABLE_SET, MAT_EN_FLAG);
173+
TI_DM_TIMER_WRITE(systick_timer_dev, 1, IRQENABLE_SET, MAT_EN_FLAG);
149174

150175
/* Load timer counter value */
151-
TI_DM_TIMER_WRITE(0, TCRR, TIMER_COUNTER);
176+
TI_DM_TIMER_WRITE(systick_timer_dev, 0, TCRR, TIMER_COUNTER);
152177

153178
/* Load timer load value */
154-
TI_DM_TIMER_WRITE(0, TLDR, LOAD_VALUE);
179+
TI_DM_TIMER_WRITE(systick_timer_dev, 0, TLDR, LOAD_VALUE);
155180

156181
/* Load timer compare value */
157-
TI_DM_TIMER_WRITE(CYC_PER_TICK, TMAR, COMPARE_VALUE);
182+
TI_DM_TIMER_WRITE(systick_timer_dev, CYC_PER_TICK, TMAR, COMPARE_VALUE);
158183

159184
/* Enable compare mode */
160-
TI_DM_TIMER_WRITE(1, TCLR, CE);
185+
TI_DM_TIMER_WRITE(systick_timer_dev, 1, TCLR, CE);
161186

162187
/* Start the timer */
163-
TI_DM_TIMER_WRITE(1, TCLR, ST);
188+
TI_DM_TIMER_WRITE(systick_timer_dev, 1, TCLR, ST);
164189

165190
irq_enable(TIMER_IRQ_NUM);
166191

167192
return 0;
168193
}
169194

170-
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
171-
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
195+
#define TI_DM_TIMER(n) \
196+
static struct ti_dm_timer_data ti_dm_timer_data_##n; \
197+
static const struct ti_dm_timer_config ti_dm_timer_config_##n = { \
198+
DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \
199+
}; \
200+
DEVICE_DT_INST_DEFINE(n, NULL, NULL, &ti_dm_timer_data_##n, &ti_dm_timer_config_##n, \
201+
PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY, NULL);
202+
203+
DT_INST_FOREACH_STATUS_OKAY(TI_DM_TIMER);
204+
205+
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);

0 commit comments

Comments
 (0)