1 /*
2  * Copyright (c) 2022 Andes Technology
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/counter.h>
8 #include <zephyr/spinlock.h>
9 #include <zephyr/irq.h>
10 #include <zephyr/arch/cpu.h>
11 #include <string.h>
12 
13 #define DT_DRV_COMPAT andestech_atcpit100
14 
15 /* register definitions */
16 #define REG_IDR   0x00 /* ID and Revision Reg.   */
17 #define REG_CFG   0x10 /* Configuration Reg.     */
18 #define REG_INTE  0x14 /* Interrupt Enable Reg.  */
19 #define REG_ISTA  0x18 /* Interrupt Status Reg.  */
20 #define REG_CHEN  0x1C /* Channel Enable Reg.    */
21 #define REG_CTRL0 0x20 /* Channel 0 Control Reg. */
22 #define REG_RELD0 0x24 /* Channel 0 Reload Reg.  */
23 #define REG_CNTR0 0x28 /* Channel 0 Counter Reg. */
24 #define REG_CTRL1 0x30 /* Channel 1 Control Reg. */
25 #define REG_RELD1 0x34 /* Channel 1 Reload Reg.  */
26 #define REG_CNTR1 0x38 /* Channel 1 Counter Reg. */
27 #define REG_CTRL2 0x40 /* Channel 2 Control Reg. */
28 #define REG_RELD2 0x44 /* Channel 2 Reload Reg.  */
29 #define REG_CNTR2 0x48 /* Channel 2 Counter Reg. */
30 #define REG_CTRL3 0x50 /* Channel 3 Control Reg. */
31 #define REG_RELD3 0x54 /* Channel 3 Reload Reg.  */
32 #define REG_CNTR3 0x58 /* Channel 3 Counter Reg. */
33 
34 #define PIT_BASE (((const struct atcpit100_config *)(dev)->config)->base)
35 #define PIT_INTE(dev) (PIT_BASE + REG_INTE)
36 #define PIT_ISTA(dev) (PIT_BASE + REG_ISTA)
37 #define PIT_CHEN(dev) (PIT_BASE + REG_CHEN)
38 #define PIT_CH_CTRL(dev, ch) (PIT_BASE + REG_CTRL0 + (ch << 4))
39 #define PIT_CH_RELD(dev, ch) (PIT_BASE + REG_RELD0 + (ch << 4))
40 #define PIT_CH_CNTR(dev, ch) (PIT_BASE + REG_CNTR0 + (ch << 4))
41 
42 #define CTRL_CH_SRC_PCLK BIT(3)
43 #define CTRL_CH_MODE_32BIT BIT(0)
44 
45 #define CHANNEL_NUM (4)
46 #define CH_NUM_PER_COUNTER (CHANNEL_NUM - 1)
47 #define TIMER0_CHANNEL(ch) BIT(((ch) * CHANNEL_NUM))
48 
49 typedef void (*atcpit100_cfg_func_t)(void);
50 
51 struct atcpit100_config {
52 	struct counter_config_info info;
53 	uint32_t base;
54 	uint32_t divider;
55 	uint32_t irq_num;
56 	atcpit100_cfg_func_t cfg_func;
57 };
58 
59 struct counter_atcpit100_ch_data {
60 	counter_alarm_callback_t alarm_callback;
61 	void *alarm_user_data;
62 };
63 
64 struct atcpit100_data {
65 	counter_top_callback_t top_callback;
66 	void *top_user_data;
67 	uint32_t guard_period;
68 	struct k_spinlock lock;
69 	struct counter_atcpit100_ch_data ch_data[CH_NUM_PER_COUNTER];
70 };
71 
get_current_tick(const struct device * dev,uint32_t ch)72 static inline uint32_t get_current_tick(const struct device *dev, uint32_t ch)
73 {
74 	const struct atcpit100_config *config = dev->config;
75 	uint32_t top, now_cnt;
76 
77 	/* Preload cycles is reload register + 1 */
78 	top = sys_read32(PIT_CH_RELD(dev, ch)) + 1;
79 	now_cnt = top - sys_read32(PIT_CH_CNTR(dev, ch));
80 
81 	return (now_cnt / config->divider);
82 }
83 
atcpit100_irq_handler(void * arg)84 static void atcpit100_irq_handler(void *arg)
85 {
86 	struct device *dev = (struct device *)arg;
87 	struct atcpit100_data *data = dev->data;
88 	counter_alarm_callback_t cb;
89 	uint32_t int_status, int_enable, ch_enable, cur_ticks;
90 	uint8_t i;
91 
92 	ch_enable = sys_read32(PIT_CHEN(dev));
93 	int_enable = sys_read32(PIT_INTE(dev));
94 	int_status = sys_read32(PIT_ISTA(dev));
95 
96 	if (int_status & TIMER0_CHANNEL(3)) {
97 		if (data->top_callback) {
98 			data->top_callback(dev, data->top_user_data);
99 		}
100 	}
101 
102 	for (i = 0; i < CH_NUM_PER_COUNTER; i++) {
103 		if (int_status & TIMER0_CHANNEL(i)) {
104 			int_enable &= ~TIMER0_CHANNEL(i);
105 			ch_enable &= ~TIMER0_CHANNEL(i);
106 		}
107 	}
108 
109 	/* Disable channel and interrupt */
110 	sys_write32(int_enable, PIT_INTE(dev));
111 	sys_write32(ch_enable, PIT_CHEN(dev));
112 
113 	/* Clear interrupt status */
114 	sys_write32(int_status, PIT_ISTA(dev));
115 
116 	for (i = 0; i < CH_NUM_PER_COUNTER; i++) {
117 		if (int_status & TIMER0_CHANNEL(i)) {
118 			cur_ticks = get_current_tick(dev, 3);
119 			cb = data->ch_data[i].alarm_callback;
120 			data->ch_data[i].alarm_callback = NULL;
121 			if (cb != NULL) {
122 				cb(dev, i, cur_ticks, data->ch_data[i].alarm_user_data);
123 			}
124 		}
125 	}
126 }
127 
counter_atcpit100_init(const struct device * dev)128 static int counter_atcpit100_init(const struct device *dev)
129 {
130 	const struct atcpit100_config *config = dev->config;
131 	uint32_t reg;
132 
133 	/* Disable all channels */
134 	sys_write32(0, PIT_CHEN(dev));
135 
136 	/* Channel 0 ~ 3, 32 bits timer, PCLK source */
137 	reg = CTRL_CH_MODE_32BIT | CTRL_CH_SRC_PCLK;
138 	sys_write32(reg, PIT_CH_CTRL(dev, 0));
139 	sys_write32(reg, PIT_CH_CTRL(dev, 1));
140 	sys_write32(reg, PIT_CH_CTRL(dev, 2));
141 	sys_write32(reg, PIT_CH_CTRL(dev, 3));
142 
143 	/* Disable all interrupt and clear all pending interrupt */
144 	sys_write32(0, PIT_INTE(dev));
145 	sys_write32(UINT32_MAX, PIT_ISTA(dev));
146 
147 	/* Select channel 3 as default counter and set max top value */
148 	reg = config->info.max_top_value * config->divider;
149 
150 	/* Set cycle - 1 to reload register */
151 	sys_write32((reg - 1), PIT_CH_RELD(dev, 3));
152 
153 	config->cfg_func();
154 
155 	irq_enable(config->irq_num);
156 
157 	return 0;
158 }
159 
atcpit100_start(const struct device * dev)160 static int atcpit100_start(const struct device *dev)
161 {
162 	struct atcpit100_data *data = dev->data;
163 	k_spinlock_key_t key;
164 	uint32_t reg;
165 
166 	key = k_spin_lock(&data->lock);
167 
168 	/* Enable channel */
169 	reg = sys_read32(PIT_CHEN(dev));
170 	reg |= TIMER0_CHANNEL(3);
171 	sys_write32(reg, PIT_CHEN(dev));
172 
173 	k_spin_unlock(&data->lock, key);
174 
175 	return 0;
176 }
177 
atcpit100_stop(const struct device * dev)178 static int atcpit100_stop(const struct device *dev)
179 {
180 	struct atcpit100_data *data = dev->data;
181 	k_spinlock_key_t key;
182 	uint32_t reg;
183 
184 	key = k_spin_lock(&data->lock);
185 
186 	/* Disable channel interrupt */
187 	reg = sys_read32(PIT_INTE(dev));
188 	reg &= ~TIMER0_CHANNEL(3);
189 	sys_write32(reg, PIT_INTE(dev));
190 
191 	/* Disable channel */
192 	reg = sys_read32(PIT_CHEN(dev));
193 	reg &= ~TIMER0_CHANNEL(3);
194 	sys_write32(reg, PIT_CHEN(dev));
195 
196 	/* Clear interrupt status */
197 	sys_write32(TIMER0_CHANNEL(3), PIT_ISTA(dev));
198 
199 	k_spin_unlock(&data->lock, key);
200 
201 	return 0;
202 }
203 
atcpit100_get_value(const struct device * dev,uint32_t * ticks)204 static int atcpit100_get_value(const struct device *dev, uint32_t *ticks)
205 {
206 	struct atcpit100_data *data = dev->data;
207 	k_spinlock_key_t key;
208 
209 	key = k_spin_lock(&data->lock);
210 
211 	*ticks = get_current_tick(dev, 3);
212 
213 	k_spin_unlock(&data->lock, key);
214 
215 	return 0;
216 }
217 
atcpit100_set_alarm(const struct device * dev,uint8_t chan_id,const struct counter_alarm_cfg * alarm_cfg)218 static int atcpit100_set_alarm(const struct device *dev, uint8_t chan_id,
219 			       const struct counter_alarm_cfg *alarm_cfg)
220 {
221 	const struct atcpit100_config *config = dev->config;
222 	struct atcpit100_data *data = dev->data;
223 	uint32_t top, now_cnt, remain_cnt, alarm_cnt, flags, reg;
224 	k_spinlock_key_t key;
225 	int err = 0;
226 
227 	if (chan_id >= CH_NUM_PER_COUNTER) {
228 		return -ENOTSUP;
229 	}
230 
231 	if (!alarm_cfg->callback) {
232 		return -EINVAL;
233 	}
234 
235 	if (data->ch_data[chan_id].alarm_callback) {
236 		return -EBUSY;
237 	}
238 
239 	key = k_spin_lock(&data->lock);
240 
241 	/* Preload cycles is reload register + 1 */
242 	top = sys_read32(PIT_CH_RELD(dev, 3)) + 1;
243 	remain_cnt = sys_read32(PIT_CH_CNTR(dev, 3));
244 	alarm_cnt = alarm_cfg->ticks * config->divider;
245 
246 	if (alarm_cnt > top) {
247 		err = -EINVAL;
248 		goto out;
249 	}
250 
251 	flags = alarm_cfg->flags;
252 	data->ch_data[chan_id].alarm_callback = alarm_cfg->callback;
253 	data->ch_data[chan_id].alarm_user_data = alarm_cfg->user_data;
254 
255 	if (flags & COUNTER_ALARM_CFG_ABSOLUTE) {
256 		uint32_t irq_on_late, max_rel_val;
257 
258 		now_cnt = top - remain_cnt;
259 		max_rel_val = top - (data->guard_period * config->divider);
260 		irq_on_late = flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
261 
262 		if (now_cnt < alarm_cnt) {
263 			/* Absolute alarm is in this round counting */
264 			reg = alarm_cnt - now_cnt;
265 			irq_on_late = 0;
266 		} else {
267 			/* Absolute alarm is in the next round counting */
268 			reg = alarm_cnt + remain_cnt;
269 		}
270 
271 		if (reg > max_rel_val) {
272 			/* Absolute alarm is in the guard period */
273 			err = -ETIME;
274 			if (!irq_on_late) {
275 				data->ch_data[chan_id].alarm_callback = NULL;
276 				goto out;
277 			}
278 		}
279 
280 		if (irq_on_late) {
281 			/* Trigger interrupt immediately */
282 			reg = 1;
283 		}
284 	} else {
285 		/* Round up decreasing counter to tick boundary */
286 		now_cnt = remain_cnt + config->divider - 1;
287 		now_cnt = (now_cnt / config->divider) * config->divider;
288 
289 		/* Adjusting relative alarm counter to tick boundary */
290 		reg = alarm_cnt - (now_cnt - remain_cnt);
291 	}
292 
293 	/* Set cycle - 1 to reload register */
294 	sys_write32((reg - 1), PIT_CH_RELD(dev, chan_id));
295 
296 	/* Enable channel interrupt */
297 	reg = sys_read32(PIT_INTE(dev));
298 	reg |= TIMER0_CHANNEL(chan_id);
299 	sys_write32(reg, PIT_INTE(dev));
300 
301 	/* Enable channel */
302 	reg = sys_read32(PIT_CHEN(dev));
303 	reg |= TIMER0_CHANNEL(chan_id);
304 	sys_write32(reg, PIT_CHEN(dev));
305 
306 out:
307 	k_spin_unlock(&data->lock, key);
308 
309 	return err;
310 }
311 
atcpit100_cancel_alarm(const struct device * dev,uint8_t chan_id)312 static int atcpit100_cancel_alarm(const struct device *dev, uint8_t chan_id)
313 {
314 	struct atcpit100_data *data = dev->data;
315 	k_spinlock_key_t key;
316 	uint32_t reg;
317 
318 	if (chan_id >= CH_NUM_PER_COUNTER) {
319 		return -ENOTSUP;
320 	}
321 
322 	key = k_spin_lock(&data->lock);
323 
324 	/* Disable channel interrupt */
325 	reg = sys_read32(PIT_INTE(dev));
326 	reg &= ~TIMER0_CHANNEL(chan_id);
327 	sys_write32(reg, PIT_INTE(dev));
328 
329 	/* Disable channel */
330 	reg = sys_read32(PIT_CHEN(dev));
331 	reg &= ~TIMER0_CHANNEL(chan_id);
332 	sys_write32(reg, PIT_CHEN(dev));
333 
334 	/* Clear interrupt status */
335 	sys_write32(TIMER0_CHANNEL(chan_id), PIT_ISTA(dev));
336 
337 	data->ch_data[chan_id].alarm_callback = NULL;
338 
339 	k_spin_unlock(&data->lock, key);
340 
341 	return 0;
342 }
343 
atcpit100_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)344 static int atcpit100_set_top_value(const struct device *dev,
345 				   const struct counter_top_cfg *cfg)
346 {
347 	const struct atcpit100_config *config = dev->config;
348 	struct atcpit100_data *data = dev->data;
349 	uint32_t ticks, reg, reset_counter = 1;
350 	k_spinlock_key_t key;
351 	int err = 0;
352 	uint8_t i;
353 
354 	for (i = 0; i < counter_get_num_of_channels(dev); i++) {
355 		if (data->ch_data[i].alarm_callback) {
356 			return -EBUSY;
357 		}
358 	}
359 
360 	if (cfg->ticks > config->info.max_top_value) {
361 		return -ENOTSUP;
362 	}
363 
364 	key = k_spin_lock(&data->lock);
365 
366 	if (cfg->callback) {
367 		/* Disable channel interrupt */
368 		reg = sys_read32(PIT_INTE(dev));
369 		reg &= ~TIMER0_CHANNEL(3);
370 		sys_write32(reg, PIT_INTE(dev));
371 
372 		data->top_callback = cfg->callback;
373 		data->top_user_data = cfg->user_data;
374 
375 		/* Enable channel interrupt */
376 		reg = sys_read32(PIT_INTE(dev));
377 		reg |= TIMER0_CHANNEL(3);
378 		sys_write32(reg, PIT_INTE(dev));
379 	}
380 
381 	if (cfg->flags & COUNTER_TOP_CFG_DONT_RESET) {
382 		/* Don't reset counter */
383 		reset_counter = 0;
384 		ticks = get_current_tick(dev, 3);
385 		if (ticks >= cfg->ticks) {
386 			err = -ETIME;
387 			if (cfg->flags & COUNTER_TOP_CFG_RESET_WHEN_LATE) {
388 				/* Reset counter if current is late */
389 				reset_counter = 1;
390 			}
391 		}
392 	}
393 
394 	/* Set cycle - 1 to reload register */
395 	reg = cfg->ticks * config->divider;
396 	sys_write32((reg - 1), PIT_CH_RELD(dev, 3));
397 
398 	if (reset_counter) {
399 		/* Disable channel */
400 		reg = sys_read32(PIT_CHEN(dev));
401 		reg &= ~TIMER0_CHANNEL(3);
402 		sys_write32(reg, PIT_CHEN(dev));
403 
404 		/* Clear interrupt status */
405 		sys_write32(TIMER0_CHANNEL(3), PIT_ISTA(dev));
406 
407 		/* Enable channel interrupt */
408 		reg = sys_read32(PIT_INTE(dev));
409 		reg |= TIMER0_CHANNEL(3);
410 		sys_write32(reg, PIT_INTE(dev));
411 
412 		/* Enable channel */
413 		reg = sys_read32(PIT_CHEN(dev));
414 		reg |= TIMER0_CHANNEL(3);
415 		sys_write32(reg, PIT_CHEN(dev));
416 	}
417 
418 	k_spin_unlock(&data->lock, key);
419 
420 	return err;
421 }
422 
atcpit100_get_pending_int(const struct device * dev)423 static uint32_t atcpit100_get_pending_int(const struct device *dev)
424 {
425 	uint32_t reg = sys_read32(PIT_ISTA(dev));
426 
427 	reg &= (TIMER0_CHANNEL(0) | TIMER0_CHANNEL(1) |
428 		TIMER0_CHANNEL(2) | TIMER0_CHANNEL(3));
429 
430 	return !(!reg);
431 }
432 
atcpit100_get_top_value(const struct device * dev)433 static uint32_t atcpit100_get_top_value(const struct device *dev)
434 {
435 	const struct atcpit100_config *config = dev->config;
436 	uint32_t top = sys_read32(PIT_CH_RELD(dev, 3)) + 1;
437 
438 	return (top / config->divider);
439 }
440 
atcpit100_get_guard_period(const struct device * dev,uint32_t flags)441 static uint32_t atcpit100_get_guard_period(const struct device *dev,
442 					   uint32_t flags)
443 {
444 	struct atcpit100_data *data = dev->data;
445 
446 	return data->guard_period;
447 }
448 
atcpit100_set_guard_period(const struct device * dev,uint32_t ticks,uint32_t flags)449 static int atcpit100_set_guard_period(const struct device *dev,
450 				      uint32_t ticks, uint32_t flags)
451 {
452 	const struct atcpit100_config *config = dev->config;
453 	struct atcpit100_data *data = dev->data;
454 	uint32_t top = sys_read32(PIT_CH_RELD(dev, 3)) + 1;
455 
456 	if ((ticks * config->divider) > top) {
457 		return -EINVAL;
458 	}
459 
460 	data->guard_period = ticks;
461 
462 	return 0;
463 }
464 
465 static DEVICE_API(counter, atcpit100_driver_api) = {
466 	.start = atcpit100_start,
467 	.stop = atcpit100_stop,
468 	.get_value = atcpit100_get_value,
469 	.set_alarm = atcpit100_set_alarm,
470 	.cancel_alarm = atcpit100_cancel_alarm,
471 	.set_top_value = atcpit100_set_top_value,
472 	.get_pending_int = atcpit100_get_pending_int,
473 	.get_top_value = atcpit100_get_top_value,
474 	.get_guard_period = atcpit100_get_guard_period,
475 	.set_guard_period = atcpit100_set_guard_period,
476 };
477 
478 #define COUNTER_ATCPIT100_INIT(n)					\
479 	static void counter_atcpit100_cfg_##n(void);			\
480 	static struct atcpit100_data atcpit100_data_##n;		\
481 									\
482 	static const struct atcpit100_config atcpit100_config_##n = {	\
483 		.info = {						\
484 			.max_top_value =				\
485 				(UINT32_MAX/DT_INST_PROP(n, prescaler)),\
486 			.freq = (DT_INST_PROP(n, clock_frequency) /	\
487 				DT_INST_PROP(n, prescaler)),		\
488 			.flags = COUNTER_CONFIG_INFO_COUNT_UP,		\
489 			.channels = CH_NUM_PER_COUNTER,			\
490 		},							\
491 		.base = DT_INST_REG_ADDR(n),				\
492 		.divider = DT_INST_PROP(n, prescaler),			\
493 		.irq_num = DT_INST_IRQN(n),				\
494 		.cfg_func = counter_atcpit100_cfg_##n,			\
495 	};								\
496 									\
497 	DEVICE_DT_INST_DEFINE(n,					\
498 		counter_atcpit100_init,					\
499 		NULL,							\
500 		&atcpit100_data_##n,					\
501 		&atcpit100_config_##n,					\
502 		PRE_KERNEL_1,						\
503 		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,			\
504 		&atcpit100_driver_api);					\
505 									\
506 	static void counter_atcpit100_cfg_##n(void)			\
507 	{								\
508 		IRQ_CONNECT(DT_INST_IRQN(n),				\
509 			    DT_INST_IRQ(n, priority),			\
510 			    atcpit100_irq_handler,			\
511 			    DEVICE_DT_INST_GET(n),			\
512 			    0);						\
513 	}
514 
515 DT_INST_FOREACH_STATUS_OKAY(COUNTER_ATCPIT100_INIT)
516