1 /*
2  * Copyright (c) 2018 Foundries.io Ltd
3  * Copyright (c) 2019 STMicroelectronics
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/init.h>
9 #include <soc.h>
10 #include <stm32_ll_lptim.h>
11 #include <stm32_ll_bus.h>
12 #include <stm32_ll_rcc.h>
13 #include <stm32_ll_pwr.h>
14 #include <stm32_ll_system.h>
15 #include <zephyr/drivers/clock_control.h>
16 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
17 #include <zephyr/drivers/timer/system_timer.h>
18 #include <zephyr/sys_clock.h>
19 #include <zephyr/irq.h>
20 #include <zephyr/drivers/counter.h>
21 #include <zephyr/pm/policy.h>
22 
23 #include <zephyr/spinlock.h>
24 
25 #define DT_DRV_COMPAT st_stm32_lptim
26 
27 #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) > 1
28 #error Only one LPTIM instance should be enabled
29 #endif
30 
31 #define LPTIM (LPTIM_TypeDef *) DT_INST_REG_ADDR(0)
32 
33 #if DT_INST_NUM_CLOCKS(0) == 1
34 #warning Kconfig for LPTIM source clock (LSI/LSE) is deprecated, use device tree.
35 static const struct stm32_pclken lptim_clk[] = {
36 	STM32_CLOCK_INFO(0, DT_DRV_INST(0)),
37 	/* Use Kconfig to configure source clocks fields */
38 	/* Fortunately, values are consistent across enabled series */
39 #ifdef CONFIG_STM32_LPTIM_CLOCK_LSI
40 	{.bus = STM32_SRC_LSI, .enr = LPTIM1_SEL(1)}
41 #else
42 	{.bus = STM32_SRC_LSE, .enr = LPTIM1_SEL(3)}
43 #endif
44 };
45 #else
46 static const struct stm32_pclken lptim_clk[] = STM32_DT_INST_CLOCKS(0);
47 #endif
48 
49 static const struct device *const clk_ctrl = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
50 
51 /*
52  * Assumptions and limitations:
53  *
54  * - system clock based on an LPTIM instance, clocked by LSI or LSE
55  * - prescaler is set to a 2^value from 1 (division of the LPTIM source clock by 1)
56  *   to 128 (division of the LPTIM source clock by 128)
57  * - using LPTIM AutoReload capability to trig the IRQ (timeout irq)
58  * - when timeout irq occurs the counter is already reset
59  * - the maximum timeout duration is reached with the lptim_time_base value
60  * - with prescaler of 1, the max timeout (LPTIM_TIMEBASE) is 2 seconds:
61  *    0xFFFF / (LSE freq (32768Hz) / 1)
62  * - with prescaler of 128, the max timeout (LPTIM_TIMEBASE) is 256 seconds:
63  *    0xFFFF / (LSE freq (32768Hz) / 128)
64  */
65 
66 static int32_t lptim_time_base;
67 static uint32_t lptim_clock_freq = CONFIG_STM32_LPTIM_CLOCK;
68 /* The prescaler given by the DTS and to apply to the lptim_clock_freq */
69 static uint32_t lptim_clock_presc = DT_PROP(DT_DRV_INST(0), st_prescaler);
70 
71 /* Minimum nb of clock cycles to have to set autoreload register correctly */
72 #define LPTIM_GUARD_VALUE 2
73 
74 /* A 32bit value cannot exceed 0xFFFFFFFF/LPTIM_TIMEBASE counting cycles.
75  * This is for example about of 65000 x 2000ms when clocked by LSI
76  */
77 static uint32_t accumulated_lptim_cnt;
78 /* Next autoreload value to set */
79 static uint32_t autoreload_next;
80 /* Indicate if the autoreload register is ready for a write */
81 static bool autoreload_ready = true;
82 
83 static struct k_spinlock lock;
84 
85 #ifdef CONFIG_STM32_LPTIM_STDBY_TIMER
86 
87 #define CURRENT_CPU \
88 	(COND_CODE_1(CONFIG_SMP, (arch_curr_cpu()->id), (_current_cpu->id)))
89 
90 #define cycle_t uint32_t
91 
92 /* This local variable indicates that the timeout was set right before
93  * entering standby state.
94  *
95  * It is used for chips that has to use a separate standby timer in such
96  * case because the LPTIM is not clocked in some low power mode state.
97  */
98 static bool timeout_stdby;
99 
100 /* Cycle counter before entering the standby state. */
101 static cycle_t lptim_cnt_pre_stdby;
102 
103 /* Standby timer value before entering the standby state. */
104 static uint32_t stdby_timer_pre_stdby;
105 
106 /* Standby timer used for timer while entering the standby state */
107 static const struct device *stdby_timer = DEVICE_DT_GET(DT_CHOSEN(st_lptim_stdby_timer));
108 
109 #endif /* CONFIG_STM32_LPTIM_STDBY_TIMER */
110 
arrm_state_get(void)111 static inline bool arrm_state_get(void)
112 {
113 	return (LL_LPTIM_IsActiveFlag_ARRM(LPTIM) && LL_LPTIM_IsEnabledIT_ARRM(LPTIM));
114 }
115 
lptim_irq_handler(const struct device * unused)116 static void lptim_irq_handler(const struct device *unused)
117 {
118 
119 	ARG_UNUSED(unused);
120 
121 	uint32_t autoreload = LL_LPTIM_GetAutoReload(LPTIM);
122 
123 	if ((LL_LPTIM_IsActiveFlag_ARROK(LPTIM) != 0)
124 		&& LL_LPTIM_IsEnabledIT_ARROK(LPTIM) != 0) {
125 		LL_LPTIM_ClearFlag_ARROK(LPTIM);
126 		if ((autoreload_next > 0) && (autoreload_next != autoreload)) {
127 			/* the new autoreload value change, we set it */
128 			autoreload_ready = false;
129 			LL_LPTIM_SetAutoReload(LPTIM, autoreload_next);
130 		} else {
131 			autoreload_ready = true;
132 		}
133 	}
134 
135 	if (arrm_state_get()) {
136 		k_spinlock_key_t key = k_spin_lock(&lock);
137 
138 		/* do not change ARR yet, sys_clock_announce will do */
139 		LL_LPTIM_ClearFLAG_ARRM(LPTIM);
140 
141 		/* increase the total nb of autoreload count
142 		 * used in the sys_clock_cycle_get_32() function.
143 		 */
144 		autoreload++;
145 
146 		accumulated_lptim_cnt += autoreload;
147 
148 		k_spin_unlock(&lock, key);
149 
150 		/* announce the elapsed time in ms (count register is 16bit) */
151 		uint32_t dticks = (autoreload
152 				* CONFIG_SYS_CLOCK_TICKS_PER_SEC)
153 				/ lptim_clock_freq;
154 
155 		sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL)
156 				? dticks : (dticks > 0));
157 	}
158 }
159 
lptim_set_autoreload(uint32_t arr)160 static void lptim_set_autoreload(uint32_t arr)
161 {
162 	/* Update autoreload register */
163 	autoreload_next = arr;
164 
165 	if (!autoreload_ready) {
166 		return;
167 	}
168 
169 	/* The ARR register ready, we could set it directly */
170 	if ((arr > 0) && (arr != LL_LPTIM_GetAutoReload(LPTIM))) {
171 		/* The new autoreload value change, we set it */
172 		autoreload_ready = false;
173 		LL_LPTIM_ClearFlag_ARROK(LPTIM);
174 		LL_LPTIM_SetAutoReload(LPTIM, arr);
175 	}
176 }
177 
z_clock_lptim_getcounter(void)178 static inline uint32_t z_clock_lptim_getcounter(void)
179 {
180 	uint32_t lp_time;
181 	uint32_t lp_time_prev_read;
182 
183 	/* It should be noted that to read reliably the content
184 	 * of the LPTIM_CNT register, two successive read accesses
185 	 * must be performed and compared
186 	 */
187 	lp_time = LL_LPTIM_GetCounter(LPTIM);
188 	do {
189 		lp_time_prev_read = lp_time;
190 		lp_time = LL_LPTIM_GetCounter(LPTIM);
191 	} while (lp_time != lp_time_prev_read);
192 	return lp_time;
193 }
194 
sys_clock_set_timeout(int32_t ticks,bool idle)195 void sys_clock_set_timeout(int32_t ticks, bool idle)
196 {
197 	/* new LPTIM AutoReload value to set (aligned on Kernel ticks) */
198 	uint32_t next_arr = 0;
199 	int err;
200 
201 	ARG_UNUSED(idle);
202 
203 #ifdef CONFIG_STM32_LPTIM_STDBY_TIMER
204 	const struct pm_state_info *next;
205 
206 	next = pm_policy_next_state(CURRENT_CPU, ticks);
207 
208 	/* Check if STANBY or STOP3 is requested */
209 	timeout_stdby = false;
210 	if ((next != NULL) && idle) {
211 #ifdef CONFIG_PM_S2RAM
212 		if (next->state == PM_STATE_SUSPEND_TO_RAM) {
213 			timeout_stdby = true;
214 		}
215 #endif
216 #ifdef CONFIG_STM32_STOP3_LP_MODE
217 		if ((next->state == PM_STATE_SUSPEND_TO_IDLE) && (next->substate_id == 4)) {
218 			timeout_stdby = true;
219 		}
220 #endif
221 	}
222 
223 	if (timeout_stdby) {
224 		uint64_t timeout_us =
225 			((uint64_t)ticks * USEC_PER_SEC) / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
226 
227 		struct counter_alarm_cfg cfg = {
228 			.callback = NULL,
229 			.ticks = counter_us_to_ticks(stdby_timer, timeout_us),
230 			.user_data = NULL,
231 			.flags = 0,
232 		};
233 
234 		/* Set the alarm using timer that runs the standby.
235 		 * Needed rump-up/setting time, lower accurency etc. should be
236 		 * included in the exit-latency in the power state definition.
237 		 */
238 		counter_cancel_channel_alarm(stdby_timer, 0);
239 		counter_set_channel_alarm(stdby_timer, 0, &cfg);
240 
241 		/* Store current values to calculate a difference in
242 		 * measurements after exiting the standby state.
243 		 */
244 		counter_get_value(stdby_timer, &stdby_timer_pre_stdby);
245 		lptim_cnt_pre_stdby = z_clock_lptim_getcounter();
246 
247 		/* Stop clocks for LPTIM, since RTC is used instead */
248 		clock_control_off(clk_ctrl, (clock_control_subsys_t) &lptim_clk[0]);
249 
250 		return;
251 	}
252 #endif /* CONFIG_STM32_LPTIM_STDBY_TIMER */
253 
254 	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
255 		return;
256 	}
257 
258 	/*
259 	 * When CONFIG_SYSTEM_CLOCK_SLOPPY_IDLE = y, ticks equals to -1
260 	 * is treated as a lptim off ; never waking up ; lptim not clocked anymore
261 	 */
262 	if (ticks == K_TICKS_FOREVER) {
263 		clock_control_off(clk_ctrl, (clock_control_subsys_t) &lptim_clk[0]);
264 		return;
265 	}
266 	/*
267 	 * When CONFIG_SYSTEM_CLOCK_SLOPPY_IDLE = n, ticks equals to INT_MAX
268 	 * is treated as a maximum possible value LPTIM_MAX_TIMEBASE (16bit counter)
269 	 */
270 
271 	/* if LPTIM clock was previously stopped, it must now be restored */
272 	err = clock_control_on(clk_ctrl, (clock_control_subsys_t) &lptim_clk[0]);
273 
274 	if (err < 0) {
275 		return;
276 	}
277 	/* passing ticks==1 means "announce the next tick",
278 	 * ticks value of zero (or even negative) is legal and
279 	 * treated identically: it simply indicates the kernel would like the
280 	 * next tick announcement as soon as possible.
281 	 */
282 	ticks = CLAMP(ticks - 1, 1, lptim_time_base);
283 
284 	k_spinlock_key_t key = k_spin_lock(&lock);
285 
286 	/* read current counter value (cannot exceed 16bit) */
287 
288 	uint32_t lp_time = z_clock_lptim_getcounter();
289 
290 	uint32_t autoreload = LL_LPTIM_GetAutoReload(LPTIM);
291 
292 	if (LL_LPTIM_IsActiveFlag_ARRM(LPTIM)
293 	    || ((autoreload - lp_time) < LPTIM_GUARD_VALUE)) {
294 		/* interrupt happens or happens soon.
295 		 * It's impossible to set autoreload value.
296 		 */
297 		k_spin_unlock(&lock, key);
298 		return;
299 	}
300 
301 	/* calculate the next arr value (cannot exceed 16bit)
302 	 * adjust the next ARR match value to align on Ticks
303 	 * from the current counter value to first next Tick
304 	 */
305 	next_arr = (((lp_time * CONFIG_SYS_CLOCK_TICKS_PER_SEC)
306 			/ lptim_clock_freq) + 1) * lptim_clock_freq
307 			/ (CONFIG_SYS_CLOCK_TICKS_PER_SEC);
308 	next_arr = next_arr + ((uint32_t)(ticks) * lptim_clock_freq)
309 			/ CONFIG_SYS_CLOCK_TICKS_PER_SEC;
310 	/* if the lptim_clock_freq <  one ticks/sec, then next_arr must be > 0 */
311 
312 	/* maximise to TIMEBASE */
313 	if (next_arr > lptim_time_base) {
314 		next_arr = lptim_time_base;
315 	}
316 	/* The new autoreload value must be LPTIM_GUARD_VALUE clock cycles
317 	 * after current lptim to make sure we don't miss
318 	 * an autoreload interrupt
319 	 */
320 	else if (next_arr < (lp_time + LPTIM_GUARD_VALUE)) {
321 		next_arr = lp_time + LPTIM_GUARD_VALUE;
322 	}
323 	/* with slow lptim_clock_freq, LPTIM_GUARD_VALUE of 1 is enough */
324 	next_arr = next_arr - 1;
325 
326 	/* Update autoreload register */
327 	lptim_set_autoreload(next_arr);
328 
329 	k_spin_unlock(&lock, key);
330 }
331 
sys_clock_lp_time_get(void)332 static uint32_t sys_clock_lp_time_get(void)
333 {
334 	uint32_t lp_time;
335 
336 	do {
337 		/* In case of counter roll-over, add the autoreload value,
338 		 * because the irq has not yet been handled
339 		 */
340 		if (arrm_state_get()) {
341 			lp_time = LL_LPTIM_GetAutoReload(LPTIM) + 1;
342 			lp_time += z_clock_lptim_getcounter();
343 			break;
344 		}
345 
346 		lp_time = z_clock_lptim_getcounter();
347 
348 		/* Check if the flag ARRM wasn't be set during the process */
349 	} while (arrm_state_get());
350 
351 	return lp_time;
352 }
353 
354 
sys_clock_elapsed(void)355 uint32_t sys_clock_elapsed(void)
356 {
357 	if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
358 		return 0;
359 	}
360 
361 	k_spinlock_key_t key = k_spin_lock(&lock);
362 
363 	uint32_t lp_time = sys_clock_lp_time_get();
364 
365 	k_spin_unlock(&lock, key);
366 
367 	/* gives the value of LPTIM counter (ms)
368 	 * since the previous 'announce'
369 	 */
370 	uint64_t ret = ((uint64_t)lp_time * CONFIG_SYS_CLOCK_TICKS_PER_SEC) / lptim_clock_freq;
371 
372 	return (uint32_t)(ret);
373 }
374 
sys_clock_cycle_get_32(void)375 uint32_t sys_clock_cycle_get_32(void)
376 {
377 	/* just gives the accumulated count in a number of hw cycles */
378 
379 	k_spinlock_key_t key = k_spin_lock(&lock);
380 
381 	uint32_t lp_time = sys_clock_lp_time_get();
382 
383 	lp_time += accumulated_lptim_cnt;
384 
385 	/* convert lptim count in a nb of hw cycles with precision */
386 	uint64_t ret = ((uint64_t)lp_time * sys_clock_hw_cycles_per_sec()) / lptim_clock_freq;
387 
388 	k_spin_unlock(&lock, key);
389 
390 	/* convert in hw cycles (keeping 32bit value) */
391 	return (uint32_t)(ret);
392 }
393 
394 /* Wait for the IER register of the stm32U5 ready, after any bit write operation */
stm32_lptim_wait_ready(void)395 void stm32_lptim_wait_ready(void)
396 {
397 #ifdef CONFIG_SOC_SERIES_STM32U5X
398 	while (LL_LPTIM_IsActiveFlag_DIEROK(LPTIM) == 0) {
399 	}
400 	LL_LPTIM_ClearFlag_DIEROK(LPTIM);
401 #else
402 	/* Empty : not relevant */
403 #endif
404 }
405 
sys_clock_driver_init(void)406 static int sys_clock_driver_init(void)
407 {
408 	uint32_t count_per_tick;
409 	int err;
410 
411 	if (!device_is_ready(clk_ctrl)) {
412 		return -ENODEV;
413 	}
414 
415 	/* Enable LPTIM bus clock */
416 	err = clock_control_on(clk_ctrl, (clock_control_subsys_t) &lptim_clk[0]);
417 	if (err < 0) {
418 		return -EIO;
419 	}
420 
421 #if defined(LL_SRDAMR_GRP1_PERIPH_LPTIM1AMEN)
422 	LL_SRDAMR_GRP1_EnableAutonomousClock(LL_SRDAMR_GRP1_PERIPH_LPTIM1AMEN);
423 #endif
424 
425 	/* Enable LPTIM clock source */
426 	err = clock_control_configure(clk_ctrl,
427 				      (clock_control_subsys_t) &lptim_clk[1],
428 				      NULL);
429 	if (err < 0) {
430 		return -EIO;
431 	}
432 
433 	/* Get LPTIM clock freq */
434 	err = clock_control_get_rate(clk_ctrl, (clock_control_subsys_t) &lptim_clk[1],
435 			       &lptim_clock_freq);
436 
437 	if (err < 0) {
438 		return -EIO;
439 	}
440 #if defined(CONFIG_SOC_SERIES_STM32L0X)
441 	/* Driver only supports freqs up to 32768Hz. On L0, LSI freq is 37KHz,
442 	 * which will overflow the LPTIM counter.
443 	 * Previous LPTIM configuration using device tree was doing forcing this
444 	 * with a Kconfig default. Impact is that time is 1.13 faster than reality.
445 	 * Following lines reproduce this behavior in order not to change behavior.
446 	 * This issue will be fixed by implementation LPTIM prescaler support.
447 	 */
448 	if (lptim_clk[1].bus == STM32_SRC_LSI) {
449 		lptim_clock_freq = KHZ(32);
450 	}
451 #endif
452 
453 #if DT_INST_NODE_HAS_PROP(0, st_timeout)
454 	/*
455 	 * Check if prescaler corresponding to the DT_INST_PROP(0, st_timeout)
456 	 * is matching the lptim_clock_presc calculated one from the lptim_clock_freq
457 	 * max lptim period is 0xFFFF/(lptim_clock_freq/lptim_clock_presc)
458 	 */
459 	if (DT_INST_PROP(0, st_timeout) >
460 		(lptim_clock_presc / lptim_clock_freq) * 0xFFFF) {
461 		return -EIO;
462 	}
463 
464 	/*
465 	 * LPTIM is counting DT_INST_PROP(0, st_timeout),
466 	 * seconds at lptim_clock_freq divided lptim_clock_presc) Hz",
467 	 * lptim_time_base is the autoreload counter
468 	 */
469 	lptim_time_base = 2 * (lptim_clock_freq *
470 		(uint32_t)DT_INST_PROP(0, st_timeout))
471 		/ lptim_clock_presc;
472 #else
473 	/* Set LPTIM time base based on clock source freq */
474 	if (lptim_clock_freq == KHZ(32)) {
475 		lptim_time_base = 0xF9FF;
476 	} else if (lptim_clock_freq == 32768) {
477 		lptim_time_base = 0xFFFF;
478 	} else {
479 		return -EIO;
480 	}
481 
482 #endif /* st_timeout */
483 
484 #if !defined(CONFIG_STM32_LPTIM_TICK_FREQ_RATIO_OVERRIDE)
485 	/*
486 	 * Check coherency between CONFIG_SYS_CLOCK_TICKS_PER_SEC
487 	 * and the lptim_clock_freq which is the CONFIG_STM32_LPTIM_CLOCK reduced
488 	 * by the lptim_clock_presc
489 	 */
490 	if (lptim_clock_presc <= 8) {
491 		__ASSERT(CONFIG_STM32_LPTIM_CLOCK / 8 >= CONFIG_SYS_CLOCK_TICKS_PER_SEC,
492 		 "It is recommended to set SYS_CLOCK_TICKS_PER_SEC to CONFIG_STM32_LPTIM_CLOCK/8");
493 	} else {
494 		__ASSERT(CONFIG_STM32_LPTIM_CLOCK / lptim_clock_presc >=
495 			CONFIG_SYS_CLOCK_TICKS_PER_SEC,
496 		 "Set SYS_CLOCK_TICKS_PER_SEC to CONFIG_STM32_LPTIM_CLOCK/lptim_clock_presc");
497 	}
498 #endif /* !CONFIG_STM32_LPTIM_TICK_FREQ_RATIO_OVERRIDE */
499 
500 	/* Actual lptim clock freq when the clock source is reduced by the prescaler */
501 	lptim_clock_freq = lptim_clock_freq / lptim_clock_presc;
502 
503 	/* Clear the event flag and possible pending interrupt */
504 	IRQ_CONNECT(DT_INST_IRQN(0),
505 		    DT_INST_IRQ(0, priority),
506 		    lptim_irq_handler, 0, 0);
507 	irq_enable(DT_INST_IRQN(0));
508 
509 #ifdef CONFIG_SOC_SERIES_STM32WLX
510 	/* Enable the LPTIM wakeup EXTI line */
511 	LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_29);
512 #endif
513 
514 	/* configure the LPTIM counter */
515 	LL_LPTIM_SetClockSource(LPTIM, LL_LPTIM_CLK_SOURCE_INTERNAL);
516 	/* the LPTIM clock freq is affected by the prescaler */
517 	LL_LPTIM_SetPrescaler(LPTIM, (__CLZ(__RBIT(lptim_clock_presc)) << LPTIM_CFGR_PRESC_Pos));
518 
519 #if defined(CONFIG_SOC_SERIES_STM32U5X) || \
520 	defined(CONFIG_SOC_SERIES_STM32H5X) || \
521 	defined(CONFIG_SOC_SERIES_STM32WBAX)
522 	LL_LPTIM_OC_SetPolarity(LPTIM, LL_LPTIM_CHANNEL_CH1,
523 				LL_LPTIM_OUTPUT_POLARITY_REGULAR);
524 #else
525 	LL_LPTIM_SetPolarity(LPTIM, LL_LPTIM_OUTPUT_POLARITY_REGULAR);
526 #endif
527 	LL_LPTIM_SetUpdateMode(LPTIM, LL_LPTIM_UPDATE_MODE_IMMEDIATE);
528 	LL_LPTIM_SetCounterMode(LPTIM, LL_LPTIM_COUNTER_MODE_INTERNAL);
529 	LL_LPTIM_DisableTimeout(LPTIM);
530 	/* counting start is initiated by software */
531 	LL_LPTIM_TrigSw(LPTIM);
532 
533 #if defined(CONFIG_SOC_SERIES_STM32U5X) || \
534 	defined(CONFIG_SOC_SERIES_STM32H5X) || \
535 	defined(CONFIG_SOC_SERIES_STM32WBAX)
536 	/* Enable the LPTIM before proceeding with configuration */
537 	LL_LPTIM_Enable(LPTIM);
538 
539 	LL_LPTIM_DisableIT_CC1(LPTIM);
540 	stm32_lptim_wait_ready();
541 	LL_LPTIM_ClearFLAG_CC1(LPTIM);
542 #else
543 	/* LPTIM interrupt set-up before enabling */
544 	/* no Compare match Interrupt */
545 	LL_LPTIM_DisableIT_CMPM(LPTIM);
546 	LL_LPTIM_ClearFLAG_CMPM(LPTIM);
547 #endif
548 
549 	/* Autoreload match Interrupt */
550 	LL_LPTIM_EnableIT_ARRM(LPTIM);
551 	stm32_lptim_wait_ready();
552 	LL_LPTIM_ClearFLAG_ARRM(LPTIM);
553 
554 	/* ARROK bit validates the write operation to ARR register */
555 	LL_LPTIM_EnableIT_ARROK(LPTIM);
556 	stm32_lptim_wait_ready();
557 	LL_LPTIM_ClearFlag_ARROK(LPTIM);
558 
559 #if !defined(CONFIG_SOC_SERIES_STM32U5X) && \
560 	!defined(CONFIG_SOC_SERIES_STM32H5X) && \
561 	!defined(CONFIG_SOC_SERIES_STM32WBAX)
562 	/* Enable the LPTIM counter */
563 	LL_LPTIM_Enable(LPTIM);
564 #endif
565 
566 	/* Set the Autoreload value once the timer is enabled */
567 	if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
568 		/* LPTIM is triggered on a LPTIM_TIMEBASE period */
569 		lptim_set_autoreload(lptim_time_base);
570 	} else {
571 		/* nb of LPTIM counter unit per kernel tick (depends on lptim clock prescaler) */
572 		count_per_tick = (lptim_clock_freq / CONFIG_SYS_CLOCK_TICKS_PER_SEC);
573 		/* LPTIM is triggered on a Tick period */
574 		lptim_set_autoreload(count_per_tick - 1);
575 	}
576 
577 	/* Start the LPTIM counter in continuous mode */
578 	LL_LPTIM_StartCounter(LPTIM, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
579 
580 #ifdef CONFIG_DEBUG
581 	/* stop LPTIM during DEBUG */
582 #if defined(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP)
583 	LL_DBGMCU_APB1_GRP1_FreezePeriph(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP);
584 #elif defined(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP)
585 	LL_DBGMCU_APB3_GRP1_FreezePeriph(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP);
586 #endif
587 
588 #endif
589 	return 0;
590 }
591 
stm32_clock_control_standby_exit(void)592 void stm32_clock_control_standby_exit(void)
593 {
594 #ifdef CONFIG_STM32_LPTIM_STDBY_TIMER
595 	if (clock_control_get_status(clk_ctrl,
596 				     (clock_control_subsys_t) &lptim_clk[0])
597 				     != CLOCK_CONTROL_STATUS_ON) {
598 		sys_clock_driver_init();
599 	}
600 #endif /* CONFIG_STM32_LPTIM_STDBY_TIMER */
601 }
602 
sys_clock_idle_exit(void)603 void sys_clock_idle_exit(void)
604 {
605 #ifdef CONFIG_STM32_LPTIM_STDBY_TIMER
606 	if (timeout_stdby) {
607 		cycle_t missed_lptim_cnt;
608 		uint32_t stdby_timer_diff, stdby_timer_post, dticks;
609 		uint64_t stdby_timer_us;
610 
611 		/* Get current value for standby timer and reset LPTIM counter value
612 		 * to start anew.
613 		 */
614 		LL_LPTIM_ResetCounter(LPTIM);
615 		counter_get_value(stdby_timer, &stdby_timer_post);
616 
617 		/* Calculate how much time has passed since last measurement for standby timer */
618 		/* Check IDLE timer overflow */
619 		if (stdby_timer_pre_stdby > stdby_timer_post) {
620 			stdby_timer_diff =
621 				(counter_get_top_value(stdby_timer) - stdby_timer_pre_stdby) +
622 				stdby_timer_post + 1;
623 
624 		} else {
625 			stdby_timer_diff = stdby_timer_post - stdby_timer_pre_stdby;
626 		}
627 		stdby_timer_us = counter_ticks_to_us(stdby_timer, stdby_timer_diff);
628 
629 		/* Convert standby time in LPTIM cnt */
630 		missed_lptim_cnt = (sys_clock_hw_cycles_per_sec() * stdby_timer_us) /
631 				   USEC_PER_SEC;
632 		/* Add the LPTIM cnt pre standby */
633 		missed_lptim_cnt += lptim_cnt_pre_stdby;
634 
635 		/* Update the cycle counter to include the cycles missed in standby */
636 		accumulated_lptim_cnt += missed_lptim_cnt;
637 
638 		/* Announce the passed ticks to the kernel */
639 		dticks = (missed_lptim_cnt * CONFIG_SYS_CLOCK_TICKS_PER_SEC)
640 				/ lptim_clock_freq;
641 		sys_clock_announce(dticks);
642 
643 		/* We've already performed all needed operations */
644 		timeout_stdby = false;
645 	}
646 #endif /* CONFIG_STM32_LPTIM_STDBY_TIMER */
647 }
648 
649 SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
650 	 CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
651