drivers: timer: move initialization setup to drivers

The weak symbol sys_clock_driver_init has been removed, therefore moving
the init responsability to the drivers themselves. As a result, the init
function has now been made static on all drivers and moved to the
bottom, following the convention used in other areas.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
Gerard Marull-Paretas 2021-11-04 12:51:39 +01:00 committed by Anas Nashif
commit b1ced75386
29 changed files with 724 additions and 648 deletions

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <soc.h>
#include <stm32_ll_lptim.h>
#include <stm32_ll_bus.h>
@ -78,141 +79,6 @@ static void lptim_irq_handler(const struct device *unused)
}
}
int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
/* enable LPTIM clock source */
#if defined(LL_APB1_GRP1_PERIPH_LPTIM1)
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1);
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_LPTIM1);
#elif defined(LL_APB3_GRP1_PERIPH_LPTIM1)
LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_LPTIM1);
LL_SRDAMR_GRP1_EnableAutonomousClock(LL_SRDAMR_GRP1_PERIPH_LPTIM1AMEN);
#endif
#if defined(CONFIG_STM32_LPTIM_CLOCK_LSI)
/* enable LSI clock */
#ifdef CONFIG_SOC_SERIES_STM32WBX
LL_RCC_LSI1_Enable();
while (!LL_RCC_LSI1_IsReady()) {
#else
LL_RCC_LSI_Enable();
while (!LL_RCC_LSI_IsReady()) {
#endif /* CONFIG_SOC_SERIES_STM32WBX */
/* Wait for LSI ready */
}
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSI);
#else /* CONFIG_STM32_LPTIM_CLOCK_LSI */
#if defined(LL_APB1_GRP1_PERIPH_PWR)
/* Enable the power interface clock */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
#endif /* LL_APB1_GRP1_PERIPH_PWR */
/* enable backup domain */
LL_PWR_EnableBkUpAccess();
/* enable LSE clock */
LL_RCC_LSE_DisableBypass();
LL_RCC_LSE_Enable();
while (!LL_RCC_LSE_IsReady()) {
/* Wait for LSE ready */
}
#ifdef RCC_BDCR_LSESYSEN
LL_RCC_LSE_EnablePropagation();
#endif /* RCC_BDCR_LSESYSEN */
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE);
#endif /* CONFIG_STM32_LPTIM_CLOCK_LSI */
/* Clear the event flag and possible pending interrupt */
IRQ_CONNECT(DT_IRQN(DT_NODELABEL(lptim1)),
DT_IRQ(DT_NODELABEL(lptim1), priority),
lptim_irq_handler, 0, 0);
irq_enable(DT_IRQN(DT_NODELABEL(lptim1)));
#ifdef CONFIG_SOC_SERIES_STM32WLX
/* Enable the LPTIM1 wakeup EXTI line */
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_29);
#endif
/* configure the LPTIM1 counter */
LL_LPTIM_SetClockSource(LPTIM1, LL_LPTIM_CLK_SOURCE_INTERNAL);
/* configure the LPTIM1 prescaler with 1 */
LL_LPTIM_SetPrescaler(LPTIM1, LL_LPTIM_PRESCALER_DIV1);
#ifdef CONFIG_SOC_SERIES_STM32U5X
LL_LPTIM_OC_SetPolarity(LPTIM1, LL_LPTIM_CHANNEL_CH1,
LL_LPTIM_OUTPUT_POLARITY_REGULAR);
#else
LL_LPTIM_SetPolarity(LPTIM1, LL_LPTIM_OUTPUT_POLARITY_REGULAR);
#endif
LL_LPTIM_SetUpdateMode(LPTIM1, LL_LPTIM_UPDATE_MODE_IMMEDIATE);
LL_LPTIM_SetCounterMode(LPTIM1, LL_LPTIM_COUNTER_MODE_INTERNAL);
LL_LPTIM_DisableTimeout(LPTIM1);
/* counting start is initiated by software */
LL_LPTIM_TrigSw(LPTIM1);
#ifdef CONFIG_SOC_SERIES_STM32U5X
/* Enable the LPTIM1 before proceeding with configuration */
LL_LPTIM_Enable(LPTIM1);
LL_LPTIM_DisableIT_CC1(LPTIM1);
while (LL_LPTIM_IsActiveFlag_DIEROK(LPTIM1) == 0) {
}
LL_LPTIM_ClearFlag_DIEROK(LPTIM1);
LL_LPTIM_ClearFLAG_CC1(LPTIM1);
#else
/* LPTIM1 interrupt set-up before enabling */
/* no Compare match Interrupt */
LL_LPTIM_DisableIT_CMPM(LPTIM1);
LL_LPTIM_ClearFLAG_CMPM(LPTIM1);
#endif
/* Autoreload match Interrupt */
LL_LPTIM_EnableIT_ARRM(LPTIM1);
#ifdef CONFIG_SOC_SERIES_STM32U5X
while (LL_LPTIM_IsActiveFlag_DIEROK(LPTIM1) == 0) {
}
LL_LPTIM_ClearFlag_DIEROK(LPTIM1);
#endif
LL_LPTIM_ClearFLAG_ARRM(LPTIM1);
/* ARROK bit validates the write operation to ARR register */
LL_LPTIM_ClearFlag_ARROK(LPTIM1);
accumulated_lptim_cnt = 0;
#ifndef CONFIG_SOC_SERIES_STM32U5X
/* Enable the LPTIM1 counter */
LL_LPTIM_Enable(LPTIM1);
#endif
/* Set the Autoreload value once the timer is enabled */
if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
/* LPTIM1 is triggered on a LPTIM_TIMEBASE period */
LL_LPTIM_SetAutoReload(LPTIM1, LPTIM_TIMEBASE);
} else {
/* LPTIM1 is triggered on a Tick period */
LL_LPTIM_SetAutoReload(LPTIM1, COUNT_PER_TICK - 1);
}
/* Start the LPTIM counter in continuous mode */
LL_LPTIM_StartCounter(LPTIM1, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
#ifdef CONFIG_DEBUG
/* stop LPTIM1 during DEBUG */
#if defined(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP)
LL_DBGMCU_APB1_GRP1_FreezePeriph(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP);
#elif defined(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP)
LL_DBGMCU_APB3_GRP1_FreezePeriph(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP);
#endif
#endif
return 0;
}
static inline uint32_t z_clock_lptim_getcounter(void)
{
uint32_t lp_time;
@ -374,3 +240,141 @@ uint32_t sys_clock_cycle_get_32(void)
/* convert in hw cycles (keeping 32bit value) */
return (uint32_t)(ret);
}
static int sys_clock_driver_init(const struct device *dev)
{
ARG_UNUSED(dev);
/* enable LPTIM clock source */
#if defined(LL_APB1_GRP1_PERIPH_LPTIM1)
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1);
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_LPTIM1);
#elif defined(LL_APB3_GRP1_PERIPH_LPTIM1)
LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_LPTIM1);
LL_SRDAMR_GRP1_EnableAutonomousClock(LL_SRDAMR_GRP1_PERIPH_LPTIM1AMEN);
#endif
#if defined(CONFIG_STM32_LPTIM_CLOCK_LSI)
/* enable LSI clock */
#ifdef CONFIG_SOC_SERIES_STM32WBX
LL_RCC_LSI1_Enable();
while (!LL_RCC_LSI1_IsReady()) {
#else
LL_RCC_LSI_Enable();
while (!LL_RCC_LSI_IsReady()) {
#endif /* CONFIG_SOC_SERIES_STM32WBX */
/* Wait for LSI ready */
}
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSI);
#else /* CONFIG_STM32_LPTIM_CLOCK_LSI */
#if defined(LL_APB1_GRP1_PERIPH_PWR)
/* Enable the power interface clock */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
#endif /* LL_APB1_GRP1_PERIPH_PWR */
/* enable backup domain */
LL_PWR_EnableBkUpAccess();
/* enable LSE clock */
LL_RCC_LSE_DisableBypass();
LL_RCC_LSE_Enable();
while (!LL_RCC_LSE_IsReady()) {
/* Wait for LSE ready */
}
#ifdef RCC_BDCR_LSESYSEN
LL_RCC_LSE_EnablePropagation();
#endif /* RCC_BDCR_LSESYSEN */
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE);
#endif /* CONFIG_STM32_LPTIM_CLOCK_LSI */
/* Clear the event flag and possible pending interrupt */
IRQ_CONNECT(DT_IRQN(DT_NODELABEL(lptim1)),
DT_IRQ(DT_NODELABEL(lptim1), priority),
lptim_irq_handler, 0, 0);
irq_enable(DT_IRQN(DT_NODELABEL(lptim1)));
#ifdef CONFIG_SOC_SERIES_STM32WLX
/* Enable the LPTIM1 wakeup EXTI line */
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_29);
#endif
/* configure the LPTIM1 counter */
LL_LPTIM_SetClockSource(LPTIM1, LL_LPTIM_CLK_SOURCE_INTERNAL);
/* configure the LPTIM1 prescaler with 1 */
LL_LPTIM_SetPrescaler(LPTIM1, LL_LPTIM_PRESCALER_DIV1);
#ifdef CONFIG_SOC_SERIES_STM32U5X
LL_LPTIM_OC_SetPolarity(LPTIM1, LL_LPTIM_CHANNEL_CH1,
LL_LPTIM_OUTPUT_POLARITY_REGULAR);
#else
LL_LPTIM_SetPolarity(LPTIM1, LL_LPTIM_OUTPUT_POLARITY_REGULAR);
#endif
LL_LPTIM_SetUpdateMode(LPTIM1, LL_LPTIM_UPDATE_MODE_IMMEDIATE);
LL_LPTIM_SetCounterMode(LPTIM1, LL_LPTIM_COUNTER_MODE_INTERNAL);
LL_LPTIM_DisableTimeout(LPTIM1);
/* counting start is initiated by software */
LL_LPTIM_TrigSw(LPTIM1);
#ifdef CONFIG_SOC_SERIES_STM32U5X
/* Enable the LPTIM1 before proceeding with configuration */
LL_LPTIM_Enable(LPTIM1);
LL_LPTIM_DisableIT_CC1(LPTIM1);
while (LL_LPTIM_IsActiveFlag_DIEROK(LPTIM1) == 0) {
}
LL_LPTIM_ClearFlag_DIEROK(LPTIM1);
LL_LPTIM_ClearFLAG_CC1(LPTIM1);
#else
/* LPTIM1 interrupt set-up before enabling */
/* no Compare match Interrupt */
LL_LPTIM_DisableIT_CMPM(LPTIM1);
LL_LPTIM_ClearFLAG_CMPM(LPTIM1);
#endif
/* Autoreload match Interrupt */
LL_LPTIM_EnableIT_ARRM(LPTIM1);
#ifdef CONFIG_SOC_SERIES_STM32U5X
while (LL_LPTIM_IsActiveFlag_DIEROK(LPTIM1) == 0) {
}
LL_LPTIM_ClearFlag_DIEROK(LPTIM1);
#endif
LL_LPTIM_ClearFLAG_ARRM(LPTIM1);
/* ARROK bit validates the write operation to ARR register */
LL_LPTIM_ClearFlag_ARROK(LPTIM1);
accumulated_lptim_cnt = 0;
#ifndef CONFIG_SOC_SERIES_STM32U5X
/* Enable the LPTIM1 counter */
LL_LPTIM_Enable(LPTIM1);
#endif
/* Set the Autoreload value once the timer is enabled */
if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
/* LPTIM1 is triggered on a LPTIM_TIMEBASE period */
LL_LPTIM_SetAutoReload(LPTIM1, LPTIM_TIMEBASE);
} else {
/* LPTIM1 is triggered on a Tick period */
LL_LPTIM_SetAutoReload(LPTIM1, COUNT_PER_TICK - 1);
}
/* Start the LPTIM counter in continuous mode */
LL_LPTIM_StartCounter(LPTIM1, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
#ifdef CONFIG_DEBUG
/* stop LPTIM1 during DEBUG */
#if defined(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP)
LL_DBGMCU_APB1_GRP1_FreezePeriph(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP);
#elif defined(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP)
LL_DBGMCU_APB3_GRP1_FreezePeriph(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP);
#endif
#endif
return 0;
}
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);